diff --git a/nomad/api/info.py b/nomad/api/info.py index 983636ebf31e8c085fb0b1c6eaaabe4e36360c8c..35cc9408e8ccd3140431e07be01bb011aec00e37 100644 --- a/nomad/api/info.py +++ b/nomad/api/info.py @@ -66,7 +66,7 @@ class InfoResource(Resource): 'normalizers': [normalizer.__name__ for normalizer in normalizing.normalizers], 'domain': { 'name': datamodel.Domain.instance.name, - 'quantities': datamodel.Domain.instance.quantities, + 'quantities': [quantity for quantity in datamodel.Domain.instance.quantities.values()], 'metrics_names': datamodel.Domain.instance.metrics_names, 'aggregations_names': datamodel.Domain.instance.aggregations_names }, diff --git a/nomad/datamodel/base.py b/nomad/datamodel/base.py index ad8ae4fc7a27409c3e1c366ca0a4bf8ef7c61734..dae862ecd283d1e4c4a49bc3b985e066436f83f1 100644 --- a/nomad/datamodel/base.py +++ b/nomad/datamodel/base.py @@ -225,7 +225,7 @@ class Domain: self.name = name self.domain_entry_class = domain_entry_class - self.quantities: List[DomainQuantity] = [] + self.quantities: Dict[str, DomainQuantity] = {} self.root_sections = root_sections reference_domain_calc = domain_entry_class() @@ -239,13 +239,13 @@ class Domain: quantities[quantity_name] = quantity quantity.name = quantity_name quantity.multi = isinstance(value, list) - self.quantities.append(quantity) + self.quantities[quantity.name] = quantity for quantity_name in quantities.keys(): assert hasattr(reference_domain_calc, quantity_name) and not hasattr(reference_general_calc, quantity_name), \ 'quantity does not exist or overrides general non domain quantity' - assert any(quantity.order_default for quantity in Domain.instances[name].quantities), \ + assert any(quantity.order_default for quantity in Domain.instances[name].quantities.values()), \ 'you need to define a order default quantity' @property @@ -255,7 +255,7 @@ class Domain: """ return { quantity.metric[0]: (quantity.metric[1], quantity.name) - for quantity in self.quantities + for quantity in self.quantities.values() if quantity.metric is not None } @@ -272,7 +272,7 @@ class Domain: """ return { quantity.name: quantity.aggregations - for quantity in self.quantities + for quantity in self.quantities.values() if quantity.aggregations > 0 } diff --git a/nomad/datamodel/dft.py b/nomad/datamodel/dft.py index 844bc62fb3556587c74c2a54daa17cb312b56d71..0a9c25b5916d4ca921e7776561fc72f76cb438bb 100644 --- a/nomad/datamodel/dft.py +++ b/nomad/datamodel/dft.py @@ -157,7 +157,7 @@ Domain('DFT', DFTCalcWithMetadata, quantities=dict( atoms=DomainQuantity( 'The atom labels of all atoms in the simulated system.', # aggregations=len(ase.data.chemical_symbols)), - aggregations=200), # quickfix for bad atom labels + aggregations=200, multi=True), # quickfix for bad atom labels basis_set=DomainQuantity( 'The used basis set functions.', aggregations=10), xc_functional=DomainQuantity( @@ -176,7 +176,7 @@ Domain('DFT', DFTCalcWithMetadata, quantities=dict( ), quantities=DomainQuantity( 'All quantities that are used by this calculation', - metric=('quantities', 'value_count') + metric=('quantities', 'value_count'), multi=True ), n_total_energies=DomainQuantity( 'Number of total energy calculations', diff --git a/nomad/search.py b/nomad/search.py index 2d0edc4c7ad32e325b2515854f4035ae7f65c1ef..9dd8aed5e7a08b911a401b7d26d0e138625b6af1 100644 --- a/nomad/search.py +++ b/nomad/search.py @@ -71,7 +71,7 @@ class Dataset(InnerDoc): class WithDomain(IndexMeta): """ Override elasticsearch_dsl metaclass to sneak in domain specific mappings """ def __new__(cls, name, bases, attrs): - for quantity in datamodel.Domain.instance.quantities: + for quantity in datamodel.Domain.instance.quantities.values(): attrs[quantity.name] = quantity.elastic_mapping return super(WithDomain, cls).__new__(cls, name, bases, attrs) @@ -143,8 +143,8 @@ class Entry(Document, metaclass=WithDomain): self.references = [ref.value for ref in source.references] self.datasets = [Dataset.from_dataset_popo(ds) for ds in source.datasets] - for quantity in datamodel.Domain.instance.quantities: - setattr(self, quantity.name, getattr(source, quantity.name)) + for quantity in datamodel.Domain.instance.quantities.keys(): + setattr(self, quantity, getattr(source, quantity)) def delete_upload(upload_id): @@ -196,7 +196,7 @@ The available search quantities in :func:`aggregate_search` as tuples with *sear elastic field and description. """ -for quantity in datamodel.Domain.instance.quantities: +for quantity in datamodel.Domain.instance.quantities.values(): search_spec = ('term', quantity.name, quantity.description) search_quantities[quantity.name] = search_spec @@ -218,7 +218,7 @@ metrics_names = list(metric for metric in metrics.keys()) order_default_quantity = None -for quantity in datamodel.Domain.instance.quantities: +for quantity in datamodel.Domain.instance.quantities.values(): if quantity.order_default: order_default_quantity = quantity.name @@ -243,8 +243,7 @@ def _construct_search(q: Q = None, time_range: Tuple[datetime, datetime] = None, values = [value] for item in values: - if key == 'atoms': - # TODO This should be configurable and not specific to atoms + if datamodel.Domain.instance.quantities[key].multi: items = item.split(',') else: items = [item]