From 715a8085bf70962b6b12e7b49445161ff304550e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com> Date: Wed, 12 Mar 2025 09:12:35 +0100 Subject: [PATCH] FIX: in consistencies in csv treatment --- README.md | 15 ++++++++++++- .../sample-management-datamodel.yml | 2 +- .../src/ext/js/ext_samplemanagement.js | 5 ++++- .../bin/sample_helpers/default_constants.yml | 2 +- .../sample_upload_add_special_properties.py | 6 ++++++ .../sample_upload_column_definitions.py | 4 +++- .../sample_upload_get_person.py | 21 +++++++++++++------ 7 files changed, 44 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 724f519..71abb5a 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,19 @@ stored in LinkAhead You can create a filled CSV template with the information about Containers as it is currently stored in LinkAhead. +### Extensibility +The registration, update and export does not only work with RecordTypes and +Properties that are defined within this module, but the data model can be +extended by users of the system: Any Property that is added to the Sample +RecordType can also be used within the workflow. Once an additional Property +was added to the RecordType (say "width"), you can select a corresponding +column during registration with the same name and also upload CSV templates +that have this column. The Sample records will be created or updated to also +have this ("width") column. + +If the Property that is added is a RecordType, it must be kind of an enum, i.e. +it should be uniquely identified either by its name or by a sole property. + ## Usage **TODO**: Add explanations, screenshots, ec. to explain the sample @@ -132,7 +145,7 @@ allow to change those. This is the central RecordType for the sample management and used to represent samples of various types -#### `Parent_Sample` (`$parent_sample_prop`) +#### `Parent_sample` (`$parent_sample_prop`) references the sample from which the sample at hand originated (for example by cutting the parent sample into multiple pieces0 diff --git a/models_and_helper_scripts/sample-management-datamodel.yml b/models_and_helper_scripts/sample-management-datamodel.yml index 4d12dc6..aef3b68 100644 --- a/models_and_helper_scripts/sample-management-datamodel.yml +++ b/models_and_helper_scripts/sample-management-datamodel.yml @@ -83,7 +83,7 @@ Sample: recommended_properties: Container: SampleType: - Parent_Sample: + Parent_sample: datatype: Sample Main User: datatype: Person diff --git a/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_samplemanagement.js b/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_samplemanagement.js index ba4dcb4..e8e46e0 100644 --- a/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_samplemanagement.js +++ b/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_samplemanagement.js @@ -42,6 +42,7 @@ const ext_samplemanagement = function($, navbar, log, form_elements, form_panel, "Latitude start", "Longitude start", "Elevation start", + "Start date", "Storage ID", "Device" ]; @@ -73,8 +74,10 @@ const ext_samplemanagement = function($, navbar, log, form_elements, form_panel, const unused_property_names = [ "Main User", + "Event", + "Container", 'NagoyaCase', - "Parent_Sample", + "Parent_sample", ] const upload_sample_template_form_config = { diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/default_constants.yml b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/default_constants.yml index f752180..c575cb6 100644 --- a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/default_constants.yml +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/default_constants.yml @@ -68,7 +68,7 @@ entity_names: labelcounter_prop: counter labelcounter_rt: LabelCounter last_name_prop: last_name - parent_sample_prop: Parent_Sample + parent_sample_prop: Parent_sample responsible_rt: Responsible start_date_prop: start_date locality_description_prop: locality_description diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_add_special_properties.py b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_add_special_properties.py index 5c559d4..9ec2fff 100644 --- a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_add_special_properties.py +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_add_special_properties.py @@ -33,10 +33,16 @@ def add_special_properties(sample: db.Record, data: pd.Series) -> db.Record: """ main_user_prop = db.get_entity_by_name(get_entity_name("Main User")) + pi_prop = db.get_entity_by_name(get_entity_name("PI")) container_rt = db.get_entity_by_name(get_entity_name("container_rt")) device_rt = db.get_entity_by_name(get_entity_name("Device")) parent_sample_prop = db.get_entity_by_name(get_entity_name("parent_sample_prop")) + if (get_column_header_name("PI") in data and + return_value_if_not_none(data[get_column_header_name("PI")]) is not None): + pi_user = get_person(return_value_if_not_none(data[get_column_header_name("PI")])) + sample = update_property(sample, pi_prop.id, pi_user, property_name=pi_prop.name) + if (get_column_header_name("Main User") in data and return_value_if_not_none(data[get_column_header_name("Main User")]) is not None): main_user = get_person(return_value_if_not_none(data[get_column_header_name("Main User")])) diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_column_definitions.py b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_column_definitions.py index 5535863..0584522 100644 --- a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_column_definitions.py +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_column_definitions.py @@ -79,6 +79,7 @@ DATATYPE_DEFINITIONS = use_custom_names({ # Must exist OBLIGATORY_COLUMNS = use_custom_names([ "entity_id", + "Start date", ]) OBLIGATORY_COLUMNS_CHILD = use_custom_names([ @@ -114,6 +115,7 @@ SPECIAL_TREATMENT_SAMPLE = use_custom_names([ "Longitude start", "Longitude stop", "Main User", + "PI", "PDFReport", "parent_sample_prop", "Sphere", @@ -124,6 +126,6 @@ SPECIAL_TREATMENT_SAMPLE = use_custom_names([ IGNORED_COLUMN_NAMES_SAMPLE = use_custom_names([ "LinkAhead URL", - "Parent Sample", + "Parent_sample", "Storage chain", ]) diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_get_person.py b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_get_person.py index 1872f62..3e94780 100644 --- a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_get_person.py +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_get_person.py @@ -21,6 +21,7 @@ from caosadvancedtools.datainconsistency import DataInconsistencyError from .utils import get_entity_name +from linkahead.cached import cached_get_entity_by, cached_query as cquery def get_person(text: str) -> db.Record: """Return the Person Record that is specifed as 'Main User' or @@ -60,11 +61,19 @@ def _get_person_by_fullname(first_name: str, last_name: str) -> db.Record: return res[0] -def _get_person_by_id(eid: str) -> db.Record: - - try: - return db.get_entity_by_id(eid, role=get_entity_name("Person")) - except db.EmptyUniqueQueryError: +def _get_person_by_id(ident: str) -> db.Record: + options = cquery(f"FIND '{get_entity_name('Person')}' WITH ID='{ident}' ") + if len(options)==1: + return options[0] + options = cquery(f"FIND '{get_entity_name('Person')}' WITH " + f"'{get_entity_name('abbreviation_prop')}'='{ident}' ") + if len(options) == 1: + return options[0] + elif len(options) == 0: + raise DataInconsistencyError( + f"Could not find a {get_entity_name('Person')} with ID {ident}." + ) + else: raise DataInconsistencyError( - f"Could not find a {get_entity_name('Person')} with ID {eid}." + f"Found multiple {get_entity_name('Person')} with {get_entity_name('abbreviation_prop')}={ident}." ) -- GitLab