Skip to content

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

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open

Morphology model #282

wants to merge 21 commits into from

Conversation

dkeller9
Copy link
Contributor

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

@dkeller9 dkeller9 requested a review from jdcourcol July 14, 2025 05:49
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(
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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 ?

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.

Whether data has been corrected for shrinkage
"""

protocol_design: str
Copy link
Contributor

@eleftherioszisis eleftherioszisis Jul 14, 2025

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

Copy link
Contributor Author

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?

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
Copy link
Contributor

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 ?

Copy link
Contributor Author

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
Copy link
Contributor

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 ?

Copy link
Contributor Author

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
Copy link
Contributor

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]
Copy link
Contributor

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 ?

Copy link
Contributor Author

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]
Copy link
Contributor

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(
Copy link
Contributor

@eleftherioszisis eleftherioszisis Jul 28, 2025

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"

Copy link
Contributor Author

@dkeller9 dkeller9 Jul 28, 2025

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 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants