def test_model_add_remove(self): """ Tests the outcome of adding and removing a model from the canonical graph. """ symbols = GraphTest.generate_canonical_symbols() models = GraphTest.generate_canonical_models() g = Graph(models=models, symbol_types=symbols, composite_models=dict()) g.remove_models({models['model6'].name: models['model6']}) self.assertTrue(models['model6'] not in g.get_models().values(), "Model was unsuccessfully removed from the graph.") for s in g._input_to_model.values(): self.assertTrue(models['model6'] not in s, "Model was unsuccessfully removed from the graph.") for s in g._output_to_model.values(): self.assertTrue(models['model6'] not in s, "Model was unsuccessfully removed from the graph.") m6 = models['model6'] del models['model6'] for m in models.values(): self.assertTrue(m in g.get_models().values(), "Too many models were removed.") g.update_models({'Model6': m6}) self.assertTrue(m6 in g.get_models().values(), "Model was unsuccessfully added to the graph.") self.assertTrue(m6 in g._input_to_model[symbols['D']], "Model was unsuccessfully added to the graph.") self.assertTrue(m6 in g._input_to_model[symbols['F']], "Model was unsuccessfully added to the graph.") self.assertTrue(m6 in g._output_to_model[symbols['A']], "Model was unsuccessfully added to the graph.")
def process_item(self, item): # Define quantities corresponding to materials doc fields # Attach quantities to materials item = MontyDecoder().process_decoded(item) logger.info("Populating material for %s", item['task_id']) material = Material() for mkey, property_name in self.materials_symbol_map.items(): value = get(item, mkey) if value: material.add_quantity(Quantity(property_name, value)) # Add custom things, e. g. computed entry computed_entry = get_entry(item) material.add_quantity(Quantity("computed_entry", computed_entry)) material.add_quantity( Quantity("external_identifier_mp", item['task_id'])) input_quantities = material.get_quantities() # Use graph to generate expanded quantity pool logger.info("Evaluating graph for %s", item['task_id']) graph = Graph() graph.remove_models({ "dimensionality_cheon": DEFAULT_MODEL_DICT['dimensionality_cheon'], "dimensionality_gorai": DEFAULT_MODEL_DICT['dimensionality_gorai'] }) new_material = graph.evaluate(material) # Format document and return logger.info("Creating doc for %s", item['task_id']) doc = {"inputs": [quantity.as_dict() for quantity in input_quantities]} for symbol, quantity in new_material.get_aggregated_quantities().items( ): all_qs = new_material._symbol_to_quantity[symbol] # Only add new quantities if len(all_qs) == 1 and list(all_qs)[0] in input_quantities: continue qs = [quantity.as_dict() for quantity in all_qs] sub_doc = { "quantities": qs, "mean": unumpy.nominal_values(quantity.value).tolist(), "std_dev": unumpy.std_devs(quantity.value).tolist(), "units": qs[0]['units'], "title": quantity._symbol_type.display_names[0] } doc[symbol.name] = sub_doc doc.update({ "task_id": item["task_id"], "pretty_formula": item["pretty_formula"] }) return jsanitize(doc, strict=True)
def process_item(self, item): # Define quantities corresponding to materials doc fields # Attach quantities to materials item = MontyDecoder().process_decoded(item) logger.info("Populating material for %s", item['task_id']) material = Material() if 'created_at' in item.keys(): date_created = item['created_at'] else: date_created = "" provenance = ProvenanceElement( source={ "source": self.source_name, "source_key": item['task_id'], "date_created": date_created }) for mkey, property_name in self.materials_symbol_map.items(): value = get(item, mkey) if value: material.add_quantity( QuantityFactory.create_quantity(property_name, value, provenance=provenance)) # Add custom things, e. g. computed entry computed_entry = get_entry(item) material.add_quantity( QuantityFactory.create_quantity("computed_entry", computed_entry, provenance=provenance)) material.add_quantity( QuantityFactory.create_quantity("external_identifier_mp", item['task_id'], provenance=provenance)) input_quantities = material.get_quantities() # Use graph to generate expanded quantity pool logger.info("Evaluating graph for %s", item['task_id']) graph = Graph() graph.remove_models({ "dimensionality_cheon": DEFAULT_MODEL_DICT['dimensionality_cheon'], "dimensionality_gorai": DEFAULT_MODEL_DICT['dimensionality_gorai'] }) new_material = graph.evaluate(material) # Format document and return logger.info("Creating doc for %s", item['task_id']) # Gives the initial inputs that were used to derive properties of a # certain material. doc = { "inputs": [StorageQuantity.from_quantity(q) for q in input_quantities] } for symbol, quantity in new_material.get_aggregated_quantities().items( ): all_qs = new_material._symbol_to_quantity[symbol] # Only add new quantities # TODO: Condition insufficiently general. # Can end up with initial quantities added as "new quantities" if len(all_qs) == 1 and list(all_qs)[0] in input_quantities: continue # Write out all quantities as dicts including the # internal ID for provenance tracing qs = [StorageQuantity.from_quantity(q).as_dict() for q in all_qs] # THE listing of all Quantities of a given symbol. sub_doc = { "quantities": qs, "mean": unumpy.nominal_values(quantity.value).tolist(), "std_dev": unumpy.std_devs(quantity.value).tolist(), "units": quantity.units.format_babel() if quantity.units else None, "title": quantity._symbol_type.display_names[0] } # Symbol Name -> Sub_Document, listing all Quantities of that type. doc[symbol.name] = sub_doc doc.update({ "task_id": item["task_id"], "pretty_formula": item["pretty_formula"] }) return jsanitize(doc, strict=True)