Skip to content

Conversation

AurelienJaquier
Copy link
Contributor

@AurelienJaquier AurelienJaquier self-assigned this Jul 23, 2025
@AurelienJaquier AurelienJaquier marked this pull request as draft July 25, 2025 07:25
@AurelienJaquier AurelienJaquier marked this pull request as ready for review July 31, 2025 11:49
@AurelienJaquier
Copy link
Contributor Author

This PR is good from my point of view, but I have an error that I really do not know how to solve. It looks like pyright cannot import ElectricalRecordingStimulusRead, but I really do not see why. Also I do not have this error when I run pyright locally.
Do you guys know how to solve this error? @GianlucaFicarelli maybe? I really do not see what is wrong here.

@GianlucaFicarelli
Copy link
Collaborator

I cannot reproduce the pyright error locally either, so it's difficult to debug.
Probably unrelated, but you could try to merge or rebase on the main branch?

app/db/model.py Outdated
class IonChannelRecording(ElectricalCellRecording):
__tablename__ = EntityType.ion_channel_recording.value

ion_channel: Mapped[IonChannel]
Copy link
Collaborator

Choose a reason for hiding this comment

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

This causes an error when running tests. Maybe you want to add ion_channel_id, and a relationship ion_channel?

@AurelienJaquier
Copy link
Contributor Author

Alright @GianlucaFicarelli I have merge the main branch and I have added ion_channel_id and a relationship ion_channel.

@AurelienJaquier
Copy link
Contributor Author

@GianlucaFicarelli could I ask for your help with the tests please? I have been trying to fix the sqlalchemy errors, but the number of errors only seem to grow

app/db/model.py Outdated
__mapper_args__ = {"polymorphic_identity": __tablename__} # noqa: RUF012


class IonChannelRecording(ElectricalCellRecording):
Copy link
Collaborator

@GianlucaFicarelli GianlucaFicarelli Aug 26, 2025

Choose a reason for hiding this comment

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

I wonder what is the reason for IonChannelRecording to inherit from ElectricalCellRecording, is it a special case of ElectricalCellRecording?
Alternatively, couldn't it be a separate class?
Or can IonChannelRecording and ElectricalCellRecording have conceptually a common base class?

Copy link
Contributor Author

@AurelienJaquier AurelienJaquier Aug 26, 2025

Choose a reason for hiding this comment

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

I have made it inherit from ElectricalCellRecording, because it is indeed a special case of ElectricalCellRecording.
In both the ion channel recording experiments and the 'regular' recording experiments having produced the ElectricalCellRecording data we currently have on the platform, the pipette is applied to a cell (this is named a whole-cell patch clamp experiment).
But in the case of an ion channel recording, the cell has been designed in the laboratory to only express one single type of ion channel, so only currents from this type of ion channel are recorded.
So this is why I made IonChannelRecording inherit from ElectricalCellRecording. I also thought it would be easier (i.e. less code to write down) to just inherit from ElectricalCellRecording.

Although making a common base class for the two classes would also be ok, in my opinion, if you think this structure would be simpler. The base class would simply have all (or most) of ElectricalCellRecording fields.

I would personnally push for IonChannelrecording inheriting from ElectricalCellRecording if that is ok with you @GianlucaFicarelli

Copy link
Collaborator

Choose a reason for hiding this comment

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

@AurelienJaquier to continue and clarify the point, if we use this class/tables hierarchy:
entity -> scientific_artifact -> electrical_cell_recording -> ion_channel_recording
then, when retrieving the list of electrical_cell_recording, also the entries for the ion_channel_recording would be returned (because for each record in the ion_channel_recording table, there is also a record in the electrical_cell_recording table)
Wouldn't be surprising if we return also electrical_cell_recording built from partial data of ion_channel_recording?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah I see. In that case, it would be better to have both classes separate, and inheriting from a RecordingBase class or something. We do not want the IonChannelRecordings to show up when we query the ElectricalCellRecordings

* origin/main:
  Validate scale and build_category in circuit filter (#352)
  Add admin delete endpoints for all routers (#281)
  root routes should not require auth, make sure tests reflect this (#351)
  Specify permission for service admin (#342)
  Add assets in ValidationResultRead schema (#348)
  Fix transaction_per_migration in alembic (#346)

label: Mapped[str]
gene: Mapped[str]
synonyms: Mapped[STRING_LIST]
Copy link
Collaborator

@GianlucaFicarelli GianlucaFicarelli Sep 9, 2025

Choose a reason for hiding this comment

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

Some points to decide or clarify:

  • Should pref_label be made unique?
  • Is there a validation possible for gene?
  • For confirmation, should only the service admin be allowed to create a new entry?
  • Do we have examples for label, gene, synonyms?

@AurelienJaquier

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

@GianlucaFicarelli GianlucaFicarelli left a comment

Choose a reason for hiding this comment

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

This can be reviewed

super_table_args = getattr(super(), "__table_args__", ())
# add the index only to the same table where the Mixin is defined, not subclasses
attr = getattr(cls, "description_vector", None)
if isinstance(attr, MappedColumn):
Copy link
Collaborator

@GianlucaFicarelli GianlucaFicarelli Sep 11, 2025

Choose a reason for hiding this comment

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

I cannot find a cleaner way to avoid adding the index to the subclasses, feel free to suggest different options.
This might not work as expected if the mixin is applied to an abstract class, but it should work in our use cases (when the mixin is applied to an intermediate concrete class, or to a final child class).

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeesh, that is a work around, fancy

Copy link
Contributor

@eleftherioszisis eleftherioszisis left a comment

Choose a reason for hiding this comment

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

Looks good!

Copy link
Collaborator

@mgeplf mgeplf left a comment

Choose a reason for hiding this comment

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

LGTM; not sure if you want to squash the alembic versions, or if they need to be 3 separate ones.

@GianlucaFicarelli
Copy link
Collaborator

LGTM; not sure if you want to squash the alembic versions, or if they need to be 3 separate ones.

I'm thinking to keep them separate because the 1st one is manual, while the other 2 are automatic (I could merge those 2, but still requires some manual copying of the operations in the correct order)

@mgeplf
Copy link
Collaborator

mgeplf commented Sep 11, 2025

I'm thinking to keep them separate

Ok, no need.

@GianlucaFicarelli
Copy link
Collaborator

Added new update endpoint introduced in #347

Copy link
Contributor

@eleftherioszisis eleftherioszisis left a comment

Choose a reason for hiding this comment

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

Nice! Thank you for adding it.

@GianlucaFicarelli GianlucaFicarelli merged commit 0a6018f into main Sep 11, 2025
1 check passed
@GianlucaFicarelli GianlucaFicarelli deleted the ion-channel-recording branch September 11, 2025 10:13
GianlucaFicarelli added a commit that referenced this pull request Sep 11, 2025
* origin/main:
  Add IonChannel and IonChannelRecording (#305)
  Add update endpoints for users (#347)
  Adds deterministic order fallback by entity id (#350)
  Validate scale and build_category in circuit filter (#352)
  Add admin delete endpoints for all routers (#281)
  root routes should not require auth, make sure tests reflect this (#351)
  Specify permission for service admin (#342)
  Add assets in ValidationResultRead schema (#348)
  Fix transaction_per_migration in alembic (#346)
  Add the ability to filter by name to IonChannelModel (#338)
GianlucaFicarelli added a commit that referenced this pull request Sep 12, 2025
…-model

* origin/main:
  Add EMCellMesh and EMDenseReconstructionDataset (#339)
  Add IonChannel and IonChannelRecording (#305)
  Add update endpoints for users (#347)
  Adds deterministic order fallback by entity id (#350)
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