class ArkaneSpecies(RMGObject): """ A class for archiving an Arkane species including its statmech data into .yml files """ def __init__(self, species=None, conformer=None, author='', level_of_theory='', model_chemistry='', frequency_scale_factor=None, use_hindered_rotors=None, use_bond_corrections=None, atom_energies='', chemkin_thermo_string='', smiles=None, adjacency_list=None, inchi=None, inchi_key=None, xyz=None, molecular_weight=None, symmetry_number=None, transport_data=None, energy_transfer_model=None, thermo=None, thermo_data=None, label=None, datetime=None, RMG_version=None, reactants=None, products=None, reaction_label=None, is_ts=None): # reactants/products/reaction_label need to be in the init() to avoid error when loading a TS YAML file, # but we don't use them if species is None and conformer is None: # Expecting to get a species or a TS when generating the object within Arkane, # or a conformer when parsing from YAML. raise ValueError('No species (or TS) or conformer was passed to the ArkaneSpecies object') if conformer is not None: self.conformer = conformer if label is None and species is not None: self.label = species.label else: self.label = label self.author = author self.level_of_theory = level_of_theory self.model_chemistry = model_chemistry self.frequency_scale_factor = frequency_scale_factor self.use_hindered_rotors = use_hindered_rotors self.use_bond_corrections = use_bond_corrections self.atom_energies = atom_energies self.xyz = xyz self.molecular_weight = molecular_weight self.symmetry_number = symmetry_number self.is_ts = is_ts if is_ts is not None else isinstance(species, TransitionState) if not self.is_ts: self.chemkin_thermo_string = chemkin_thermo_string self.smiles = smiles self.adjacency_list = adjacency_list self.inchi = inchi self.inchi_key = inchi_key self.transport_data = transport_data self.energy_transfer_model = energy_transfer_model self.thermo = thermo self.thermo_data = thermo_data else: # initialize TS-related attributes self.imaginary_frequency = None self.reaction_label = '' self.reactants = list() self.products = list() if species is not None: self.update_species_attributes(species) self.RMG_version = RMG_version if RMG_version is not None else __version__ self.datetime = datetime if datetime is not None else time.strftime("%Y-%m-%d %H:%M") def __repr__(self): """ Return a string representation that can be used to reconstruct the object """ result = '{0!r}'.format(self.__class__.__name__) result += '{' for key, value in self.as_dict().iteritems(): if key != 'class': result += '{0!r}: {1!r}'.format(str(key), str(value)) result += '}' return result def update_species_attributes(self, species=None): """ Update the object with a new species/TS (while keeping non-species-dependent attributes unchanged) """ if species is None: raise ValueError('No species was passed to ArkaneSpecies') self.label = species.label if isinstance(species, TransitionState): self.imaginary_frequency = species.frequency if species.conformer is not None: self.conformer = species.conformer self.xyz = self.update_xyz_string() elif species.molecule is not None and len(species.molecule) > 0: self.smiles = species.molecule[0].toSMILES() self.adjacency_list = species.molecule[0].toAdjacencyList() try: inchi = toInChI(species.molecule[0], backend='try-all', aug_level=0) except ValueError: inchi = '' try: inchi_key = toInChIKey(species.molecule[0], backend='try-all', aug_level=0) except ValueError: inchi_key = '' self.inchi = inchi self.inchi_key = inchi_key if species.conformer is not None: self.conformer = species.conformer self.xyz = self.update_xyz_string() self.molecular_weight = species.molecularWeight if species.symmetryNumber != -1: self.symmetry_number = species.symmetryNumber if species.transportData is not None: self.transport_data = species.transportData # called `collisionModel` in Arkane if species.energyTransferModel is not None: self.energy_transfer_model = species.energyTransferModel if species.thermo is not None: self.thermo = species.thermo.as_dict() thermo_data = species.getThermoData() h298 = thermo_data.getEnthalpy(298) / 4184. s298 = thermo_data.getEntropy(298) / 4.184 cp = dict() for t in [300,400,500,600,800,1000,1500,2000,2400]: temp_str = '{0} K'.format(t) cp[temp_str] = '{0:.2f}'.format(thermo_data.getHeatCapacity(t) / 4.184) self.thermo_data = {'H298': '{0:.2f} kcal/mol'.format(h298), 'S298': '{0:.2f} cal/mol*K'.format(s298), 'Cp (cal/mol*K)': cp} def update_xyz_string(self): if self.conformer is not None and self.conformer.number is not None: # generate the xyz-format string from the Conformer coordinates xyz_string = '{0}\n{1}'.format(len(self.conformer.number.value_si), self.label) for i, coorlist in enumerate(self.conformer.coordinates.value_si): for element in elementList: if element.number == int(self.conformer.number.value_si[i]): element_symbol = element.symbol break else: raise ValueError('Could not find element symbol corresponding to atom number {0}'.format( self.conformer.number.value_si[i])) xyz_string += '\n{0} {1} {2} {3}'.format(element_symbol, coorlist[0], coorlist[1], coorlist[2]) else: xyz_string = '' return xyz_string def save_yaml(self, path): """ Save the species with all statMech data to a .yml file """ if not os.path.exists(os.path.join(os.path.abspath(path), 'species', '')): os.mkdir(os.path.join(os.path.abspath(path), 'species', '')) valid_chars = "-_.()<=>+ %s%s" % (string.ascii_letters, string.digits) filename = os.path.join('species', ''.join(c for c in self.label if c in valid_chars) + '.yml') full_path = os.path.join(path, filename) with open(full_path, 'w') as f: yaml.dump(data=self.as_dict(), stream=f) logging.debug('Dumping species {0} data as {1}'.format(self.label, filename)) def load_yaml(self, path, species, pdep=False): """ Load the all statMech data from the .yml file in `path` into `species` `pdep` is a boolean specifying whether or not jobList includes a pressureDependentJob. """ logging.info('Loading statistical mechanics parameters for {0} from .yml file...'.format(species.label)) with open(path, 'r') as f: data = yaml.safe_load(stream=f) try: if species.label != data['label']: logging.debug('Found different labels for species: {0} in input file, and {1} in the .yml file. ' 'Using the label "{0}" for this species.'.format(species.label, data['label'])) except KeyError: # Lacking label in the YAML file is strange, but accepted logging.debug('Did not find label for species {0} in .yml file.'.format(species.label)) try: class_name = data['class'] except KeyError: raise KeyError("Can only make objects if the `class` attribute in the dictionary is known") if class_name != 'ArkaneSpecies': raise KeyError("Expected a ArkaneSpecies object, but got {0}".format(class_name)) del data['class'] class_dict = {'ScalarQuantity': ScalarQuantity, 'ArrayQuantity': ArrayQuantity, 'Conformer': Conformer, 'LinearRotor': LinearRotor, 'NonlinearRotor': NonlinearRotor, 'KRotor': KRotor, 'SphericalTopRotor': SphericalTopRotor, 'HinderedRotor': HinderedRotor, 'FreeRotor': FreeRotor, 'IdealGasTranslation': IdealGasTranslation, 'HarmonicOscillator': HarmonicOscillator, 'TransportData': TransportData, 'SingleExponentialDown': SingleExponentialDown, 'Wilhoit': Wilhoit, 'NASA': NASA, } freq_data = None if 'imaginary_frequency' in data: freq_data = data['imaginary_frequency'] del data['imaginary_frequency'] self.make_object(data=data, class_dict=class_dict) if freq_data is not None: self.imaginary_frequency = ScalarQuantity() self.imaginary_frequency.make_object(data=freq_data, class_dict=dict()) self.adjacency_list = data['adjacency_list'] if 'adjacency_list' in data else None self.inchi = data['inchi'] if 'inchi' in data else None self.smiles = data['smiles'] if 'smiles' in data else None self.is_ts = data['is_ts'] if 'is_ts' in data else False if pdep and not self.is_ts and (self.transport_data is None or self.energy_transfer_model is None): raise ValueError('Transport data and an energy transfer model must be given if pressure-dependent ' 'calculations are requested. Check file {0}'.format(path)) if pdep and not self.is_ts and self.smiles is None and self.adjacency_list is None\ and self.inchi is None and self.molecular_weight is None: raise ValueError('The molecular weight was not specified, and a structure was not given so it could ' 'not be calculated. Specify either the molecular weight or structure if ' 'pressure-dependent calculations are requested. Check file {0}'.format(path)) logging.debug("Parsed all YAML objects")
class ArkaneSpecies(RMGObject): """ A class for archiving an Arkane species including its statmech data into .yml files """ def __init__(self, species=None, conformer=None, author='', level_of_theory='', model_chemistry='', frequency_scale_factor=None, use_hindered_rotors=None, use_bond_corrections=None, atom_energies='', chemkin_thermo_string='', smiles=None, adjacency_list=None, inchi=None, inchi_key=None, xyz=None, molecular_weight=None, symmetry_number=None, transport_data=None, energy_transfer_model=None, thermo=None, thermo_data=None, label=None, datetime=None, RMG_version=None, reactants=None, products=None, reaction_label=None, is_ts=None, charge=None, formula=None, multiplicity=None): # reactants/products/reaction_label need to be in the init() to avoid error when loading a TS YAML file, # but we don't use them super(ArkaneSpecies, self).__init__() if species is None and conformer is None: # Expecting to get a species or a TS when generating the object within Arkane, # or a conformer when parsing from YAML. raise ValueError( 'No species (or TS) or conformer was passed to the ArkaneSpecies object' ) if conformer is not None: self.conformer = conformer if label is None and species is not None: self.label = species.label else: self.label = label self.author = author self.level_of_theory = level_of_theory self.model_chemistry = model_chemistry self.frequency_scale_factor = frequency_scale_factor self.use_hindered_rotors = use_hindered_rotors self.use_bond_corrections = use_bond_corrections self.atom_energies = atom_energies self.xyz = xyz self.molecular_weight = molecular_weight self.symmetry_number = symmetry_number self.charge = charge self.multiplicity = multiplicity self.is_ts = is_ts if is_ts is not None else isinstance( species, TransitionState) if not self.is_ts: self.chemkin_thermo_string = chemkin_thermo_string self.smiles = smiles self.adjacency_list = adjacency_list self.inchi = inchi self.inchi_key = inchi_key self.transport_data = transport_data self.energy_transfer_model = energy_transfer_model self.thermo = thermo self.thermo_data = thermo_data self.formula = formula else: # initialize TS-related attributes self.imaginary_frequency = None self.reaction_label = '' self.reactants = list() self.products = list() if species is not None: self.update_species_attributes(species) self.RMG_version = RMG_version if RMG_version is not None else __version__ self.datetime = datetime if datetime is not None else time.strftime( "%Y-%m-%d %H:%M") def __repr__(self): """ Return a string representation that can be used to reconstruct the object """ result = '{0!r}'.format(self.__class__.__name__) result += '{' for key, value in self.as_dict().items(): if key != 'class': result += '{0!r}: {1!r}'.format(str(key), str(value)) result += '}' return result def update_species_attributes(self, species=None): """ Update the object with a new species/TS (while keeping non-species-dependent attributes unchanged) """ if species is None: raise ValueError('No species was passed to ArkaneSpecies') # Don't overwrite the label if it already exists self.label = self.label or species.label if isinstance(species, TransitionState): self.imaginary_frequency = species.frequency if species.conformer is not None: self.conformer = species.conformer self.xyz = self.update_xyz_string() elif species.molecule is not None and len(species.molecule) > 0: self.smiles = species.molecule[0].to_smiles() self.adjacency_list = species.molecule[0].to_adjacency_list() self.charge = species.molecule[0].get_net_charge() self.multiplicity = species.molecule[0].multiplicity self.formula = species.molecule[0].get_formula() try: inchi = to_inchi(species.molecule[0], backend='try-all', aug_level=0) except ValueError: inchi = '' try: inchi_key = to_inchi_key(species.molecule[0], backend='try-all', aug_level=0) except ValueError: inchi_key = '' self.inchi = inchi self.inchi_key = inchi_key if species.conformer is not None: self.conformer = species.conformer self.xyz = self.update_xyz_string() self.molecular_weight = species.molecular_weight if species.symmetry_number != -1: self.symmetry_number = species.symmetry_number if species.transport_data is not None: self.transport_data = species.transport_data # called `collisionModel` in Arkane if species.energy_transfer_model is not None: self.energy_transfer_model = species.energy_transfer_model if species.thermo is not None: self.thermo = species.thermo.as_dict() data = species.get_thermo_data() h298 = data.get_enthalpy(298) / 4184. s298 = data.get_entropy(298) / 4.184 temperatures = np.array( [300, 400, 500, 600, 800, 1000, 1500, 2000, 2400]) cp = [] for t in temperatures: cp.append(data.get_heat_capacity(t) / 4.184) self.thermo_data = ThermoData( H298=(h298, 'kcal/mol'), S298=(s298, 'cal/(mol*K)'), Tdata=(temperatures, 'K'), Cpdata=(cp, 'cal/(mol*K)'), ) def update_xyz_string(self): """ Generate an xyz string built from self.conformer, and standardize the result Returns: str: 3D coordinates in an XYZ format. """ xyz_list = list() if self.conformer is not None and self.conformer.number is not None: # generate the xyz-format string from self.conformer.coordinates and self.conformer.number xyz_list.append(str(len(self.conformer.number.value_si))) xyz_list.append(self.label) for number, coordinate in zip(self.conformer.number.value_si, self.conformer.coordinates.value_si): element_symbol = get_element(int(number)).symbol row = '{0:4}'.format(element_symbol) row += '{0:14.8f}{1:14.8f}{2:14.8f}'.format( *(coordinate * 1e10).tolist()) # convert m to Angstrom xyz_list.append(row) return '\n'.join(xyz_list) def save_yaml(self, path): """ Save the species with all statMech data to a .yml file """ if not os.path.exists( os.path.join(os.path.abspath(path), 'species', '')): os.mkdir(os.path.join(os.path.abspath(path), 'species', '')) valid_chars = "-_.()<=>+ %s%s" % (string.ascii_letters, string.digits) filename = os.path.join( 'species', ''.join(c for c in self.label if c in valid_chars) + '.yml') full_path = os.path.join(path, filename) with open(full_path, 'w') as f: yaml.dump(data=self.as_dict(), stream=f) logging.debug('Dumping species {0} data as {1}'.format( self.label, filename)) def load_yaml(self, path, label=None, pdep=False): """ Load the all statMech data from the .yml file in `path` into `species` `pdep` is a boolean specifying whether or not job_list includes a pressureDependentJob. """ yml_file = os.path.basename(path) if label: logging.info( 'Loading statistical mechanics parameters for {0} from {1} file...' .format(label, yml_file)) else: logging.info( 'Loading statistical mechanics parameters from {0} file...'. format(yml_file)) with open(path, 'r') as f: content = f.read() content = replace_yaml_syntax(content, label) data = yaml.safe_load(stream=content) if label: # First, warn the user if the label doesn't match try: if label != data['label']: logging.debug( 'Found different labels for species: {0} in input file, and {1} in the .yml file. ' 'Using the label "{0}" for this species.'.format( label, data['label'])) except KeyError: # Lacking label in the YAML file is strange, but accepted logging.debug( 'Did not find label for species {0} in .yml file.'.format( label)) # Then, set the ArkaneSpecies label to the user supplied label data['label'] = label try: class_name = data['class'] except KeyError: raise KeyError( "Can only make objects if the `class` attribute in the dictionary is known" ) if class_name != 'ArkaneSpecies': raise KeyError( "Expected a ArkaneSpecies object, but got {0}".format( class_name)) del data['class'] freq_data = None if 'imaginary_frequency' in data: freq_data = data['imaginary_frequency'] del data['imaginary_frequency'] if not data['is_ts']: if 'smiles' in data: data['species'] = Species(smiles=data['smiles']) elif 'adjacency_list' in data: data['species'] = Species().from_adjacency_list( data['adjacency_list']) elif 'inchi' in data: data['species'] = Species(inchi=data['inchi']) else: raise ValueError( 'Cannot load ArkaneSpecies from YAML file {0}. Either `smiles`, `adjacency_list`, or ' 'InChI must be specified'.format(path)) # Finally, set the species label so that the special attributes are updated properly data['species'].label = data['label'] self.make_object(data=data, class_dict=ARKANE_CLASS_DICT) if freq_data is not None: self.imaginary_frequency = ScalarQuantity() self.imaginary_frequency.make_object(data=freq_data, class_dict=ARKANE_CLASS_DICT) if pdep and not self.is_ts and self.smiles is None and self.adjacency_list is None \ and self.inchi is None and self.molecular_weight is None: raise ValueError( 'The molecular weight was not specified, and a structure was not given so it could ' 'not be calculated. Specify either the molecular weight or structure if ' 'pressure-dependent calculations are requested. Check file {0}' .format(path)) logging.debug("Parsed all YAML objects")
class ArkaneSpecies(RMGObject): """ A class for archiving an Arkane species including its statmech data into .yml files """ def __init__(self, species=None, conformer=None, author='', level_of_theory='', model_chemistry='', frequency_scale_factor=None, use_hindered_rotors=None, use_bond_corrections=None, atom_energies='', chemkin_thermo_string='', smiles=None, adjacency_list=None, inchi=None, inchi_key=None, xyz=None, molecular_weight=None, symmetry_number=None, transport_data=None, energy_transfer_model=None, thermo=None, thermo_data=None, label=None, datetime=None, RMG_version=None, reactants=None, products=None, reaction_label=None, is_ts=None): # reactants/products/reaction_label need to be in the init() to avoid error when loading a TS YAML file, # but we don't use them if species is None and conformer is None: # Expecting to get a species or a TS when generating the object within Arkane, # or a conformer when parsing from YAML. raise ValueError( 'No species (or TS) or conformer was passed to the ArkaneSpecies object' ) if conformer is not None: self.conformer = conformer if label is None and species is not None: self.label = species.label else: self.label = label self.author = author self.level_of_theory = level_of_theory self.model_chemistry = model_chemistry self.frequency_scale_factor = frequency_scale_factor self.use_hindered_rotors = use_hindered_rotors self.use_bond_corrections = use_bond_corrections self.atom_energies = atom_energies self.xyz = xyz self.molecular_weight = molecular_weight self.symmetry_number = symmetry_number self.is_ts = is_ts if is_ts is not None else isinstance( species, TransitionState) if not self.is_ts: self.chemkin_thermo_string = chemkin_thermo_string self.smiles = smiles self.adjacency_list = adjacency_list self.inchi = inchi self.inchi_key = inchi_key self.transport_data = transport_data self.energy_transfer_model = energy_transfer_model self.thermo = thermo self.thermo_data = thermo_data else: # initialize TS-related attributes self.imaginary_frequency = None self.reaction_label = '' self.reactants = list() self.products = list() if species is not None: self.update_species_attributes(species) self.RMG_version = RMG_version if RMG_version is not None else __version__ self.datetime = datetime if datetime is not None else time.strftime( "%Y-%m-%d %H:%M") def __repr__(self): """ Return a string representation that can be used to reconstruct the object """ result = '{0!r}'.format(self.__class__.__name__) result += '{' for key, value in self.as_dict().iteritems(): if key != 'class': result += '{0!r}: {1!r}'.format(str(key), str(value)) result += '}' return result def update_species_attributes(self, species=None): """ Update the object with a new species/TS (while keeping non-species-dependent attributes unchanged) """ if species is None: raise ValueError('No species was passed to ArkaneSpecies') self.label = species.label if isinstance(species, TransitionState): self.imaginary_frequency = species.frequency if species.conformer is not None: self.conformer = species.conformer self.xyz = self.update_xyz_string() elif species.molecule is not None and len(species.molecule) > 0: self.smiles = species.molecule[0].toSMILES() self.adjacency_list = species.molecule[0].toAdjacencyList() try: inchi = toInChI(species.molecule[0], backend='try-all', aug_level=0) except ValueError: inchi = '' try: inchi_key = toInChIKey(species.molecule[0], backend='try-all', aug_level=0) except ValueError: inchi_key = '' self.inchi = inchi self.inchi_key = inchi_key if species.conformer is not None: self.conformer = species.conformer self.xyz = self.update_xyz_string() self.molecular_weight = species.molecularWeight if species.symmetryNumber != -1: self.symmetry_number = species.symmetryNumber if species.transportData is not None: self.transport_data = species.transportData # called `collisionModel` in Arkane if species.energyTransferModel is not None: self.energy_transfer_model = species.energyTransferModel if species.thermo is not None: self.thermo = species.thermo.as_dict() thermo_data = species.getThermoData() h298 = thermo_data.getEnthalpy(298) / 4184. s298 = thermo_data.getEntropy(298) / 4.184 cp = dict() for t in [300, 400, 500, 600, 800, 1000, 1500, 2000, 2400]: temp_str = '{0} K'.format(t) cp[temp_str] = '{0:.2f}'.format( thermo_data.getHeatCapacity(t) / 4.184) self.thermo_data = { 'H298': '{0:.2f} kcal/mol'.format(h298), 'S298': '{0:.2f} cal/mol*K'.format(s298), 'Cp (cal/mol*K)': cp } def update_xyz_string(self): if self.conformer is not None and self.conformer.number is not None: # generate the xyz-format string from the Conformer coordinates xyz_string = '{0}\n{1}'.format(len(self.conformer.number.value_si), self.label) for i, coorlist in enumerate(self.conformer.coordinates.value_si): for element in elementList: if element.number == int( self.conformer.number.value_si[i]): element_symbol = element.symbol break else: raise ValueError( 'Could not find element symbol corresponding to atom number {0}' .format(self.conformer.number.value_si[i])) xyz_string += '\n{0} {1} {2} {3}'.format( element_symbol, coorlist[0], coorlist[1], coorlist[2]) else: xyz_string = '' return xyz_string def save_yaml(self, path): """ Save the species with all statMech data to a .yml file """ if not os.path.exists( os.path.join(os.path.abspath(path), 'species', '')): os.mkdir(os.path.join(os.path.abspath(path), 'species', '')) valid_chars = "-_.()<=>+ %s%s" % (string.ascii_letters, string.digits) filename = os.path.join( 'species', ''.join(c for c in self.label if c in valid_chars) + '.yml') full_path = os.path.join(path, filename) with open(full_path, 'w') as f: yaml.dump(data=self.as_dict(), stream=f) logging.debug('Dumping species {0} data as {1}'.format( self.label, filename)) def load_yaml(self, path, species, pdep=False): """ Load the all statMech data from the .yml file in `path` into `species` `pdep` is a boolean specifying whether or not jobList includes a pressureDependentJob. """ logging.info( 'Loading statistical mechanics parameters for {0} from .yml file...' .format(species.label)) with open(path, 'r') as f: data = yaml.safe_load(stream=f) try: if species.label != data['label']: logging.debug( 'Found different labels for species: {0} in input file, and {1} in the .yml file. ' 'Using the label "{0}" for this species.'.format( species.label, data['label'])) except KeyError: # Lacking label in the YAML file is strange, but accepted logging.debug( 'Did not find label for species {0} in .yml file.'.format( species.label)) try: class_name = data['class'] except KeyError: raise KeyError( "Can only make objects if the `class` attribute in the dictionary is known" ) if class_name != 'ArkaneSpecies': raise KeyError( "Expected a ArkaneSpecies object, but got {0}".format( class_name)) del data['class'] class_dict = { 'ScalarQuantity': ScalarQuantity, 'ArrayQuantity': ArrayQuantity, 'Conformer': Conformer, 'LinearRotor': LinearRotor, 'NonlinearRotor': NonlinearRotor, 'KRotor': KRotor, 'SphericalTopRotor': SphericalTopRotor, 'HinderedRotor': HinderedRotor, 'FreeRotor': FreeRotor, 'IdealGasTranslation': IdealGasTranslation, 'HarmonicOscillator': HarmonicOscillator, 'TransportData': TransportData, 'SingleExponentialDown': SingleExponentialDown, 'Wilhoit': Wilhoit, 'NASA': NASA, } freq_data = None if 'imaginary_frequency' in data: freq_data = data['imaginary_frequency'] del data['imaginary_frequency'] self.make_object(data=data, class_dict=class_dict) if freq_data is not None: self.imaginary_frequency = ScalarQuantity() self.imaginary_frequency.make_object(data=freq_data, class_dict=dict()) self.adjacency_list = data[ 'adjacency_list'] if 'adjacency_list' in data else None self.inchi = data['inchi'] if 'inchi' in data else None self.smiles = data['smiles'] if 'smiles' in data else None self.is_ts = data['is_ts'] if 'is_ts' in data else False if pdep and not self.is_ts and (self.transport_data is None or self.energy_transfer_model is None): raise ValueError( 'Transport data and an energy transfer model must be given if pressure-dependent ' 'calculations are requested. Check file {0}'.format(path)) if pdep and not self.is_ts and self.smiles is None and self.adjacency_list is None\ and self.inchi is None and self.molecular_weight is None: raise ValueError( 'The molecular weight was not specified, and a structure was not given so it could ' 'not be calculated. Specify either the molecular weight or structure if ' 'pressure-dependent calculations are requested. Check file {0}' .format(path)) logging.debug("Parsed all YAML objects")