def build_tip3p_smirnoff_force_field(): """Combines the smirnoff99Frosst and tip3p offxml files into a single one which can be consumed by the property estimator. Returns ------- SmirnoffForceFieldSource The force field containing both smirnoff99Frosst-1.1.0 and TIP3P parameters """ from openforcefield.typing.engines.smirnoff import ForceField smirnoff_force_field_path = 'smirnoff99Frosst-1.1.0.offxml' tip3p_force_field_path = get_data_filename('forcefield/tip3p.offxml') smirnoff_force_field_with_tip3p = ForceField(smirnoff_force_field_path, tip3p_force_field_path) return SmirnoffForceFieldSource.from_object( smirnoff_force_field_with_tip3p)
def request_estimate(self, property_set, force_field_source, options=None, parameter_gradient_keys=None): """Requests that a PropertyEstimatorServer attempt to estimate the provided property set using the supplied force field and estimator options. Parameters ---------- property_set : PhysicalPropertyDataSet The set of properties to attempt to estimate. force_field_source : ForceFieldSource or openforcefield.typing.engines.smirnoff.ForceField The source of the force field parameters to use for the calculations. options : PropertyEstimatorOptions, optional A set of estimator options. If None, default options will be used. parameter_gradient_keys: list of ParameterGradientKey, optional A list of references to all of the parameters which all observables should be differentiated with respect to. Returns ------- PropertyEstimatorClient.Request An object which will provide access the the results of the request. """ from openforcefield.typing.engines import smirnoff if property_set is None or force_field_source is None: raise ValueError('Both a data set and force field source must be ' 'present to compute physical properties.') if options is None: options = PropertyEstimatorOptions() if isinstance(force_field_source, smirnoff.ForceField): force_field_source = SmirnoffForceFieldSource.from_object( force_field_source) if len(options.allowed_calculation_layers) == 0: raise ValueError( 'A submission contains no allowed calculation layers.') properties_list = [] property_types = set() # Refactor the properties into a list, and extract the types # of properties to be estimated (e.g 'Denisty', 'DielectricConstant'). for substance_tag in property_set.properties: for physical_property in property_set.properties[substance_tag]: properties_list.append(physical_property) type_name = type(physical_property).__name__ if type_name not in registered_properties: raise ValueError( f'The property estimator does not support {type_name} properties.' ) if type_name in property_types: continue property_types.add(type_name) if options.workflow_options is None: options.workflow_options = {} # Assign default workflows in the cases where the user hasn't # provided one, and validate all of the workflows to be used # in the estimation. for type_name in property_types: if type_name not in options.workflow_schemas: options.workflow_schemas[type_name] = {} if type_name not in options.workflow_options: options.workflow_options[type_name] = {} for calculation_layer in options.allowed_calculation_layers: property_type = registered_properties[type_name]() if (calculation_layer not in options.workflow_options[type_name] or options.workflow_options[type_name][calculation_layer] is None): options.workflow_options[type_name][ calculation_layer] = WorkflowOptions() if (calculation_layer not in options.workflow_schemas[type_name] or options.workflow_schemas[type_name][calculation_layer] is None): default_schema = property_type.get_default_workflow_schema( calculation_layer, options.workflow_options[type_name][calculation_layer]) options.workflow_schemas[type_name][ calculation_layer] = default_schema workflow = options.workflow_schemas[type_name][ calculation_layer] if workflow is None: # Not all properties may support every calculation layer. continue # Handle the cases where some protocol types should be replaced with # others. workflow.replace_protocol_types( options.workflow_options[type_name] [calculation_layer].protocol_replacements) # Will raise the correct exception for non-valid interfaces. workflow.validate_interfaces() # Enforce the global option of whether to allow merging or not. for protocol_schema_name in workflow.protocols: protocol_schema = workflow.protocols[protocol_schema_name] if not options.allow_protocol_merging: protocol_schema.inputs['.allow_merging'] = False submission = PropertyEstimatorSubmission( properties=properties_list, force_field_source=force_field_source, options=options, parameter_gradient_keys=parameter_gradient_keys) request_id = IOLoop.current().run_sync( lambda: self._send_calculations_to_server(submission)) request_object = PropertyEstimatorClient.Request( request_id, self._connection_options, self) return request_object