Skip to content

Conversation

@apdavison
Copy link
Member

This is a proposal for how to include predefined metadata instances (e.g. controlled terms) in the Python library (cf #24). Usage example:

In [1]: from openminds.latest.controlled_terms import AgeCategory

In [2]: AgeCategory.adult
Out[2]: <openminds.latest.controlled_terms.age_category.AgeCategory at 0x104eb3970>

In [3]: AgeCategory.adult.id
Out[3]: 'https://openminds.ebrains.eu/instances/ageCategory/adult'

In [4]: AgeCategory.adult.definition
Out[4]: "'Adult' categorizes the life cycle stage of an animal or human that reached sexual maturity."

@apdavison apdavison added this to the 0.2.0 milestone Nov 28, 2023
@apdavison apdavison added the enhancement New feature or request label Nov 28, 2023
@ehennestad
Copy link

I don't quite understand from the jinja template whether all the instances will be embedded into the python class?

I had done something similar before in the openMINDS MATLAB package, but with suggestions from Lyuba ended up doing it differently.

This is the example of a schema definition for AgeCategory.
https://github.com/openMetadataInitiative/openMINDS_MATLAB/blob/main/code/schemas/latest/%2Bopenminds/%2Bcontrolledterms/AgeCategory.m#L1

As you can see, it has a hidden CONTROLLED_INSTANCES property, and this holds the name of all known instances of this schema. In the ControlledTerm superclass there is a case in the constructor to deserialise an json ld instance if the constructor is called with an input argument which matches one of the names in the CONTROLLED_INSTANCES property

Example:

adult = openminds.controlledterms.AgeCategory('adult')

adult = 

  AgeCategory (https://openminds.ebrains.eu/controlledTerms/AgeCategory) with properties:

                     definition: "''Adult'' categorizes the life cycle stage of an animal or human that reached sexual maturity."
                    description: ""
             interlexIdentifier: "http://uri.interlex.org/base/ilx_0729043"
             knowledgeSpaceLink: ""
                           name: "adult"
    preferredOntologyIdentifier: "http://purl.obolibrary.org/obo/UBERON_0000113"
                        synonym: ["adult stage"    "post-juvenile adult"    "post-juvenile adult stage"]

  Required Properties: name

>> adult.id

ans =

    'https://openminds.ebrains.eu/instances/ageCategory/adult'

@lzehl
Copy link
Member

lzehl commented Nov 28, 2023

@ehennestad I let Andrew respond but it is not loading all instances into the class only the one of the stated type (as it is done for MATLAB as well, more or less)

@apdavison apdavison force-pushed the instances-as-class-attributes branch from 8a730da to 962ce62 Compare November 28, 2023 15:45
@Peyman-N
Copy link
Member

Python name generated for 4-(2-Hydroxyethyl)-1-piperazineEthanesulfonicAcid is four_(2_hydroxyethyl)_1_piperazine_ethanesulfonic_acid which is not a valid python variable name.
6,7-Dinitro-1,4-dihydroquinoxaline-2,3-dione is converted to six,7_dinitro_1,4_dihydroquinoxaline_2,3_dione.

@ehennestad
Copy link

ehennestad commented Feb 27, 2024

Python name generated for 4-(2-Hydroxyethyl)-1-piperazineEthanesulfonicAcid is four_(2_hydroxyethyl)_1_piperazine_ethanesulfonic_acid which is not a valid python variable name.
6,7-Dinitro-1,4-dihydroquinoxaline-2,3-dione is converted to six,7_dinitro_1,4_dihydroquinoxaline_2,3_dione.

I also had this issue with a lot of instance names, as MATLAB is very strict about property names.

I ended up changing the constructor for controlled term classes to create the object from a controlled instance if the constructor input is a string which is recognised as a known controlled instance, for example:
openminds.controlledterms.MolecularEntity('4-(2-Hydroxyethyl)-1-piperazineEthanesulfonicAcid')

and it returns the instance:

ans = 

  MolecularEntity (https://openminds.ebrains.eu/controlledTerms/MolecularEntity) with properties:

                     definition: "HEPES (4-(2-hydroxyethyl)-1-piperazineethanesulfonic acid) is a zwitterionic sulfonic acid buffering agent; one of the twenty Good's buffers. [adapted from W  ikipedia (https://en.wikipedia.org/wiki/HEPES)]"
                    description: ""
             interlexIdentifier: "http://uri.interlex.org/base/ilx_0484759"
             knowledgeSpaceLink: "https://knowledge-space.org/wiki/CHEBI:42334#2-4-2-hydroxyethyl-piperazin-1-yl-ethanesulfonic-acid"
                           name: "4-(2-hydroxyethyl)-1-piperazine ethanesulfonic acid"
    preferredOntologyIdentifier: "http://purl.obolibrary.org/obo/CHEBI_42334"
                        synonym: ["HEPES"    "2-[4-(2-hydroxyethyl)piperazin-1-yl]ethane-1-sulfonic acid"]

  Required Properties: name

I think this is a better solution because you can keep using all the original names and don't have to worry about remapping them

* pipeline:
  fix typo in comment
  update support link
  Use plural attribute names where the property is an array
  Add "Development" section to README
  Ensure `pipeline` branch has the same README as `main`
  sort the preamble, to eliminate random changes from run to run
  Fix for #23
  regression test for #23

# Conflicts:
#	build.py
#	pipeline/translator.py
@apdavison
Copy link
Member Author

@ehennestad and @Peyman-N I've fixed the Python name generation, but I've also added a by_name() class method to controlled-terms classes, similar to the solution suggested by @ehennestad. This method also uses synonyms for lookups, e.g.:

In [1]: from openminds.latest.controlled_terms import MolecularEntity

In [2]: MolecularEntity.by_name("HEPES") == MolecularEntity.by_name("4-(2-hydroxyethyl)-1-piperazine ethanesulfonic acid")
Out[2]: True

@lzehl lzehl merged commit 5579fb3 into pipeline Mar 11, 2024
@lzehl lzehl deleted the instances-as-class-attributes branch March 11, 2024 06:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants