Update dependencies and migrate to Node 18 minimum support

Upgraded multiple package versions, including `@esbuild` and dependencies like `@mui/x-data-grid-premium`. Adjusted `node` engine requirement to `>=18` for compatibility. This ensures modernization and alignment with current toolchain standards.
This commit is contained in:
GotthardG
2025-03-04 10:42:24 +01:00
parent c3cf463f06
commit 2e1d87c31b
11 changed files with 1911 additions and 273 deletions

View File

@ -260,6 +260,14 @@ class Image(Base):
sample_id = Column(Integer, ForeignKey("samples.id"), nullable=False)
class ExperimentParameters(Base):
__tablename__ = "experiment_parameters"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
run_number = Column(Integer, nullable=False)
beamline_parameters = Column(JSON, nullable=True)
sample_id = Column(Integer, ForeignKey("samples.id"), nullable=False)
# class Results(Base):
# __tablename__ = "results"
#

View File

@ -12,6 +12,8 @@ from app.schemas import (
Image,
ImageCreate,
SampleResult,
ExperimentParametersCreate,
ExperimentParametersRead,
)
from app.models import (
Puck as PuckModel,
@ -19,6 +21,7 @@ from app.models import (
SampleEvent as SampleEventModel,
Image as ImageModel,
Dewar as DewarModel,
ExperimentParameters as ExperimentParametersModel,
)
from app.dependencies import get_db
import logging
@ -192,7 +195,7 @@ async def upload_sample_image(
@router.get("/results", response_model=List[SampleResult])
async def get_sample_results(active_pgroup: str, db: Session = Depends(get_db)):
# Query samples for the active pgroup using joins
# Query samples for the active pgroup using joins.
samples = (
db.query(SampleModel)
.join(SampleModel.puck)
@ -207,8 +210,18 @@ async def get_sample_results(active_pgroup: str, db: Session = Depends(get_db)):
results = []
for sample in samples:
# Query images associated with each sample
# Query images associated with the sample.
images = db.query(ImageModel).filter(ImageModel.sample_id == sample.id).all()
# Query experiment parameters (which include beamline parameters) for the
# sample.
experiment_parameters = (
db.query(ExperimentParametersModel)
.filter(ExperimentParametersModel.sample_id == sample.id)
.all()
)
print("Experiment Parameters for sample", sample.id, experiment_parameters)
results.append(
{
"sample_id": sample.id,
@ -221,7 +234,52 @@ async def get_sample_results(active_pgroup: str, db: Session = Depends(get_db)):
{"id": img.id, "filepath": img.filepath, "comment": img.comment}
for img in images
],
"experiment_runs": [
{
"id": ex.id,
"run_number": ex.run_number,
"beamline_parameters": ex.beamline_parameters,
"sample_id": ex.sample_id,
}
for ex in experiment_parameters
],
}
)
return results
@router.post(
"/samples/{sample_id}/experiment_parameters",
response_model=ExperimentParametersRead,
)
def create_experiment_parameters_for_sample(
sample_id: int,
exp_params: ExperimentParametersCreate,
db: Session = Depends(get_db),
):
# Calculate the new run_number for the given sample.
# This assumes that the run_number is computed as one plus the maximum
# current value.
last_exp = (
db.query(ExperimentParametersModel)
.filter(ExperimentParametersModel.sample_id == sample_id)
.order_by(ExperimentParametersModel.run_number.desc())
.first()
)
new_run_number = last_exp.run_number + 1 if last_exp else 1
# Create a new ExperimentParameters record. The beamline_parameters are
# stored as JSON.
new_exp = ExperimentParametersModel(
run_number=new_run_number,
beamline_parameters=exp_params.beamline_parameters.dict()
if exp_params.beamline_parameters
else None,
sample_id=sample_id,
)
db.add(new_exp)
db.commit()
db.refresh(new_exp)
return new_exp

View File

@ -812,9 +812,97 @@ class ImageInfo(BaseModel):
comment: Optional[str] = None
class RotationParameters(BaseModel):
omegaStart_deg: float
omegaStep: float
chi: float
phi: float
numberOfImages: int
exposureTime_s: float
class gridScanParamers(BaseModel):
xStart: float
xStep: float
yStart: float
yStep: float
zStart: float
zStep: float
numberOfImages: int
exposureTime_s: float
class jetParameters(BaseModel):
hplc_pump_ml_min: float
pressure_bar: float
jetDiameter_um: int
jetSpeed_mm_s: float
exposureTime_s: float
class detector(BaseModel):
manufacturer: str
model: str
type: str
serialNumber: str
detectorDistance_mm: float
beamCenterX_px: float
beamCenterY_px: float
pixelSizeX_um: float
pixelSizeY_um: float
class BeamlineParameters(BaseModel):
synchrotron: str
beamline: str
detector: detector
wavelength: float
# energy: float
ringCurrent_A: float
ringMode: str
undulator: Optional[str] = None
undulatorgap_mm: Optional[float] = None
monochromator: str
# bandwidth_percent: float
transmission: float
focusingOptic: str
beamlineFluxAtSample_ph_s: Optional[float] = None
beamSizeWidth: Optional[float] = None
beamSizeHeight: Optional[float] = None
# dose_MGy: float
rotation: Optional[RotationParameters] = None
gridScan: Optional[gridScanParamers] = None
jet: Optional[jetParameters] = None
cryojetTemperature_K: Optional[float] = None
humidifierTemperature_K: Optional[float] = None
humidifierHumidity: Optional[float] = None
# experimentalHutchTemerature_K: Optional[float] = None
# experimentalHutchHumidity_percent: Optional[float] = None
# beamstopDistance_mm: Optional[float] = None
# beamstopDiameter_mm: Optional[float] = None
class ExperimentParametersBase(BaseModel):
run_number: int
beamline_parameters: Optional[BeamlineParameters] = None
sample_id: int
class ExperimentParametersCreate(ExperimentParametersBase):
run_number: Optional[int] = None
class ExperimentParametersRead(ExperimentParametersBase):
id: int
class Config:
from_attributes = True
class SampleResult(BaseModel):
sample_id: int
sample_name: str
puck_name: Optional[str]
dewar_name: Optional[str]
images: List[ImageInfo]
experiment_runs: Optional[List[ExperimentParametersRead]] = []

View File

@ -139,6 +139,15 @@ def on_startup():
print(f"{environment.capitalize()} environment: Regenerating database.")
# Base.metadata.drop_all(bind=engine)
# Base.metadata.create_all(bind=engine)
# from sqlalchemy.engine import reflection
# from app.models import ExperimentParameters # adjust the import as needed
# inspector = reflection.Inspector.from_engine(engine)
# tables_exist = inspector.get_table_names()
#
# if ExperimentParameters.__tablename__ not in tables_exist:
# print("Creating missing table: ExperimentParameters")
# ExperimentParameters.__table__.create(bind=engine)
#
if environment == "dev":
from app.database import load_sample_data