From a427ca3fc94733322a7acf39b22bcc7bdb6ac64f Mon Sep 17 00:00:00 2001 From: Markus Scheidgen <markus.scheidgen@gmail.com> Date: Tue, 23 Apr 2019 12:21:02 +0200 Subject: [PATCH] Fixed bug with searching multi quantities (atoms, quantities). --- nomad/api/info.py | 2 +- nomad/datamodel/base.py | 10 +++++----- nomad/datamodel/dft.py | 4 ++-- nomad/search.py | 13 ++++++------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/nomad/api/info.py b/nomad/api/info.py index 983636ebf3..35cc9408e8 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 ad8ae4fc7a..dae862ecd2 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 844bc62fb3..0a9c25b591 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 2d0edc4c7a..9dd8aed5e7 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] -- GitLab