-
Notifications
You must be signed in to change notification settings - Fork 0
Morphology model #282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Morphology model #282
Conversation
app/db/model.py
Outdated
pipeline_state: Mapped[PipelineType | None] = mapped_column( | ||
Enum(PipelineType, name="pipeline_type"), nullable=True | ||
) | ||
is_related_to: Mapped[list[uuid.UUID] | None] = mapped_column( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a relationship, not an array of ids because there will be no referential integrity if these ids are deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, perhaps this could be handled through the is_derived_from source and target table we discussed previously, in which case the is_related_field could be removed. But even if that is done, deletion of an id means that it would still need to be removed from the relationship table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure I understand. I read the document but I don't know what the relationship is . Is it a derivation ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdcourcol this was preserved from the current implementation (we discussed in one of the first meetings). In my understanding it is the relationship of raw morphology - linked to a repaired - linked to a clone etc.
app/schemas/morphology.py
Outdated
Whether data has been corrected for shrinkage | ||
""" | ||
|
||
protocol_design: str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be constrained with a StrEnum
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lidakanari what items should be in the protocol_design StrEnum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the protocol design is added when we have a respective document for this. We only have a full protocol document for LNMC, and the rest are from papers. There was a list shared with @jdcourcol last year, but I'm not sure what is best to do here, should we register protocols, link to existing papers?
app/db/model.py
Outdated
class ComputationallySynthesizedMorphologyMethod(MorphologyProtocol): | ||
__tablename__ = "computationally_synthesized_morphology_protocol" | ||
id: Mapped[uuid.UUID] = mapped_column(ForeignKey("morphology_protocol.id"), primary_key=True) | ||
method: Mapped[str] # This 'method' might need further typing based on your vocabulary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not "name" ? and why not a property on the base "MorphologyProtocol" class ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that this is particular to the SynthesizedMorphology class. But perhaps it could be changed to name, if @lidakanari thinks it is okay.
app/db/model.py
Outdated
class ModifiedMorphologyMethod(MorphologyProtocol): | ||
__tablename__ = "modified_morphology_protocol" | ||
id: Mapped[uuid.UUID] = mapped_column(ForeignKey("morphology_protocol.id"), primary_key=True) | ||
method: Mapped[MethodsType] # Assuming MethodsType is an Enum or similar |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
above it is a string. Here is it a enum ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is polymorphic because the methods can vary considerably.
__tablename__ = "morphology_protocol" | ||
protocol_document: Mapped[str | None] | ||
protocol_design: Mapped[str] | ||
type: Mapped[str] # Discriminator column for polymorphism |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need that ? @GianlucaFicarelli ?
|
||
class MorphologyProtocol(Identifiable): # Inherit from Identifiable for primary key and timestamps | ||
__tablename__ = "morphology_protocol" | ||
protocol_document: Mapped[str | None] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what that is ? a URL ? a DOI ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is the url pointing to the protocol document. But perhaps we should upload the document into the system and have this point to it? What do you think?
class MorphologyProtocol(Identifiable): # Inherit from Identifiable for primary key and timestamps | ||
__tablename__ = "morphology_protocol" | ||
protocol_document: Mapped[str | None] | ||
protocol_design: Mapped[str] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here ?
ForeignKey("morphology_protocol.id"), nullable=True, index=True | ||
) | ||
# Relationship to the polymorphic MorphologyProtocol | ||
morphology_protocol: Mapped["MorphologyProtocol"] = relationship( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that the morphology protocol carries information about the generation_type, do we really need it as a separate column?
If we need to filter by generation_type for instance we could introduce a nested filter of the form morphology_protocol__type="experimental"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eleftherioszisis are you proposing to remove the generation type and just use morphology protocol ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only issue I can see with that is that placeholder might not have a protocol.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But perhaps it would just be empty in the case of placeholder. Okay, I will remove generation type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eleftherioszisis please have a look and see if you agree if the way this is now done. I've also changed the schema to remove generation type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Let me clean and get the PR in shape first.
Co-authored-by: Eleftherios Zisis <[email protected]>
This branch includes a minimal set of commits to illustrate the data model, and is branched off of a more recent main. The primary files affected are: model.py, types.py, and morphology.py (although this is intended just to give context to the data model). "ReconstructionCellMorphology" is changed to "CellMorphology" because now the reconstruction morphologies are a subtype of cell morphology. Because the different sub-clases of morphology were not made programmatic subclasses of cell morphology for the sake of maintaining compatibility with how this structure is processed, the extra data needed for the subclasses is in the "extended_data" field. A text description of all the different morphology components is in: https://openbraininstitute.sharepoint.com/:w:/r/sites/OBI-Scientificstaff/_layouts/15/Doc.aspx?sourcedoc=%7BEEE86C08-A09D-469E-9849-CD85599E4026%7D&file=General_schema.docx&action=default&mobileredirect=true&DefaultItemOpen=1