From 92d4caf9ca1dc9865375fc0744882ef2a0106e1d Mon Sep 17 00:00:00 2001 From: Guilherme de Freitas Date: Mon, 12 May 2025 09:49:18 +0100 Subject: [PATCH 1/3] Bump schema version --- .github/workflows/test-and-publish.yml | 2 +- HISTORY.rst | 5 + jupyterhub.sqlite | Bin 0 -> 143360 bytes jupyterhub_cookie_secret | 1 + test | 4500 ++++++++++++++++++++++++ 5 files changed, 4507 insertions(+), 1 deletion(-) create mode 100644 jupyterhub.sqlite create mode 100644 jupyterhub_cookie_secret create mode 100644 test diff --git a/.github/workflows/test-and-publish.yml b/.github/workflows/test-and-publish.yml index 7b0c087c..984ceb05 100644 --- a/.github/workflows/test-and-publish.yml +++ b/.github/workflows/test-and-publish.yml @@ -4,7 +4,7 @@ on: push: env: - DATABASE_SCHEMA: 4.6.0 + DATABASE_SCHEMA: 4.7.0 permissions: contents: read diff --git a/HISTORY.rst b/HISTORY.rst index 3df1ecc3..d3381a6c 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -5,6 +5,11 @@ History Unreleased / main ------------------- +11.0.3 (2025-05-12) +------------------- + +* Update database schema to v4.7.0 + 11.0.2 (2025-03-13) ------------------- diff --git a/jupyterhub.sqlite b/jupyterhub.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..f8db8e5e4915eda4024fee0b6bda8c0d1fdd3d32 GIT binary patch literal 143360 zcmeI*&2QW09S3mIb|g!Q%%)wYd7W31lO^2@6od)c0=yBU&*kQnSA2w_qb}4olFrXc_qA1qOp6B6<_%M>4pfQ%% zU$?PEJ`bOl&+{V5`Y~C%ykfeBykXfb-Ia^NQ-UZ8-;rfO5U!Fx)8tR^^)z`f5*(19 zV&w6lhgXF&+wUGBsYBAIG|!aux%Xhu1vn1@2tWV=5P$##AOHafKmY;|fWRXZ_{umb z?8Na5`7TQT63GAff&c^{009U<00Izz00bZa0SG|gfC!9vCqe&$^al_@00Izz00bZa z0SG_<0uX=z1R!uw1?c<#k+B&;`s3Iy$F|4=d_e#L5P$##AOHafKmY;|fWV;^cx5CZ zWUoz+y4H20U8CRRo2I)ZJ9^8IJBHmd9mllVj;uSf={mA?vu)T{r_A=2VVmyMwaRcp z7*|@Oj$v;b_G^~o%6i>3w@r6Pw%W~|t5aQ)dhKCHEyK0VI%|cqrQ0Os+Be07aN^~OQQEgPS8q3T zyCKtqh|bk1$7pU$U8C{;Bhm+g^pW&;=>zGrLp{mSc?duN0uX=z1Rwwb2tWV=5P-mw zCXgD=itHB_BkAFB(fhr|Fg?kBcQKS4K9Qoo5(wh|pS13wy%2x^1Rwwb2tWV=5P$## zAOHafJh%Y;{GZEH1Fds`H)#uL?iur}Jq^8nbU70T~D0-t*Qs&p^^kSpF zv0j>=YbXmFI{o~ANcyKBeMY|F3jz>;00bZa0SG_<0uX=z1Rwx`Ctcv!@PrurzJlHV zPk*Q2z5oA(ApK4H#gpDav>yTxfB*y_009U<00Izz00ba#zy!WAd`a9Zeqd;N_)==G z&;M!szbJhuNFR><{(u>wI}m^X1Rwwb2tWV=5P$##AOL~GBQPN*g~`cG=J*f0ogLS( z$-hDPUGLGw?)p{s@BfL?zXj>v(w`0w3VI3w2tWV=5P$##AOHafKmY;|IOqbI;mK6* zcLCnt|Mwq3`mgk#gWhxW4+0Q?00bZa0SG_<0uX=z1R!vT1da@ih^bNXZ6uW%_3r=w zM36q0J~>1N=qdyt009U<00Izz00bZa0SG|gzzZbE`+sq0XoS4~Ptni+g{KaDm(f88 zKmY;|fB*y_009U<00Izzz@ZkPpa0|i|Dm1&=sW}<009U<00Izz00bZa0SFud0et>{ z2nHElga8B}009U<00Izz00bZafkQ8V&;Jko6aWAOAOHafKmY;|fB*y_009Ub0s-&u z|9@YQ{vy492)c_dLI45~fB*y_009U<00Izz00f={fft9;f+!r%2xUPS`q5j3d|~!< zzHqvr$Vy?cpe&Zop2-)Lh2rcBVp>S~8RPks;-Zp2Qz+&a&gL`HXTtH}R|F{|{c7xF zW@Jn__RO(Ar(ZkzkE6dH{ayM*;?JY+jr=w7v*A~UMPWy{NdChY1R%f!?v5W%W^+05 zUdz?jn?~0$Y;DuFx*e^hcle{Hm#S*HrpmSQxfNCB)8v_Sik&eV@^Yo7UQnxYWwj<( zuB@z_lG7=#$N`BX!LL=9FO{or%HLDplxO@ZPRT)eIa+w+`i=PY zUU6oF{dDA4SF7ssg$gY#C@d#e)mPQ3T3J%pSg#y;#%$!|)rx#xT~SGgm&$8P<@4&E zRRxXm0Qt&-G_E#wa!_^Y+})QYHa73fva#`su&t&+$A&+8iW?g~jgF0XW`I8{azI*3 zZ|j>zLtEd`^sc)lpIcpBQOgx>a3lU?{9=`J;}~vh!aQ_5Lx8 zRp+-$qd)n|f)+=oireMroK^&tvj+!@Ga+N3)y{R`MWpx{A9qw{#>anU%sN!Jv%s+ zOXn7j?KToz-I~H3X72oOG?~q2#e2nY;W>1yoD?U|PVFMz)>}qM6S(P(me~&WP})bL ztGh-+K2M%lYs;6|b4*irTuraL=C+eJ%1#*LG+(f2CtjGqu8;@ytZ9);N13$-5b-(*he#+ zJDE&mzdb%k#=p>e(r`v^?~JfHd-pQyFx$)6wX>Tc( zuP;>Y$Zqq(yG~(061TPCWcJx-#k(gM6Is;TWL^6|MmQ?}D=v{n9QC$Dc(u39_me_wQklm z+D)>*#}0?M9>)@C&;84^cDEI_wphq<8&0HUu@bb-^*XpS_X8HwZug0uX=z1Rwwb2tWV=5P-me7Qp@g2YPtXIS4=i0uX=z z1Rwwb2tWV=5P$#^$RzT@sCYw=ew%q|bZ7KpVtyohxu&Id_cI6I5ed*I-Czmnb%X#PV!3b&We)fMI)6nuU6N;a82eOi3Sivgq|Q)b=p z!hJ~yb^Q3N{LGEzrgJ#BV!$M&5oVF;%uUdT4~q*bW2KVj@^Mr_s@d2rkUq#2l%WMD zNVK#6Fh=e7n%?~oxhEpb+n>76LWt=-(irP+e=BWsO@-^E@i5d(tCk)b1Y^yvRg%V$K3<0 z9kSn&aK3(3^x0`++atfbMZ2{378l9w2d9%Z@S)kI z?`@wA%1`0y-EDtL=e~6!kzJbDV`4d4Frl36y^Sv=vlA2Id(VZ@q-2L-;iUBEm$|9a zTSNn6^!o;W-WM^>MULi6XW1l*ifRMG@6Gmx6$XYkOsCV-ccP)_UKwpmt6S|2({4r6 z>Q;;FVU6(e`psSldMUr)#l9NtZPT{eEfR(wW~Aidj1MAWH*Blr)v_6_gl$UqJw^HXs?(Jkd3NJ(Qt7+zku3Iu-x$Lxw%9#Pz59)# zv-|lj2 zWur_8KmY;|fB*y_009U<00Izz00bTn0o?!pc#H#D0Rad=00Izz00bZa0SG_<0ub0w z0et?ypSma;0uX=z1Rwwb2tWV=5P$##An(3>!vym$JAWwy3uyDj%{q1w|Xb0m#S*Hrpn8e^XeONzr6Bl zMegO7XS@<}#jhu_7bZo4)#2P|ny#VgUDsmA(HfQB#gp$0Pb9OGlj3`qU46Z2^iq0{ zWWPbR^0^h2t2mwNI)<&84bs?}dO@w8lG7=2X4|YAv9rBAa%Ht9SFWtA(9B!9vt=~o z*UQzVi{1t&+izHV_NNgNp;)MT~ft)Vp?0iq|)Mz zTOHFj98Gt*(@ouRHNEbd+orq2rL-;A2rE_cg(7Q@Q@1*XBiGb7YP8g))yi6}S|${7 z=X%6jeyzHEsa$ZXtE*LY`9g(WI^(D0Y7Z?Ijm4RDbA}aDw#P;<+Y{qdDhc`)$~S5^B?k+_0qZe!o0K}dsf-K5n<5$vA$AS zzI;WMXS~DRF~SkoEHaa~H1C*iX_$v=D4(CSmdqS;!!+zZtxo4Qzn09NofdD4!TNNz zblcGCR)fqEZ!$*CJQrV~ku*OyrHPyk*XZoCiR|+9pfwt~LQ^6KUw_;DYBD=LExtR> zR%s+D@^FG%r;!AC<{=lFajU+iw>K$3x9vt3H(Me>awEQg1}t)a2}W~sn?P(G4OpGl z&G!9!O-Ju@HZtkSLX1M}u@cFAjpTmd2^+m8Xl0-E8zgb_^x+n8v?eF)yXHUS*F`U# vt1!&le+8#=!RP', 'Best CC', 'CC(1/2)', 'Weak CC', 'CFOM', 'Pseudo_free_CC', 'CC of partial model'), comment='metric') + statisticsValue: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True), comment='the statistics value') + nReflections: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + recordTimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime, server_default=text('current_timestamp()')) + + Phasing_has_Scaling: Mapped['PhasingHasScaling'] = relationship('PhasingHasScaling', foreign_keys=[phasingHasScalingId1], back_populates='PhasingStatistics') + Phasing_has_Scaling: Mapped['PhasingHasScaling'] = relationship('PhasingHasScaling', foreign_keys=[phasingHasScalingId2], back_populates='PhasingStatistics') + PhasingStep: Mapped['PhasingStep'] = relationship('PhasingStep', back_populates='PhasingStatistics') + + +t_Project_has_BLSample = Table( + 'Project_has_BLSample', Base.metadata, + Column('projectId', INTEGER(11), primary_key=True, nullable=False), + Column('blSampleId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], ondelete='CASCADE', onupdate='CASCADE', name='Project_has_BLSample_FK2'), + ForeignKeyConstraint(['projectId'], ['Project.projectId'], ondelete='CASCADE', onupdate='CASCADE', name='Project_has_BLSample_FK1'), + Index('Project_has_BLSample_FK2', 'blSampleId') +) + + +t_Project_has_Person = Table( + 'Project_has_Person', Base.metadata, + Column('projectId', INTEGER(11), primary_key=True, nullable=False), + Column('personId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['personId'], ['Person.personId'], ondelete='CASCADE', name='project_has_person_FK2'), + ForeignKeyConstraint(['projectId'], ['Project.projectId'], ondelete='CASCADE', name='project_has_person_FK1'), + Index('project_has_person_FK2', 'personId') +) + + +class ProjectHasUser(Base): + __tablename__ = 'Project_has_User' + __table_args__ = ( + ForeignKeyConstraint(['projectid'], ['Project.projectId'], name='Project_Has_user_FK1'), + Index('Project_Has_user_FK1', 'projectid') + ) + + projecthasuserid: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + projectid: Mapped[int] = mapped_column(INTEGER(11)) + username: Mapped[Optional[str]] = mapped_column(String(15)) + + Project: Mapped['Project'] = relationship('Project', back_populates='Project_has_User') + + +class ProposalHasPerson(Base): + __tablename__ = 'ProposalHasPerson' + __table_args__ = ( + ForeignKeyConstraint(['personId'], ['Person.personId'], name='fk_ProposalHasPerson_Personal'), + ForeignKeyConstraint(['proposalId'], ['Proposal.proposalId'], name='fk_ProposalHasPerson_Proposal'), + Index('fk_ProposalHasPerson_Personal', 'personId'), + Index('fk_ProposalHasPerson_Proposal', 'proposalId') + ) + + proposalHasPersonId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + proposalId: Mapped[int] = mapped_column(INTEGER(10)) + personId: Mapped[int] = mapped_column(INTEGER(10)) + role: Mapped[Optional[str]] = mapped_column(Enum('Co-Investigator', 'Principal Investigator', 'Alternate Contact', 'ERA Admin', 'Associate')) + + Person: Mapped['Person'] = relationship('Person', back_populates='ProposalHasPerson') + Proposal: Mapped['Proposal'] = relationship('Proposal', back_populates='ProposalHasPerson') + + +class Protein(Base): + __tablename__ = 'Protein' + __table_args__ = ( + ForeignKeyConstraint(['componentTypeId'], ['ComponentType.componentTypeId'], ondelete='CASCADE', onupdate='CASCADE', name='protein_fk3'), + ForeignKeyConstraint(['concentrationTypeId'], ['ConcentrationType.concentrationTypeId'], ondelete='CASCADE', onupdate='CASCADE', name='protein_fk4'), + ForeignKeyConstraint(['proposalId'], ['Proposal.proposalId'], ondelete='CASCADE', onupdate='CASCADE', name='Protein_ibfk_1'), + Index('ProteinAcronym_Index', 'proposalId', 'acronym'), + Index('Protein_FKIndex2', 'personId'), + Index('Protein_Index2', 'acronym'), + Index('protein_fk3', 'componentTypeId'), + Index('protein_fk4', 'concentrationTypeId') + ) + + proteinId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + proposalId: Mapped[int] = mapped_column(INTEGER(10), server_default=text('0')) + hazardGroup: Mapped[int] = mapped_column(TINYINT(3), server_default=text('1'), comment='A.k.a. risk group') + containmentLevel: Mapped[int] = mapped_column(TINYINT(3), server_default=text('1'), comment='A.k.a. biosafety level, which indicates the level of containment required') + bltimeStamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp()')) + name: Mapped[Optional[str]] = mapped_column(String(255)) + acronym: Mapped[Optional[str]] = mapped_column(String(45)) + description: Mapped[Optional[str]] = mapped_column(Text, comment='A description/summary using words and sentences') + safetyLevel: Mapped[Optional[str]] = mapped_column(Enum('GREEN', 'YELLOW', 'RED')) + molecularMass: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + proteinType: Mapped[Optional[str]] = mapped_column(String(45)) + personId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + isCreatedBySampleSheet: Mapped[Optional[int]] = mapped_column(TINYINT(1), server_default=text('0')) + sequence: Mapped[Optional[str]] = mapped_column(Text) + MOD_ID: Mapped[Optional[str]] = mapped_column(String(20)) + componentTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + concentrationTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + global_: Mapped[Optional[int]] = mapped_column('global', TINYINT(1), server_default=text('0')) + externalId: Mapped[Optional[bytes]] = mapped_column(BINARY(16)) + density: Mapped[Optional[float]] = mapped_column(Float) + abundance: Mapped[Optional[float]] = mapped_column(Float, comment='Deprecated') + isotropy: Mapped[Optional[str]] = mapped_column(Enum('isotropic', 'anisotropic')) + + Project: Mapped[List['Project']] = relationship('Project', secondary='Project_has_Protein', back_populates='Protein') + ComponentType: Mapped['ComponentType'] = relationship('ComponentType', back_populates='Protein') + ConcentrationType: Mapped['ConcentrationType'] = relationship('ConcentrationType', back_populates='Protein') + Proposal: Mapped['Proposal'] = relationship('Proposal', back_populates='Protein') + ComponentSubType: Mapped[List['ComponentSubType']] = relationship('ComponentSubType', secondary='Component_has_SubType', back_populates='Protein') + ComponentLattice: Mapped[List['ComponentLattice']] = relationship('ComponentLattice', back_populates='Protein') + Crystal: Mapped[List['Crystal']] = relationship('Crystal', back_populates='Protein') + Protein_has_PDB: Mapped[List['ProteinHasPDB']] = relationship('ProteinHasPDB', back_populates='Protein') + BLSampleType_has_Component: Mapped[List['BLSampleTypeHasComponent']] = relationship('BLSampleTypeHasComponent', back_populates='Protein') + ScreenComponent: Mapped[List['ScreenComponent']] = relationship('ScreenComponent', back_populates='Protein') + + +class SWOnceToken(Base): + __tablename__ = 'SW_onceToken' + __table_args__ = ( + ForeignKeyConstraint(['personId'], ['Person.personId'], name='SW_onceToken_fk1'), + ForeignKeyConstraint(['proposalId'], ['Proposal.proposalId'], name='SW_onceToken_fk2'), + Index('SW_onceToken_fk1', 'personId'), + Index('SW_onceToken_fk2', 'proposalId'), + Index('SW_onceToken_recordTimeStamp_idx', 'recordTimeStamp'), + {'comment': 'One-time use tokens needed for token auth in order to grant ' + 'access to file downloads and webcams (and some images)'} + ) + + onceTokenId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + recordTimeStamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp()')) + token: Mapped[Optional[str]] = mapped_column(String(128)) + personId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + proposalId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + validity: Mapped[Optional[str]] = mapped_column(String(200)) + + Person: Mapped['Person'] = relationship('Person', back_populates='SW_onceToken') + Proposal: Mapped['Proposal'] = relationship('Proposal', back_populates='SW_onceToken') + + +class Screen(Base): + __tablename__ = 'Screen' + __table_args__ = ( + ForeignKeyConstraint(['containerTypeId'], ['ContainerType.containerTypeId'], onupdate='CASCADE', name='Screen_fk_containerTypeId'), + ForeignKeyConstraint(['proposalId'], ['Proposal.proposalId'], name='Screen_fk1'), + Index('Screen_fk1', 'proposalId'), + Index('Screen_fk_containerTypeId', 'containerTypeId') + ) + + screenId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + name: Mapped[Optional[str]] = mapped_column(String(45)) + proposalId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + global_: Mapped[Optional[int]] = mapped_column('global', TINYINT(1)) + containerTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + + ContainerType: Mapped['ContainerType'] = relationship('ContainerType', back_populates='Screen') + Proposal: Mapped['Proposal'] = relationship('Proposal', back_populates='Screen') + ScreenComponentGroup: Mapped[List['ScreenComponentGroup']] = relationship('ScreenComponentGroup', back_populates='Screen') + Container: Mapped[List['Container']] = relationship('Container', back_populates='Screen') + + +class BFFault(Base): + __tablename__ = 'BF_fault' + __table_args__ = ( + ForeignKeyConstraint(['assigneeId'], ['Person.personId'], name='bf_fault_FK4'), + ForeignKeyConstraint(['personId'], ['Person.personId'], name='bf_fault_FK3'), + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], name='bf_fault_FK1'), + ForeignKeyConstraint(['subcomponentId'], ['BF_subcomponent.subcomponentId'], name='bf_fault_FK2'), + Index('bf_fault_FK1', 'sessionId'), + Index('bf_fault_FK2', 'subcomponentId'), + Index('bf_fault_FK3', 'personId'), + Index('bf_fault_FK4', 'assigneeId') + ) + + faultId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + sessionId: Mapped[int] = mapped_column(INTEGER(10)) + owner: Mapped[Optional[str]] = mapped_column(String(50)) + subcomponentId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + starttime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + endtime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + beamtimelost: Mapped[Optional[int]] = mapped_column(TINYINT(1)) + beamtimelost_starttime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + beamtimelost_endtime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + title: Mapped[Optional[str]] = mapped_column(String(200)) + description: Mapped[Optional[str]] = mapped_column(Text) + resolved: Mapped[Optional[int]] = mapped_column(TINYINT(1)) + resolution: Mapped[Optional[str]] = mapped_column(Text) + attachment: Mapped[Optional[str]] = mapped_column(String(200)) + eLogId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + assignee: Mapped[Optional[str]] = mapped_column(String(50)) + personId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + assigneeId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + + Person: Mapped['Person'] = relationship('Person', foreign_keys=[assigneeId], back_populates='BF_fault') + Person: Mapped['Person'] = relationship('Person', foreign_keys=[personId], back_populates='BF_fault') + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='BF_fault') + BF_subcomponent: Mapped['BFSubcomponent'] = relationship('BFSubcomponent', back_populates='BF_fault') + + +class BLSampleGroupHasBLSample(Base): + __tablename__ = 'BLSampleGroup_has_BLSample' + __table_args__ = ( + ForeignKeyConstraint(['blSampleGroupId'], ['BLSampleGroup.blSampleGroupId'], name='BLSampleGroup_has_BLSample_ibfk1'), + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], name='BLSampleGroup_has_BLSample_ibfk2'), + ForeignKeyConstraint(['blSampleTypeId'], ['BLSampleType.blSampleTypeId'], name='BLSampleGroup_has_BLSample_ibfk3'), + Index('BLSampleGroup_has_BLSample_ibfk2', 'blSampleId'), + Index('BLSampleGroup_has_BLSample_ibfk3', 'blSampleTypeId') + ) + + blSampleGroupId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + blSampleId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + groupOrder: Mapped[Optional[int]] = mapped_column(MEDIUMINT(9)) + type: Mapped[Optional[str]] = mapped_column(Enum('background', 'container', 'sample', 'calibrant', 'capillary')) + blSampleTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + + BLSampleGroup: Mapped['BLSampleGroup'] = relationship('BLSampleGroup', back_populates='BLSampleGroup_has_BLSample') + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='BLSampleGroup_has_BLSample') + BLSampleType: Mapped['BLSampleType'] = relationship('BLSampleType', back_populates='BLSampleGroup_has_BLSample') + + +class BLSampleHasDataCollectionPlan(Base): + __tablename__ = 'BLSample_has_DataCollectionPlan' + __table_args__ = ( + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], name='BLSample_has_DataCollectionPlan_ibfk1'), + ForeignKeyConstraint(['dataCollectionPlanId'], ['DiffractionPlan.diffractionPlanId'], name='BLSample_has_DataCollectionPlan_ibfk2'), + Index('BLSample_has_DataCollectionPlan_ibfk2', 'dataCollectionPlanId') + ) + + blSampleId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + dataCollectionPlanId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + planOrder: Mapped[Optional[int]] = mapped_column(SMALLINT(5)) + + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='BLSample_has_DataCollectionPlan') + DiffractionPlan: Mapped['DiffractionPlan'] = relationship('DiffractionPlan', back_populates='BLSample_has_DataCollectionPlan') + + +class BLSessionHasSCPosition(Base): + __tablename__ = 'BLSession_has_SCPosition' + __table_args__ = ( + ForeignKeyConstraint(['blsessionid'], ['BLSession.sessionId'], ondelete='CASCADE', onupdate='CASCADE', name='blsession_has_scposition_FK1'), + Index('blsession_has_scposition_FK1', 'blsessionid') + ) + + blsessionhasscpositionid: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + blsessionid: Mapped[int] = mapped_column(INTEGER(11)) + scContainer: Mapped[Optional[int]] = mapped_column(SMALLINT(5), comment='Position of container within sample changer') + containerPosition: Mapped[Optional[int]] = mapped_column(SMALLINT(5), comment='Position of sample within container') + + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='BLSession_has_SCPosition') + + +class BeamlineAction(Base): + __tablename__ = 'BeamlineAction' + __table_args__ = ( + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], name='BeamlineAction_ibfk1'), + Index('BeamlineAction_ibfk1', 'sessionId') + ) + + beamlineActionId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + startTimestamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp() ON UPDATE current_timestamp()')) + endTimestamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text("'0000-00-00 00:00:00'")) + sessionId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + message: Mapped[Optional[str]] = mapped_column(String(255)) + parameter: Mapped[Optional[str]] = mapped_column(String(50)) + value: Mapped[Optional[str]] = mapped_column(String(30)) + loglevel: Mapped[Optional[str]] = mapped_column(Enum('DEBUG', 'CRITICAL', 'INFO')) + status: Mapped[Optional[str]] = mapped_column(Enum('PAUSED', 'RUNNING', 'TERMINATED', 'COMPLETE', 'ERROR', 'EPICSFAIL')) + + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='BeamlineAction') + + +class ComponentLattice(Base): + __tablename__ = 'ComponentLattice' + __table_args__ = ( + ForeignKeyConstraint(['componentId'], ['Protein.proteinId'], name='ComponentLattice_ibfk1'), + Index('ComponentLattice_ibfk1', 'componentId') + ) + + componentLatticeId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + componentId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + spaceGroup: Mapped[Optional[str]] = mapped_column(String(20)) + cell_a: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_b: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_c: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_alpha: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_beta: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_gamma: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + + Protein: Mapped['Protein'] = relationship('Protein', back_populates='ComponentLattice') + + +t_Component_has_SubType = Table( + 'Component_has_SubType', Base.metadata, + Column('componentId', INTEGER(10), primary_key=True, nullable=False), + Column('componentSubTypeId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['componentId'], ['Protein.proteinId'], ondelete='CASCADE', name='component_has_SubType_fk1'), + ForeignKeyConstraint(['componentSubTypeId'], ['ComponentSubType.componentSubTypeId'], ondelete='CASCADE', onupdate='CASCADE', name='component_has_SubType_fk2'), + Index('component_has_SubType_fk2', 'componentSubTypeId') +) + + +class Crystal(Base): + __tablename__ = 'Crystal' + __table_args__ = ( + ForeignKeyConstraint(['diffractionPlanId'], ['DiffractionPlan.diffractionPlanId'], ondelete='CASCADE', onupdate='CASCADE', name='Crystal_ibfk_2'), + ForeignKeyConstraint(['proteinId'], ['Protein.proteinId'], ondelete='CASCADE', onupdate='CASCADE', name='Crystal_ibfk_1'), + Index('Crystal_FKIndex1', 'proteinId'), + Index('Crystal_FKIndex2', 'diffractionPlanId') + ) + + crystalId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + proteinId: Mapped[int] = mapped_column(INTEGER(10), server_default=text('0')) + recordTimeStamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp()'), comment='Creation or last update date/time') + diffractionPlanId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + crystalUUID: Mapped[Optional[str]] = mapped_column(String(45)) + name: Mapped[Optional[str]] = mapped_column(String(255)) + spaceGroup: Mapped[Optional[str]] = mapped_column(String(20)) + morphology: Mapped[Optional[str]] = mapped_column(String(255)) + color: Mapped[Optional[str]] = mapped_column(String(45)) + size_X: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + size_Y: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + size_Z: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_a: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_b: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_c: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_alpha: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_beta: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + cell_gamma: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + comments: Mapped[Optional[str]] = mapped_column(String(255)) + pdbFileName: Mapped[Optional[str]] = mapped_column(String(255), comment='pdb file name') + pdbFilePath: Mapped[Optional[str]] = mapped_column(String(1024), comment='pdb file path') + abundance: Mapped[Optional[float]] = mapped_column(Float) + theoreticalDensity: Mapped[Optional[float]] = mapped_column(Float) + + BLSample: Mapped[List['BLSample']] = relationship('BLSample', back_populates='Crystal') + DiffractionPlan: Mapped['DiffractionPlan'] = relationship('DiffractionPlan', back_populates='Crystal') + Protein: Mapped['Protein'] = relationship('Protein', back_populates='Crystal') + BLSampleType_has_Component: Mapped[List['BLSampleTypeHasComponent']] = relationship('BLSampleTypeHasComponent', back_populates='Crystal') + CrystalComposition: Mapped[List['CrystalComposition']] = relationship('CrystalComposition', back_populates='Crystal') + Crystal_has_UUID: Mapped[List['CrystalHasUUID']] = relationship('CrystalHasUUID', back_populates='Crystal') + + +class DataCollectionGroup(Base): + __tablename__ = 'DataCollectionGroup' + __table_args__ = ( + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], ondelete='CASCADE', onupdate='CASCADE', name='DataCollectionGroup_ibfk_1'), + ForeignKeyConstraint(['experimentTypeId'], ['ExperimentType.experimentTypeId'], name='DataCollectionGroup_ibfk_4'), + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], ondelete='CASCADE', onupdate='CASCADE', name='DataCollectionGroup_ibfk_2'), + Index('DataCollectionGroup_FKIndex1', 'blSampleId'), + Index('DataCollectionGroup_FKIndex2', 'sessionId'), + Index('DataCollectionGroup_ibfk_4', 'experimentTypeId'), + {'comment': 'a dataCollectionGroup is a group of dataCollection for a spe'} + ) + + dataCollectionGroupId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True, comment='Primary key (auto-incremented)') + sessionId: Mapped[int] = mapped_column(INTEGER(10), comment='references Session table') + comments: Mapped[Optional[str]] = mapped_column(String(1024), comment='comments') + blSampleId: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='references BLSample table') + experimentType: Mapped[Optional[str]] = mapped_column(Enum('SAD', 'SAD - Inverse Beam', 'OSC', 'Collect - Multiwedge', 'MAD', 'Helical', 'Multi-positional', 'Mesh', 'Burn', 'MAD - Inverse Beam', 'Characterization', 'Dehydration', 'tomo', 'experiment', 'EM', 'PDF', 'PDF+Bragg', 'Bragg', 'single particle', 'Serial Fixed', 'Serial Jet', 'Standard', 'Time Resolved', 'Diamond Anvil High Pressure', 'Custom', 'XRF map', 'Energy scan', 'XRF spectrum', 'XRF map xas', 'Mesh3D', 'Screening', 'Still', 'SSX-Chip', 'SSX-Jet', 'Metal ID'), comment='Standard: Routine structure determination experiment. Time Resolved: Investigate the change of a system over time. Custom: Special or non-standard data collection.') + startTime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime, comment='Start time of the dataCollectionGroup') + endTime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime, comment='end time of the dataCollectionGroup') + crystalClass: Mapped[Optional[str]] = mapped_column(String(20), comment='Crystal Class for industrials users') + detectorMode: Mapped[Optional[str]] = mapped_column(String(255), comment='Detector mode') + actualSampleBarcode: Mapped[Optional[str]] = mapped_column(String(45), comment='Actual sample barcode') + actualSampleSlotInContainer: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Actual sample slot number in container') + actualContainerBarcode: Mapped[Optional[str]] = mapped_column(String(45), comment='Actual container barcode') + actualContainerSlotInSC: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Actual container slot number in sample changer') + xtalSnapshotFullPath: Mapped[Optional[str]] = mapped_column(String(255)) + scanParameters: Mapped[Optional[str]] = mapped_column(LONGTEXT) + experimentTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + + DataCollection: Mapped[List['DataCollection']] = relationship('DataCollection', back_populates='DataCollectionGroup') + Screening: Mapped[List['Screening']] = relationship('Screening', back_populates='DataCollectionGroup') + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='DataCollectionGroup') + ExperimentType: Mapped['ExperimentType'] = relationship('ExperimentType', back_populates='DataCollectionGroup') + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='DataCollectionGroup') + Project: Mapped[List['Project']] = relationship('Project', secondary='Project_has_DCGroup', back_populates='DataCollectionGroup') + Atlas: Mapped[List['Atlas']] = relationship('Atlas', back_populates='DataCollectionGroup') + GridInfo: Mapped[List['GridInfo']] = relationship('GridInfo', back_populates='DataCollectionGroup') + XrayCentring: Mapped[List['XrayCentring']] = relationship('XrayCentring', back_populates='DataCollectionGroup') + + +class DataCollectionPlanHasDetector(Base): + __tablename__ = 'DataCollectionPlan_has_Detector' + __table_args__ = ( + ForeignKeyConstraint(['dataCollectionPlanId'], ['DiffractionPlan.diffractionPlanId'], name='DataCollectionPlan_has_Detector_ibfk1'), + ForeignKeyConstraint(['detectorId'], ['Detector.detectorId'], name='DataCollectionPlan_has_Detector_ibfk2'), + Index('DataCollectionPlan_has_Detector_ibfk2', 'detectorId'), + Index('dataCollectionPlanId', 'dataCollectionPlanId', 'detectorId', unique=True) + ) + + dataCollectionPlanHasDetectorId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + dataCollectionPlanId: Mapped[int] = mapped_column(INTEGER(11)) + detectorId: Mapped[int] = mapped_column(INTEGER(11)) + exposureTime: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + distance: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + roll: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + + DiffractionPlan: Mapped['DiffractionPlan'] = relationship('DiffractionPlan', back_populates='DataCollectionPlan_has_Detector') + Detector: Mapped['Detector'] = relationship('Detector', back_populates='DataCollectionPlan_has_Detector') + + +class DewarRegistry(Base): + __tablename__ = 'DewarRegistry' + __table_args__ = ( + ForeignKeyConstraint(['labContactId'], ['LabContact.labContactId'], ondelete='SET NULL', onupdate='CASCADE', name='DewarRegistry_ibfk_2'), + ForeignKeyConstraint(['proposalId'], ['Proposal.proposalId'], onupdate='CASCADE', name='DewarRegistry_ibfk_1'), + Index('DewarRegistry_ibfk_1', 'proposalId'), + Index('DewarRegistry_ibfk_2', 'labContactId'), + Index('facilityCode', 'facilityCode', unique=True) + ) + + dewarRegistryId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + facilityCode: Mapped[str] = mapped_column(String(20)) + bltimestamp: Mapped[datetime.datetime] = mapped_column(DateTime, server_default=text('current_timestamp()')) + proposalId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + labContactId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + purchaseDate: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + manufacturerSerialNumber: Mapped[Optional[str]] = mapped_column(String(15), comment='Dewar serial number as given by manufacturer. Used to be typically 5 or 6 digits, more likely to be 11 alphanumeric chars in future') + + LabContact: Mapped['LabContact'] = relationship('LabContact', back_populates='DewarRegistry') + Proposal: Mapped['Proposal'] = relationship('Proposal', back_populates='DewarRegistry') + DewarRegistry_has_Proposal: Mapped[List['DewarRegistryHasProposal']] = relationship('DewarRegistryHasProposal', back_populates='DewarRegistry') + DewarReport: Mapped[List['DewarReport']] = relationship('DewarReport', back_populates='DewarRegistry') + + +class EnergyScan(Base): + __tablename__ = 'EnergyScan' + __table_args__ = ( + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], name='ES_ibfk_2'), + ForeignKeyConstraint(['blSubSampleId'], ['BLSubSample.blSubSampleId'], name='ES_ibfk_3'), + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], ondelete='CASCADE', onupdate='CASCADE', name='ES_ibfk_1'), + Index('ES_ibfk_2', 'blSampleId'), + Index('ES_ibfk_3', 'blSubSampleId'), + Index('EnergyScan_FKIndex2', 'sessionId') + ) + + energyScanId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + sessionId: Mapped[int] = mapped_column(INTEGER(10)) + blSampleId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + fluorescenceDetector: Mapped[Optional[str]] = mapped_column(String(255)) + scanFileFullPath: Mapped[Optional[str]] = mapped_column(String(255)) + jpegChoochFileFullPath: Mapped[Optional[str]] = mapped_column(String(255)) + element: Mapped[Optional[str]] = mapped_column(String(45)) + startEnergy: Mapped[Optional[float]] = mapped_column(Float) + endEnergy: Mapped[Optional[float]] = mapped_column(Float) + transmissionFactor: Mapped[Optional[float]] = mapped_column(Float) + exposureTime: Mapped[Optional[float]] = mapped_column(Float) + axisPosition: Mapped[Optional[float]] = mapped_column(Float) + synchrotronCurrent: Mapped[Optional[float]] = mapped_column(Float) + temperature: Mapped[Optional[float]] = mapped_column(Float) + peakEnergy: Mapped[Optional[float]] = mapped_column(Float) + peakFPrime: Mapped[Optional[float]] = mapped_column(Float) + peakFDoublePrime: Mapped[Optional[float]] = mapped_column(Float) + inflectionEnergy: Mapped[Optional[float]] = mapped_column(Float) + inflectionFPrime: Mapped[Optional[float]] = mapped_column(Float) + inflectionFDoublePrime: Mapped[Optional[float]] = mapped_column(Float) + xrayDose: Mapped[Optional[float]] = mapped_column(Float) + startTime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + endTime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + edgeEnergy: Mapped[Optional[str]] = mapped_column(String(255)) + filename: Mapped[Optional[str]] = mapped_column(String(255)) + beamSizeVertical: Mapped[Optional[float]] = mapped_column(Float) + beamSizeHorizontal: Mapped[Optional[float]] = mapped_column(Float) + choochFileFullPath: Mapped[Optional[str]] = mapped_column(String(255)) + crystalClass: Mapped[Optional[str]] = mapped_column(String(20)) + comments: Mapped[Optional[str]] = mapped_column(String(1024)) + flux: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True), comment='flux measured before the energyScan') + flux_end: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True), comment='flux measured after the energyScan') + workingDirectory: Mapped[Optional[str]] = mapped_column(String(45)) + blSubSampleId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='EnergyScan') + BLSubSample: Mapped['BLSubSample'] = relationship('BLSubSample', back_populates='EnergyScan') + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='EnergyScan') + Project: Mapped[List['Project']] = relationship('Project', secondary='Project_has_EnergyScan', back_populates='EnergyScan') + BLSample_has_EnergyScan: Mapped[List['BLSampleHasEnergyScan']] = relationship('BLSampleHasEnergyScan', back_populates='EnergyScan') + + +class Event(Base): + __tablename__ = 'Event' + __table_args__ = ( + ForeignKeyConstraint(['componentId'], ['Component.componentId'], name='Event_ibfk_2'), + ForeignKeyConstraint(['eventChainId'], ['EventChain.eventChainId'], ondelete='CASCADE', onupdate='CASCADE', name='Event_ibfk_1'), + ForeignKeyConstraint(['eventTypeId'], ['EventType.eventTypeId'], name='Event_ibfk_3'), + Index('componentId', 'componentId'), + Index('eventChainId', 'eventChainId'), + Index('eventTypeId', 'eventTypeId'), + {'comment': 'Describes an event that occurred during a data collection and ' + 'should be taken into account for data analysis. Can optionally be ' + 'repeated at a specified frequency.'} + ) + + eventId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + eventChainId: Mapped[int] = mapped_column(INTEGER(11)) + eventTypeId: Mapped[int] = mapped_column(INTEGER(11)) + offset: Mapped[float] = mapped_column(Float, comment='Start of the event relative to data collection start time in seconds.') + componentId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + name: Mapped[Optional[str]] = mapped_column(String(255)) + duration: Mapped[Optional[float]] = mapped_column(Float, comment='Duration of the event if applicable.') + period: Mapped[Optional[float]] = mapped_column(Float, comment='Repetition period if applicable in seconds.') + repetition: Mapped[Optional[float]] = mapped_column(Float, comment='Number of repetitions if applicable.') + + Component: Mapped['Component'] = relationship('Component', back_populates='Event') + EventChain: Mapped['EventChain'] = relationship('EventChain', back_populates='Event') + EventType: Mapped['EventType'] = relationship('EventType', back_populates='Event') + + +class ExperimentKindDetails(Base): + __tablename__ = 'ExperimentKindDetails' + __table_args__ = ( + ForeignKeyConstraint(['diffractionPlanId'], ['DiffractionPlan.diffractionPlanId'], ondelete='CASCADE', onupdate='CASCADE', name='EKD_ibfk_1'), + Index('ExperimentKindDetails_FKIndex1', 'diffractionPlanId') + ) + + experimentKindId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + diffractionPlanId: Mapped[int] = mapped_column(INTEGER(10)) + exposureIndex: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + dataCollectionType: Mapped[Optional[str]] = mapped_column(String(45)) + dataCollectionKind: Mapped[Optional[str]] = mapped_column(String(45)) + wedgeValue: Mapped[Optional[float]] = mapped_column(Float) + + DiffractionPlan: Mapped['DiffractionPlan'] = relationship('DiffractionPlan', back_populates='ExperimentKindDetails') + + +t_Project_has_Protein = Table( + 'Project_has_Protein', Base.metadata, + Column('projectId', INTEGER(11), primary_key=True, nullable=False), + Column('proteinId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['projectId'], ['Project.projectId'], ondelete='CASCADE', name='project_has_protein_FK1'), + ForeignKeyConstraint(['proteinId'], ['Protein.proteinId'], ondelete='CASCADE', name='project_has_protein_FK2'), + Index('project_has_protein_FK2', 'proteinId') +) + + +t_Project_has_Session = Table( + 'Project_has_Session', Base.metadata, + Column('projectId', INTEGER(11), primary_key=True, nullable=False), + Column('sessionId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['projectId'], ['Project.projectId'], ondelete='CASCADE', onupdate='CASCADE', name='project_has_session_FK1'), + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], ondelete='CASCADE', onupdate='CASCADE', name='project_has_session_FK2'), + Index('project_has_session_FK2', 'sessionId') +) + + +class ProteinHasPDB(Base): + __tablename__ = 'Protein_has_PDB' + __table_args__ = ( + ForeignKeyConstraint(['pdbid'], ['PDB.pdbId'], name='Protein_Has_PDB_fk2'), + ForeignKeyConstraint(['proteinid'], ['Protein.proteinId'], name='Protein_Has_PDB_fk1'), + Index('Protein_Has_PDB_fk1', 'proteinid'), + Index('Protein_Has_PDB_fk2', 'pdbid') + ) + + proteinhaspdbid: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + proteinid: Mapped[int] = mapped_column(INTEGER(11)) + pdbid: Mapped[int] = mapped_column(INTEGER(11)) + + PDB: Mapped['PDB'] = relationship('PDB', back_populates='Protein_has_PDB') + Protein: Mapped['Protein'] = relationship('Protein', back_populates='Protein_has_PDB') + + +class RobotAction(Base): + __tablename__ = 'RobotAction' + __table_args__ = ( + ForeignKeyConstraint(['blsampleId'], ['BLSample.blSampleId'], name='RobotAction_FK2'), + ForeignKeyConstraint(['blsessionId'], ['BLSession.sessionId'], name='RobotAction_FK1'), + Index('RobotAction_FK1', 'blsessionId'), + Index('RobotAction_FK2', 'blsampleId'), + {'comment': 'Robot actions as reported by GDA'} + ) + + robotActionId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + blsessionId: Mapped[int] = mapped_column(INTEGER(11)) + startTimestamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp() ON UPDATE current_timestamp()')) + endTimestamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text("'0000-00-00 00:00:00'")) + blsampleId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + actionType: Mapped[Optional[str]] = mapped_column(Enum('LOAD', 'UNLOAD', 'DISPOSE', 'STORE', 'WASH', 'ANNEAL', 'MOSAIC')) + status: Mapped[Optional[str]] = mapped_column(Enum('SUCCESS', 'ERROR', 'CRITICAL', 'WARNING', 'EPICSFAIL', 'COMMANDNOTSENT')) + message: Mapped[Optional[str]] = mapped_column(String(255)) + containerLocation: Mapped[Optional[int]] = mapped_column(SMALLINT(6)) + dewarLocation: Mapped[Optional[int]] = mapped_column(SMALLINT(6)) + sampleBarcode: Mapped[Optional[str]] = mapped_column(String(45)) + xtalSnapshotBefore: Mapped[Optional[str]] = mapped_column(String(255)) + xtalSnapshotAfter: Mapped[Optional[str]] = mapped_column(String(255)) + + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='RobotAction') + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='RobotAction') + + +class SampleComposition(Base): + __tablename__ = 'SampleComposition' + __table_args__ = ( + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], name='SampleComposition_ibfk_2'), + ForeignKeyConstraint(['componentId'], ['Component.componentId'], name='SampleComposition_ibfk_1'), + ForeignKeyConstraint(['concentrationTypeId'], ['ConcentrationType.concentrationTypeId'], name='SampleComposition_ibfk_3'), + Index('blSampleId', 'blSampleId'), + Index('componentId', 'componentId'), + Index('concentrationTypeId', 'concentrationTypeId'), + {'comment': 'Links a sample to its components with a specified abundance or ' + 'ratio.'} + ) + + sampleCompositionId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + componentId: Mapped[int] = mapped_column(INTEGER(11)) + blSampleId: Mapped[int] = mapped_column(INTEGER(11)) + concentrationTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + abundance: Mapped[Optional[float]] = mapped_column(Float, comment='Abundance or concentration in the unit defined by concentrationTypeId.') + ratio: Mapped[Optional[float]] = mapped_column(Float) + pH: Mapped[Optional[float]] = mapped_column(Float) + + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='SampleComposition') + Component: Mapped['Component'] = relationship('Component', back_populates='SampleComposition') + ConcentrationType: Mapped['ConcentrationType'] = relationship('ConcentrationType', back_populates='SampleComposition') + + +class ScanParametersModel(Base): + __tablename__ = 'ScanParametersModel' + __table_args__ = ( + ForeignKeyConstraint(['dataCollectionPlanId'], ['DiffractionPlan.diffractionPlanId'], onupdate='CASCADE', name='PDF_Model_ibfk2'), + ForeignKeyConstraint(['scanParametersServiceId'], ['ScanParametersService.scanParametersServiceId'], onupdate='CASCADE', name='PDF_Model_ibfk1'), + Index('PDF_Model_ibfk1', 'scanParametersServiceId'), + Index('PDF_Model_ibfk2', 'dataCollectionPlanId') + ) + + scanParametersModelId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + scanParametersServiceId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + dataCollectionPlanId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + sequenceNumber: Mapped[Optional[int]] = mapped_column(TINYINT(3)) + start: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + stop: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + step: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + array: Mapped[Optional[str]] = mapped_column(Text) + duration: Mapped[Optional[int]] = mapped_column(MEDIUMINT(8), comment='Duration for parameter change in seconds') + + DiffractionPlan: Mapped['DiffractionPlan'] = relationship('DiffractionPlan', back_populates='ScanParametersModel') + ScanParametersService: Mapped['ScanParametersService'] = relationship('ScanParametersService', back_populates='ScanParametersModel') + + +class ScreenComponentGroup(Base): + __tablename__ = 'ScreenComponentGroup' + __table_args__ = ( + ForeignKeyConstraint(['screenId'], ['Screen.screenId'], name='ScreenComponentGroup_fk1'), + Index('ScreenComponentGroup_fk1', 'screenId') + ) + + screenComponentGroupId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + screenId: Mapped[int] = mapped_column(INTEGER(11)) + position: Mapped[Optional[int]] = mapped_column(SMALLINT(6)) + + BLSample: Mapped[List['BLSample']] = relationship('BLSample', back_populates='ScreenComponentGroup') + Screen: Mapped['Screen'] = relationship('Screen', back_populates='ScreenComponentGroup') + ScreenComponent: Mapped[List['ScreenComponent']] = relationship('ScreenComponent', back_populates='ScreenComponentGroup') + + +class SessionType(Base): + __tablename__ = 'SessionType' + __table_args__ = ( + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], ondelete='CASCADE', onupdate='CASCADE', name='SessionType_ibfk_1'), + Index('SessionType_FKIndex1', 'sessionId') + ) + + sessionTypeId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + sessionId: Mapped[int] = mapped_column(INTEGER(10)) + typeName: Mapped[str] = mapped_column(String(31)) + + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='SessionType') + + +class SessionHasPerson(Base): + __tablename__ = 'Session_has_Person' + __table_args__ = ( + ForeignKeyConstraint(['personId'], ['Person.personId'], ondelete='CASCADE', onupdate='CASCADE', name='Session_has_Person_ibfk_2'), + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], ondelete='CASCADE', onupdate='CASCADE', name='Session_has_Person_ibfk_1'), + Index('Session_has_Person_FKIndex2', 'personId') + ) + + sessionId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True, server_default=text('0')) + personId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True, server_default=text('0')) + role: Mapped[Optional[str]] = mapped_column(Enum('Local Contact', 'Local Contact 2', 'Staff', 'Team Leader', 'Co-Investigator', 'Principal Investigator', 'Alternate Contact', 'Data Access', 'Team Member', 'ERA Admin', 'Associate')) + remote: Mapped[Optional[int]] = mapped_column(TINYINT(1), server_default=text('0')) + + Person: Mapped['Person'] = relationship('Person', back_populates='Session_has_Person') + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='Session_has_Person') + + +class Shipping(Base): + __tablename__ = 'Shipping' + __table_args__ = ( + ForeignKeyConstraint(['deliveryAgent_flightCodePersonId'], ['Person.personId'], name='Shipping_ibfk_4'), + ForeignKeyConstraint(['proposalId'], ['Proposal.proposalId'], ondelete='CASCADE', onupdate='CASCADE', name='Shipping_ibfk_1'), + ForeignKeyConstraint(['returnLabContactId'], ['LabContact.labContactId'], ondelete='CASCADE', onupdate='CASCADE', name='Shipping_ibfk_3'), + ForeignKeyConstraint(['sendingLabContactId'], ['LabContact.labContactId'], ondelete='CASCADE', onupdate='CASCADE', name='Shipping_ibfk_2'), + Index('Shipping_FKIndex1', 'proposalId'), + Index('Shipping_FKIndex2', 'sendingLabContactId'), + Index('Shipping_FKIndex3', 'returnLabContactId'), + Index('Shipping_FKIndexCreationDate', 'creationDate'), + Index('Shipping_FKIndexName', 'shippingName'), + Index('Shipping_FKIndexStatus', 'shippingStatus'), + Index('Shipping_ibfk_4', 'deliveryAgent_flightCodePersonId'), + Index('laboratoryId', 'laboratoryId') + ) + + shippingId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + proposalId: Mapped[int] = mapped_column(INTEGER(10), server_default=text('0')) + shippingName: Mapped[Optional[str]] = mapped_column(String(45)) + deliveryAgent_agentName: Mapped[Optional[str]] = mapped_column(String(45)) + deliveryAgent_shippingDate: Mapped[Optional[datetime.date]] = mapped_column(Date) + deliveryAgent_deliveryDate: Mapped[Optional[datetime.date]] = mapped_column(Date) + deliveryAgent_agentCode: Mapped[Optional[str]] = mapped_column(String(45)) + deliveryAgent_flightCode: Mapped[Optional[str]] = mapped_column(String(45)) + shippingStatus: Mapped[Optional[str]] = mapped_column(String(45)) + bltimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + laboratoryId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + isStorageShipping: Mapped[Optional[int]] = mapped_column(TINYINT(1), server_default=text('0')) + creationDate: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + comments: Mapped[Optional[str]] = mapped_column(String(1000)) + sendingLabContactId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + returnLabContactId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + returnCourier: Mapped[Optional[str]] = mapped_column(String(45)) + dateOfShippingToUser: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + shippingType: Mapped[Optional[str]] = mapped_column(String(45)) + SAFETYLEVEL: Mapped[Optional[str]] = mapped_column(String(8)) + deliveryAgent_flightCodeTimestamp: Mapped[Optional[datetime.datetime]] = mapped_column(TIMESTAMP, comment='Date flight code created, if automatic') + deliveryAgent_label: Mapped[Optional[str]] = mapped_column(Text, comment='Base64 encoded pdf of airway label') + readyByTime: Mapped[Optional[datetime.time]] = mapped_column(Time, comment='Time shipment will be ready') + closeTime: Mapped[Optional[datetime.time]] = mapped_column(Time, comment='Time after which shipment cannot be picked up') + physicalLocation: Mapped[Optional[str]] = mapped_column(String(50), comment='Where shipment can be picked up from: i.e. Stores') + deliveryAgent_pickupConfirmationTimestamp: Mapped[Optional[datetime.datetime]] = mapped_column(TIMESTAMP, comment='Date picked confirmed') + deliveryAgent_pickupConfirmation: Mapped[Optional[str]] = mapped_column(String(10), comment='Confirmation number of requested pickup') + deliveryAgent_readyByTime: Mapped[Optional[datetime.time]] = mapped_column(Time, comment='Confirmed ready-by time') + deliveryAgent_callinTime: Mapped[Optional[datetime.time]] = mapped_column(Time, comment='Confirmed courier call-in time') + deliveryAgent_productcode: Mapped[Optional[str]] = mapped_column(String(10), comment='A code that identifies which shipment service was used') + deliveryAgent_flightCodePersonId: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='The person who created the AWB (for auditing)') + extra: Mapped[Optional[str]] = mapped_column(LONGTEXT, comment='JSON column for facility-specific or hard-to-define attributes') + source: Mapped[Optional[str]] = mapped_column(String(50), server_default=text('current_user()')) + externalShippingIdToSynchrotron: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='ID for shipping to synchrotron in external application') + + Project: Mapped[List['Project']] = relationship('Project', secondary='Project_has_Shipping', back_populates='Shipping') + BLSession: Mapped[List['BLSession']] = relationship('BLSession', secondary='ShippingHasSession', back_populates='Shipping') + Person: Mapped['Person'] = relationship('Person', back_populates='Shipping') + Proposal: Mapped['Proposal'] = relationship('Proposal', back_populates='Shipping') + LabContact: Mapped['LabContact'] = relationship('LabContact', foreign_keys=[returnLabContactId], back_populates='Shipping') + LabContact: Mapped['LabContact'] = relationship('LabContact', foreign_keys=[sendingLabContactId], back_populates='Shipping') + CourierTermsAccepted: Mapped[List['CourierTermsAccepted']] = relationship('CourierTermsAccepted', back_populates='Shipping') + Dewar: Mapped[List['Dewar']] = relationship('Dewar', back_populates='Shipping') + + +class XFEFluorescenceSpectrum(Base): + __tablename__ = 'XFEFluorescenceSpectrum' + __table_args__ = ( + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], ondelete='CASCADE', onupdate='CASCADE', name='XFE_ibfk_2'), + ForeignKeyConstraint(['blSubSampleId'], ['BLSubSample.blSubSampleId'], name='XFE_ibfk_3'), + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], ondelete='CASCADE', onupdate='CASCADE', name='XFE_ibfk_1'), + Index('XFEFluorescnceSpectrum_FKIndex1', 'blSampleId'), + Index('XFEFluorescnceSpectrum_FKIndex2', 'sessionId'), + Index('XFE_ibfk_3', 'blSubSampleId') + ) + + xfeFluorescenceSpectrumId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + sessionId: Mapped[int] = mapped_column(INTEGER(10)) + blSampleId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + jpegScanFileFullPath: Mapped[Optional[str]] = mapped_column(String(255)) + startTime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + endTime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + filename: Mapped[Optional[str]] = mapped_column(String(255)) + exposureTime: Mapped[Optional[float]] = mapped_column(Float) + axisPosition: Mapped[Optional[float]] = mapped_column(Float) + beamTransmission: Mapped[Optional[float]] = mapped_column(Float) + annotatedPymcaXfeSpectrum: Mapped[Optional[str]] = mapped_column(String(255)) + fittedDataFileFullPath: Mapped[Optional[str]] = mapped_column(String(255)) + scanFileFullPath: Mapped[Optional[str]] = mapped_column(String(255)) + energy: Mapped[Optional[float]] = mapped_column(Float) + beamSizeVertical: Mapped[Optional[float]] = mapped_column(Float) + beamSizeHorizontal: Mapped[Optional[float]] = mapped_column(Float) + crystalClass: Mapped[Optional[str]] = mapped_column(String(20)) + comments: Mapped[Optional[str]] = mapped_column(String(1024)) + blSubSampleId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + flux: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True), comment='flux measured before the xrfSpectra') + flux_end: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True), comment='flux measured after the xrfSpectra') + workingDirectory: Mapped[Optional[str]] = mapped_column(String(512)) + + Project: Mapped[List['Project']] = relationship('Project', secondary='Project_has_XFEFSpectrum', back_populates='XFEFluorescenceSpectrum') + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='XFEFluorescenceSpectrum') + BLSubSample: Mapped['BLSubSample'] = relationship('BLSubSample', back_populates='XFEFluorescenceSpectrum') + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='XFEFluorescenceSpectrum') + + +class Atlas(Base): + __tablename__ = 'Atlas' + __table_args__ = ( + ForeignKeyConstraint(['dataCollectionGroupId'], ['DataCollectionGroup.dataCollectionGroupId'], onupdate='CASCADE', name='Atlas_fk_dataCollectionGroupId'), + Index('Atlas_fk_dataCollectionGroupId', 'dataCollectionGroupId'), + {'comment': 'Atlas of a Cryo-EM grid'} + ) + + atlasId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + dataCollectionGroupId: Mapped[int] = mapped_column(INTEGER(11)) + atlasImage: Mapped[str] = mapped_column(String(255), comment='path to atlas image') + pixelSize: Mapped[float] = mapped_column(Float, comment='pixel size of atlas image') + cassetteSlot: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + + DataCollectionGroup: Mapped['DataCollectionGroup'] = relationship('DataCollectionGroup', back_populates='Atlas') + GridSquare: Mapped[List['GridSquare']] = relationship('GridSquare', back_populates='Atlas') + + +class BLSampleTypeHasComponent(Base): + __tablename__ = 'BLSampleType_has_Component' + __table_args__ = ( + ForeignKeyConstraint(['blSampleTypeId'], ['Crystal.crystalId'], ondelete='CASCADE', onupdate='CASCADE', name='blSampleType_has_Component_fk1'), + ForeignKeyConstraint(['componentId'], ['Protein.proteinId'], ondelete='CASCADE', onupdate='CASCADE', name='blSampleType_has_Component_fk2'), + Index('blSampleType_has_Component_fk2', 'componentId') + ) + + blSampleTypeId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + componentId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + abundance: Mapped[Optional[float]] = mapped_column(Float) + + Crystal: Mapped['Crystal'] = relationship('Crystal', back_populates='BLSampleType_has_Component') + Protein: Mapped['Protein'] = relationship('Protein', back_populates='BLSampleType_has_Component') + + +class BLSampleHasEnergyScan(Base): + __tablename__ = 'BLSample_has_EnergyScan' + __table_args__ = ( + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], ondelete='CASCADE', onupdate='CASCADE', name='BLSample_has_EnergyScan_ibfk_1'), + ForeignKeyConstraint(['energyScanId'], ['EnergyScan.energyScanId'], ondelete='CASCADE', onupdate='CASCADE', name='BLSample_has_EnergyScan_ibfk_2'), + Index('BLSample_has_EnergyScan_FKIndex1', 'blSampleId'), + Index('BLSample_has_EnergyScan_FKIndex2', 'energyScanId') + ) + + blSampleId: Mapped[int] = mapped_column(INTEGER(10), server_default=text('0')) + energyScanId: Mapped[int] = mapped_column(INTEGER(10), server_default=text('0')) + blSampleHasEnergyScanId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='BLSample_has_EnergyScan') + EnergyScan: Mapped['EnergyScan'] = relationship('EnergyScan', back_populates='BLSample_has_EnergyScan') + + +class CourierTermsAccepted(Base): + __tablename__ = 'CourierTermsAccepted' + __table_args__ = ( + ForeignKeyConstraint(['personId'], ['Person.personId'], name='CourierTermsAccepted_ibfk_2'), + ForeignKeyConstraint(['proposalId'], ['Proposal.proposalId'], name='CourierTermsAccepted_ibfk_1'), + ForeignKeyConstraint(['shippingId'], ['Shipping.shippingId'], ondelete='CASCADE', onupdate='CASCADE', name='CourierTermsAccepted_ibfk_3'), + Index('CourierTermsAccepted_ibfk_1', 'proposalId'), + Index('CourierTermsAccepted_ibfk_2', 'personId'), + Index('CourierTermsAccepted_ibfk_3', 'shippingId'), + {'comment': 'Records acceptances of the courier T and C'} + ) + + courierTermsAcceptedId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + proposalId: Mapped[int] = mapped_column(INTEGER(10)) + personId: Mapped[int] = mapped_column(INTEGER(10)) + shippingName: Mapped[Optional[str]] = mapped_column(String(100)) + timestamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime, server_default=text('current_timestamp()')) + shippingId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + + Person: Mapped['Person'] = relationship('Person', back_populates='CourierTermsAccepted') + Proposal: Mapped['Proposal'] = relationship('Proposal', back_populates='CourierTermsAccepted') + Shipping: Mapped['Shipping'] = relationship('Shipping', back_populates='CourierTermsAccepted') + + +class CrystalComposition(Base): + __tablename__ = 'CrystalComposition' + __table_args__ = ( + ForeignKeyConstraint(['componentId'], ['Component.componentId'], name='CrystalComposition_ibfk_1'), + ForeignKeyConstraint(['concentrationTypeId'], ['ConcentrationType.concentrationTypeId'], name='CrystalComposition_ibfk_3'), + ForeignKeyConstraint(['crystalId'], ['Crystal.crystalId'], name='CrystalComposition_ibfk_2'), + Index('componentId', 'componentId'), + Index('concentrationTypeId', 'concentrationTypeId'), + Index('crystalId', 'crystalId'), + {'comment': 'Links a crystal to its components with a specified abundance or ' + 'ratio.'} + ) + + crystalCompositionId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + componentId: Mapped[int] = mapped_column(INTEGER(11)) + crystalId: Mapped[int] = mapped_column(INTEGER(11)) + concentrationTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + abundance: Mapped[Optional[float]] = mapped_column(Float, comment='Abundance or concentration in the unit defined by concentrationTypeId.') + ratio: Mapped[Optional[float]] = mapped_column(Float) + pH: Mapped[Optional[float]] = mapped_column(Float) + + Component: Mapped['Component'] = relationship('Component', back_populates='CrystalComposition') + ConcentrationType: Mapped['ConcentrationType'] = relationship('ConcentrationType', back_populates='CrystalComposition') + Crystal: Mapped['Crystal'] = relationship('Crystal', back_populates='CrystalComposition') + + +class CrystalHasUUID(Base): + __tablename__ = 'Crystal_has_UUID' + __table_args__ = ( + ForeignKeyConstraint(['crystalId'], ['Crystal.crystalId'], ondelete='CASCADE', onupdate='CASCADE', name='ibfk_1'), + Index('Crystal_has_UUID_FKIndex1', 'crystalId'), + Index('Crystal_has_UUID_FKIndex2', 'UUID') + ) + + crystal_has_UUID_Id: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + crystalId: Mapped[int] = mapped_column(INTEGER(10)) + UUID: Mapped[Optional[str]] = mapped_column(String(45)) + imageURL: Mapped[Optional[str]] = mapped_column(String(255)) + + Crystal: Mapped['Crystal'] = relationship('Crystal', back_populates='Crystal_has_UUID') + + +class Dewar(Base): + __tablename__ = 'Dewar' + __table_args__ = ( + ForeignKeyConstraint(['firstExperimentId'], ['BLSession.sessionId'], ondelete='SET NULL', onupdate='CASCADE', name='Dewar_fk_firstExperimentId'), + ForeignKeyConstraint(['shippingId'], ['Shipping.shippingId'], ondelete='CASCADE', onupdate='CASCADE', name='Dewar_ibfk_1'), + Index('Dewar_FKIndex1', 'shippingId'), + Index('Dewar_FKIndex2', 'firstExperimentId'), + Index('Dewar_FKIndexCode', 'code'), + Index('Dewar_FKIndexStatus', 'dewarStatus'), + Index('barCode', 'barCode', unique=True) + ) + + dewarId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + shippingId: Mapped[int] = mapped_column(INTEGER(10)) + type: Mapped[str] = mapped_column(Enum('Dewar', 'Toolbox', 'Parcel'), server_default=text("'Dewar'")) + code: Mapped[Optional[str]] = mapped_column(String(45)) + comments: Mapped[Optional[str]] = mapped_column(String(1024)) + storageLocation: Mapped[Optional[str]] = mapped_column(String(45)) + dewarStatus: Mapped[Optional[str]] = mapped_column(String(45)) + bltimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + isStorageDewar: Mapped[Optional[int]] = mapped_column(TINYINT(1), server_default=text('0')) + barCode: Mapped[Optional[str]] = mapped_column(String(45)) + firstExperimentId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + customsValue: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + transportValue: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + trackingNumberToSynchrotron: Mapped[Optional[str]] = mapped_column(String(30)) + trackingNumberFromSynchrotron: Mapped[Optional[str]] = mapped_column(String(30)) + facilityCode: Mapped[Optional[str]] = mapped_column(String(20)) + weight: Mapped[Optional[float]] = mapped_column(Float, comment='dewar weight in kg') + deliveryAgent_barcode: Mapped[Optional[str]] = mapped_column(String(30), comment='Courier piece barcode (not the airway bill)') + extra: Mapped[Optional[str]] = mapped_column(LONGTEXT, comment='JSON column for facility-specific or hard-to-define attributes, e.g. LN2 top-ups and contents checks') + source: Mapped[Optional[str]] = mapped_column(String(50), server_default=text('current_user()')) + externalShippingIdFromSynchrotron: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='ID for shipping from synchrotron in external application') + + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='Dewar') + Shipping: Mapped['Shipping'] = relationship('Shipping', back_populates='Dewar') + Container: Mapped[List['Container']] = relationship('Container', foreign_keys='[Container.currentDewarId]', back_populates='Dewar') + Container: Mapped[List['Container']] = relationship('Container', foreign_keys='[Container.dewarId]', back_populates='Dewar') + DewarTransportHistory: Mapped[List['DewarTransportHistory']] = relationship('DewarTransportHistory', back_populates='Dewar') + ContainerHistory: Mapped[List['ContainerHistory']] = relationship('ContainerHistory', back_populates='Dewar') + + +class DewarRegistryHasProposal(Base): + __tablename__ = 'DewarRegistry_has_Proposal' + __table_args__ = ( + ForeignKeyConstraint(['dewarRegistryId'], ['DewarRegistry.dewarRegistryId'], name='DewarRegistry_has_Proposal_ibfk1'), + ForeignKeyConstraint(['labContactId'], ['LabContact.labContactId'], onupdate='CASCADE', name='DewarRegistry_has_Proposal_ibfk4'), + ForeignKeyConstraint(['personId'], ['Person.personId'], name='DewarRegistry_has_Proposal_ibfk3'), + ForeignKeyConstraint(['proposalId'], ['Proposal.proposalId'], name='DewarRegistry_has_Proposal_ibfk2'), + Index('DewarRegistry_has_Proposal_ibfk2', 'proposalId'), + Index('DewarRegistry_has_Proposal_ibfk3', 'personId'), + Index('DewarRegistry_has_Proposal_ibfk4', 'labContactId'), + Index('dewarRegistryId', 'dewarRegistryId', 'proposalId', unique=True) + ) + + dewarRegistryHasProposalId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + dewarRegistryId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + proposalId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + personId: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Person registering the dewar') + recordTimestamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime, server_default=text('current_timestamp()')) + labContactId: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='Owner of the dewar') + + DewarRegistry: Mapped['DewarRegistry'] = relationship('DewarRegistry', back_populates='DewarRegistry_has_Proposal') + LabContact: Mapped['LabContact'] = relationship('LabContact', back_populates='DewarRegistry_has_Proposal') + Person: Mapped['Person'] = relationship('Person', back_populates='DewarRegistry_has_Proposal') + Proposal: Mapped['Proposal'] = relationship('Proposal', back_populates='DewarRegistry_has_Proposal') + + +class DewarReport(Base): + __tablename__ = 'DewarReport' + __table_args__ = ( + ForeignKeyConstraint(['facilityCode'], ['DewarRegistry.facilityCode'], ondelete='CASCADE', name='DewarReport_ibfk_1'), + Index('DewarReportIdx1', 'facilityCode') + ) + + dewarReportId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + facilityCode: Mapped[str] = mapped_column(String(20)) + bltimestamp: Mapped[datetime.datetime] = mapped_column(DateTime, server_default=text('current_timestamp()')) + report: Mapped[Optional[str]] = mapped_column(Text) + attachment: Mapped[Optional[str]] = mapped_column(String(255)) + + DewarRegistry: Mapped['DewarRegistry'] = relationship('DewarRegistry', back_populates='DewarReport') + + +class GridInfo(Base): + __tablename__ = 'GridInfo' + __table_args__ = ( + ForeignKeyConstraint(['dataCollectionGroupId'], ['DataCollectionGroup.dataCollectionGroupId'], name='GridInfo_ibfk_2'), + ForeignKeyConstraint(['dataCollectionId'], ['DataCollection.dataCollectionId'], ondelete='CASCADE', onupdate='CASCADE', name='GridInfo_fk_dataCollectionId'), + Index('GridInfo_fk_dataCollectionId', 'dataCollectionId'), + Index('GridInfo_ibfk_2', 'dataCollectionGroupId'), + Index('workflowMeshId', 'workflowMeshId') + ) + + gridInfoId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True, comment='Primary key (auto-incremented)') + recordTimeStamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp()'), comment='Creation or last update date/time') + xOffset: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + yOffset: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + dx_mm: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + dy_mm: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + steps_x: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + steps_y: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + meshAngle: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + workflowMeshId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + orientation: Mapped[Optional[str]] = mapped_column(Enum('vertical', 'horizontal'), server_default=text("'horizontal'")) + dataCollectionGroupId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + pixelsPerMicronX: Mapped[Optional[float]] = mapped_column(Float) + pixelsPerMicronY: Mapped[Optional[float]] = mapped_column(Float) + snapshot_offsetXPixel: Mapped[Optional[float]] = mapped_column(Float) + snapshot_offsetYPixel: Mapped[Optional[float]] = mapped_column(Float) + snaked: Mapped[Optional[int]] = mapped_column(TINYINT(1), server_default=text('0'), comment='True: The images associated with the DCG were collected in a snaked pattern') + dataCollectionId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + patchesX: Mapped[Optional[int]] = mapped_column(INTEGER(10), server_default=text('1'), comment='Number of patches the grid is made up of in the X direction') + patchesY: Mapped[Optional[int]] = mapped_column(INTEGER(10), server_default=text('1'), comment='Number of patches the grid is made up of in the Y direction') + micronsPerPixelX: Mapped[Optional[float]] = mapped_column(Float) + micronsPerPixelY: Mapped[Optional[float]] = mapped_column(Float) + + DataCollectionGroup: Mapped['DataCollectionGroup'] = relationship('DataCollectionGroup', back_populates='GridInfo') + DataCollection: Mapped['DataCollection'] = relationship('DataCollection', back_populates='GridInfo') + XRFFluorescenceMapping: Mapped[List['XRFFluorescenceMapping']] = relationship('XRFFluorescenceMapping', back_populates='GridInfo') + + +t_Project_has_DCGroup = Table( + 'Project_has_DCGroup', Base.metadata, + Column('projectId', INTEGER(11), primary_key=True, nullable=False), + Column('dataCollectionGroupId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['dataCollectionGroupId'], ['DataCollectionGroup.dataCollectionGroupId'], ondelete='CASCADE', onupdate='CASCADE', name='Project_has_DCGroup_FK2'), + ForeignKeyConstraint(['projectId'], ['Project.projectId'], ondelete='CASCADE', onupdate='CASCADE', name='Project_has_DCGroup_FK1'), + Index('Project_has_DCGroup_FK2', 'dataCollectionGroupId') +) + + +t_Project_has_EnergyScan = Table( + 'Project_has_EnergyScan', Base.metadata, + Column('projectId', INTEGER(11), primary_key=True, nullable=False), + Column('energyScanId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['energyScanId'], ['EnergyScan.energyScanId'], ondelete='CASCADE', onupdate='CASCADE', name='project_has_energyscan_FK2'), + ForeignKeyConstraint(['projectId'], ['Project.projectId'], ondelete='CASCADE', onupdate='CASCADE', name='project_has_energyscan_FK1'), + Index('project_has_energyscan_FK2', 'energyScanId') +) + + +t_Project_has_Shipping = Table( + 'Project_has_Shipping', Base.metadata, + Column('projectId', INTEGER(11), primary_key=True, nullable=False), + Column('shippingId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['projectId'], ['Project.projectId'], ondelete='CASCADE', name='project_has_shipping_FK1'), + ForeignKeyConstraint(['shippingId'], ['Shipping.shippingId'], ondelete='CASCADE', name='project_has_shipping_FK2'), + Index('project_has_shipping_FK2', 'shippingId') +) + + +t_Project_has_XFEFSpectrum = Table( + 'Project_has_XFEFSpectrum', Base.metadata, + Column('projectId', INTEGER(11), primary_key=True, nullable=False), + Column('xfeFluorescenceSpectrumId', INTEGER(11), primary_key=True, nullable=False), + ForeignKeyConstraint(['projectId'], ['Project.projectId'], ondelete='CASCADE', name='project_has_xfefspectrum_FK1'), + ForeignKeyConstraint(['xfeFluorescenceSpectrumId'], ['XFEFluorescenceSpectrum.xfeFluorescenceSpectrumId'], ondelete='CASCADE', name='project_has_xfefspectrum_FK2'), + Index('project_has_xfefspectrum_FK2', 'xfeFluorescenceSpectrumId') +) + + +class ScreenComponent(Base): + __tablename__ = 'ScreenComponent' + __table_args__ = ( + ForeignKeyConstraint(['componentId'], ['Protein.proteinId'], name='ScreenComponent_fk2'), + ForeignKeyConstraint(['screenComponentGroupId'], ['ScreenComponentGroup.screenComponentGroupId'], name='ScreenComponent_fk1'), + Index('ScreenComponent_fk1', 'screenComponentGroupId'), + Index('ScreenComponent_fk2', 'componentId') + ) + + screenComponentId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + screenComponentGroupId: Mapped[int] = mapped_column(INTEGER(11)) + componentId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + concentration: Mapped[Optional[float]] = mapped_column(Float) + pH: Mapped[Optional[float]] = mapped_column(Float) + + Protein: Mapped['Protein'] = relationship('Protein', back_populates='ScreenComponent') + ScreenComponentGroup: Mapped['ScreenComponentGroup'] = relationship('ScreenComponentGroup', back_populates='ScreenComponent') + + +t_ShippingHasSession = Table( + 'ShippingHasSession', Base.metadata, + Column('shippingId', INTEGER(10), primary_key=True, nullable=False), + Column('sessionId', INTEGER(10), primary_key=True, nullable=False), + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], ondelete='CASCADE', onupdate='CASCADE', name='ShippingHasSession_ibfk_2'), + ForeignKeyConstraint(['shippingId'], ['Shipping.shippingId'], ondelete='CASCADE', onupdate='CASCADE', name='ShippingHasSession_ibfk_1'), + Index('ShippingHasSession_FKIndex2', 'sessionId') +) + + +class XrayCentring(Base): + __tablename__ = 'XrayCentring' + __table_args__ = ( + ForeignKeyConstraint(['dataCollectionGroupId'], ['DataCollectionGroup.dataCollectionGroupId'], ondelete='CASCADE', onupdate='CASCADE', name='XrayCentring_ibfk_1'), + Index('dataCollectionGroupId', 'dataCollectionGroupId'), + {'comment': 'Xray Centring analysis associated with one or more grid scans.'} + ) + + xrayCentringId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + dataCollectionGroupId: Mapped[int] = mapped_column(INTEGER(11), comment='references DataCollectionGroup table') + status: Mapped[Optional[str]] = mapped_column(Enum('success', 'failed', 'pending')) + xrayCentringType: Mapped[Optional[str]] = mapped_column(Enum('2d', '3d')) + + DataCollectionGroup: Mapped['DataCollectionGroup'] = relationship('DataCollectionGroup', back_populates='XrayCentring') + XrayCentringResult: Mapped[List['XrayCentringResult']] = relationship('XrayCentringResult', back_populates='XrayCentring') + + +class Container(Base): + __tablename__ = 'Container' + __table_args__ = ( + ForeignKeyConstraint(['containerRegistryId'], ['ContainerRegistry.containerRegistryId'], name='Container_ibfk8'), + ForeignKeyConstraint(['containerTypeId'], ['ContainerType.containerTypeId'], name='Container_ibfk10'), + ForeignKeyConstraint(['currentDewarId'], ['Dewar.dewarId'], name='Container_fk_currentDewarId'), + ForeignKeyConstraint(['dewarId'], ['Dewar.dewarId'], ondelete='CASCADE', onupdate='CASCADE', name='Container_ibfk_1'), + ForeignKeyConstraint(['experimentTypeId'], ['ExperimentType.experimentTypeId'], name='Container_fk_experimentTypeId'), + ForeignKeyConstraint(['imagerId'], ['Imager.imagerId'], name='Container_ibfk4'), + ForeignKeyConstraint(['ownerId'], ['Person.personId'], name='Container_ibfk5'), + ForeignKeyConstraint(['parentContainerId'], ['Container.containerId'], name='Container_fk_parentContainerId'), + ForeignKeyConstraint(['priorityPipelineId'], ['ProcessingPipeline.processingPipelineId'], name='Container_ibfk9'), + ForeignKeyConstraint(['requestedImagerId'], ['Imager.imagerId'], name='Container_ibfk7'), + ForeignKeyConstraint(['scheduleId'], ['Schedule.scheduleId'], name='Container_ibfk3'), + ForeignKeyConstraint(['screenId'], ['Screen.screenId'], name='Container_ibfk2'), + ForeignKeyConstraint(['sessionId'], ['BLSession.sessionId'], ondelete='SET NULL', onupdate='CASCADE', name='Container_ibfk6'), + Index('Container_FKIndex', 'beamlineLocation'), + Index('Container_FKIndex1', 'dewarId'), + Index('Container_FKIndexStatus', 'containerStatus'), + Index('Container_UNIndex1', 'barcode', unique=True), + Index('Container_fk_currentDewarId', 'currentDewarId'), + Index('Container_fk_experimentTypeId', 'experimentTypeId'), + Index('Container_fk_parentContainerId', 'parentContainerId'), + Index('Container_ibfk10', 'containerTypeId'), + Index('Container_ibfk2', 'screenId'), + Index('Container_ibfk3', 'scheduleId'), + Index('Container_ibfk4', 'imagerId'), + Index('Container_ibfk5', 'ownerId'), + Index('Container_ibfk6', 'sessionId'), + Index('Container_ibfk7', 'requestedImagerId'), + Index('Container_ibfk8', 'containerRegistryId'), + Index('Container_ibfk9', 'priorityPipelineId') + ) + + containerId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + dewarId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + code: Mapped[Optional[str]] = mapped_column(String(45)) + containerType: Mapped[Optional[str]] = mapped_column(String(20)) + capacity: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + sampleChangerLocation: Mapped[Optional[str]] = mapped_column(String(20)) + containerStatus: Mapped[Optional[str]] = mapped_column(String(45)) + bltimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + beamlineLocation: Mapped[Optional[str]] = mapped_column(String(20)) + screenId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + scheduleId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + barcode: Mapped[Optional[str]] = mapped_column(String(45)) + imagerId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + sessionId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + ownerId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + requestedImagerId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + requestedReturn: Mapped[Optional[int]] = mapped_column(TINYINT(1), server_default=text('0'), comment='True for requesting return, False means container will be disposed') + comments: Mapped[Optional[str]] = mapped_column(String(255)) + experimentType: Mapped[Optional[str]] = mapped_column(String(20)) + storageTemperature: Mapped[Optional[float]] = mapped_column(Float, comment='NULL=ambient') + containerRegistryId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + scLocationUpdated: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + priorityPipelineId: Mapped[Optional[int]] = mapped_column(INTEGER(11), server_default=text('6'), comment='Processing pipeline to prioritise, defaults to 6 which is xia2/DIALS') + experimentTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + containerTypeId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + currentDewarId: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='The dewar with which the container is currently associated') + parentContainerId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + source: Mapped[Optional[str]] = mapped_column(String(50), server_default=text('current_user()')) + + BLSample: Mapped[List['BLSample']] = relationship('BLSample', back_populates='Container') + ContainerRegistry: Mapped['ContainerRegistry'] = relationship('ContainerRegistry', back_populates='Container') + ContainerType: Mapped['ContainerType'] = relationship('ContainerType', back_populates='Container') + Dewar: Mapped['Dewar'] = relationship('Dewar', foreign_keys=[currentDewarId], back_populates='Container') + Dewar: Mapped['Dewar'] = relationship('Dewar', foreign_keys=[dewarId], back_populates='Container') + ExperimentType: Mapped['ExperimentType'] = relationship('ExperimentType', back_populates='Container') + Imager: Mapped['Imager'] = relationship('Imager', foreign_keys=[imagerId], back_populates='Container') + Person: Mapped['Person'] = relationship('Person', back_populates='Container') + Container: Mapped['Container'] = relationship('Container', remote_side=[containerId], back_populates='Container_reverse') + Container_reverse: Mapped[List['Container']] = relationship('Container', remote_side=[parentContainerId], back_populates='Container') + ProcessingPipeline: Mapped['ProcessingPipeline'] = relationship('ProcessingPipeline', back_populates='Container') + Imager: Mapped['Imager'] = relationship('Imager', foreign_keys=[requestedImagerId], back_populates='Container') + Schedule: Mapped['Schedule'] = relationship('Schedule', back_populates='Container') + Screen: Mapped['Screen'] = relationship('Screen', back_populates='Container') + BLSession: Mapped['BLSession'] = relationship('BLSession', back_populates='Container') + BF_automationFault: Mapped[List['BFAutomationFault']] = relationship('BFAutomationFault', back_populates='Container') + ContainerHistory: Mapped[List['ContainerHistory']] = relationship('ContainerHistory', back_populates='Container') + ContainerInspection: Mapped[List['ContainerInspection']] = relationship('ContainerInspection', back_populates='Container') + ContainerQueue: Mapped[List['ContainerQueue']] = relationship('ContainerQueue', back_populates='Container') + + +class DewarTransportHistory(Base): + __tablename__ = 'DewarTransportHistory' + __table_args__ = ( + ForeignKeyConstraint(['dewarId'], ['Dewar.dewarId'], ondelete='CASCADE', onupdate='CASCADE', name='DewarTransportHistory_ibfk_1'), + Index('DewarTransportHistory_FKIndex1', 'dewarId') + ) + + DewarTransportHistoryId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + dewarStatus: Mapped[str] = mapped_column(String(45)) + storageLocation: Mapped[str] = mapped_column(String(45)) + arrivalDate: Mapped[datetime.datetime] = mapped_column(DateTime) + dewarId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + + Dewar: Mapped['Dewar'] = relationship('Dewar', back_populates='DewarTransportHistory') + + +class GridSquare(Base): + __tablename__ = 'GridSquare' + __table_args__ = ( + ForeignKeyConstraint(['atlasId'], ['Atlas.atlasId'], onupdate='CASCADE', name='GridSquare_fk_atlasId'), + Index('GridSquare_fk_atlasId', 'atlasId'), + {'comment': 'Details of a Cryo-EM grid square including image captured at grid ' + 'square magnification'} + ) + + gridSquareId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + atlasId: Mapped[int] = mapped_column(INTEGER(11)) + gridSquareLabel: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='grid square reference from acquisition software') + gridSquareImage: Mapped[Optional[str]] = mapped_column(String(255), comment='path to grid square image') + pixelLocationX: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='pixel location of grid square centre on atlas image (x)') + pixelLocationY: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='pixel location of grid square centre on atlas image (y)') + height: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='grid square height on atlas image in pixels') + width: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='grid square width on atlas image in pixels') + angle: Mapped[Optional[float]] = mapped_column(Float, comment='angle of grid square relative to atlas image') + stageLocationX: Mapped[Optional[float]] = mapped_column(Float, comment='x stage position (microns)') + stageLocationY: Mapped[Optional[float]] = mapped_column(Float, comment='y stage position (microns)') + qualityIndicator: Mapped[Optional[float]] = mapped_column(Float, comment='metric for determining quality of grid square') + pixelSize: Mapped[Optional[float]] = mapped_column(Float, comment='pixel size of grid square image') + + Atlas: Mapped['Atlas'] = relationship('Atlas', back_populates='GridSquare') + FoilHole: Mapped[List['FoilHole']] = relationship('FoilHole', back_populates='GridSquare') + Tomogram: Mapped[List['Tomogram']] = relationship('Tomogram', back_populates='GridSquare') + + +class XRFFluorescenceMapping(Base): + __tablename__ = 'XRFFluorescenceMapping' + __table_args__ = ( + ForeignKeyConstraint(['autoProcProgramId'], ['AutoProcProgram.autoProcProgramId'], name='XRFFluorescenceMapping_ibfk3'), + ForeignKeyConstraint(['gridInfoId'], ['GridInfo.gridInfoId'], name='XRFFluorescenceMapping_ibfk2'), + ForeignKeyConstraint(['xrfFluorescenceMappingROIId'], ['XRFFluorescenceMappingROI.xrfFluorescenceMappingROIId'], ondelete='CASCADE', onupdate='CASCADE', name='XRFFluorescenceMapping_ibfk1'), + Index('XRFFluorescenceMapping_ibfk1', 'xrfFluorescenceMappingROIId'), + Index('XRFFluorescenceMapping_ibfk2', 'gridInfoId'), + Index('XRFFluorescenceMapping_ibfk3', 'autoProcProgramId'), + {'comment': 'An XRF map generated from an XRF Mapping ROI based on data from a ' + 'gridscan of a sample'} + ) + + xrfFluorescenceMappingId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + xrfFluorescenceMappingROIId: Mapped[int] = mapped_column(INTEGER(11)) + gridInfoId: Mapped[int] = mapped_column(INTEGER(11)) + dataFormat: Mapped[str] = mapped_column(String(15), comment='Description of format and any compression, i.e. json+gzip for gzipped json') + data: Mapped[bytes] = mapped_column(LONGBLOB, comment='The actual data') + opacity: Mapped[float] = mapped_column(Float, server_default=text('1'), comment='Display opacity') + points: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='The number of points available, for realtime feedback') + colourMap: Mapped[Optional[str]] = mapped_column(String(20), comment='Colour map for displaying the data') + min: Mapped[Optional[int]] = mapped_column(INTEGER(3), comment='Min value in the data for histogramming') + max: Mapped[Optional[int]] = mapped_column(INTEGER(3), comment='Max value in the data for histogramming') + autoProcProgramId: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Related autoproc programid') + + AutoProcProgram: Mapped['AutoProcProgram'] = relationship('AutoProcProgram', back_populates='XRFFluorescenceMapping') + GridInfo: Mapped['GridInfo'] = relationship('GridInfo', back_populates='XRFFluorescenceMapping') + XRFFluorescenceMappingROI: Mapped['XRFFluorescenceMappingROI'] = relationship('XRFFluorescenceMappingROI', back_populates='XRFFluorescenceMapping') + XFEFluorescenceComposite: Mapped[List['XFEFluorescenceComposite']] = relationship('XFEFluorescenceComposite', foreign_keys='[XFEFluorescenceComposite.b]', back_populates='XRFFluorescenceMapping') + XFEFluorescenceComposite: Mapped[List['XFEFluorescenceComposite']] = relationship('XFEFluorescenceComposite', foreign_keys='[XFEFluorescenceComposite.g]', back_populates='XRFFluorescenceMapping') + XFEFluorescenceComposite: Mapped[List['XFEFluorescenceComposite']] = relationship('XFEFluorescenceComposite', foreign_keys='[XFEFluorescenceComposite.r]', back_populates='XRFFluorescenceMapping') + + +class XrayCentringResult(Base): + __tablename__ = 'XrayCentringResult' + __table_args__ = ( + ForeignKeyConstraint(['xrayCentringId'], ['XrayCentring.xrayCentringId'], ondelete='CASCADE', onupdate='CASCADE', name='XrayCentringResult_ibfk_1'), + Index('xrayCentringId', 'xrayCentringId'), + {'comment': 'Xray Centring result.'} + ) + + xrayCentringResultId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + xrayCentringId: Mapped[int] = mapped_column(INTEGER(11), comment='references XrayCentring table') + centreOfMassX: Mapped[Optional[float]] = mapped_column(Float, comment='x-coordinate corresponding to the centre of mass of the crystal (in voxels)') + centreOfMassY: Mapped[Optional[float]] = mapped_column(Float, comment='y-coordinate corresponding to the centre of mass of the crystal (in voxels)') + centreOfMassZ: Mapped[Optional[float]] = mapped_column(Float, comment='z-coordinate corresponding to the centre of mass of the crystal (in voxels)') + maxVoxelX: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='x-coordinate of the voxel with the maximum value within this crystal volume') + maxVoxelY: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='y-coordinate of the voxel with the maximum value within this crystal volume') + maxVoxelZ: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='z-coordinate of the voxel with the maximum value within this crystal volume') + numberOfVoxels: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='Number of voxels within the specified bounding box') + totalCount: Mapped[Optional[float]] = mapped_column(Float, comment='The sum of the values of all the voxels within the specified bounding box') + boundingBoxMinX: Mapped[Optional[float]] = mapped_column(Float, comment='Minimum x-coordinate of the bounding box containing the crystal (in voxels)') + boundingBoxMaxX: Mapped[Optional[float]] = mapped_column(Float, comment='Maximum x-coordinate of the bounding box containing the crystal (in voxels)') + boundingBoxMinY: Mapped[Optional[float]] = mapped_column(Float, comment='Minimum y-coordinate of the bounding box containing the crystal (in voxels)') + boundingBoxMaxY: Mapped[Optional[float]] = mapped_column(Float, comment='Maximum y-coordinate of the bounding box containing the crystal (in voxels)') + boundingBoxMinZ: Mapped[Optional[float]] = mapped_column(Float, comment='Minimum z-coordinate of the bounding box containing the crystal (in voxels)') + boundingBoxMaxZ: Mapped[Optional[float]] = mapped_column(Float, comment='Maximum z-coordinate of the bounding box containing the crystal (in voxels)') + status: Mapped[Optional[str]] = mapped_column(Enum('success', 'failure', 'pending'), comment='to be removed') + gridInfoId: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='to be removed') + + XrayCentring: Mapped['XrayCentring'] = relationship('XrayCentring', back_populates='XrayCentringResult') + + +class BFAutomationFault(Base): + __tablename__ = 'BF_automationFault' + __table_args__ = ( + ForeignKeyConstraint(['automationErrorId'], ['BF_automationError.automationErrorId'], name='BF_automationFault_ibfk1'), + ForeignKeyConstraint(['containerId'], ['Container.containerId'], name='BF_automationFault_ibfk2'), + Index('BF_automationFault_ibfk1', 'automationErrorId'), + Index('BF_automationFault_ibfk2', 'containerId') + ) + + automationFaultId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + faultTimeStamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp()')) + automationErrorId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + containerId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + severity: Mapped[Optional[str]] = mapped_column(Enum('1', '2', '3')) + stacktrace: Mapped[Optional[str]] = mapped_column(Text) + resolved: Mapped[Optional[int]] = mapped_column(TINYINT(1)) + + BF_automationError: Mapped['BFAutomationError'] = relationship('BFAutomationError', back_populates='BF_automationFault') + Container: Mapped['Container'] = relationship('Container', back_populates='BF_automationFault') + + +class ContainerHistory(Base): + __tablename__ = 'ContainerHistory' + __table_args__ = ( + ForeignKeyConstraint(['containerId'], ['Container.containerId'], ondelete='CASCADE', onupdate='CASCADE', name='ContainerHistory_ibfk1'), + ForeignKeyConstraint(['currentDewarId'], ['Dewar.dewarId'], name='ContainerHistory_fk_dewarId'), + Index('ContainerHistory_fk_dewarId', 'currentDewarId'), + Index('ContainerHistory_ibfk1', 'containerId') + ) + + containerHistoryId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + blTimeStamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp()')) + containerId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + location: Mapped[Optional[str]] = mapped_column(String(45)) + status: Mapped[Optional[str]] = mapped_column(String(45)) + beamlineName: Mapped[Optional[str]] = mapped_column(String(20)) + currentDewarId: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='The dewar with which the container was associated at the creation of this row') + + Container: Mapped['Container'] = relationship('Container', back_populates='ContainerHistory') + Dewar: Mapped['Dewar'] = relationship('Dewar', back_populates='ContainerHistory') + + +class ContainerInspection(Base): + __tablename__ = 'ContainerInspection' + __table_args__ = ( + ForeignKeyConstraint(['containerId'], ['Container.containerId'], ondelete='CASCADE', onupdate='CASCADE', name='ContainerInspection_fk1'), + ForeignKeyConstraint(['imagerId'], ['Imager.imagerId'], name='ContainerInspection_fk3'), + ForeignKeyConstraint(['inspectionTypeId'], ['InspectionType.inspectionTypeId'], name='ContainerInspection_fk2'), + ForeignKeyConstraint(['scheduleComponentid'], ['ScheduleComponent.scheduleComponentId'], name='ContainerInspection_fk4'), + Index('ContainerInspection_fk4', 'scheduleComponentid'), + Index('ContainerInspection_idx2', 'inspectionTypeId'), + Index('ContainerInspection_idx3', 'imagerId'), + Index('ContainerInspection_idx4', 'containerId', 'scheduleComponentid', 'state', 'manual') + ) + + containerInspectionId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + containerId: Mapped[int] = mapped_column(INTEGER(11)) + inspectionTypeId: Mapped[int] = mapped_column(INTEGER(11)) + imagerId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + temperature: Mapped[Optional[float]] = mapped_column(Float) + blTimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + scheduleComponentid: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + state: Mapped[Optional[str]] = mapped_column(String(20)) + priority: Mapped[Optional[int]] = mapped_column(SMALLINT(6)) + manual: Mapped[Optional[int]] = mapped_column(TINYINT(1)) + scheduledTimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + completedTimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime) + + BLSampleImage: Mapped[List['BLSampleImage']] = relationship('BLSampleImage', back_populates='ContainerInspection') + Container: Mapped['Container'] = relationship('Container', back_populates='ContainerInspection') + Imager: Mapped['Imager'] = relationship('Imager', back_populates='ContainerInspection') + InspectionType: Mapped['InspectionType'] = relationship('InspectionType', back_populates='ContainerInspection') + ScheduleComponent: Mapped['ScheduleComponent'] = relationship('ScheduleComponent', back_populates='ContainerInspection') + + +class ContainerQueue(Base): + __tablename__ = 'ContainerQueue' + __table_args__ = ( + ForeignKeyConstraint(['containerId'], ['Container.containerId'], ondelete='CASCADE', onupdate='CASCADE', name='ContainerQueue_ibfk1'), + ForeignKeyConstraint(['personId'], ['Person.personId'], onupdate='CASCADE', name='ContainerQueue_ibfk2'), + Index('ContainerQueue_ibfk1', 'containerId'), + Index('ContainerQueue_ibfk2', 'personId'), + Index('ContainerQueue_idx1', 'containerId', 'completedTimeStamp') + ) + + containerQueueId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + containerId: Mapped[int] = mapped_column(INTEGER(10)) + createdTimeStamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp()')) + personId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + completedTimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(TIMESTAMP) + + Container: Mapped['Container'] = relationship('Container', back_populates='ContainerQueue') + Person: Mapped['Person'] = relationship('Person', back_populates='ContainerQueue') + ContainerQueueSample: Mapped[List['ContainerQueueSample']] = relationship('ContainerQueueSample', back_populates='ContainerQueue') + + +class FoilHole(Base): + __tablename__ = 'FoilHole' + __table_args__ = ( + ForeignKeyConstraint(['gridSquareId'], ['GridSquare.gridSquareId'], onupdate='CASCADE', name='FoilHole_fk_gridSquareId'), + Index('FoilHole_fk_gridSquareId', 'gridSquareId'), + {'comment': 'Details of a Cryo-EM foil hole within a grid square including ' + 'image captured at foil hole magnification if applicable'} + ) + + foilHoleId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + gridSquareId: Mapped[int] = mapped_column(INTEGER(11)) + foilHoleLabel: Mapped[str] = mapped_column(String(30), comment='foil hole reference name from acquisition software') + foilHoleImage: Mapped[Optional[str]] = mapped_column(String(255), comment='path to foil hole image, nullable as there is not always a foil hole image') + pixelLocationX: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='pixel location of foil hole centre on grid square image (x)') + pixelLocationY: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='pixel location of foil hole centre on grid square image (y)') + diameter: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='foil hole diameter on grid square image in pixels') + stageLocationX: Mapped[Optional[float]] = mapped_column(Float, comment='x stage position (microns)') + stageLocationY: Mapped[Optional[float]] = mapped_column(Float, comment='y stage position (microns)') + qualityIndicator: Mapped[Optional[float]] = mapped_column(Float, comment='metric for determining quality of foil hole') + pixelSize: Mapped[Optional[float]] = mapped_column(Float, comment='pixel size of foil hole image') + + GridSquare: Mapped['GridSquare'] = relationship('GridSquare', back_populates='FoilHole') + Movie: Mapped[List['Movie']] = relationship('Movie', back_populates='FoilHole') + + +class Tomogram(Base): + __tablename__ = 'Tomogram' + __table_args__ = ( + ForeignKeyConstraint(['autoProcProgramId'], ['AutoProcProgram.autoProcProgramId'], ondelete='SET NULL', onupdate='CASCADE', name='Tomogram_fk_autoProcProgramId'), + ForeignKeyConstraint(['dataCollectionId'], ['DataCollection.dataCollectionId'], ondelete='CASCADE', onupdate='CASCADE', name='Tomogram_fk_dataCollectionId'), + ForeignKeyConstraint(['gridSquareId'], ['GridSquare.gridSquareId'], name='Tomogram_fk_gridSquareId'), + Index('Tomogram_fk_autoProcProgramId', 'autoProcProgramId'), + Index('Tomogram_fk_dataCollectionId', 'dataCollectionId'), + Index('Tomogram_fk_gridSquareId', 'gridSquareId'), + {'comment': 'For storing per-sample, per-position data analysis results ' + '(reconstruction)'} + ) + + tomogramId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + dataCollectionId: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='FK to\xa0DataCollection\xa0table') + autoProcProgramId: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='FK, gives processing times/status and software information') + volumeFile: Mapped[Optional[str]] = mapped_column(String(255), comment='.mrc\xa0file representing the reconstructed tomogram volume') + stackFile: Mapped[Optional[str]] = mapped_column(String(255), comment='.mrc\xa0file containing the motion corrected images ordered by angle used as input for the reconstruction') + sizeX: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='unit: pixels') + sizeY: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='unit: pixels') + sizeZ: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='unit: pixels') + pixelSpacing: Mapped[Optional[float]] = mapped_column(Float, comment='Angstrom/pixel conversion factor') + residualErrorMean: Mapped[Optional[float]] = mapped_column(Float, comment='Alignment error, unit: nm') + residualErrorSD: Mapped[Optional[float]] = mapped_column(Float, comment='Standard deviation of the alignment error, unit: nm') + xAxisCorrection: Mapped[Optional[float]] = mapped_column(Float, comment='X axis angle (etomo), unit: degrees') + tiltAngleOffset: Mapped[Optional[float]] = mapped_column(Float, comment='tilt Axis offset (etomo), unit: degrees') + zShift: Mapped[Optional[float]] = mapped_column(Float, comment='shift to center volumen in Z (etomo)') + fileDirectory: Mapped[Optional[str]] = mapped_column(String(255), comment='Directory path for files referenced by this table') + centralSliceImage: Mapped[Optional[str]] = mapped_column(String(255), comment='Tomogram central slice file') + tomogramMovie: Mapped[Optional[str]] = mapped_column(String(255), comment='Movie traversing the tomogram across an axis') + xyShiftPlot: Mapped[Optional[str]] = mapped_column(String(255), comment='XY shift plot file') + projXY: Mapped[Optional[str]] = mapped_column(String(255), comment='XY projection file') + projXZ: Mapped[Optional[str]] = mapped_column(String(255), comment='XZ projection file') + recordTimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime, server_default=text('current_timestamp()'), comment='Creation or last update date/time') + globalAlignmentQuality: Mapped[Optional[float]] = mapped_column(Float, comment='Quality of fit metric for the alignment of the tilt series corresponding to this tomogram') + gridSquareId: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='FK, references medium mag map in GridSquare') + + AutoProcProgram: Mapped['AutoProcProgram'] = relationship('AutoProcProgram', back_populates='Tomogram') + DataCollection: Mapped['DataCollection'] = relationship('DataCollection', back_populates='Tomogram') + GridSquare: Mapped['GridSquare'] = relationship('GridSquare', back_populates='Tomogram') + ProcessedTomogram: Mapped[List['ProcessedTomogram']] = relationship('ProcessedTomogram', back_populates='Tomogram') + TiltImageAlignment: Mapped[List['TiltImageAlignment']] = relationship('TiltImageAlignment', back_populates='Tomogram') + + +class XFEFluorescenceComposite(Base): + __tablename__ = 'XFEFluorescenceComposite' + __table_args__ = ( + ForeignKeyConstraint(['b'], ['XRFFluorescenceMapping.xrfFluorescenceMappingId'], name='XFEFluorescenceComposite_ibfk3'), + ForeignKeyConstraint(['g'], ['XRFFluorescenceMapping.xrfFluorescenceMappingId'], name='XFEFluorescenceComposite_ibfk2'), + ForeignKeyConstraint(['r'], ['XRFFluorescenceMapping.xrfFluorescenceMappingId'], name='XFEFluorescenceComposite_ibfk1'), + Index('XFEFluorescenceComposite_ibfk1', 'r'), + Index('XFEFluorescenceComposite_ibfk2', 'g'), + Index('XFEFluorescenceComposite_ibfk3', 'b'), + {'comment': 'A composite XRF map composed of three XRFFluorescenceMapping ' + 'entries creating r, g, b layers'} + ) + + xfeFluorescenceCompositeId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + r: Mapped[int] = mapped_column(INTEGER(10), comment='Red layer') + g: Mapped[int] = mapped_column(INTEGER(10), comment='Green layer') + b: Mapped[int] = mapped_column(INTEGER(10), comment='Blue layer') + rOpacity: Mapped[float] = mapped_column(Float, server_default=text('1'), comment='Red layer opacity') + bOpacity: Mapped[float] = mapped_column(Float, server_default=text('1'), comment='Red layer opacity') + gOpacity: Mapped[float] = mapped_column(Float, server_default=text('1'), comment='Red layer opacity') + opacity: Mapped[float] = mapped_column(Float, server_default=text('1'), comment='Total map opacity') + + XRFFluorescenceMapping: Mapped['XRFFluorescenceMapping'] = relationship('XRFFluorescenceMapping', foreign_keys=[b], back_populates='XFEFluorescenceComposite') + XRFFluorescenceMapping: Mapped['XRFFluorescenceMapping'] = relationship('XRFFluorescenceMapping', foreign_keys=[g], back_populates='XFEFluorescenceComposite') + XRFFluorescenceMapping: Mapped['XRFFluorescenceMapping'] = relationship('XRFFluorescenceMapping', foreign_keys=[r], back_populates='XFEFluorescenceComposite') + + +class ContainerQueueSample(Base): + __tablename__ = 'ContainerQueueSample' + __table_args__ = ( + ForeignKeyConstraint(['blSampleId'], ['BLSample.blSampleId'], name='ContainerQueueSample_blSampleId'), + ForeignKeyConstraint(['blSubSampleId'], ['BLSubSample.blSubSampleId'], ondelete='CASCADE', onupdate='CASCADE', name='ContainerQueueSample_ibfk2'), + ForeignKeyConstraint(['containerQueueId'], ['ContainerQueue.containerQueueId'], ondelete='CASCADE', onupdate='CASCADE', name='ContainerQueueSample_ibfk1'), + ForeignKeyConstraint(['dataCollectionPlanId'], ['DiffractionPlan.diffractionPlanId'], name='ContainerQueueSample_dataCollectionPlanId'), + Index('ContainerQueueSample_blSampleId', 'blSampleId'), + Index('ContainerQueueSample_dataCollectionPlanId', 'dataCollectionPlanId'), + Index('ContainerQueueSample_ibfk1', 'containerQueueId'), + Index('ContainerQueueSample_ibfk2', 'blSubSampleId') + ) + + containerQueueSampleId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + containerQueueId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + blSubSampleId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + status: Mapped[Optional[str]] = mapped_column(String(20), comment='The status of the queued item, i.e. skipped, reinspect. Completed / failed should be inferred from related DataCollection') + startTime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime, comment='Start time of processing the queue item') + endTime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime, comment='End time of processing the queue item') + dataCollectionPlanId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + blSampleId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + + BLSample: Mapped['BLSample'] = relationship('BLSample', back_populates='ContainerQueueSample') + BLSubSample: Mapped['BLSubSample'] = relationship('BLSubSample', back_populates='ContainerQueueSample') + ContainerQueue: Mapped['ContainerQueue'] = relationship('ContainerQueue', back_populates='ContainerQueueSample') + DiffractionPlan: Mapped['DiffractionPlan'] = relationship('DiffractionPlan', back_populates='ContainerQueueSample') + + +class Movie(Base): + __tablename__ = 'Movie' + __table_args__ = ( + ForeignKeyConstraint(['dataCollectionId'], ['DataCollection.dataCollectionId'], name='Movie_ibfk1'), + ForeignKeyConstraint(['foilHoleId'], ['FoilHole.foilHoleId'], onupdate='CASCADE', name='Movie_fk_foilHoleId'), + Index('Movie_fk_foilHoleId', 'foilHoleId'), + Index('Movie_ibfk1', 'dataCollectionId') + ) + + movieId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + createdTimeStamp: Mapped[datetime.datetime] = mapped_column(TIMESTAMP, server_default=text('current_timestamp() ON UPDATE current_timestamp()')) + dataCollectionId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + movieNumber: Mapped[Optional[int]] = mapped_column(MEDIUMINT(8)) + movieFullPath: Mapped[Optional[str]] = mapped_column(String(255)) + positionX: Mapped[Optional[float]] = mapped_column(Float) + positionY: Mapped[Optional[float]] = mapped_column(Float) + nominalDefocus: Mapped[Optional[float]] = mapped_column(Float, comment='Nominal defocus, Units: A') + angle: Mapped[Optional[float]] = mapped_column(Float, comment='unit: degrees relative to perpendicular to beam') + fluence: Mapped[Optional[float]] = mapped_column(Float, comment='accumulated electron fluence from start to end of acquisition of this movie (commonly, but incorrectly, referred to as ‘dose’)') + numberOfFrames: Mapped[Optional[int]] = mapped_column(INTEGER(11), comment='number of frames per movie. This should be equivalent to the number of\xa0MotionCorrectionDrift\xa0entries, but the latter is a property of data analysis, whereas the number of frames is an intrinsic property of acquisition.') + foilHoleId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + templateLabel: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + + DataCollection: Mapped['DataCollection'] = relationship('DataCollection', back_populates='Movie') + FoilHole: Mapped['FoilHole'] = relationship('FoilHole', back_populates='Movie') + MotionCorrection: Mapped[List['MotionCorrection']] = relationship('MotionCorrection', back_populates='Movie') + TiltImageAlignment: Mapped[List['TiltImageAlignment']] = relationship('TiltImageAlignment', back_populates='Movie') + + +class ProcessedTomogram(Base): + __tablename__ = 'ProcessedTomogram' + __table_args__ = ( + ForeignKeyConstraint(['tomogramId'], ['Tomogram.tomogramId'], ondelete='CASCADE', onupdate='CASCADE', name='ProcessedTomogram_ibfk_1'), + Index('tomogramId', 'tomogramId'), + {'comment': "Indicates the sample's location on a multi-sample pin, where 1 is " + "closest to the pin base or a sample's position in a cryo-EM " + 'cassette'} + ) + + processedTomogramId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + tomogramId: Mapped[int] = mapped_column(INTEGER(11), comment='references Tomogram table') + filePath: Mapped[Optional[str]] = mapped_column(String(255), comment='location on disk for the tomogram file') + processingType: Mapped[Optional[str]] = mapped_column(String(255), comment='nature of the processed tomogram') + + Tomogram: Mapped['Tomogram'] = relationship('Tomogram', back_populates='ProcessedTomogram') + + +class MotionCorrection(Base): + __tablename__ = 'MotionCorrection' + __table_args__ = ( + ForeignKeyConstraint(['autoProcProgramId'], ['AutoProcProgram.autoProcProgramId'], name='MotionCorrection_ibfk2'), + ForeignKeyConstraint(['dataCollectionId'], ['DataCollection.dataCollectionId'], name='_MotionCorrection_ibfk1'), + ForeignKeyConstraint(['movieId'], ['Movie.movieId'], name='MotionCorrection_ibfk3'), + Index('MotionCorrection_ibfk2', 'autoProcProgramId'), + Index('MotionCorrection_ibfk3', 'movieId'), + Index('_MotionCorrection_ibfk1', 'dataCollectionId') + ) + + motionCorrectionId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + dataCollectionId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + autoProcProgramId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + imageNumber: Mapped[Optional[int]] = mapped_column(SMALLINT(5), comment='Movie number, sequential in time 1-n') + firstFrame: Mapped[Optional[int]] = mapped_column(SMALLINT(5), comment='First frame of movie used') + lastFrame: Mapped[Optional[int]] = mapped_column(SMALLINT(5), comment='Last frame of movie used') + dosePerFrame: Mapped[Optional[float]] = mapped_column(Float, comment='Dose per frame, Units: e-/A^2') + doseWeight: Mapped[Optional[float]] = mapped_column(Float, comment='Dose weight, Units: dimensionless') + totalMotion: Mapped[Optional[float]] = mapped_column(Float, comment='Total motion, Units: A') + averageMotionPerFrame: Mapped[Optional[float]] = mapped_column(Float, comment='Average motion per frame, Units: A') + driftPlotFullPath: Mapped[Optional[str]] = mapped_column(String(255), comment='Full path to the drift plot') + micrographFullPath: Mapped[Optional[str]] = mapped_column(String(255), comment='Full path to the micrograph') + micrographSnapshotFullPath: Mapped[Optional[str]] = mapped_column(String(255), comment='Full path to a snapshot (jpg) of the micrograph') + patchesUsedX: Mapped[Optional[int]] = mapped_column(MEDIUMINT(8), comment='Number of patches used in x (for motioncor2)') + patchesUsedY: Mapped[Optional[int]] = mapped_column(MEDIUMINT(8), comment='Number of patches used in y (for motioncor2)') + fftFullPath: Mapped[Optional[str]] = mapped_column(String(255), comment='Full path to the jpg image of the raw micrograph FFT') + fftCorrectedFullPath: Mapped[Optional[str]] = mapped_column(String(255), comment='Full path to the jpg image of the drift corrected micrograph FFT') + comments: Mapped[Optional[str]] = mapped_column(String(255)) + movieId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + + AutoProcProgram: Mapped['AutoProcProgram'] = relationship('AutoProcProgram', back_populates='MotionCorrection') + DataCollection: Mapped['DataCollection'] = relationship('DataCollection', back_populates='MotionCorrection') + Movie: Mapped['Movie'] = relationship('Movie', back_populates='MotionCorrection') + CTF: Mapped[List['CTF']] = relationship('CTF', back_populates='MotionCorrection') + ParticlePicker: Mapped[List['ParticlePicker']] = relationship('ParticlePicker', back_populates='MotionCorrection') + RelativeIceThickness: Mapped[List['RelativeIceThickness']] = relationship('RelativeIceThickness', back_populates='MotionCorrection') + + +class TiltImageAlignment(Base): + __tablename__ = 'TiltImageAlignment' + __table_args__ = ( + ForeignKeyConstraint(['movieId'], ['Movie.movieId'], ondelete='CASCADE', onupdate='CASCADE', name='TiltImageAlignment_fk_movieId'), + ForeignKeyConstraint(['tomogramId'], ['Tomogram.tomogramId'], ondelete='CASCADE', onupdate='CASCADE', name='TiltImageAlignment_fk_tomogramId'), + Index('TiltImageAlignment_fk_tomogramId', 'tomogramId'), + {'comment': 'For storing per-movie analysis results (reconstruction)'} + ) + + movieId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True, comment='FK to\xa0Movie\xa0table') + tomogramId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True, comment='FK to\xa0Tomogram\xa0table; tuple (movieID, tomogramID) is unique') + defocusU: Mapped[Optional[float]] = mapped_column(Float, comment='unit: Angstroms') + defocusV: Mapped[Optional[float]] = mapped_column(Float, comment='unit: Angstroms') + psdFile: Mapped[Optional[str]] = mapped_column(String(255)) + resolution: Mapped[Optional[float]] = mapped_column(Float, comment='unit: Angstroms') + fitQuality: Mapped[Optional[float]] = mapped_column(Float) + refinedMagnification: Mapped[Optional[float]] = mapped_column(Float, comment='unitless') + refinedTiltAngle: Mapped[Optional[float]] = mapped_column(Float, comment='units: degrees') + refinedTiltAxis: Mapped[Optional[float]] = mapped_column(Float, comment='units: degrees') + residualError: Mapped[Optional[float]] = mapped_column(Float, comment='Residual error, unit: nm') + + Movie: Mapped['Movie'] = relationship('Movie', back_populates='TiltImageAlignment') + Tomogram: Mapped['Tomogram'] = relationship('Tomogram', back_populates='TiltImageAlignment') + + +class CTF(Base): + __tablename__ = 'CTF' + __table_args__ = ( + ForeignKeyConstraint(['autoProcProgramId'], ['AutoProcProgram.autoProcProgramId'], name='CTF_ibfk2'), + ForeignKeyConstraint(['motionCorrectionId'], ['MotionCorrection.motionCorrectionId'], name='CTF_ibfk1'), + Index('CTF_ibfk1', 'motionCorrectionId'), + Index('CTF_ibfk2', 'autoProcProgramId') + ) + + ctfId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + motionCorrectionId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + autoProcProgramId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + boxSizeX: Mapped[Optional[float]] = mapped_column(Float, comment='Box size in x, Units: pixels') + boxSizeY: Mapped[Optional[float]] = mapped_column(Float, comment='Box size in y, Units: pixels') + minResolution: Mapped[Optional[float]] = mapped_column(Float, comment='Minimum resolution for CTF, Units: A') + maxResolution: Mapped[Optional[float]] = mapped_column(Float, comment='Units: A') + minDefocus: Mapped[Optional[float]] = mapped_column(Float, comment='Units: A') + maxDefocus: Mapped[Optional[float]] = mapped_column(Float, comment='Units: A') + defocusStepSize: Mapped[Optional[float]] = mapped_column(Float, comment='Units: A') + astigmatism: Mapped[Optional[float]] = mapped_column(Float, comment='Units: A') + astigmatismAngle: Mapped[Optional[float]] = mapped_column(Float, comment='Units: deg?') + estimatedResolution: Mapped[Optional[float]] = mapped_column(Float, comment='Units: A') + estimatedDefocus: Mapped[Optional[float]] = mapped_column(Float, comment='Units: A') + amplitudeContrast: Mapped[Optional[float]] = mapped_column(Float, comment='Units: %?') + ccValue: Mapped[Optional[float]] = mapped_column(Float, comment='Correlation value') + fftTheoreticalFullPath: Mapped[Optional[str]] = mapped_column(String(255), comment='Full path to the jpg image of the simulated FFT') + comments: Mapped[Optional[str]] = mapped_column(String(255)) + + AutoProcProgram: Mapped['AutoProcProgram'] = relationship('AutoProcProgram', back_populates='CTF') + MotionCorrection: Mapped['MotionCorrection'] = relationship('MotionCorrection', back_populates='CTF') + + +class ParticlePicker(Base): + __tablename__ = 'ParticlePicker' + __table_args__ = ( + ForeignKeyConstraint(['firstMotionCorrectionId'], ['MotionCorrection.motionCorrectionId'], onupdate='CASCADE', name='ParticlePicker_fk_motionCorrectionId'), + ForeignKeyConstraint(['programId'], ['AutoProcProgram.autoProcProgramId'], onupdate='CASCADE', name='ParticlePicker_fk_programId'), + Index('ParticlePicker_fk_motionCorrectionId', 'firstMotionCorrectionId'), + Index('ParticlePicker_fk_particlePickerProgramId', 'programId'), + {'comment': 'An instance of a particle picker program that was run'} + ) + + particlePickerId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + programId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + firstMotionCorrectionId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + particlePickingTemplate: Mapped[Optional[str]] = mapped_column(String(255), comment='Cryolo model') + particleDiameter: Mapped[Optional[float]] = mapped_column(Float, comment='Unit: nm') + numberOfParticles: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + summaryImageFullPath: Mapped[Optional[str]] = mapped_column(String(255), comment='Generated summary micrograph image with highlighted particles') + + MotionCorrection: Mapped['MotionCorrection'] = relationship('MotionCorrection', back_populates='ParticlePicker') + AutoProcProgram: Mapped['AutoProcProgram'] = relationship('AutoProcProgram', back_populates='ParticlePicker') + ParticleClassificationGroup: Mapped[List['ParticleClassificationGroup']] = relationship('ParticleClassificationGroup', back_populates='ParticlePicker') + + +class RelativeIceThickness(Base): + __tablename__ = 'RelativeIceThickness' + __table_args__ = ( + ForeignKeyConstraint(['autoProcProgramId'], ['AutoProcProgram.autoProcProgramId'], onupdate='CASCADE', name='RelativeIceThickness_fk_programId'), + ForeignKeyConstraint(['motionCorrectionId'], ['MotionCorrection.motionCorrectionId'], onupdate='CASCADE', name='RelativeIceThickness_fk_motionCorrectionId'), + Index('RelativeIceThickness_fk_motionCorrectionId', 'motionCorrectionId'), + Index('RelativeIceThickness_fk_programId', 'autoProcProgramId') + ) + + relativeIceThicknessId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + motionCorrectionId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + autoProcProgramId: Mapped[Optional[int]] = mapped_column(INTEGER(11)) + minimum: Mapped[Optional[float]] = mapped_column(Float, comment='Minimum relative ice thickness, Unitless') + q1: Mapped[Optional[float]] = mapped_column(Float, comment='Quartile 1, unitless') + median: Mapped[Optional[float]] = mapped_column(Float, comment='Median relative ice thickness, Unitless') + q3: Mapped[Optional[float]] = mapped_column(Float, comment='Quartile 3, unitless') + maximum: Mapped[Optional[float]] = mapped_column(Float, comment='Minimum relative ice thickness, Unitless') + + AutoProcProgram: Mapped['AutoProcProgram'] = relationship('AutoProcProgram', back_populates='RelativeIceThickness') + MotionCorrection: Mapped['MotionCorrection'] = relationship('MotionCorrection', back_populates='RelativeIceThickness') + + +class ParticleClassificationGroup(Base): + __tablename__ = 'ParticleClassificationGroup' + __table_args__ = ( + ForeignKeyConstraint(['particlePickerId'], ['ParticlePicker.particlePickerId'], ondelete='CASCADE', onupdate='CASCADE', name='ParticleClassificationGroup_fk_particlePickerId'), + ForeignKeyConstraint(['programId'], ['AutoProcProgram.autoProcProgramId'], onupdate='CASCADE', name='ParticleClassificationGroup_fk_programId'), + Index('ParticleClassificationGroup_fk_particlePickerId', 'particlePickerId'), + Index('ParticleClassificationGroup_fk_programId', 'programId') + ) + + particleClassificationGroupId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + particlePickerId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + programId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + type: Mapped[Optional[str]] = mapped_column(Enum('2D', '3D'), comment='Indicates the type of particle classification') + batchNumber: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Corresponding to batch number') + numberOfParticlesPerBatch: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='total number of particles per batch (a large integer)') + numberOfClassesPerBatch: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + symmetry: Mapped[Optional[str]] = mapped_column(String(20)) + binnedPixelSize: Mapped[Optional[float]] = mapped_column(Float, comment='Binned pixel size. Unit: Angstroms') + + ParticlePicker: Mapped['ParticlePicker'] = relationship('ParticlePicker', back_populates='ParticleClassificationGroup') + AutoProcProgram: Mapped['AutoProcProgram'] = relationship('AutoProcProgram', back_populates='ParticleClassificationGroup') + ParticleClassification: Mapped[List['ParticleClassification']] = relationship('ParticleClassification', back_populates='ParticleClassificationGroup') + + +class ParticleClassification(Base): + __tablename__ = 'ParticleClassification' + __table_args__ = ( + ForeignKeyConstraint(['particleClassificationGroupId'], ['ParticleClassificationGroup.particleClassificationGroupId'], ondelete='CASCADE', onupdate='CASCADE', name='ParticleClassification_fk_particleClassificationGroupId'), + Index('ParticleClassification_fk_particleClassificationGroupId', 'particleClassificationGroupId'), + {'comment': 'Results of 2D or 2D classification'} + ) + + particleClassificationId: Mapped[int] = mapped_column(INTEGER(10), primary_key=True) + classNumber: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Identified of the class. A unique ID given by Relion') + classImageFullPath: Mapped[Optional[str]] = mapped_column(String(255), comment='The PNG of the class') + particlesPerClass: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Number of particles within the selected class, can then be used together with the total number above to calculate the percentage') + rotationAccuracy: Mapped[Optional[float]] = mapped_column(Float, comment='???') + translationAccuracy: Mapped[Optional[float]] = mapped_column(Float, comment='Unit: Angstroms') + estimatedResolution: Mapped[Optional[float]] = mapped_column(Float, comment='???, Unit: Angstroms') + overallFourierCompleteness: Mapped[Optional[float]] = mapped_column(Float) + particleClassificationGroupId: Mapped[Optional[int]] = mapped_column(INTEGER(10)) + classDistribution: Mapped[Optional[float]] = mapped_column(Float, comment='Provides a figure of merit for the class, higher number is better') + selected: Mapped[Optional[int]] = mapped_column(TINYINT(1), server_default=text('0'), comment='Indicates whether the class is selected for further processing or not') + bFactorFitIntercept: Mapped[Optional[float]] = mapped_column(Float, comment='Intercept of quadratic fit to refinement resolution against the logarithm of the number of particles') + bFactorFitLinear: Mapped[Optional[float]] = mapped_column(Float, comment='Linear coefficient of quadratic fit to refinement resolution against the logarithm of the number of particles, equal to half of the B factor') + bFactorFitQuadratic: Mapped[Optional[float]] = mapped_column(Float, comment='Quadratic coefficient of quadratic fit to refinement resolution against the logarithm of the number of particles') + + CryoemInitialModel: Mapped[List['CryoemInitialModel']] = relationship('CryoemInitialModel', secondary='ParticleClassification_has_CryoemInitialModel', back_populates='ParticleClassification') + ParticleClassificationGroup: Mapped['ParticleClassificationGroup'] = relationship('ParticleClassificationGroup', back_populates='ParticleClassification') + BFactorFit: Mapped[List['BFactorFit']] = relationship('BFactorFit', back_populates='ParticleClassification') + + +class BFactorFit(Base): + __tablename__ = 'BFactorFit' + __table_args__ = ( + ForeignKeyConstraint(['particleClassificationId'], ['ParticleClassification.particleClassificationId'], name='BFactorFit_fk_particleClassificationId'), + Index('BFactorFit_fk_particleClassificationId', 'particleClassificationId'), + {'comment': 'CryoEM reconstruction resolution as a function of the number of ' + 'particles for the creation of a Rosenthal-Henderson plot and the ' + 'calculation of B-factors'} + ) + + bFactorFitId: Mapped[int] = mapped_column(INTEGER(11), primary_key=True) + particleClassificationId: Mapped[int] = mapped_column(INTEGER(11)) + resolution: Mapped[Optional[float]] = mapped_column(Float, comment='Resolution of a refined map using a given number of particles') + numberOfParticles: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Number of particles used in refinement') + particleBatchSize: Mapped[Optional[int]] = mapped_column(INTEGER(10), comment='Number of particles in the batch that the B-factor analysis was performed on') + + ParticleClassification: Mapped['ParticleClassification'] = relationship('ParticleClassification', back_populates='BFactorFit') + + +t_ParticleClassification_has_CryoemInitialModel = Table( + 'ParticleClassification_has_CryoemInitialModel', Base.metadata, + Column('particleClassificationId', INTEGER(10), primary_key=True, nullable=False), + Column('cryoemInitialModelId', INTEGER(10), primary_key=True, nullable=False), + ForeignKeyConstraint(['cryoemInitialModelId'], ['CryoemInitialModel.cryoemInitialModelId'], ondelete='CASCADE', onupdate='CASCADE', name='ParticleClassification_has_InitialModel_fk2'), + ForeignKeyConstraint(['particleClassificationId'], ['ParticleClassification.particleClassificationId'], ondelete='CASCADE', onupdate='CASCADE', name='ParticleClassification_has_CryoemInitialModel_fk1'), + Index('ParticleClassification_has_InitialModel_fk2', 'cryoemInitialModelId') +) From b98540b1bfb1ddfa3c1edc5d82beccf5ce13bf88 Mon Sep 17 00:00:00 2001 From: Guilherme de Freitas Date: Mon, 12 May 2025 09:53:29 +0100 Subject: [PATCH 2/3] =?UTF-8?q?Bump=20version:=2011.0.2=20=E2=86=92=2011.0?= =?UTF-8?q?.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- src/ispyb/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 46d8b871..b0d6cfac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "ispyb" -version = "11.0.2" +version = "11.0.3" description = "Python package to access ISPyB database" authors = [ { name = "Diamond Light Source", email = "scientificsoftware@diamond.ac.uk" }, @@ -59,7 +59,7 @@ unfixable = ["F841"] ignore = ["E501"] [tool.bumpversion] -current_version = "11.0.2" +current_version = "11.0.3" commit = true tag = true diff --git a/src/ispyb/__init__.py b/src/ispyb/__init__.py index 430f6038..47600138 100644 --- a/src/ispyb/__init__.py +++ b/src/ispyb/__init__.py @@ -3,7 +3,7 @@ import os import warnings -__version__ = "11.0.2" +__version__ = "11.0.3" _log = logging.getLogger("ispyb") From 1158543e89dc6e836369a18c978d72acdf1c2565 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 09:55:49 +0100 Subject: [PATCH 3/3] Update ISPyB ORM schema to database schema v4.7.0 (#237) Generated with sqlacodegen 3.0.0rc5 SQLAlchemy 2.0.40 Co-authored-by: ISPyB-API Azure build --- src/ispyb/sqlalchemy/_auto_db_schema.py | 71 +++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/src/ispyb/sqlalchemy/_auto_db_schema.py b/src/ispyb/sqlalchemy/_auto_db_schema.py index d0a12306..99af2921 100644 --- a/src/ispyb/sqlalchemy/_auto_db_schema.py +++ b/src/ispyb/sqlalchemy/_auto_db_schema.py @@ -1,4 +1,4 @@ -__schema_version__ = "4.6.0" +__schema_version__ = "4.7.0" import datetime import decimal from typing import List, Optional @@ -3804,6 +3804,8 @@ class Shipping(Base): ForeignKeyConstraint( ["deliveryAgent_flightCodePersonId"], ["Person.personId"], + ondelete="SET NULL", + onupdate="CASCADE", name="Shipping_ibfk_4", ), ForeignKeyConstraint( @@ -3816,14 +3818,14 @@ class Shipping(Base): ForeignKeyConstraint( ["returnLabContactId"], ["LabContact.labContactId"], - ondelete="CASCADE", + ondelete="SET NULL", onupdate="CASCADE", name="Shipping_ibfk_3", ), ForeignKeyConstraint( ["sendingLabContactId"], ["LabContact.labContactId"], - ondelete="CASCADE", + ondelete="SET NULL", onupdate="CASCADE", name="Shipping_ibfk_2", ), @@ -4166,6 +4168,7 @@ class DewarRegistryHasProposal(Base): ForeignKeyConstraint( ["labContactId"], ["LabContact.labContactId"], + ondelete="SET NULL", onupdate="CASCADE", name="DewarRegistry_has_Proposal_ibfk4", ), @@ -4677,6 +4680,9 @@ class BLSample(Base): BLSampleImage: Mapped[List["BLSampleImage"]] = relationship( "BLSampleImage", back_populates="BLSample" ) + BLSamplePosition: Mapped[List["BLSamplePosition"]] = relationship( + "BLSamplePosition", back_populates="BLSample" + ) BLSample_has_DataCollectionPlan: Mapped[List["BLSampleHasDataCollectionPlan"]] = ( relationship("BLSampleHasDataCollectionPlan", back_populates="BLSample") ) @@ -4707,6 +4713,9 @@ class BLSample(Base): XFEFluorescenceSpectrum: Mapped[List["XFEFluorescenceSpectrum"]] = relationship( "XFEFluorescenceSpectrum", back_populates="BLSample" ) + XrayCentringResult: Mapped[List["XrayCentringResult"]] = relationship( + "XrayCentringResult", back_populates="BLSample" + ) BLSample_has_EnergyScan: Mapped[List["BLSampleHasEnergyScan"]] = relationship( "BLSampleHasEnergyScan", back_populates="BLSample" ) @@ -4962,6 +4971,39 @@ class BLSampleImage(Base): ) +class BLSamplePosition(Base): + __tablename__ = "BLSamplePosition" + __table_args__ = ( + ForeignKeyConstraint( + ["blSampleId"], + ["BLSample.blSampleId"], + name="BLSamplePosition_fk_blSampleId", + ), + Index("BLSamplePosition_fk_blSampleId", "blSampleId"), + ) + + blSamplePositionId: Mapped[int] = mapped_column( + INTEGER(11), primary_key=True, comment="Primary key (auto-incremented)" + ) + blSampleId: Mapped[int] = mapped_column( + INTEGER(11), comment="FK, references parent sample" + ) + posX: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + posY: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + posZ: Mapped[Optional[decimal.Decimal]] = mapped_column(Double(asdecimal=True)) + recordTimeStamp: Mapped[Optional[datetime.datetime]] = mapped_column( + DateTime, comment="Creation or last update date/time" + ) + positionType: Mapped[Optional[str]] = mapped_column( + Enum("dispensing"), + comment="Type of marked position (e.g.: dispensing location)", + ) + + BLSample: Mapped["BLSample"] = relationship( + "BLSample", back_populates="BLSamplePosition" + ) + + class BLSampleHasDataCollectionPlan(Base): __tablename__ = "BLSample_has_DataCollectionPlan" __table_args__ = ( @@ -6221,6 +6263,13 @@ class XFEFluorescenceSpectrum(Base): class XrayCentringResult(Base): __tablename__ = "XrayCentringResult" __table_args__ = ( + ForeignKeyConstraint( + ["blSampleId"], + ["BLSample.blSampleId"], + ondelete="SET NULL", + onupdate="CASCADE", + name="XrayCentringResult_fk_blSampleId", + ), ForeignKeyConstraint( ["xrayCentringId"], ["XrayCentring.xrayCentringId"], @@ -6228,6 +6277,7 @@ class XrayCentringResult(Base): onupdate="CASCADE", name="XrayCentringResult_ibfk_1", ), + Index("XrayCentringResult_fk_blSampleId", "blSampleId"), Index("xrayCentringId", "xrayCentringId"), {"comment": "Xray Centring result."}, ) @@ -6297,7 +6347,14 @@ class XrayCentringResult(Base): gridInfoId: Mapped[Optional[int]] = mapped_column( INTEGER(11), comment="to be removed" ) + blSampleId: Mapped[Optional[int]] = mapped_column( + INTEGER(11), + comment="The BLSample attributed for this x-ray centring result, i.e. the actual sample even for multi-pins", + ) + BLSample: Mapped["BLSample"] = relationship( + "BLSample", back_populates="XrayCentringResult" + ) XrayCentring: Mapped["XrayCentring"] = relationship( "XrayCentring", back_populates="XrayCentringResult" ) @@ -8449,6 +8506,14 @@ class ParticleClassification(Base): Float, comment="Quadratic coefficient of quadratic fit to refinement resolution against the logarithm of the number of particles", ) + angularEfficiency: Mapped[Optional[decimal.Decimal]] = mapped_column( + Double(asdecimal=True), + comment="Variation in resolution across different angles, 1-2sig/mean", + ) + suggestedTilt: Mapped[Optional[decimal.Decimal]] = mapped_column( + Double(asdecimal=True), + comment="Suggested stage tilt angle to improve angular efficiency. Unit: degrees", + ) CryoemInitialModel: Mapped[List["CryoemInitialModel"]] = relationship( "CryoemInitialModel",