diff --git a/backend/app/models.py b/backend/app/models.py index a69d99a6d7b0946168f7548458b98eadca5f095b..0ea3d80c18d0a8f7dd3efe69799dc2cbc959c04e 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -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" # diff --git a/backend/app/routers/sample.py b/backend/app/routers/sample.py index 20e034e6bf352057e95eb2846a1cb9b4a1dd7962..b52b88c5dbe7d06aba06125f5d758ff380e23a32 100644 --- a/backend/app/routers/sample.py +++ b/backend/app/routers/sample.py @@ -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 diff --git a/backend/app/schemas.py b/backend/app/schemas.py index c31aba6beef15b7e6ca1582df0b0e26891f1ad49..7e8c132863b318b86c8949a25becdf7a2288c1dc 100644 --- a/backend/app/schemas.py +++ b/backend/app/schemas.py @@ -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]] = [] diff --git a/backend/main.py b/backend/main.py index c4b9484c0cf5afb2cde98d5916ebd6ece86ab484..99a65052800d95bfcbf6639dd36610d815f93954 100644 --- a/backend/main.py +++ b/backend/main.py @@ -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 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 02969bd82f55e0a819f08bff4b9129a2114dac3b..0c9eb10312bd7d6fab039aef67040769ca40b7e8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -21,7 +21,8 @@ "@mui/icons-material": "^6.1.5", "@mui/material": "^6.1.6", "@mui/system": "^6.1.6", - "@mui/x-data-grid": "^7.23.3", + "@mui/x-data-grid-premium": "^7.27.2", + "@mui/x-tree-view": "^7.26.0", "axios": "^1.7.7", "chokidar": "^4.0.1", "dayjs": "^1.11.13", @@ -53,7 +54,7 @@ "openapi-typescript": "^7.4.2", "typescript": "^5.5.3", "typescript-eslint": "^8.7.0", - "vite": "^5.4.8", + "vite": "^6.2.0", "vite-plugin-svgr": "^4.2.0" } }, @@ -648,9 +649,9 @@ "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", + "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", "cpu": [ "ppc64" ], @@ -661,13 +662,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", + "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", "cpu": [ "arm" ], @@ -678,13 +679,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", + "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", "cpu": [ "arm64" ], @@ -695,13 +696,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", + "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", "cpu": [ "x64" ], @@ -712,13 +713,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", + "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", "cpu": [ "arm64" ], @@ -729,13 +730,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", + "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", "cpu": [ "x64" ], @@ -746,13 +747,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", + "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", "cpu": [ "arm64" ], @@ -763,13 +764,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", + "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", "cpu": [ "x64" ], @@ -780,13 +781,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", + "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", "cpu": [ "arm" ], @@ -797,13 +798,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", + "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", "cpu": [ "arm64" ], @@ -814,13 +815,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", + "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", "cpu": [ "ia32" ], @@ -831,13 +832,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", + "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", "cpu": [ "loong64" ], @@ -848,13 +849,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", + "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", "cpu": [ "mips64el" ], @@ -865,13 +866,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", + "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", "cpu": [ "ppc64" ], @@ -882,13 +883,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", + "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", "cpu": [ "riscv64" ], @@ -899,13 +900,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", + "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", "cpu": [ "s390x" ], @@ -916,13 +917,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", + "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", "cpu": [ "x64" ], @@ -933,13 +934,30 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", + "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", + "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", "cpu": [ "x64" ], @@ -950,13 +968,30 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", + "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", + "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", "cpu": [ "x64" ], @@ -967,13 +1002,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", + "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", "cpu": [ "x64" ], @@ -984,13 +1019,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", + "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", "cpu": [ "arm64" ], @@ -1001,13 +1036,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", + "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", "cpu": [ "ia32" ], @@ -1018,13 +1053,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", + "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", "cpu": [ "x64" ], @@ -1035,7 +1070,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -1409,9 +1444,9 @@ "license": "MIT" }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.0.tgz", - "integrity": "sha512-6u74wi+9zeNlukrCtYYET8Ed/n9AS27DiaXCZKAD3TRGFaqiyYSsQgN2disW83pI/cM1Q2lJY1JX4YfwvNtlNw==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.6.tgz", + "integrity": "sha512-rho5Q4IscbrVmK9rCrLTJmjLjfH6m/NcqKr/mchvck0EIXlyYUB9+Z0oVmkt/+Mben43LMRYBH8q/Uzxj/c4Vw==", "license": "MIT", "funding": { "type": "opencollective", @@ -1445,16 +1480,16 @@ } }, "node_modules/@mui/material": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.0.tgz", - "integrity": "sha512-hNIgwdM9U3DNmowZ8mU59oFmWoDKjc92FqQnQva3Pxh6xRKWtD2Ej7POUHMX8Dwr1OpcSUlT2+tEMeLb7WYsIg==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.6.tgz", + "integrity": "sha512-6UyAju+DBOdMogfYmLiT3Nu7RgliorimNBny1pN/acOjc+THNFVE7hlxLyn3RDONoZJNDi/8vO4AQQr6dLAXqA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.4.0", - "@mui/system": "^6.4.0", + "@mui/core-downloads-tracker": "^6.4.6", + "@mui/system": "^6.4.6", "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.0", + "@mui/utils": "^6.4.6", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", @@ -1473,7 +1508,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.4.0", + "@mui/material-pigment-css": "^6.4.6", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1494,13 +1529,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.0.tgz", - "integrity": "sha512-rNHci8MP6NOdEWAfZ/RBMO5Rhtp1T6fUDMSmingg9F1T6wiUeodIQ+NuTHh2/pMoUSeP9GdHdgMhMmfsXxOMuw==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.6.tgz", + "integrity": "sha512-T5FxdPzCELuOrhpA2g4Pi6241HAxRwZudzAuL9vBvniuB5YU82HCmrARw32AuCiyTfWzbrYGGpZ4zyeqqp9RvQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.4.0", + "@mui/utils": "^6.4.6", "prop-types": "^15.8.1" }, "engines": { @@ -1521,9 +1556,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.0.tgz", - "integrity": "sha512-ek/ZrDujrger12P6o4luQIfRd2IziH7jQod2WMbLqGE03Iy0zUwYmckRTVhRQTLPNccpD8KXGcALJF+uaUQlbg==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.6.tgz", + "integrity": "sha512-vSWYc9ZLX46be5gP+FCzWVn5rvDr4cXC5JBZwSIkYk9xbC7GeV+0kCvB8Q6XLFQJy+a62bbqtmdwS4Ghi9NBlQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", @@ -1555,16 +1590,16 @@ } }, "node_modules/@mui/system": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.0.tgz", - "integrity": "sha512-wTDyfRlaZCo2sW2IuOsrjeE5dl0Usrs6J7DxE3GwNCVFqS5wMplM2YeNiV3DO7s53RfCqbho+gJY6xaB9KThUA==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.6.tgz", + "integrity": "sha512-FQjWwPec7pMTtB/jw5f9eyLynKFZ6/Ej9vhm5kGdtmts1z5b7Vyn3Rz6kasfYm1j2TfrfGnSXRvvtwVWxjpz6g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.4.0", - "@mui/styled-engine": "^6.4.0", + "@mui/private-theming": "^6.4.6", + "@mui/styled-engine": "^6.4.6", "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.0", + "@mui/utils": "^6.4.6", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1609,9 +1644,9 @@ } }, "node_modules/@mui/utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.0.tgz", - "integrity": "sha512-woOTATWNsTNR3YBh2Ixkj3l5RaxSiGoC9G8gOpYoFw1mZM77LWJeuMHFax7iIW4ahK0Cr35TF9DKtrafJmOmNQ==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.6.tgz", + "integrity": "sha512-43nZeE1pJF2anGafNydUcYFPtHwAqiBiauRtaMvurdrZI3YrUjHkAu43RBsxef7OFtJMXGiHFvq43kb7lig0sA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", @@ -1639,25 +1674,120 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.23.6.tgz", - "integrity": "sha512-NcCZH99ZBLRlCcfLwwhCkVowNZHgjy0XZ/c6EuTRMSZl1UqF8ouwitP1ZfAa1idDIWCHFhxo446U/93aGMqOyQ==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.27.2.tgz", + "integrity": "sha512-Nj6PWp6WN0gkps676j1Jai3mP1fQotJbqMTvllU7LwQp09S/RE/uJicYdqfeWQLxtQipWm5dnAY63gzsTiAHGA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0", - "@mui/x-internals": "7.23.6", + "@mui/x-internals": "7.26.0", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "reselect": "^5.1.1", + "use-sync-external-store": "^1.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-data-grid-premium": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid-premium/-/x-data-grid-premium-7.27.2.tgz", + "integrity": "sha512-owoTnwMIzuItn7MZlkfPI7p70LUQWySAY5tENoohfJHDpr2QMw1vwhGStIXTZmKlHJF28aDusT2XENlCpOVEhQ==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-data-grid": "7.27.2", + "@mui/x-data-grid-pro": "7.27.2", + "@mui/x-internals": "7.26.0", + "@mui/x-license": "7.26.0", + "@types/format-util": "^1.0.4", "clsx": "^2.1.1", + "exceljs": "^4.4.0", "prop-types": "^15.8.1", "reselect": "^5.1.1" }, "engines": { "node": ">=14.0.0" }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-data-grid-premium/node_modules/@mui/x-internals": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.26.0.tgz", + "integrity": "sha512-VxTCYQcZ02d3190pdvys2TDg9pgbvewAVakEopiOgReKAUhLdRlgGJHcOA/eAuGLyK1YIo26A6Ow6ZKlSRLwMg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@mui/x-data-grid-pro": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-7.27.2.tgz", + "integrity": "sha512-uwT8ym3xxHEY3h7hOIh1O3T+SzkYR8jT5ho7nWQfwAR4whlKkOYt0GOYsj1HQJZSZ1WpUdxCRk6V5dYNLp1rvw==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-data-grid": "7.27.2", + "@mui/x-internals": "7.26.0", + "@mui/x-license": "7.26.0", + "@types/format-util": "^1.0.4", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "reselect": "^5.1.1" + }, + "engines": { + "node": ">=14.0.0" + }, "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", @@ -1675,6 +1805,46 @@ } } }, + "node_modules/@mui/x-data-grid-pro/node_modules/@mui/x-internals": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.26.0.tgz", + "integrity": "sha512-VxTCYQcZ02d3190pdvys2TDg9pgbvewAVakEopiOgReKAUhLdRlgGJHcOA/eAuGLyK1YIo26A6Ow6ZKlSRLwMg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@mui/x-data-grid/node_modules/@mui/x-internals": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.26.0.tgz", + "integrity": "sha512-VxTCYQcZ02d3190pdvys2TDg9pgbvewAVakEopiOgReKAUhLdRlgGJHcOA/eAuGLyK1YIo26A6Ow6ZKlSRLwMg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@mui/x-date-pickers": { "version": "7.23.6", "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.23.6.tgz", @@ -1747,6 +1917,102 @@ "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.23.6.tgz", "integrity": "sha512-hT1Pa4PNCnxwiauPbYMC3p4DiEF1x05Iu4C1MtC/jMJ1LtthymLmTuQ6ZQ53/R9FeqK6sYd6A6noR+vNMjp5DA==", "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@mui/x-license": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@mui/x-license/-/x-license-7.26.0.tgz", + "integrity": "sha512-WxwBGk6xXF0vi4IGCCojMHjQsAXvltjP+YgFTTgWVFhIpDFDu89xLOwRnSWrhCwD6dlK/BwKgn2UgxTE8BZGFQ==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-internals": "7.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@mui/x-license/node_modules/@mui/x-internals": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.26.0.tgz", + "integrity": "sha512-VxTCYQcZ02d3190pdvys2TDg9pgbvewAVakEopiOgReKAUhLdRlgGJHcOA/eAuGLyK1YIo26A6Ow6ZKlSRLwMg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@mui/x-tree-view": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-7.26.0.tgz", + "integrity": "sha512-adZwVj6/edNowi2RIeyGPTcfdP4EXtMGo0mk2LQogG8m8bZkZRjOQoQ7pkBF0UPMaIAwzCadq2OWj3MPH4DP5A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-internals": "7.26.0", + "@types/react-transition-group": "^4.4.11", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-tree-view/node_modules/@mui/x-internals": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.26.0.tgz", + "integrity": "sha512-VxTCYQcZ02d3190pdvys2TDg9pgbvewAVakEopiOgReKAUhLdRlgGJHcOA/eAuGLyK1YIo26A6Ow6ZKlSRLwMg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0" @@ -2524,6 +2790,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/format-util": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/format-util/-/format-util-1.0.4.tgz", + "integrity": "sha512-xrCYOdHh5zA3LUrn6CvspYwlzSWxPso11Lx32WnAG6KvLCRecKZ/Rh21PLXUkzUFsQmrGcx/traJAFjR6dVS5Q==", + "license": "MIT" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -3441,6 +3713,15 @@ "node": ">=10" } }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/crc-32": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", @@ -3712,9 +3993,9 @@ } }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", + "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -3722,32 +4003,34 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.25.0", + "@esbuild/android-arm": "0.25.0", + "@esbuild/android-arm64": "0.25.0", + "@esbuild/android-x64": "0.25.0", + "@esbuild/darwin-arm64": "0.25.0", + "@esbuild/darwin-x64": "0.25.0", + "@esbuild/freebsd-arm64": "0.25.0", + "@esbuild/freebsd-x64": "0.25.0", + "@esbuild/linux-arm": "0.25.0", + "@esbuild/linux-arm64": "0.25.0", + "@esbuild/linux-ia32": "0.25.0", + "@esbuild/linux-loong64": "0.25.0", + "@esbuild/linux-mips64el": "0.25.0", + "@esbuild/linux-ppc64": "0.25.0", + "@esbuild/linux-riscv64": "0.25.0", + "@esbuild/linux-s390x": "0.25.0", + "@esbuild/linux-x64": "0.25.0", + "@esbuild/netbsd-arm64": "0.25.0", + "@esbuild/netbsd-x64": "0.25.0", + "@esbuild/openbsd-arm64": "0.25.0", + "@esbuild/openbsd-x64": "0.25.0", + "@esbuild/sunos-x64": "0.25.0", + "@esbuild/win32-arm64": "0.25.0", + "@esbuild/win32-ia32": "0.25.0", + "@esbuild/win32-x64": "0.25.0" } }, "node_modules/escalade": { @@ -5478,9 +5761,9 @@ } }, "node_modules/postcss": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", - "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dev": true, "funding": [ { @@ -6678,6 +6961,15 @@ "dev": true, "license": "MIT" }, + "node_modules/use-sync-external-store": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", + "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", @@ -6709,21 +7001,21 @@ } }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz", + "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -6732,19 +7024,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -6765,6 +7063,12 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, @@ -6948,12 +7252,18 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/yaml-ast-parser": { diff --git a/frontend/package.json b/frontend/package.json index 140f8c3467539cee13364e64ee1b07b00f5bedfa..ac47655471d4027d17e515d6a48b708824082d4a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,7 +27,8 @@ "@mui/icons-material": "^6.1.5", "@mui/material": "^6.1.6", "@mui/system": "^6.1.6", - "@mui/x-data-grid": "^7.23.3", + "@mui/x-data-grid-premium": "^7.27.2", + "@mui/x-tree-view": "^7.26.0", "axios": "^1.7.7", "chokidar": "^4.0.1", "dayjs": "^1.11.13", @@ -59,7 +60,7 @@ "openapi-typescript": "^7.4.2", "typescript": "^5.5.3", "typescript-eslint": "^8.7.0", - "vite": "^5.4.8", + "vite": "^6.2.0", "vite-plugin-svgr": "^4.2.0" } } diff --git a/frontend/src/components/ResultGrid.tsx b/frontend/src/components/ResultGrid.tsx index 586b3ea5173a0c5050d8201f9972c027da868d5c..9ede4e43371c5debf95a502866121056a858f644 100644 --- a/frontend/src/components/ResultGrid.tsx +++ b/frontend/src/components/ResultGrid.tsx @@ -1,30 +1,131 @@ -// TypeScript (ResultGrid.tsx snippet) import React, { useEffect, useState } from 'react'; -import { DataGrid, GridColDef } from '@mui/x-data-grid'; +import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium'; +import IconButton from '@mui/material/IconButton'; +import InfoIcon from '@mui/icons-material/Info'; import { OpenAPI, SamplesService } from '../../openapi'; import './SampleImage.css'; - +// Extend your image info interface if needed. interface ImageInfo { id: number; filepath: string; comment?: string; } +// This represents an experiment run as returned by your API. +interface ExperimentParameters { + id: number; + run_number: number; + sample_id: number; + beamline_parameters: { + beamSizeHeight: number; + beamSizeWidth: number; + beamline: string; + beamlineFluxAtSample_ph_s: number; + cryojetTemperature_K?: number | null; + detector: { + beamCenterX_px: number; + beamCenterY_px: number; + detectorDistance_mm: number; + manufacturer: string; + model: string; + pixelSizeX_um: number; + pixelSizeY_um: number; + serialNumber: string; + type: string; + }; + rotation?: { + chi: number; + exposureTime_s: number; + numberOfImages: number | null; + omegaStart_deg: number; + omegaStep: number; + phi: number; + } | null; + gridScan?: { + xStart: number; + xStep: number; + yStart: number; + yStep: number; + zStart: number; + zStep: number; + numberOfImages: number; + exposureTime_s: number; + } | null; + focusingOptic?: string; + humidifierHumidity?: number | null; + humidifierTemperature_K?: number | null; + jet?: any; + monochromator?: string; + ringCurrent_A?: number; + ringMode?: string; + synchrotron?: string; + transmission?: number; + undulator?: any; + undulatorgap_mm?: any; + wavelength?: number; + }; +} + +// Represents a sample returned by the API. interface SampleResult { sample_id: number; sample_name: string; puck_name?: string; dewar_name?: string; images: ImageInfo[]; + experiment_runs?: ExperimentParameters[]; +} + +// A flat tree row type for the grid. +interface TreeRow { + id: string; + hierarchy: (string | number)[]; + type: 'sample' | 'run'; + sample_id: number; + sample_name?: string; + puck_name?: string; + dewar_name?: string; + images?: ImageInfo[]; + run_number?: number; + beamline_parameters?: ExperimentParameters['beamline_parameters']; + experimentType?: string; + numberOfImages?: number; } interface ResultGridProps { activePgroup: string; } +// Helper function to safely get the number of images. +const getNumberOfImages = (run: ExperimentParameters): number => { + const params = run.beamline_parameters; + if (params.rotation && params.rotation.numberOfImages != null) { + return params.rotation.numberOfImages; + } else if (params.gridScan && params.gridScan.numberOfImages != null) { + return params.gridScan.numberOfImages; + } + return 0; +}; + +// Helper function to determine the experiment type. +const getExperimentType = (run: ExperimentParameters): string => { + const params = run.beamline_parameters; + if (params.rotation && params.rotation.numberOfImages != null && params.rotation.omegaStep != null) { + const numImages = params.rotation.numberOfImages; + const omegaStep = params.rotation.omegaStep; + if ([1, 2, 4].includes(numImages) && omegaStep === 90) { + return "Characterization"; + } + return "Rotation"; + } else if (params.gridScan) { + return "Grid Scan"; + } + return "Rotation"; +}; + const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => { - const [rows, setRows] = useState<SampleResult[]>([]); + const [rows, setRows] = useState<TreeRow[]>([]); const [basePath, setBasePath] = useState(''); useEffect(() => { @@ -44,99 +145,124 @@ const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => { console.log('Environment Mode:', mode); console.log('Resolved OpenAPI.BASE:', OpenAPI.BASE); - // Update the base path for images setBasePath(`${OpenAPI.BASE}/`); }, []); useEffect(() => { - const fetchData = () => { - console.log("Fetching sample results for active_pgroup:", activePgroup); - SamplesService.getSampleResultsSamplesResultsGet(activePgroup) - .then((response: SampleResult[]) => { - console.log("Response received:", response); - setRows(response); - }) - .catch((err: Error) => { - console.error("Error fetching sample results:", err); - }); - }; + console.log('Fetching sample results for active_pgroup:', activePgroup); + SamplesService.getSampleResultsSamplesResultsGet(activePgroup) + .then((response: SampleResult[]) => { + console.log('Response received:', response); + const treeRows: TreeRow[] = []; - // Fetch data initially. - fetchData(); + response.forEach((sample) => { + // Add the sample row. + const sampleRow: TreeRow = { + id: `sample-${sample.sample_id}`, + hierarchy: [sample.sample_id], + type: 'sample', + sample_id: sample.sample_id, + sample_name: sample.sample_name, + puck_name: sample.puck_name, + dewar_name: sample.dewar_name, + images: sample.images, + }; + treeRows.push(sampleRow); - // Set up an interval to refresh data every 15 seconds (adjust as needed) - const intervalId = setInterval(fetchData, 15000); + // Add experiment run rows. + if (sample.experiment_runs) { + sample.experiment_runs.forEach((run) => { + const experimentType = getExperimentType(run); + const numImages = getNumberOfImages(run); + const runRow: TreeRow = { + id: `run-${sample.sample_id}-${run.run_number}`, + hierarchy: [sample.sample_id, run.run_number], + type: 'run', + sample_id: sample.sample_id, + run_number: run.run_number, + beamline_parameters: run.beamline_parameters, + experimentType, + numberOfImages: numImages, + images: sample.images, + }; + treeRows.push(runRow); + }); + } + }); - // Clean up when component unmounts or activePgroup changes. - return () => clearInterval(intervalId); + setRows(treeRows); + }) + .catch((error) => { + console.error('Error fetching sample results:', error); + }); }, [activePgroup]); - + // Define the grid columns, including the new processing results column. const columns: GridColDef[] = [ - { field: 'sample_id', headerName: 'ID', width: 70 }, - { field: 'sample_name', headerName: 'Sample Name', width: 150 }, - { field: 'puck_name', headerName: 'Puck Name', width: 150 }, - { field: 'dewar_name', headerName: 'Dewar Name', width: 150 }, { - field: 'images', - headerName: 'Images', - width: 300, + field: 'sample_name', + headerName: 'Sample Name', + width: 200, + renderCell: (params) => (params.row.type === 'sample' ? params.value : null), + }, + { + field: 'puck_name', + headerName: 'Puck Name', + width: 150, + renderCell: (params) => (params.row.type === 'sample' ? params.value : null), + }, + { + field: 'dewar_name', + headerName: 'Dewar Name', + width: 150, + renderCell: (params) => (params.row.type === 'sample' ? params.value : null), + }, + { + field: 'experimentType', + headerName: 'Experiment Type', + width: 150, + renderCell: (params) => (params.row.type === 'run' ? params.value : null), + }, + { + field: 'numberOfImages', + headerName: 'Number of Images', + width: 150, + renderCell: (params) => (params.row.type === 'run' ? params.value : null), + }, + { + field: 'processingResults', + headerName: 'Processing Results', + width: 180, renderCell: (params) => { - const imageList: ImageInfo[] = params.value; - if (!imageList || imageList.length === 0) { - return null; + if (params.row.type === 'run') { + return ( + <IconButton + aria-label="processing results placeholder" + onClick={() => { + // Placeholder for processing results details. + console.log('Clicked processing details for run', params.row.run_number); + }} + > + <InfoIcon /> + </IconButton> + ); } - - // Filter the images to include only the two bb_raster images - const filteredImages = imageList.filter( - (img) => - img.filepath.includes("bb_raster_0") || - img.filepath.includes("bb_raster_90") - ); - - if (filteredImages.length === 0) { - return null; - } - - return ( - <div style={{ display: 'flex', alignItems: 'center' }}> - {filteredImages.map((img) => { - const url = basePath + img.filepath; - return ( - <img - key={img.id} - src={url} - alt={img.comment || 'sample'} - className="zoom-image" - style={{ - width: 40, - height: 40, - marginRight: 5, - borderRadius: 4, - }} - /> - ); - })} - </div> - ); + return null; }, }, - ]; return ( - <DataGrid - rows={rows} - columns={columns} - pageSize={10} - getRowId={(row) => row.sample_id} - sx={{ - '& .MuiDataGrid-cell': { - overflow: 'visible', - }, - }} - /> - + <div style={{ height: 600, width: '100%' }}> + <DataGridPremium + rows={rows} + columns={columns} + treeData + getTreeDataPath={(row: TreeRow) => row.hierarchy} + defaultGroupingExpansionDepth={-1} + getRowId={(row) => row.id} + /> + </div> ); }; diff --git a/frontend/src/components/RunDetails.tsx b/frontend/src/components/RunDetails.tsx new file mode 100644 index 0000000000000000000000000000000000000000..60003f3b5d4140e5cdc4524962b03d6def1a6bb2 --- /dev/null +++ b/frontend/src/components/RunDetails.tsx @@ -0,0 +1,84 @@ +import {SimpleTreeView, TreeItem} from "@mui/x-tree-view"; +import React from "react"; + + +interface ExperimentParameters { + id: number; + run_number: number; + beamline_parameters: { + synchrotron: string; + beamline: string; + detector: { + manufacturer: string; + model: string; + type: string; + serial_number: string; + detector_distance_mm: number; + beam_center_x_px: number; + beam_center_y_px: number; + pixel_size_x_um: number; + pixel_size_y_um: number; + number_of_images: number; + exposure_time_s: number; + }; + // Add additional fields if needed. + }; +} + +<SimpleTreeView + defaultCollapseIcon="▾" + defaultExpandIcon="▸" + sx={{ fontSize: '0.875rem' }} +> + <TreeItem nodeId="detector-group" label={<strong>Detector Details</strong>}> + <TreeItem nodeId="detector-group" label={<strong>Detector Details</strong>}> + <TreeItem + nodeId="detector-manufacturer" + label={`Manufacturer: ${detector?.manufacturer || 'N/A'}`} + /> + <TreeItem + nodeId="detector-model" + label={`Model: ${detector?.model || 'N/A'}`} + /> + <TreeItem + nodeId="detector-type" + label={`Type: ${detector?.type || 'N/A'}`} + /> + <TreeItem + nodeId="detector-serial" + label={`Serial Number: ${detector?.serial_number || 'N/A'}`} + /> + <TreeItem + nodeId="detector-distance" + label={`Distance (mm): ${detector?.detector_distance_mm ?? 'N/A'}`} + /> + <TreeItem + nodeId="beam-center" + label={ + detector + ? `Beam Center: x:${detector.beam_center_x_px}, y:${detector.beam_center_y_px}` + : 'Beam Center: N/A' + } + /> + <TreeItem + nodeId="pixel-size" + label={ + detector + ? `Pixel Size (µm): x:${detector.pixel_size_x_um}, y:${detector.pixel_size_y_um}` + : 'Pixel Size: N/A' + } + /> + <TreeItem + nodeId="img-count" + label={`Number of Images: ${detector?.number_of_images ?? 'N/A'}`} + /> + <TreeItem + nodeId="exposure-time" + label={`Exposure Time (s): ${detector?.exposure_time_s ?? 'N/A'}`} + /> + </TreeItem> + + + + </TreeItem> +</SimpleTreeView> \ No newline at end of file diff --git a/frontend/src/components/SampleTracker.tsx b/frontend/src/components/SampleTracker.tsx index c10442a34e0741d493726a1e6c9fab202dbaec20..cfafd182e86fc8e4a6229058a1310b3fe016e1c6 100644 --- a/frontend/src/components/SampleTracker.tsx +++ b/frontend/src/components/SampleTracker.tsx @@ -52,7 +52,7 @@ const SampleTracker: React.FC<SampleTrackerProps> = ({ activePgroup }) => { fetchPucks(); const interval = setInterval(() => { fetchPucks(); - }, 1000); + }, 100000); return () => clearInterval(interval); }, [activePgroup]); diff --git a/pyproject.toml b/pyproject.toml index 3e87e4dace6ac9f18840f71270679ea8a5bcd3ad..a22f5fe7ccc96767fad3198a6f68b79d0ecba595 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "aareDB" -version = "0.1.0a23" +version = "0.1.0a24" description = "Backend for next gen sample management system" authors = [{name = "Guillaume Gotthard", email = "guillaume.gotthard@psi.ch"}] license = {text = "MIT"} diff --git a/testfunctions.ipynb b/testfunctions.ipynb index fdc21e59b3f52b6e2667d363022a2b91b5e6ea6d..091b5efc3338d82e93a8042d80e48c048155d262 100644 --- a/testfunctions.ipynb +++ b/testfunctions.ipynb @@ -3,8 +3,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-02-26T13:09:58.719218Z", - "start_time": "2025-02-26T13:09:58.716771Z" + "end_time": "2025-03-04T09:22:38.371102Z", + "start_time": "2025-03-04T09:22:37.939673Z" } }, "cell_type": "code", @@ -41,12 +41,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "0.1.0a21\n", + "0.1.0a24\n", "https://127.0.0.1:8000\n" ] } ], - "execution_count": 86 + "execution_count": 1 }, { "metadata": {}, @@ -57,7 +57,7 @@ "## Fetch all Shipments, list corresponding dewars and pucks\n", "\n", "from datetime import date, datetime\n", - "from aareDBclient import ShipmentsApi\n", + "from aareDBclient import ShipmentsApi, SamplesApi, GridScanParamers\n", "from aareDBclient.models import Shipment\n", "\n", "with aareDBclient.ApiClient(configuration) as api_client:\n", @@ -176,8 +176,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-02-26T12:04:05.046079Z", - "start_time": "2025-02-26T12:04:04.954761Z" + "end_time": "2025-03-03T10:06:33.111482Z", + "start_time": "2025-03-03T10:06:33.082367Z" } }, "cell_type": "code", @@ -206,13 +206,13 @@ "text": [ "The response of PucksApi->get_pucks_by_slot_pucks_slot_slot_identifier_get:\n", "\n", - "[PuckWithTellPosition(id=1, puck_name='PUCK-001', puck_type='Unipuck', puck_location_in_dewar=1, dewar_id=1, dewar_name='Dewar One', pgroup='p20001, p20002', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=2, puck_name='PUCK002', puck_type='Unipuck', puck_location_in_dewar=2, dewar_id=1, dewar_name='Dewar One', pgroup='p20001, p20002', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=3, puck_name='PUCK003', puck_type='Unipuck', puck_location_in_dewar=3, dewar_id=1, dewar_name='Dewar One', pgroup='p20001, p20002', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=4, puck_name='PUCK004', puck_type='Unipuck', puck_location_in_dewar=4, dewar_id=1, dewar_name='Dewar One', pgroup='p20001, p20002', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=5, puck_name='PUCK005', puck_type='Unipuck', puck_location_in_dewar=5, dewar_id=1, dewar_name='Dewar One', pgroup='p20001, p20002', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=6, puck_name='PUCK006', puck_type='Unipuck', puck_location_in_dewar=6, dewar_id=1, dewar_name='Dewar One', pgroup='p20001, p20002', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=7, puck_name='PUCK007', puck_type='Unipuck', puck_location_in_dewar=7, dewar_id=1, dewar_name='Dewar One', pgroup='p20001, p20002', samples=None, tell_position=None)]\n" + "[PuckWithTellPosition(id=1, puck_name='PUCK-001', puck_type='Unipuck', puck_location_in_dewar=1, dewar_id=1, dewar_name='Dewar One', pgroup='p20001', samples=None, tell_position='A2'),\n", + " PuckWithTellPosition(id=2, puck_name='PUCK002', puck_type='Unipuck', puck_location_in_dewar=2, dewar_id=1, dewar_name='Dewar One', pgroup='p20001', samples=None, tell_position='A1'),\n", + " PuckWithTellPosition(id=3, puck_name='PUCK003', puck_type='Unipuck', puck_location_in_dewar=3, dewar_id=1, dewar_name='Dewar One', pgroup='p20001', samples=None, tell_position='F2'),\n", + " PuckWithTellPosition(id=4, puck_name='PUCK004', puck_type='Unipuck', puck_location_in_dewar=4, dewar_id=1, dewar_name='Dewar One', pgroup='p20001', samples=None, tell_position=None),\n", + " PuckWithTellPosition(id=5, puck_name='PUCK005', puck_type='Unipuck', puck_location_in_dewar=5, dewar_id=1, dewar_name='Dewar One', pgroup='p20001', samples=None, tell_position=None),\n", + " PuckWithTellPosition(id=6, puck_name='PUCK006', puck_type='Unipuck', puck_location_in_dewar=6, dewar_id=1, dewar_name='Dewar One', pgroup='p20001', samples=None, tell_position='F1'),\n", + " PuckWithTellPosition(id=7, puck_name='PUCK007', puck_type='Unipuck', puck_location_in_dewar=7, dewar_id=1, dewar_name='Dewar One', pgroup='p20001', samples=None, tell_position=None)]\n" ] }, { @@ -224,7 +224,7 @@ ] } ], - "execution_count": 77 + "execution_count": 2 }, { "metadata": { @@ -328,8 +328,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-02-26T12:04:41.352140Z", - "start_time": "2025-02-26T12:04:41.331320Z" + "end_time": "2025-03-03T10:06:39.979358Z", + "start_time": "2025-03-03T10:06:39.957359Z" } }, "cell_type": "code", @@ -408,7 +408,7 @@ " Sample ID: 13, Sample Name: Sample013, Position: 13, Mount count: 0\n", " Sample ID: 14, Sample Name: Sample014, Position: 14, Mount count: 1\n", " Sample ID: 15, Sample Name: Sample015, Position: 15, Mount count: 0\n", - " Sample ID: 16, Sample Name: Sample016, Position: 16, Mount count: 0\n" + " Sample ID: 16, Sample Name: Sample016, Position: 16, Mount count: 1\n" ] }, { @@ -420,7 +420,7 @@ ] } ], - "execution_count": 79 + "execution_count": 3 }, { "metadata": { @@ -534,6 +534,8 @@ }, "cell_type": "code", "source": [ + "# post images to sample database\n", + "\n", "import os\n", "import mimetypes\n", "import requests\n", @@ -602,6 +604,958 @@ "execution_count": null, "source": "help(api_instance.upload_sample_images_samples_samples_sample_id_upload_images_post)", "id": "cb1b99e6327fff84" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-04T09:17:34.613556Z", + "start_time": "2025-03-04T09:17:34.599367Z" + } + }, + "cell_type": "code", + "source": [ + "# post experiment results to sample database\n", + "\n", + "from aareDBclient.models import (\n", + " ExperimentParametersCreate,\n", + " RotationParameters,\n", + " BeamlineParameters,\n", + " GridScanParamers\n", + ")\n", + "\n", + "\n", + "## Build the nested parameters\n", + "#rotation = RotationParameters(\n", + "# omegaStart_deg=0.0,\n", + "# omegaStep=90.0,\n", + "# phi=10.0,\n", + "# chi=0.0,\n", + "# numberOfImages=4,\n", + "# exposureTime_s=0.02\n", + "#)\n", + "\n", + "gridscan = GridScanParamers(\n", + " xStart=0.0,\n", + " xStep=0.1,\n", + " yStart=0.0,\n", + " yStep= 0.1,\n", + " zStart=0.0,\n", + " zStep=0.0,\n", + " numberOfImages=4600,\n", + " exposureTime_s=0.001\n", + ")\n", + "\n", + "# If your client code requires you to build a detector model,\n", + "# you can either use a Detector model or pass a dictionary.\n", + "# Here we pass a dictionary.\n", + "detector_data = {\n", + " \"manufacturer\": \"DECTRIS\",\n", + " \"model\": \"PILATUS4 2M\",\n", + " \"type\": \"photon-counting\",\n", + " \"serialNumber\": \"16684dscsd668468\",\n", + " \"detectorDistance_mm\": 95.0,\n", + " \"beamCenterX_px\": 512.0,\n", + " \"beamCenterY_px\": 512.0,\n", + " \"pixelSizeX_um\": 150.0,\n", + " \"pixelSizeY_um\": 150.0,\n", + "}\n", + "\n", + "beamline_params = BeamlineParameters(\n", + " synchrotron=\"Swiss Light Source\",\n", + " beamline=\"PXIII\",\n", + " detector=detector_data,\n", + " wavelength=1.0,\n", + " ringCurrent_A=0.0,\n", + " ringMode=\"Machine Down\",\n", + " monochromator=\"Si111\",\n", + " transmission=1.00,\n", + " focusingOptic=\"Kirkpatrick-Baez\",\n", + " beamlineFluxAtSample_ph_s=0,\n", + " beamSizeWidth=30.0,\n", + " beamSizeHeight=30.0,\n", + "# rotation=rotation # Optional nested parameter\n", + " gridScan=gridscan\n", + " # gridScan and jet are optional and can be added similarly\n", + ")\n", + "\n", + "# Prepare the experiment parameters payload.\n", + "# Note that the run_number will be set on the server side, so you can leave\n", + "# it out or set it to a dummy value if your client model requires it.\n", + "experiment_params_payload = ExperimentParametersCreate(\n", + " # run_number can be omitted/ignored if computed on the server\n", + " beamline_parameters=beamline_params,\n", + " sample_id=15 # change sample_id to an existing sample in your database\n", + ")\n", + "\n", + "# Now, use the API instance to send the POST request\n", + "with aareDBclient.ApiClient(configuration) as api_client:\n", + " api_instance = aareDBclient.SamplesApi(api_client)\n", + "\n", + " try:\n", + " # Call the endpoint. The endpoint path expects the sample_id.\n", + " api_response = api_instance.create_experiment_parameters_for_sample_samples_samples_sample_id_experiment_parameters_post(\n", + " sample_id=experiment_params_payload.sample_id,\n", + " experiment_parameters_create=experiment_params_payload\n", + ")\n", + "\n", + " print(\"API Response:\")\n", + " print(api_response)\n", + " except ApiException as e:\n", + " print(\"Exception when calling ExperimentParametersApi->create_experiment_parameters_for_sample:\")\n", + " print(e)\n" + ], + "id": "421ba0710f29a5fa", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "API Response:\n", + "run_number=3 beamline_parameters=BeamlineParameters(synchrotron='Swiss Light Source', beamline='PXIII', detector=Detector(manufacturer='DECTRIS', model='PILATUS4 2M', type='photon-counting', serial_number='16684dscsd668468', detector_distance_mm=95.0, beam_center_x_px=512.0, beam_center_y_px=512.0, pixel_size_x_um=150.0, pixel_size_y_um=150.0), wavelength=1.0, ring_current_a=0.0, ring_mode='Machine Down', undulator=None, undulatorgap_mm=None, monochromator='Si111', transmission=1.0, focusing_optic='Kirkpatrick-Baez', beamline_flux_at_sample_ph_s=0.0, beam_size_width=30.0, beam_size_height=30.0, rotation=None, grid_scan=GridScanParamers(x_start=0.0, x_step=0.1, y_start=0.0, y_step=0.1, z_start=0.0, z_step=0.0, number_of_images=4600, exposure_time_s=0.001), jet=None, cryojet_temperature_k=None, humidifier_temperature_k=None, humidifier_humidity=None) sample_id=15 id=10\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", + " warnings.warn(\n" + ] + } + ], + "execution_count": 12 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-04T09:22:51.456656Z", + "start_time": "2025-03-04T09:22:51.403762Z" + } + }, + "cell_type": "code", + "source": [ + "# get experiment results to sample database\n", + "\n", + "with aareDBclient.ApiClient(configuration) as api_client:\n", + " # Create an instance of the API class\n", + " api_instance = aareDBclient.SamplesApi(api_client)\n", + "\n", + " # GET request: Fetch all pucks in the tell\n", + " try:\n", + " # Call the API method to fetch pucks\n", + " all_results_response = api_instance.get_sample_results_samples_results_get(active_pgroup=\"p20001\")\n", + "\n", + " # Debug response structure by printing it in JSON format\n", + " formatted_response = json.dumps(\n", + " [p.to_dict() for p in all_results_response], # Assuming the API response can be converted to dicts\n", + " indent=4 # Use indentation for readability\n", + " )\n", + " print(\"The response of PucksApi->get_all_pucks_in_tell (formatted):\\n\")\n", + " print(formatted_response)\n", + "\n", + " ## Iterate through each puck and print information\n", + " #for p in all_results_response:\n", + " # print(f\"Puck ID: {p.id}, Puck Name: {p.puck_name}\")\n", + " #\n", + " # ## Check if the puck has any samples\n", + " # if hasattr(p, 'samples') and p.samples: # Ensure 'samples' attribute exists and is not empty\n", + " # for sample in p.samples:\n", + " # print(f\" Sample ID: {sample.id}, Sample Name: {sample.sample_name}, Position: {sample.position}, Mount count: {sample.mount_count}\")\n", + " # else:\n", + " # print(\" No samples found in this puck.\")\n", + " #\n", + " except ApiException as e:\n", + " print(\"Exception when calling PucksApi->get_all_pucks_in_tell: %s\\n\" % e)" + ], + "id": "6079a4f10102e906", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The response of PucksApi->get_all_pucks_in_tell (formatted):\n", + "\n", + "[\n", + " {\n", + " \"sample_id\": 1,\n", + " \"sample_name\": \"Sample001\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 2,\n", + " \"sample_name\": \"Sample002\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 3,\n", + " \"sample_name\": \"Sample003\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 4,\n", + " \"sample_name\": \"Sample004\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 5,\n", + " \"sample_name\": \"Sample005\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 6,\n", + " \"sample_name\": \"Sample006\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 7,\n", + " \"sample_name\": \"Sample007\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 8,\n", + " \"sample_name\": \"Sample008\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 9,\n", + " \"sample_name\": \"Sample009\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 10,\n", + " \"sample_name\": \"Sample010\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 11,\n", + " \"sample_name\": \"Sample011\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 12,\n", + " \"sample_name\": \"Sample012\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 13,\n", + " \"sample_name\": \"Sample013\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 14,\n", + " \"sample_name\": \"Sample014\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 15,\n", + " \"sample_name\": \"Sample015\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": [\n", + " {\n", + " \"run_number\": 1,\n", + " \"beamline_parameters\": {\n", + " \"synchrotron\": \"Swiss Light Source\",\n", + " \"beamline\": \"PXIII\",\n", + " \"detector\": {\n", + " \"manufacturer\": \"DECTRIS\",\n", + " \"model\": \"PILATUS4 2M\",\n", + " \"type\": \"photon-counting\",\n", + " \"serialNumber\": \"16684dscsd668468\",\n", + " \"detectorDistance_mm\": 95.0,\n", + " \"beamCenterX_px\": 512.0,\n", + " \"beamCenterY_px\": 512.0,\n", + " \"pixelSizeX_um\": 150.0,\n", + " \"pixelSizeY_um\": 150.0\n", + " },\n", + " \"wavelength\": 1.0,\n", + " \"ringCurrent_A\": 0.0,\n", + " \"ringMode\": \"Machine Down\",\n", + " \"monochromator\": \"Si111\",\n", + " \"transmission\": 1.0,\n", + " \"focusingOptic\": \"Kirkpatrick-Baez\",\n", + " \"beamlineFluxAtSample_ph_s\": 0.0,\n", + " \"beamSizeWidth\": 30.0,\n", + " \"beamSizeHeight\": 30.0,\n", + " \"rotation\": {\n", + " \"omegaStart_deg\": 0.0,\n", + " \"omegaStep\": 0.5,\n", + " \"chi\": 0.0,\n", + " \"phi\": 10.0,\n", + " \"numberOfImages\": 3600,\n", + " \"exposureTime_s\": 0.02\n", + " },\n", + " \"undulator\": null,\n", + " \"undulatorgap_mm\": null,\n", + " \"gridScan\": null,\n", + " \"jet\": null,\n", + " \"cryojetTemperature_K\": null,\n", + " \"humidifierTemperature_K\": null,\n", + " \"humidifierHumidity\": null\n", + " },\n", + " \"sample_id\": 15,\n", + " \"id\": 8\n", + " },\n", + " {\n", + " \"run_number\": 2,\n", + " \"beamline_parameters\": {\n", + " \"synchrotron\": \"Swiss Light Source\",\n", + " \"beamline\": \"PXIII\",\n", + " \"detector\": {\n", + " \"manufacturer\": \"DECTRIS\",\n", + " \"model\": \"PILATUS4 2M\",\n", + " \"type\": \"photon-counting\",\n", + " \"serialNumber\": \"16684dscsd668468\",\n", + " \"detectorDistance_mm\": 95.0,\n", + " \"beamCenterX_px\": 512.0,\n", + " \"beamCenterY_px\": 512.0,\n", + " \"pixelSizeX_um\": 150.0,\n", + " \"pixelSizeY_um\": 150.0\n", + " },\n", + " \"wavelength\": 1.0,\n", + " \"ringCurrent_A\": 0.0,\n", + " \"ringMode\": \"Machine Down\",\n", + " \"monochromator\": \"Si111\",\n", + " \"transmission\": 1.0,\n", + " \"focusingOptic\": \"Kirkpatrick-Baez\",\n", + " \"beamlineFluxAtSample_ph_s\": 0.0,\n", + " \"beamSizeWidth\": 30.0,\n", + " \"beamSizeHeight\": 30.0,\n", + " \"rotation\": {\n", + " \"omegaStart_deg\": 0.0,\n", + " \"omegaStep\": 90.0,\n", + " \"chi\": 0.0,\n", + " \"phi\": 10.0,\n", + " \"numberOfImages\": 4,\n", + " \"exposureTime_s\": 0.02\n", + " },\n", + " \"undulator\": null,\n", + " \"undulatorgap_mm\": null,\n", + " \"gridScan\": null,\n", + " \"jet\": null,\n", + " \"cryojetTemperature_K\": null,\n", + " \"humidifierTemperature_K\": null,\n", + " \"humidifierHumidity\": null\n", + " },\n", + " \"sample_id\": 15,\n", + " \"id\": 9\n", + " },\n", + " {\n", + " \"run_number\": 3,\n", + " \"beamline_parameters\": {\n", + " \"synchrotron\": \"Swiss Light Source\",\n", + " \"beamline\": \"PXIII\",\n", + " \"detector\": {\n", + " \"manufacturer\": \"DECTRIS\",\n", + " \"model\": \"PILATUS4 2M\",\n", + " \"type\": \"photon-counting\",\n", + " \"serialNumber\": \"16684dscsd668468\",\n", + " \"detectorDistance_mm\": 95.0,\n", + " \"beamCenterX_px\": 512.0,\n", + " \"beamCenterY_px\": 512.0,\n", + " \"pixelSizeX_um\": 150.0,\n", + " \"pixelSizeY_um\": 150.0\n", + " },\n", + " \"wavelength\": 1.0,\n", + " \"ringCurrent_A\": 0.0,\n", + " \"ringMode\": \"Machine Down\",\n", + " \"monochromator\": \"Si111\",\n", + " \"transmission\": 1.0,\n", + " \"focusingOptic\": \"Kirkpatrick-Baez\",\n", + " \"beamlineFluxAtSample_ph_s\": 0.0,\n", + " \"beamSizeWidth\": 30.0,\n", + " \"beamSizeHeight\": 30.0,\n", + " \"gridScan\": {\n", + " \"xStart\": 0.0,\n", + " \"xStep\": 0.1,\n", + " \"yStart\": 0.0,\n", + " \"yStep\": 0.1,\n", + " \"zStart\": 0.0,\n", + " \"zStep\": 0.0,\n", + " \"numberOfImages\": 4600,\n", + " \"exposureTime_s\": 0.001\n", + " },\n", + " \"undulator\": null,\n", + " \"undulatorgap_mm\": null,\n", + " \"rotation\": null,\n", + " \"jet\": null,\n", + " \"cryojetTemperature_K\": null,\n", + " \"humidifierTemperature_K\": null,\n", + " \"humidifierHumidity\": null\n", + " },\n", + " \"sample_id\": 15,\n", + " \"id\": 10\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"sample_id\": 16,\n", + " \"sample_name\": \"Sample016\",\n", + " \"puck_name\": \"PUCK-001\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [\n", + " {\n", + " \"id\": 3,\n", + " \"filepath\": \"images/p20001/2025-02-26/Dewar One/PUCK-001/16/bb_raster_0.jpg\",\n", + " \"comment\": null\n", + " },\n", + " {\n", + " \"id\": 4,\n", + " \"filepath\": \"images/p20001/2025-02-26/Dewar One/PUCK-001/16/bb_raster_90.jpg\",\n", + " \"comment\": null\n", + " }\n", + " ],\n", + " \"experiment_runs\": [\n", + " {\n", + " \"run_number\": 1,\n", + " \"beamline_parameters\": {\n", + " \"synchrotron\": \"Swiss Light Source\",\n", + " \"beamline\": \"PXIII\",\n", + " \"detector\": {\n", + " \"manufacturer\": \"DECTRIS\",\n", + " \"model\": \"PILATUS4 2M\",\n", + " \"type\": \"photon-counting\",\n", + " \"serialNumber\": \"16684dscsd668468\",\n", + " \"detectorDistance_mm\": 95.0,\n", + " \"beamCenterX_px\": 512.0,\n", + " \"beamCenterY_px\": 512.0,\n", + " \"pixelSizeX_um\": 150.0,\n", + " \"pixelSizeY_um\": 150.0\n", + " },\n", + " \"wavelength\": 1.0,\n", + " \"ringCurrent_A\": 0.0,\n", + " \"ringMode\": \"Machine Down\",\n", + " \"monochromator\": \"Si111\",\n", + " \"transmission\": 1.0,\n", + " \"focusingOptic\": \"Kirkpatrick-Baez\",\n", + " \"beamlineFluxAtSample_ph_s\": 0.0,\n", + " \"beamSizeWidth\": 30.0,\n", + " \"beamSizeHeight\": 30.0,\n", + " \"rotation\": {\n", + " \"omegaStart_deg\": 0.0,\n", + " \"omegaStep\": 0.5,\n", + " \"chi\": 0.0,\n", + " \"phi\": 10.0,\n", + " \"numberOfImages\": 3600,\n", + " \"exposureTime_s\": 0.02\n", + " },\n", + " \"undulator\": null,\n", + " \"undulatorgap_mm\": null,\n", + " \"gridScan\": null,\n", + " \"jet\": null,\n", + " \"cryojetTemperature_K\": null,\n", + " \"humidifierTemperature_K\": null,\n", + " \"humidifierHumidity\": null\n", + " },\n", + " \"sample_id\": 16,\n", + " \"id\": 5\n", + " },\n", + " {\n", + " \"run_number\": 2,\n", + " \"beamline_parameters\": {\n", + " \"synchrotron\": \"Swiss Light Source\",\n", + " \"beamline\": \"PXIII\",\n", + " \"detector\": {\n", + " \"manufacturer\": \"DECTRIS\",\n", + " \"model\": \"PILATUS4 2M\",\n", + " \"type\": \"photon-counting\",\n", + " \"serialNumber\": \"16684dscsd668468\",\n", + " \"detectorDistance_mm\": 95.0,\n", + " \"beamCenterX_px\": 512.0,\n", + " \"beamCenterY_px\": 512.0,\n", + " \"pixelSizeX_um\": 150.0,\n", + " \"pixelSizeY_um\": 150.0\n", + " },\n", + " \"wavelength\": 1.0,\n", + " \"ringCurrent_A\": 0.0,\n", + " \"ringMode\": \"Machine Down\",\n", + " \"monochromator\": \"Si111\",\n", + " \"transmission\": 1.0,\n", + " \"focusingOptic\": \"Kirkpatrick-Baez\",\n", + " \"beamlineFluxAtSample_ph_s\": 0.0,\n", + " \"beamSizeWidth\": 30.0,\n", + " \"beamSizeHeight\": 30.0,\n", + " \"rotation\": {\n", + " \"omegaStart_deg\": 0.0,\n", + " \"omegaStep\": 0.5,\n", + " \"chi\": 0.0,\n", + " \"phi\": 10.0,\n", + " \"numberOfImages\": 3600,\n", + " \"exposureTime_s\": 0.02\n", + " },\n", + " \"undulator\": null,\n", + " \"undulatorgap_mm\": null,\n", + " \"gridScan\": null,\n", + " \"jet\": null,\n", + " \"cryojetTemperature_K\": null,\n", + " \"humidifierTemperature_K\": null,\n", + " \"humidifierHumidity\": null\n", + " },\n", + " \"sample_id\": 16,\n", + " \"id\": 6\n", + " },\n", + " {\n", + " \"run_number\": 3,\n", + " \"beamline_parameters\": {\n", + " \"synchrotron\": \"Swiss Light Source\",\n", + " \"beamline\": \"PXIII\",\n", + " \"detector\": {\n", + " \"manufacturer\": \"DECTRIS\",\n", + " \"model\": \"PILATUS4 2M\",\n", + " \"type\": \"photon-counting\",\n", + " \"serialNumber\": \"16684dscsd668468\",\n", + " \"detectorDistance_mm\": 95.0,\n", + " \"beamCenterX_px\": 512.0,\n", + " \"beamCenterY_px\": 512.0,\n", + " \"pixelSizeX_um\": 150.0,\n", + " \"pixelSizeY_um\": 150.0\n", + " },\n", + " \"wavelength\": 1.0,\n", + " \"ringCurrent_A\": 0.0,\n", + " \"ringMode\": \"Machine Down\",\n", + " \"monochromator\": \"Si111\",\n", + " \"transmission\": 1.0,\n", + " \"focusingOptic\": \"Kirkpatrick-Baez\",\n", + " \"beamlineFluxAtSample_ph_s\": 0.0,\n", + " \"beamSizeWidth\": 30.0,\n", + " \"beamSizeHeight\": 30.0,\n", + " \"rotation\": {\n", + " \"omegaStart_deg\": 0.0,\n", + " \"omegaStep\": 0.5,\n", + " \"chi\": 0.0,\n", + " \"phi\": 10.0,\n", + " \"numberOfImages\": 3600,\n", + " \"exposureTime_s\": 0.02\n", + " },\n", + " \"undulator\": null,\n", + " \"undulatorgap_mm\": null,\n", + " \"gridScan\": null,\n", + " \"jet\": null,\n", + " \"cryojetTemperature_K\": null,\n", + " \"humidifierTemperature_K\": null,\n", + " \"humidifierHumidity\": null\n", + " },\n", + " \"sample_id\": 16,\n", + " \"id\": 7\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"sample_id\": 17,\n", + " \"sample_name\": \"Sample017\",\n", + " \"puck_name\": \"PUCK002\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 18,\n", + " \"sample_name\": \"Sample018\",\n", + " \"puck_name\": \"PUCK002\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 19,\n", + " \"sample_name\": \"Sample019\",\n", + " \"puck_name\": \"PUCK002\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 20,\n", + " \"sample_name\": \"Sample020\",\n", + " \"puck_name\": \"PUCK002\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 21,\n", + " \"sample_name\": \"Sample021\",\n", + " \"puck_name\": \"PUCK002\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 22,\n", + " \"sample_name\": \"Sample022\",\n", + " \"puck_name\": \"PUCK002\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 23,\n", + " \"sample_name\": \"Sample023\",\n", + " \"puck_name\": \"PUCK002\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 24,\n", + " \"sample_name\": \"Sample024\",\n", + " \"puck_name\": \"PUCK003\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 25,\n", + " \"sample_name\": \"Sample025\",\n", + " \"puck_name\": \"PUCK003\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 26,\n", + " \"sample_name\": \"Sample026\",\n", + " \"puck_name\": \"PUCK003\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 27,\n", + " \"sample_name\": \"Sample027\",\n", + " \"puck_name\": \"PUCK003\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 28,\n", + " \"sample_name\": \"Sample028\",\n", + " \"puck_name\": \"PUCK003\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 29,\n", + " \"sample_name\": \"Sample029\",\n", + " \"puck_name\": \"PUCK004\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 30,\n", + " \"sample_name\": \"Sample030\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 31,\n", + " \"sample_name\": \"Sample031\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 32,\n", + " \"sample_name\": \"Sample032\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 33,\n", + " \"sample_name\": \"Sample033\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 34,\n", + " \"sample_name\": \"Sample034\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 35,\n", + " \"sample_name\": \"Sample035\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 36,\n", + " \"sample_name\": \"Sample036\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 37,\n", + " \"sample_name\": \"Sample037\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 38,\n", + " \"sample_name\": \"Sample038\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 39,\n", + " \"sample_name\": \"Sample039\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 40,\n", + " \"sample_name\": \"Sample040\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 41,\n", + " \"sample_name\": \"Sample041\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 42,\n", + " \"sample_name\": \"Sample042\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 43,\n", + " \"sample_name\": \"Sample043\",\n", + " \"puck_name\": \"PUCK005\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 44,\n", + " \"sample_name\": \"Sample044\",\n", + " \"puck_name\": \"PUCK006\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 45,\n", + " \"sample_name\": \"Sample045\",\n", + " \"puck_name\": \"PUCK006\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 46,\n", + " \"sample_name\": \"Sample046\",\n", + " \"puck_name\": \"PUCK006\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 47,\n", + " \"sample_name\": \"Sample047\",\n", + " \"puck_name\": \"PUCK006\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 48,\n", + " \"sample_name\": \"Sample048\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 49,\n", + " \"sample_name\": \"Sample049\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 50,\n", + " \"sample_name\": \"Sample050\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 51,\n", + " \"sample_name\": \"Sample051\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 52,\n", + " \"sample_name\": \"Sample052\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 53,\n", + " \"sample_name\": \"Sample053\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 54,\n", + " \"sample_name\": \"Sample054\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 55,\n", + " \"sample_name\": \"Sample055\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 56,\n", + " \"sample_name\": \"Sample056\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 57,\n", + " \"sample_name\": \"Sample057\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 58,\n", + " \"sample_name\": \"Sample058\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 59,\n", + " \"sample_name\": \"Sample059\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 60,\n", + " \"sample_name\": \"Sample060\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " },\n", + " {\n", + " \"sample_id\": 61,\n", + " \"sample_name\": \"Sample061\",\n", + " \"puck_name\": \"PUCK007\",\n", + " \"dewar_name\": \"Dewar One\",\n", + " \"images\": [],\n", + " \"experiment_runs\": []\n", + " }\n", + "]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", + " warnings.warn(\n" + ] + } + ], + "execution_count": 2 } ], "metadata": {