def test_deserializer_error(): """ Test deserialize a missing file. """ with pytest.raises(RuntimeError): deserialize("missing_file.json")
def test_serializer_round_trips(serializer): """ Test serializing data to and from file with no compression. """ # get data in a dict format data = deserialize(get_data("settings_with_workflow.json")) file_name = "settings_with_workflow" + serializer # now export to file and back with temp_directory(): serialize(serializable=data, file_name=file_name, compression=None) deserialized_data = deserialize(file_name=file_name) assert data == deserialized_data
def test_compression_serialization_round_trip_file_name( serialization, compression): """ Test all of the different serialization and compression combinations. Here the compression is in the file name. """ # get data in a dict format data = deserialize(get_data("settings_with_workflow.json")) file_name = "".join( ["settings_with_workflow", ".", serialization, ".", compression]) # now export the file and read back with temp_directory(): serialize(serializable=data, file_name=file_name, compression=None) deserialized_data = deserialize(file_name=file_name) assert data == deserialized_data
def import_workflow(self, workflow: Union[str, Dict], clear_existing: bool = True) -> None: """ Instance the workflow from a workflow object or from an input file. Args: workflow: The name of the file the workflow should be created from or a workflow dictionary. clear_existing: If the current workflow should be deleted and replaced or extended. """ if clear_existing: self.clear_workflow() if isinstance(workflow, str): workflow = deserialize(workflow) if isinstance(workflow, dict): # this should be a workflow dict that we can just load # if this is from the settings file make sure to unpack the dict first. workflow = workflow.get("workflow", workflow) # load in the workflow for value in workflow.values(): # check if this is not the first instance of the component component = get_component(value["type"]) self.add_workflow_components(component.parse_obj(value))
def parse_file( cls, path, *, content_type: str = None, encoding: str = "utf8", proto=None, allow_pickle: bool = False, ) -> "WorkflowFactory": """ Here we overwrite the parse function to work with json and yaml and to unpack the workflow. """ data = deserialize(file_name=path) optimizer = data.pop("optimizer") fragmentation_engine = data.pop("fragmentation_engine") if fragmentation_engine is not None: fragmenter = get_fragmentation_engine(**fragmentation_engine) else: fragmenter = None workflow = cls.parse_obj(data) # set the fragmentation engine workflow.fragmentation_engine = fragmenter # now we need to re init the optimizer and the targets opt_targets = optimizer.pop("optimization_targets") opt_engine = get_optimizer(**optimizer) opt_engine.clear_optimization_targets() for target in opt_targets: opt_engine.set_optimization_target(target=target["name"], **target) workflow.optimizer = opt_engine return workflow
def load_dataset(data: Union[str, Dict]) -> "BasicDataset": """ Create a new instance dataset from the file or dict of the dataset. This removes the need of knowing what the dataset type is. Parameters: data: The file path or dict of the dataset from which we should load the data. Raises: DatasetRegisterError: If no registered dataset can load the given dataset type. Returns: An instance of the correct dataset loaded with the data. """ if isinstance(data, str): # load the file raw_data = deserialize(data) else: raw_data = data dataset_type = registered_datasets.get(raw_data["dataset_type"].lower(), None) if dataset_type is not None: return dataset_type(**raw_data) else: raise DatasetRegisterError( f"No registered dataset can load the type {dataset_type}.")
def test_torsionprofile_metadata(): """ Make sure that when using the torsionprofile target we make the metatdat.json file. """ from openff.qcsubmit.serializers import deserialize torsion_target = TorsionProfile_SMIRNOFF() target_schema = biphenyl_target(target=torsion_target) # now load in a scan result we have saved result_data = TorsionDriveCollectionResult.parse_file( get_data("biphenyl.json.xz")) # now try and update the results target_schema.update_with_results(results=result_data) assert target_schema.ready_for_fitting is True # now try and prep for fitting with temp_directory(): torsion_target.prep_for_fitting(fitting_target=target_schema) # we should only have one torsion drive to do here folders = os.listdir(".") assert len(folders) == 1 target_files = os.listdir(folders[0]) assert "molecule.pdb" in target_files assert "scan.xyz" in target_files assert "molecule.mol2" in target_files assert "qdata.txt" in target_files assert "metadata.json" in target_files metadata = deserialize( file_name=os.path.join(folders[0], "metadata.json")) # now make sure the json is complete entry = target_schema.tasks[0] assert entry.dihedrals[0] == tuple(metadata["dihedrals"][0]) for data in entry.reference_data(): assert data.extras["dihedral_angle"] in metadata[ "torsion_grid_ids"]
def parse_file( cls: Type["Model"], path: Union[str, Path], *, content_type: str = None, encoding: str = "utf8", proto: Protocol = None, allow_pickle: bool = False, ) -> "Model": data = deserialize(file_name=path) return cls(**data)
def check_functional_groups(cls, functional_group): """ Check the functional groups which can be passed as a file name or as a dictionary are valid. Note: This check could be quite fragile. """ if functional_group is None or functional_group is False: return functional_group elif isinstance(functional_group, str): fgroups = deserialize(functional_group) # simple check on the smarts for smarts in fgroups.values(): if "[" not in smarts: raise ValueError( f"Some functional group smarts were not valid {smarts}." ) return functional_group
def import_settings(self, settings: Union[str, Dict], clear_workflow: bool = True) -> None: """ Import settings and workflow from a file. Args: settings: The name of the file the settings should be extracted from or the reference to a settings dictionary. clear_workflow: If the current workflow should be extended or replaced. """ if isinstance(settings, str): data = deserialize(settings) # take the workflow out and import the settings workflow = data.pop("workflow") elif isinstance(settings, dict): workflow = settings.pop("workflow") data = settings else: raise RuntimeError( "The input type could not be converted into a settings dictionary." ) # now set the factory meta settings for key, value in data.items(): if hasattr(self, key): setattr(self, key, value) else: continue # now we want to add the workflow back in self.import_workflow(workflow=workflow, clear_existing=clear_workflow)
def _load_submittable(self): from openff.qcsubmit.serializers import deserialize spec = deserialize(self.submittable) return spec
def from_file(cls, file_name: str): """Create a factory from the serialised model file.""" data = deserialize(file_name=file_name) return cls(**data)
def get_data(file_name): """ Return the deserialized dataset file. """ return deserialize(file_name=file_name)