Refactor beamtime relationships in models and related APIs
Updated relationships for beamtime in models to support many-to-many associations with pucks, samples, and dewars. Refactored API endpoints to accommodate these changes, ensuring accurate assignment and retrieval of data. Improved sample data generation logic and incremented the application version for the new updates.
This commit is contained in:
parent
0fa038be94
commit
6a0953c913
@ -407,17 +407,43 @@ beamtimes = [
|
||||
),
|
||||
Beamtime(
|
||||
id=2,
|
||||
pgroups="p20003",
|
||||
pgroups="p20001",
|
||||
shift="afternoon",
|
||||
beamtime_name="p20003-test",
|
||||
beamtime_name="p20001-test",
|
||||
beamline="X06DA",
|
||||
start_date=datetime.strptime("07.05.2025", "%d.%m.%Y").date(),
|
||||
end_date=datetime.strptime("08.05.2025", "%d.%m.%Y").date(),
|
||||
start_date=datetime.strptime("06.05.2025", "%d.%m.%Y").date(),
|
||||
end_date=datetime.strptime("07.05.2025", "%d.%m.%Y").date(),
|
||||
status="confirmed",
|
||||
comments="this is a test beamtime",
|
||||
proposal_id=2,
|
||||
local_contact_id=2,
|
||||
),
|
||||
Beamtime(
|
||||
id=3,
|
||||
pgroups="p20003",
|
||||
shift="morning",
|
||||
beamtime_name="p20003-test",
|
||||
beamline="X06SA",
|
||||
start_date=datetime.strptime("06.05.2025", "%d.%m.%Y").date(),
|
||||
end_date=datetime.strptime("06.05.2025", "%d.%m.%Y").date(),
|
||||
status="confirmed",
|
||||
comments="this is a test beamtime",
|
||||
proposal_id=1,
|
||||
local_contact_id=1,
|
||||
),
|
||||
Beamtime(
|
||||
id=4,
|
||||
pgroups="p20002",
|
||||
shift="night",
|
||||
beamtime_name="p20002-test",
|
||||
beamline="X06DA",
|
||||
start_date=datetime.strptime("08.05.2025", "%d.%m.%Y").date(),
|
||||
end_date=datetime.strptime("08.05.2025", "%d.%m.%Y").date(),
|
||||
status="confirmed",
|
||||
comments="this is a test beamtime",
|
||||
proposal_id=3,
|
||||
local_contact_id=2,
|
||||
),
|
||||
]
|
||||
|
||||
# Define shipments
|
||||
@ -679,7 +705,8 @@ samples = []
|
||||
sample_id_counter = 1
|
||||
# Assign a beamtime to each dewar
|
||||
dewar_to_beamtime = {
|
||||
dewar.id: random.choice([1, 2]) for dewar in dewars # Or use actual beamtime ids
|
||||
dewar.id: random.choice([1, 2, 3, 4])
|
||||
for dewar in dewars # Or use actual beamtime ids
|
||||
}
|
||||
|
||||
# Update dewars and their pucks with consistent beamtime
|
||||
@ -688,10 +715,9 @@ for dewar in dewars:
|
||||
|
||||
for puck in pucks:
|
||||
dewar_id = puck.dewar_id # Assuming puck has dewar_id
|
||||
assigned_beamtime = dewar_to_beamtime[dewar_id]
|
||||
puck.beamtime_id = (
|
||||
assigned_beamtime # Associate puck to the same beamtime as its dewar
|
||||
)
|
||||
assigned_beamtime = dewar_to_beamtime[dewar_id] # this is the id (int)
|
||||
# Fix here: use assigned_beamtime (which is the id)
|
||||
assigned_beamtime_obj = next(b for b in beamtimes if b.id == assigned_beamtime)
|
||||
|
||||
positions_with_samples = random.randint(1, 16)
|
||||
occupied_positions = random.sample(range(1, 17), positions_with_samples)
|
||||
@ -703,11 +729,14 @@ for puck in pucks:
|
||||
sample_name=f"Sample{sample_id_counter:03}",
|
||||
position=pos,
|
||||
puck_id=puck.id,
|
||||
beamtime_id=assigned_beamtime,
|
||||
)
|
||||
sample.beamtimes.append(
|
||||
assigned_beamtime_obj
|
||||
) # assigned_beamtime_obj is a Beamtime instance
|
||||
samples.append(sample)
|
||||
sample_id_counter += 1
|
||||
|
||||
|
||||
# Define possible event types for samples
|
||||
event_types = ["Mounting", "Failed", "Unmounting", "Lost"]
|
||||
|
||||
|
@ -9,6 +9,7 @@ from sqlalchemy import (
|
||||
Boolean,
|
||||
func,
|
||||
Enum,
|
||||
Table,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
from .database import Base
|
||||
@ -16,6 +17,26 @@ from datetime import datetime
|
||||
import enum
|
||||
|
||||
|
||||
dewar_beamtime_association = Table(
|
||||
"dewar_beamtime_association",
|
||||
Base.metadata,
|
||||
Column("dewar_id", Integer, ForeignKey("dewars.id")),
|
||||
Column("beamtime_id", Integer, ForeignKey("beamtimes.id")),
|
||||
)
|
||||
puck_beamtime_association = Table(
|
||||
"puck_beamtime_association",
|
||||
Base.metadata,
|
||||
Column("puck_id", Integer, ForeignKey("pucks.id")),
|
||||
Column("beamtime_id", Integer, ForeignKey("beamtimes.id")),
|
||||
)
|
||||
sample_beamtime_association = Table(
|
||||
"sample_beamtime_association",
|
||||
Base.metadata,
|
||||
Column("sample_id", Integer, ForeignKey("samples.id")),
|
||||
Column("beamtime_id", Integer, ForeignKey("beamtimes.id")),
|
||||
)
|
||||
|
||||
|
||||
class Shipment(Base):
|
||||
__tablename__ = "shipments"
|
||||
|
||||
@ -120,8 +141,9 @@ class Dewar(Base):
|
||||
beamline_location = None
|
||||
local_contact_id = Column(Integer, ForeignKey("local_contacts.id"), nullable=True)
|
||||
local_contact = relationship("LocalContact")
|
||||
beamtime = relationship("Beamtime", back_populates="dewars")
|
||||
beamtime_id = Column(Integer, ForeignKey("beamtimes.id"), nullable=True)
|
||||
beamtimes = relationship(
|
||||
"Beamtime", secondary=dewar_beamtime_association, back_populates="dewars"
|
||||
)
|
||||
|
||||
@property
|
||||
def number_of_pucks(self) -> int:
|
||||
@ -155,9 +177,8 @@ class Puck(Base):
|
||||
dewar = relationship("Dewar", back_populates="pucks")
|
||||
samples = relationship("Sample", back_populates="puck")
|
||||
events = relationship("PuckEvent", back_populates="puck")
|
||||
beamtime_id = Column(Integer, ForeignKey("beamtimes.id"), nullable=True)
|
||||
beamtime = relationship(
|
||||
"Beamtime", back_populates="pucks", foreign_keys=[beamtime_id]
|
||||
beamtimes = relationship(
|
||||
"Beamtime", secondary=puck_beamtime_association, back_populates="pucks"
|
||||
)
|
||||
|
||||
|
||||
@ -178,8 +199,9 @@ class Sample(Base):
|
||||
puck = relationship("Puck", back_populates="samples")
|
||||
events = relationship("SampleEvent", back_populates="sample", lazy="joined")
|
||||
images = relationship("Image", back_populates="sample", lazy="joined")
|
||||
beamtime_id = Column(Integer, ForeignKey("beamtimes.id"), nullable=True)
|
||||
beamtime = relationship("Beamtime", back_populates="samples")
|
||||
beamtimes = relationship(
|
||||
"Beamtime", secondary=sample_beamtime_association, back_populates="samples"
|
||||
)
|
||||
|
||||
@property
|
||||
def mount_count(self) -> int:
|
||||
@ -262,9 +284,15 @@ class Beamtime(Base):
|
||||
local_contact_id = Column(Integer, ForeignKey("local_contacts.id"), nullable=False)
|
||||
|
||||
local_contact = relationship("LocalContact")
|
||||
dewars = relationship("Dewar", back_populates="beamtime")
|
||||
pucks = relationship("Puck", back_populates="beamtime")
|
||||
samples = relationship("Sample", back_populates="beamtime")
|
||||
dewars = relationship(
|
||||
"Dewar", secondary=dewar_beamtime_association, back_populates="beamtimes"
|
||||
)
|
||||
pucks = relationship(
|
||||
"Puck", secondary=puck_beamtime_association, back_populates="beamtimes"
|
||||
)
|
||||
samples = relationship(
|
||||
"Sample", secondary=sample_beamtime_association, back_populates="beamtimes"
|
||||
)
|
||||
|
||||
|
||||
class Image(Base):
|
||||
|
@ -36,6 +36,7 @@ from app.models import (
|
||||
LogisticsEvent,
|
||||
PuckEvent,
|
||||
SampleEvent,
|
||||
Beamtime as BeamtimeModel,
|
||||
)
|
||||
from app.dependencies import get_db
|
||||
import qrcode
|
||||
@ -598,18 +599,37 @@ async def assign_beamtime_to_dewar(
|
||||
if not dewar:
|
||||
raise HTTPException(status_code=404, detail="Dewar not found")
|
||||
|
||||
dewar.beamtime_id = None if beamtime_id == 0 else beamtime_id
|
||||
# Find the Beamtime instance, if not unassigning
|
||||
beamtime = (
|
||||
db.query(BeamtimeModel).filter(BeamtimeModel.id == beamtime_id).first()
|
||||
if beamtime_id
|
||||
else None
|
||||
)
|
||||
|
||||
if beamtime_id == 0:
|
||||
dewar.beamtimes = []
|
||||
else:
|
||||
dewar.beamtimes = [
|
||||
beamtime
|
||||
] # assign one; append if you want to support multiple
|
||||
|
||||
db.commit()
|
||||
db.refresh(dewar)
|
||||
for puck in dewar.pucks:
|
||||
puck.beamtime_id = None if beamtime_id == 0 else beamtime_id
|
||||
if beamtime_id == 0:
|
||||
puck.beamtimes = []
|
||||
else:
|
||||
puck.beamtimes = [beamtime]
|
||||
for sample in puck.samples:
|
||||
has_sample_event = (
|
||||
db.query(SampleEvent).filter(SampleEvent.sample_id == sample.id).count()
|
||||
> 0
|
||||
)
|
||||
if not has_sample_event:
|
||||
sample.beamtime_id = None if beamtime_id == 0 else beamtime_id
|
||||
if beamtime_id == 0:
|
||||
sample.beamtimes = []
|
||||
else:
|
||||
sample.beamtimes = [beamtime]
|
||||
|
||||
db.commit()
|
||||
return {"status": "success", "dewar_id": dewar.id, "beamtime_id": beamtime_id}
|
||||
@ -726,5 +746,12 @@ async def get_single_shipment(id: int, db: Session = Depends(get_db)):
|
||||
operation_id="get_dewars_by_beamtime",
|
||||
)
|
||||
async def get_dewars_by_beamtime(beamtime_id: int, db: Session = Depends(get_db)):
|
||||
"""List all dewars assigned to a given beamtime."""
|
||||
return db.query(DewarModel).filter(DewarModel.beamtime_id == beamtime_id).all()
|
||||
beamtime = (
|
||||
db.query(BeamtimeModel)
|
||||
.options(joinedload(BeamtimeModel.dewars))
|
||||
.filter(BeamtimeModel.id == beamtime_id)
|
||||
.first()
|
||||
)
|
||||
if not beamtime:
|
||||
raise HTTPException(status_code=404, detail="Beamtime not found")
|
||||
return beamtime.dewars
|
||||
|
@ -1,6 +1,6 @@
|
||||
from datetime import datetime
|
||||
from fastapi import APIRouter, HTTPException, status, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
from sqlalchemy.sql import func
|
||||
from typing import List
|
||||
import uuid
|
||||
@ -21,6 +21,7 @@ from app.models import (
|
||||
LogisticsEvent as LogisticsEventModel,
|
||||
Dewar as DewarModel,
|
||||
SampleEvent,
|
||||
Beamtime as BeamtimeModel,
|
||||
)
|
||||
from app.dependencies import get_db
|
||||
import logging
|
||||
@ -664,23 +665,38 @@ async def get_pucks_by_slot(slot_identifier: str, db: Session = Depends(get_db))
|
||||
@router.patch("/puck/{puck_id}/assign-beamtime", operation_id="assignPuckToBeamtime")
|
||||
async def assign_beamtime_to_puck(
|
||||
puck_id: int,
|
||||
beamtime_id: int, # If you want ?beamtime_id=123 in the query
|
||||
beamtime_id: int, # expects ?beamtime_id=123 in the query
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
puck = db.query(PuckModel).filter(PuckModel.id == puck_id).first()
|
||||
if not puck:
|
||||
raise HTTPException(status_code=404, detail="Puck not found")
|
||||
|
||||
puck.beamtime_id = None if beamtime_id == 0 else beamtime_id
|
||||
beamtime = (
|
||||
db.query(BeamtimeModel).filter(BeamtimeModel.id == beamtime_id).first()
|
||||
if beamtime_id
|
||||
else None
|
||||
)
|
||||
|
||||
if beamtime_id == 0:
|
||||
puck.beamtimes = []
|
||||
else:
|
||||
puck.beamtimes = [
|
||||
beamtime
|
||||
] # or use .append(beamtime) if you want to support multiple
|
||||
|
||||
db.commit()
|
||||
db.refresh(puck)
|
||||
# Update samples
|
||||
# Update samples as well
|
||||
for sample in puck.samples:
|
||||
has_sample_event = (
|
||||
db.query(SampleEvent).filter(SampleEvent.sample_id == sample.id).count() > 0
|
||||
)
|
||||
if not has_sample_event:
|
||||
sample.beamtime_id = None if beamtime_id == 0 else beamtime_id
|
||||
if beamtime_id == 0:
|
||||
sample.beamtimes = []
|
||||
else:
|
||||
sample.beamtimes = [beamtime]
|
||||
db.commit()
|
||||
return {"status": "success", "puck_id": puck.id, "beamtime_id": beamtime_id}
|
||||
|
||||
@ -691,5 +707,12 @@ async def assign_beamtime_to_puck(
|
||||
operation_id="get_pucks_by_beamtime",
|
||||
)
|
||||
async def get_pucks_by_beamtime(beamtime_id: int, db: Session = Depends(get_db)):
|
||||
"""List all pucks assigned to a given beamtime."""
|
||||
return db.query(PuckModel).filter(PuckModel.beamtime_id == beamtime_id).all()
|
||||
beamtime = (
|
||||
db.query(BeamtimeModel)
|
||||
.options(joinedload(BeamtimeModel.pucks)) # eager load pucks
|
||||
.filter(BeamtimeModel.id == beamtime_id)
|
||||
.first()
|
||||
)
|
||||
if not beamtime:
|
||||
raise HTTPException(status_code=404, detail="Beamtime not found")
|
||||
return beamtime.pucks
|
||||
|
@ -32,6 +32,7 @@ from app.models import (
|
||||
Results as ResultsModel,
|
||||
Jobs as JobModel,
|
||||
JobStatus,
|
||||
Beamtime as BeamtimeModel,
|
||||
)
|
||||
from app.dependencies import get_db
|
||||
import logging
|
||||
@ -463,6 +464,7 @@ async def get_results_for_run_and_sample(
|
||||
formatted_results = [
|
||||
ResultResponse(
|
||||
id=result.id,
|
||||
status=result.status,
|
||||
sample_id=result.sample_id,
|
||||
run_id=result.run_id,
|
||||
result=ProcessingResults(**result.result),
|
||||
@ -479,5 +481,12 @@ async def get_results_for_run_and_sample(
|
||||
operation_id="get_samples_by_beamtime",
|
||||
)
|
||||
async def get_samples_by_beamtime(beamtime_id: int, db: Session = Depends(get_db)):
|
||||
"""List all samples assigned to a given beamtime."""
|
||||
return db.query(SampleModel).filter(SampleModel.beamtime_id == beamtime_id).all()
|
||||
beamtime = (
|
||||
db.query(BeamtimeModel)
|
||||
.options(joinedload(BeamtimeModel.samples))
|
||||
.filter(BeamtimeModel.id == beamtime_id)
|
||||
.first()
|
||||
)
|
||||
if not beamtime:
|
||||
raise HTTPException(status_code=404, detail="Beamtime not found")
|
||||
return beamtime.samples
|
||||
|
@ -373,13 +373,13 @@ class Results(BaseModel):
|
||||
resolution: float
|
||||
unit_cell: str
|
||||
spacegroup: str
|
||||
rmerge: float
|
||||
rmeas: float
|
||||
isig: float
|
||||
rmerge: List[CurvePoint]
|
||||
rmeas: List[CurvePoint]
|
||||
isig: List[CurvePoint]
|
||||
cc: List[CurvePoint]
|
||||
cchalf: List[CurvePoint]
|
||||
completeness: float
|
||||
multiplicity: float
|
||||
completeness: List[CurvePoint]
|
||||
multiplicity: List[CurvePoint]
|
||||
nobs: int
|
||||
total_refl: int
|
||||
unique_refl: int
|
||||
@ -478,6 +478,55 @@ class AddressMinimal(BaseModel):
|
||||
id: int
|
||||
|
||||
|
||||
class Beamtime(BaseModel):
|
||||
id: int
|
||||
pgroups: str
|
||||
shift: str
|
||||
beamtime_name: str
|
||||
beamline: str
|
||||
start_date: date
|
||||
end_date: date
|
||||
status: str
|
||||
comments: Optional[constr(max_length=200)] = None
|
||||
proposal_id: Optional[int]
|
||||
local_contact_id: Optional[int]
|
||||
local_contact: Optional[LocalContact]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class BeamtimeCreate(BaseModel):
|
||||
pgroups: str # this should be changed to pgroup
|
||||
shift: str
|
||||
beamtime_name: str
|
||||
beamline: str
|
||||
start_date: date
|
||||
end_date: date
|
||||
status: str
|
||||
comments: Optional[constr(max_length=200)] = None
|
||||
proposal_id: Optional[int]
|
||||
local_contact_id: Optional[int]
|
||||
|
||||
|
||||
class BeamtimeResponse(BaseModel):
|
||||
id: int
|
||||
pgroups: str
|
||||
shift: str
|
||||
beamtime_name: str
|
||||
beamline: str
|
||||
start_date: date
|
||||
end_date: date
|
||||
status: str
|
||||
comments: Optional[str] = None
|
||||
proposal_id: Optional[int]
|
||||
local_contact_id: Optional[int]
|
||||
local_contact: Optional[LocalContact]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class Sample(BaseModel):
|
||||
id: int
|
||||
sample_name: str
|
||||
@ -493,6 +542,7 @@ class Sample(BaseModel):
|
||||
mount_count: Optional[int] = None
|
||||
unmount_count: Optional[int] = None
|
||||
# results: Optional[Results] = None
|
||||
beamtimes: List[Beamtime] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
@ -507,6 +557,7 @@ class SampleCreate(BaseModel):
|
||||
comments: Optional[str] = None
|
||||
results: Optional[Results] = None
|
||||
events: Optional[List[str]] = None
|
||||
beamtime_ids: List[int] = []
|
||||
|
||||
class Config:
|
||||
populate_by_name = True
|
||||
@ -534,7 +585,7 @@ class PuckCreate(BaseModel):
|
||||
puck_type: str
|
||||
puck_location_in_dewar: int
|
||||
samples: List[SampleCreate] = []
|
||||
beamtime_id: Optional[int] = None
|
||||
beamtime_ids: List[int] = []
|
||||
|
||||
|
||||
class PuckUpdate(BaseModel):
|
||||
@ -542,7 +593,7 @@ class PuckUpdate(BaseModel):
|
||||
puck_type: Optional[str] = None
|
||||
puck_location_in_dewar: Optional[int] = None
|
||||
dewar_id: Optional[int] = None
|
||||
beamtime_id: Optional[int] = None
|
||||
beamtime_ids: List[int] = []
|
||||
|
||||
|
||||
class Puck(BaseModel):
|
||||
@ -551,9 +602,9 @@ class Puck(BaseModel):
|
||||
puck_type: str
|
||||
puck_location_in_dewar: int
|
||||
dewar_id: int
|
||||
beamtime_id: Optional[int] = None
|
||||
events: List[PuckEvent] = []
|
||||
samples: List[Sample] = []
|
||||
beamtimes: List[Beamtime] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
@ -573,6 +624,7 @@ class DewarBase(BaseModel):
|
||||
contact_id: Optional[int]
|
||||
return_address_id: Optional[int]
|
||||
pucks: List[PuckCreate] = []
|
||||
beamtimes: List[Beamtime] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
@ -605,6 +657,7 @@ class DewarUpdate(BaseModel):
|
||||
status: Optional[str] = None
|
||||
contact_id: Optional[int] = None
|
||||
address_id: Optional[int] = None
|
||||
beamtime_ids: List[int] = []
|
||||
|
||||
|
||||
class DewarSchema(BaseModel):
|
||||
@ -786,55 +839,6 @@ class DewarWithPucksResponse(BaseModel):
|
||||
pucks: List[PuckResponse]
|
||||
|
||||
|
||||
class Beamtime(BaseModel):
|
||||
id: int
|
||||
pgroups: str
|
||||
shift: str
|
||||
beamtime_name: str
|
||||
beamline: str
|
||||
start_date: date
|
||||
end_date: date
|
||||
status: str
|
||||
comments: Optional[constr(max_length=200)] = None
|
||||
proposal_id: Optional[int]
|
||||
local_contact_id: Optional[int]
|
||||
local_contact: Optional[LocalContact]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class BeamtimeCreate(BaseModel):
|
||||
pgroups: str # this should be changed to pgroup
|
||||
shift: str
|
||||
beamtime_name: str
|
||||
beamline: str
|
||||
start_date: date
|
||||
end_date: date
|
||||
status: str
|
||||
comments: Optional[constr(max_length=200)] = None
|
||||
proposal_id: Optional[int]
|
||||
local_contact_id: Optional[int]
|
||||
|
||||
|
||||
class BeamtimeResponse(BaseModel):
|
||||
id: int
|
||||
pgroups: str
|
||||
shift: str
|
||||
beamtime_name: str
|
||||
beamline: str
|
||||
start_date: date
|
||||
end_date: date
|
||||
status: str
|
||||
comments: Optional[str] = None
|
||||
proposal_id: Optional[int]
|
||||
local_contact_id: Optional[int]
|
||||
local_contact: Optional[LocalContact]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class ImageCreate(BaseModel):
|
||||
pgroup: str
|
||||
sample_id: int
|
||||
|
@ -168,8 +168,8 @@ async def lifespan(app: FastAPI):
|
||||
load_slots_data(db)
|
||||
else: # dev or test environments
|
||||
print(f"{environment.capitalize()} environment: Regenerating database.")
|
||||
Base.metadata.drop_all(bind=engine)
|
||||
Base.metadata.create_all(bind=engine)
|
||||
# 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)
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "aareDB"
|
||||
version = "0.1.1a2"
|
||||
version = "0.1.1a3"
|
||||
description = "Backend for next gen sample management system"
|
||||
authors = [{name = "Guillaume Gotthard", email = "guillaume.gotthard@psi.ch"}]
|
||||
license = {text = "MIT"}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ssl_cert_path": "ssl/cert.pem",
|
||||
"ssl_key_path": "ssl/key.pem",
|
||||
"OPENAPI_URL": "https://127.0.0.1:8000/openapi.json",
|
||||
"OPENAPI_URL": "https://0.0.0.0:8000/openapi.json",
|
||||
"SCHEMA_PATH": "./src/openapi.json",
|
||||
"OUTPUT_DIRECTORY": "./openapi",
|
||||
"PORT": 8000,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium';
|
||||
import { useNavigate } from 'react-router-dom'; // For navigation
|
||||
import { BeamtimesService } from '../../openapi';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {Beamtime, BeamtimesService} from '../../openapi';
|
||||
import { Chip, Typography } from '@mui/material';
|
||||
|
||||
interface BeamtimeRecord {
|
||||
|
@ -59,32 +59,59 @@ const Calendar: React.FC = () => {
|
||||
setFetchError(null);
|
||||
try {
|
||||
const beamtimes = await BeamtimesService.getMyBeamtimesProtectedBeamtimesMyBeamtimesGet();
|
||||
const formattedEvents: CustomEvent[] = beamtimes.map((beamtime: any) => ({
|
||||
id: `${beamtime.beamline}-${beamtime.start_date}`,
|
||||
title: `${beamtime.beamline}: ${beamtime.shift}`,
|
||||
start: beamtime.start_date,
|
||||
end: beamtime.end_date,
|
||||
beamtime_id: beamtime.id,
|
||||
beamline: beamtime.beamline || 'Unknown',
|
||||
beamtime_shift: beamtime.shift || 'Unknown',
|
||||
backgroundColor: beamlineColors[beamtime.beamline] || beamlineColors.Unknown,
|
||||
borderColor: '#000',
|
||||
textColor: '#fff',
|
||||
}));
|
||||
const grouped: { [key: string]: any[] } = {};
|
||||
beamtimes.forEach((beamtime: any) => {
|
||||
const key = `${beamtime.start_date}|${beamtime.beamline}|${beamtime.pgroups}`;
|
||||
if (!grouped[key]) grouped[key] = [];
|
||||
grouped[key].push(beamtime);
|
||||
});
|
||||
|
||||
const formattedEvents: CustomEvent[] = Object.values(grouped).map((group) => {
|
||||
const shifts = group.map((bt: any) => bt.shift).join(" + ");
|
||||
const ids = group.map((bt: any) => bt.id);
|
||||
const first = group[0];
|
||||
return {
|
||||
id: `${first.beamline}-${first.start_date}-${first.pgroups}`, // ensure uniqueness
|
||||
title: `${first.beamline}: ${shifts}`,
|
||||
start: first.start_date,
|
||||
end: first.end_date,
|
||||
beamtime_ids: ids,
|
||||
beamline: first.beamline || 'Unknown',
|
||||
beamtime_shift: shifts,
|
||||
backgroundColor: beamlineColors[first.beamline] || beamlineColors.Unknown,
|
||||
borderColor: '#000',
|
||||
textColor: '#fff',
|
||||
beamtimes: group,
|
||||
};
|
||||
});
|
||||
setEvents(formattedEvents);
|
||||
|
||||
|
||||
// Fetch associations for all
|
||||
const assoc: { [id: string]: { dewars: string[]; pucks: string[] } } = {};
|
||||
|
||||
await Promise.all(
|
||||
beamtimes.map(async (bm: any) => {
|
||||
const [dewars, pucks] = await Promise.all([
|
||||
DewarsService.getDewarsByBeamtime(bm.id),
|
||||
PucksService.getPucksByBeamtime(bm.id),
|
||||
]);
|
||||
const eventId = `${bm.beamline}-${bm.start_date}`;
|
||||
Object.values(grouped).map(async (group) => {
|
||||
// multiple (or single) beamtimes per group
|
||||
const ids = group.map((bt: any) => bt.id);
|
||||
// fetch and merge for all ids in this group:
|
||||
let dewarsSet = new Set<string>();
|
||||
let pucksSet = new Set<string>();
|
||||
await Promise.all(
|
||||
ids.map(async (beamtimeId: number) => {
|
||||
const [dewars, pucks] = await Promise.all([
|
||||
DewarsService.getDewarsByBeamtime(beamtimeId),
|
||||
PucksService.getPucksByBeamtime(beamtimeId),
|
||||
]);
|
||||
dewars.forEach((d: any) => dewarsSet.add(d.id));
|
||||
pucks.forEach((p: any) => pucksSet.add(p.id));
|
||||
})
|
||||
);
|
||||
// key must match event id
|
||||
const eventId = `${group[0].beamline}-${group[0].start_date}-${group[0].pgroups}`;
|
||||
assoc[eventId] = {
|
||||
dewars: dewars.map((d: any) => d.id),
|
||||
pucks: pucks.map((p: any) => p.id),
|
||||
dewars: Array.from(dewarsSet),
|
||||
pucks: Array.from(pucksSet),
|
||||
};
|
||||
})
|
||||
);
|
||||
@ -119,20 +146,29 @@ const Calendar: React.FC = () => {
|
||||
}, [eventDetails]);
|
||||
|
||||
// Refresh associations after (un)assign action
|
||||
const refetchEventAssociations = async (beamtimeId: number, eventId: string) => {
|
||||
const [dewars, pucks] = await Promise.all([
|
||||
DewarsService.getDewarsByBeamtime(beamtimeId),
|
||||
PucksService.getPucksByBeamtime(beamtimeId),
|
||||
]);
|
||||
const refetchEventAssociations = async (beamtimeIds: number[], eventId: string) => {
|
||||
let dewarsSet = new Set<string>();
|
||||
let pucksSet = new Set<string>();
|
||||
await Promise.all(
|
||||
beamtimeIds.map(async (beamtimeId: number) => {
|
||||
const [dewars, pucks] = await Promise.all([
|
||||
DewarsService.getDewarsByBeamtime(beamtimeId),
|
||||
PucksService.getPucksByBeamtime(beamtimeId),
|
||||
]);
|
||||
dewars.forEach((d: any) => dewarsSet.add(d.id));
|
||||
pucks.forEach((p: any) => pucksSet.add(p.id));
|
||||
})
|
||||
);
|
||||
setEventAssociations(prev => ({
|
||||
...prev,
|
||||
[eventId]: {
|
||||
dewars: dewars.map((d: any) => d.id),
|
||||
pucks: pucks.map((p: any) => p.id),
|
||||
dewars: Array.from(dewarsSet),
|
||||
pucks: Array.from(pucksSet),
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
const handleEventClick = (eventInfo: any) => {
|
||||
const clickedEventId = eventInfo.event.id;
|
||||
setSelectedEventId(clickedEventId);
|
||||
@ -171,77 +207,115 @@ const Calendar: React.FC = () => {
|
||||
const handleDewarAssignment = async (dewarId: string) => {
|
||||
if (!selectedEventId) return;
|
||||
const event = events.find(e => e.id === selectedEventId)!;
|
||||
const beamtimeId = event.beamtime_id;
|
||||
if (!beamtimeId) return;
|
||||
// Is this dewar already assigned here?
|
||||
const beamtimeIds: number[] = event.beamtime_ids || [];
|
||||
if (!beamtimeIds.length) return;
|
||||
const assigned = eventAssociations[selectedEventId]?.dewars.includes(dewarId);
|
||||
try {
|
||||
if (assigned) {
|
||||
await DewarsService.assignDewarToBeamtime(Number(dewarId), 0);
|
||||
} else {
|
||||
await DewarsService.assignDewarToBeamtime(Number(dewarId), Number(beamtimeId));
|
||||
}
|
||||
await refetchEventAssociations(Number(beamtimeId), selectedEventId);
|
||||
await Promise.all(
|
||||
beamtimeIds.map(btId =>
|
||||
assigned
|
||||
? DewarsService.assignDewarToBeamtime(Number(dewarId), 0)
|
||||
: DewarsService.assignDewarToBeamtime(Number(dewarId), Number(btId))
|
||||
)
|
||||
);
|
||||
await refetchEventAssociations(beamtimeIds, selectedEventId);
|
||||
} catch (e) {
|
||||
// Optionally report error
|
||||
}
|
||||
/* error handling */}
|
||||
};
|
||||
|
||||
|
||||
// Unified assign/unassign for Pucks
|
||||
const handlePuckAssignment = async (puckId: string) => {
|
||||
if (!selectedEventId) return;
|
||||
const event = events.find(e => e.id === selectedEventId)!;
|
||||
const beamtimeId = event.beamtime_id;
|
||||
if (!beamtimeId) return;
|
||||
const beamtimeIds: number[] = event.beamtime_ids || [];
|
||||
if (!beamtimeIds.length) return;
|
||||
const assigned = eventAssociations[selectedEventId]?.pucks.includes(puckId);
|
||||
try {
|
||||
if (assigned) {
|
||||
await PucksService.assignPuckToBeamtime(Number(puckId), 0);
|
||||
} else {
|
||||
await PucksService.assignPuckToBeamtime(Number(puckId), Number(beamtimeId));
|
||||
}
|
||||
await refetchEventAssociations(Number(beamtimeId), selectedEventId);
|
||||
} catch (e) {
|
||||
// Optionally report error
|
||||
}
|
||||
await Promise.all(
|
||||
beamtimeIds.map(async btId =>
|
||||
assigned
|
||||
? PucksService.assignPuckToBeamtime(Number(puckId), 0)
|
||||
: PucksService.assignPuckToBeamtime(Number(puckId), Number(btId))
|
||||
)
|
||||
);
|
||||
await refetchEventAssociations(beamtimeIds, selectedEventId);
|
||||
} catch (e) {/* error handling */}
|
||||
};
|
||||
|
||||
|
||||
// For displaying badge in calendar and UI
|
||||
const eventContent = (eventInfo: any) => {
|
||||
const beamline = eventInfo.event.extendedProps.beamline || 'Unknown';
|
||||
const isSelected = selectedEventId === eventInfo.event.id;
|
||||
const isSubmitted = eventInfo.event.extendedProps.isSubmitted;
|
||||
const hasAssociations =
|
||||
eventAssociations[eventInfo.event.id]?.dewars.length > 0 ||
|
||||
eventAssociations[eventInfo.event.id]?.pucks.length > 0;
|
||||
const backgroundColor = isSubmitted
|
||||
? darkenColor(beamlineColors[beamline] || beamlineColors.Unknown, -20)
|
||||
: isSelected
|
||||
? '#FFD700'
|
||||
: (beamlineColors[beamline] || beamlineColors.Unknown);
|
||||
const beamtimesInGroup = eventInfo.event.extendedProps.beamtimes
|
||||
? eventInfo.event.extendedProps.beamtimes.length
|
||||
: 1;
|
||||
const minHeight = beamtimesInGroup * 26;
|
||||
const beamline = eventInfo.event.extendedProps.beamline || 'Unknown';
|
||||
const isSelected = selectedEventId === eventInfo.event.id;
|
||||
const isSubmitted = eventInfo.event.extendedProps.isSubmitted;
|
||||
const assoc = eventAssociations[eventInfo.event.id] || { dewars: [], pucks: [] };
|
||||
const backgroundColor = isSubmitted
|
||||
? darkenColor(beamlineColors[beamline] || beamlineColors.Unknown, -20)
|
||||
: isSelected
|
||||
? '#FFD700'
|
||||
: (beamlineColors[beamline] || beamlineColors.Unknown);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: backgroundColor,
|
||||
color: 'white',
|
||||
border: isSelected ? '2px solid black' : 'none',
|
||||
borderRadius: '3px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
cursor: 'pointer',
|
||||
overflow: 'hidden',
|
||||
boxSizing: 'border-box',
|
||||
}}
|
||||
>
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: backgroundColor,
|
||||
color: 'white',
|
||||
border: isSelected ? '2px solid black' : 'none',
|
||||
borderRadius: '3px',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
cursor: 'pointer',
|
||||
overflow: 'hidden',
|
||||
boxSizing: 'border-box',
|
||||
padding: '0 6px',
|
||||
minHeight: `${minHeight}px`,
|
||||
}}
|
||||
>
|
||||
<span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
|
||||
{eventInfo.event.title}
|
||||
{hasAssociations && <span style={{marginLeft: 8}}>🧊</span>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
</span>
|
||||
<span style={{ display: 'flex', alignItems: 'center', gap: 6, marginLeft: 8 }}>
|
||||
<span title="Dewars" style={{ display: 'flex', alignItems: 'center', fontSize: 13 }}>
|
||||
🧊
|
||||
<span style={{
|
||||
background: 'rgba(0,0,0,0.45)',
|
||||
borderRadius: '8px',
|
||||
marginLeft: 2,
|
||||
minWidth: 14,
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
padding: '0 4px',
|
||||
fontWeight: 600,
|
||||
textAlign: 'center'
|
||||
}}>{assoc.dewars.length}</span>
|
||||
</span>
|
||||
<span title="Pucks" style={{ display: 'flex', alignItems: 'center', fontSize: 13 }}>
|
||||
⚪
|
||||
<span style={{
|
||||
background: 'rgba(0,0,0,0.45)',
|
||||
borderRadius: '8px',
|
||||
marginLeft: 2,
|
||||
minWidth: 14,
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
padding: '0 4px',
|
||||
fontWeight: 600,
|
||||
textAlign: 'center'
|
||||
}}>{assoc.pucks.length}</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// Used in Dewar/Puck assign status reporting
|
||||
function getAssignedEventForDewar(dewarId: string) {
|
||||
|
@ -446,21 +446,21 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-05-05T13:31:12.902282Z",
|
||||
"start_time": "2025-05-05T13:31:12.900432Z"
|
||||
"end_time": "2025-05-08T13:31:36.929465Z",
|
||||
"start_time": "2025-05-08T13:31:36.925054Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "sample_id = 277",
|
||||
"source": "sample_id = 44",
|
||||
"id": "54d4d46ca558e7b9",
|
||||
"outputs": [],
|
||||
"execution_count": 7
|
||||
"execution_count": 28
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-05-05T13:31:16.752616Z",
|
||||
"start_time": "2025-05-05T13:31:16.720296Z"
|
||||
"end_time": "2025-05-08T13:31:40.023546Z",
|
||||
"start_time": "2025-05-08T13:31:39.978510Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@ -512,7 +512,7 @@
|
||||
"DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): localhost:8000\n",
|
||||
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1103: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n",
|
||||
" warnings.warn(\n",
|
||||
"DEBUG:urllib3.connectionpool:https://localhost:8000 \"POST /samples/samples/277/events HTTP/1.1\" 200 413\n"
|
||||
"DEBUG:urllib3.connectionpool:https://localhost:8000 \"POST /samples/samples/44/events HTTP/1.1\" 200 884\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -522,29 +522,29 @@
|
||||
"Payload being sent to API:\n",
|
||||
"{\"event_type\":\"Collecting\"}\n",
|
||||
"API response:\n",
|
||||
"('id', 277)\n",
|
||||
"('sample_name', 'Sample277')\n",
|
||||
"('position', 15)\n",
|
||||
"('puck_id', 30)\n",
|
||||
"('id', 44)\n",
|
||||
"('sample_name', 'Sample044')\n",
|
||||
"('position', 7)\n",
|
||||
"('puck_id', 7)\n",
|
||||
"('crystalname', None)\n",
|
||||
"('proteinname', None)\n",
|
||||
"('positioninpuck', None)\n",
|
||||
"('priority', None)\n",
|
||||
"('comments', None)\n",
|
||||
"('data_collection_parameters', None)\n",
|
||||
"('events', [SampleEventResponse(event_type='Mounting', id=533, sample_id=277, timestamp=datetime.datetime(2025, 5, 4, 14, 9)), SampleEventResponse(event_type='Collecting', id=534, sample_id=277, timestamp=datetime.datetime(2025, 5, 5, 13, 31, 16, 741949))])\n",
|
||||
"('events', [SampleEventResponse(event_type='Mounting', id=87, sample_id=44, timestamp=datetime.datetime(2025, 5, 7, 10, 16)), SampleEventResponse(event_type='Unmounting', id=88, sample_id=44, timestamp=datetime.datetime(2025, 5, 7, 10, 16, 50)), SampleEventResponse(event_type='Collecting', id=507, sample_id=44, timestamp=datetime.datetime(2025, 5, 8, 13, 31, 40, 6059))])\n",
|
||||
"('mount_count', 0)\n",
|
||||
"('unmount_count', 0)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 8
|
||||
"execution_count": 29
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-04-29T14:27:46.730515Z",
|
||||
"start_time": "2025-04-29T14:27:46.622922Z"
|
||||
"end_time": "2025-05-08T13:31:43.663278Z",
|
||||
"start_time": "2025-05-08T13:31:43.651369Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@ -572,18 +572,18 @@
|
||||
"traceback": [
|
||||
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
|
||||
"\u001B[0;31mAttributeError\u001B[0m Traceback (most recent call last)",
|
||||
"Cell \u001B[0;32mIn[48], line 8\u001B[0m\n\u001B[1;32m 4\u001B[0m api_instance \u001B[38;5;241m=\u001B[39m aareDBclient\u001B[38;5;241m.\u001B[39mSamplesApi(api_client)\n\u001B[1;32m 6\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m 7\u001B[0m \u001B[38;5;66;03m# Get the last sample event\u001B[39;00m\n\u001B[0;32m----> 8\u001B[0m last_event_response \u001B[38;5;241m=\u001B[39m \u001B[43mapi_instance\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget_last_sample_event_samples_samples_sample_id_events_last_get\u001B[49m(\u001B[38;5;241m27\u001B[39m)\n\u001B[1;32m 9\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mThe response of get_last_sample_event:\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 10\u001B[0m pprint(last_event_response)\n",
|
||||
"Cell \u001B[0;32mIn[30], line 8\u001B[0m\n\u001B[1;32m 4\u001B[0m api_instance \u001B[38;5;241m=\u001B[39m aareDBclient\u001B[38;5;241m.\u001B[39mSamplesApi(api_client)\n\u001B[1;32m 6\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m 7\u001B[0m \u001B[38;5;66;03m# Get the last sample event\u001B[39;00m\n\u001B[0;32m----> 8\u001B[0m last_event_response \u001B[38;5;241m=\u001B[39m \u001B[43mapi_instance\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget_last_sample_event_samples_samples_sample_id_events_last_get\u001B[49m(\u001B[38;5;241m27\u001B[39m)\n\u001B[1;32m 9\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mThe response of get_last_sample_event:\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 10\u001B[0m pprint(last_event_response)\n",
|
||||
"\u001B[0;31mAttributeError\u001B[0m: 'SamplesApi' object has no attribute 'get_last_sample_event_samples_samples_sample_id_events_last_get'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 48
|
||||
"execution_count": 30
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-05-05T13:31:21.833174Z",
|
||||
"start_time": "2025-05-05T13:31:21.791711Z"
|
||||
"end_time": "2025-05-08T13:31:46.103881Z",
|
||||
"start_time": "2025-05-08T13:31:46.061151Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@ -654,7 +654,7 @@
|
||||
"DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): 127.0.0.1:8000\n",
|
||||
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1103: 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",
|
||||
"DEBUG:urllib3.connectionpool:https://127.0.0.1:8000 \"POST /samples/277/upload-images HTTP/1.1\" 200 205\n"
|
||||
"DEBUG:urllib3.connectionpool:https://127.0.0.1:8000 \"POST /samples/44/upload-images HTTP/1.1\" 200 203\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -664,11 +664,11 @@
|
||||
"Uploading after_dc.jpeg.jpg...\n",
|
||||
"API Response for after_dc.jpeg.jpg:\n",
|
||||
"200\n",
|
||||
"{'pgroup': 'p20003', 'sample_id': 277, 'sample_event_id': 534, 'filepath': 'images/p20003/2025-05-05/Dewar Five/PKK007/15/Collecting_2025-05-05_13-31-16/after_dc.jpeg.jpg', 'status': 'active', 'comment': None, 'id': 1}\n"
|
||||
"{'pgroup': 'p20001', 'sample_id': 44, 'sample_event_id': 507, 'filepath': 'images/p20001/2025-05-08/Dewar One/PUCK007/7/Collecting_2025-05-08_13-31-40/after_dc.jpeg.jpg', 'status': 'active', 'comment': None, 'id': 1}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 9
|
||||
"execution_count": 31
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@ -681,8 +681,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-05-05T13:34:32.164108Z",
|
||||
"start_time": "2025-05-05T13:34:32.130230Z"
|
||||
"end_time": "2025-05-08T13:53:49.337315Z",
|
||||
"start_time": "2025-05-08T13:53:49.288039Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@ -799,7 +799,7 @@
|
||||
"DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): localhost:8000\n",
|
||||
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1103: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n",
|
||||
" warnings.warn(\n",
|
||||
"DEBUG:urllib3.connectionpool:https://localhost:8000 \"POST /samples/samples/277/experiment_parameters HTTP/1.1\" 200 904\n"
|
||||
"DEBUG:urllib3.connectionpool:https://localhost:8000 \"POST /samples/samples/44/experiment_parameters HTTP/1.1\" 200 903\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -807,17 +807,17 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"API Response:\n",
|
||||
"run_number=2 type='standard' 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=232.0, beam_center_x_px=768.0, beam_center_y_px=857.0, pixel_size_x_um=150.0, pixel_size_y_um=150.0), wavelength=1.033, ring_current_a=0.4, ring_mode='Machine Development', undulator=None, undulatorgap_mm=None, monochromator='Si111', transmission=10.0, focusing_optic='Kirkpatrick-Baez', beamline_flux_at_sample_ph_s=0.0, beam_size_width=30.0, beam_size_height=30.0, characterization=None, rotation=RotationParameters(omega_start_deg=0.0, omega_step=0.2, chi=0.0, phi=10.0, number_of_images=1800, exposure_time_s=0.01), grid_scan=None, jet=None, cryojet_temperature_k=None, humidifier_temperature_k=None, humidifier_humidity=None) dataset=None sample_id=277 id=2\n"
|
||||
"run_number=2 type='standard' 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=232.0, beam_center_x_px=768.0, beam_center_y_px=857.0, pixel_size_x_um=150.0, pixel_size_y_um=150.0), wavelength=1.033, ring_current_a=0.4, ring_mode='Machine Development', undulator=None, undulatorgap_mm=None, monochromator='Si111', transmission=10.0, focusing_optic='Kirkpatrick-Baez', beamline_flux_at_sample_ph_s=0.0, beam_size_width=30.0, beam_size_height=30.0, characterization=None, rotation=RotationParameters(omega_start_deg=0.0, omega_step=0.2, chi=0.0, phi=10.0, number_of_images=1800, exposure_time_s=0.01), grid_scan=None, jet=None, cryojet_temperature_k=None, humidifier_temperature_k=None, humidifier_humidity=None) dataset=None sample_id=44 id=2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 13
|
||||
"execution_count": 34
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-05-05T13:34:49.891432Z",
|
||||
"start_time": "2025-05-05T13:34:49.872697Z"
|
||||
"end_time": "2025-05-08T13:53:58.864551Z",
|
||||
"start_time": "2025-05-08T13:53:58.837176Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@ -859,7 +859,7 @@
|
||||
"DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): localhost:8000\n",
|
||||
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1103: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n",
|
||||
" warnings.warn(\n",
|
||||
"DEBUG:urllib3.connectionpool:https://localhost:8000 \"PATCH /samples/update-dataset/277/2 HTTP/1.1\" 200 1085\n"
|
||||
"DEBUG:urllib3.connectionpool:https://localhost:8000 \"PATCH /samples/update-dataset/44/2 HTTP/1.1\" 200 1084\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -867,11 +867,11 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Dataset updated successfully:\n",
|
||||
"run_number=2 type='standard' 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=232.0, beam_center_x_px=768.0, beam_center_y_px=857.0, pixel_size_x_um=150.0, pixel_size_y_um=150.0), wavelength=1.033, ring_current_a=0.4, ring_mode='Machine Development', undulator=None, undulatorgap_mm=None, monochromator='Si111', transmission=10.0, focusing_optic='Kirkpatrick-Baez', beamline_flux_at_sample_ph_s=0.0, beam_size_width=30.0, beam_size_height=30.0, characterization=None, rotation=RotationParameters(omega_start_deg=0.0, omega_step=0.2, chi=0.0, phi=10.0, number_of_images=1800, exposure_time_s=0.01), grid_scan=None, jet=None, cryojet_temperature_k=None, humidifier_temperature_k=None, humidifier_humidity=None) dataset=Datasets(filepath='/das/work/p11/p11206/raw_data/vincent/20250415_6D_SLS2_1st_data/20250415_fullbeam_dtz220_Lyso102_again_360deg', status='written', written_at=datetime.datetime(2025, 5, 5, 15, 34, 49, 874526)) sample_id=277 id=2\n"
|
||||
"run_number=2 type='standard' 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=232.0, beam_center_x_px=768.0, beam_center_y_px=857.0, pixel_size_x_um=150.0, pixel_size_y_um=150.0), wavelength=1.033, ring_current_a=0.4, ring_mode='Machine Development', undulator=None, undulatorgap_mm=None, monochromator='Si111', transmission=10.0, focusing_optic='Kirkpatrick-Baez', beamline_flux_at_sample_ph_s=0.0, beam_size_width=30.0, beam_size_height=30.0, characterization=None, rotation=RotationParameters(omega_start_deg=0.0, omega_step=0.2, chi=0.0, phi=10.0, number_of_images=1800, exposure_time_s=0.01), grid_scan=None, jet=None, cryojet_temperature_k=None, humidifier_temperature_k=None, humidifier_humidity=None) dataset=Datasets(filepath='/das/work/p11/p11206/raw_data/vincent/20250415_6D_SLS2_1st_data/20250415_fullbeam_dtz220_Lyso102_again_360deg', status='written', written_at=datetime.datetime(2025, 5, 8, 15, 53, 58, 838599)) sample_id=44 id=2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 15
|
||||
"execution_count": 35
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user