Displaying Processing Results in the frontend
This commit is contained in:
parent
5a0047b6d5
commit
68f87f0d8d
@ -17,6 +17,7 @@ from app.schemas import (
|
|||||||
ImageInfo,
|
ImageInfo,
|
||||||
ResultResponse,
|
ResultResponse,
|
||||||
ResultCreate,
|
ResultCreate,
|
||||||
|
Results as ProcessingResults,
|
||||||
)
|
)
|
||||||
from app.models import (
|
from app.models import (
|
||||||
Puck as PuckModel,
|
Puck as PuckModel,
|
||||||
@ -374,17 +375,29 @@ def create_result(payload: ResultCreate, db: Session = Depends(get_db)):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/results", response_model=list[ResultResponse])
|
@router.get(
|
||||||
# def get_results(sample_id: int, result_id: int, db: Session = Depends(get_db)):
|
"/processing-results/{sample_id}/{run_id}", response_model=List[ResultResponse]
|
||||||
# query = db.query(Results)
|
)
|
||||||
#
|
async def get_results_for_run_and_sample(
|
||||||
# if sample_id:
|
sample_id: int, run_id: int, db: Session = Depends(get_db)
|
||||||
# query = query.filter(Results.sample_id == sample_id)
|
):
|
||||||
# if result_id:
|
results = (
|
||||||
# query = query.filter(Results.result_id == result_id)
|
db.query(ResultsModel)
|
||||||
#
|
.filter(ResultsModel.sample_id == sample_id, ResultsModel.run_id == run_id)
|
||||||
# results = query.all()
|
.all()
|
||||||
# if not results:
|
)
|
||||||
# raise HTTPException(status_code=404, detail="No results found")
|
|
||||||
#
|
if not results:
|
||||||
# return results
|
raise HTTPException(status_code=404, detail="Results not found.")
|
||||||
|
|
||||||
|
formatted_results = [
|
||||||
|
ResultResponse(
|
||||||
|
id=result.id,
|
||||||
|
sample_id=result.sample_id,
|
||||||
|
run_id=result.run_id,
|
||||||
|
result=ProcessingResults(**result.result),
|
||||||
|
)
|
||||||
|
for result in results
|
||||||
|
]
|
||||||
|
|
||||||
|
return formatted_results
|
||||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "aareDB"
|
name = "aareDB"
|
||||||
version = "0.1.0a25"
|
version = "0.1.0a26"
|
||||||
description = "Backend for next gen sample management system"
|
description = "Backend for next gen sample management system"
|
||||||
authors = [{name = "Guillaume Gotthard", email = "guillaume.gotthard@psi.ch"}]
|
authors = [{name = "Guillaume Gotthard", email = "guillaume.gotthard@psi.ch"}]
|
||||||
license = {text = "MIT"}
|
license = {text = "MIT"}
|
||||||
|
@ -85,6 +85,7 @@ interface TreeRow {
|
|||||||
id: string;
|
id: string;
|
||||||
hierarchy: (string | number)[];
|
hierarchy: (string | number)[];
|
||||||
type: 'sample' | 'run';
|
type: 'sample' | 'run';
|
||||||
|
experimentId?: number;
|
||||||
sample_id: number;
|
sample_id: number;
|
||||||
sample_name?: string;
|
sample_name?: string;
|
||||||
puck_name?: string;
|
puck_name?: string;
|
||||||
@ -209,6 +210,7 @@ const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => {
|
|||||||
id: `run-${sample.sample_id}-${run.run_number}`,
|
id: `run-${sample.sample_id}-${run.run_number}`,
|
||||||
hierarchy: [sample.sample_id, run.run_number],
|
hierarchy: [sample.sample_id, run.run_number],
|
||||||
type: 'run',
|
type: 'run',
|
||||||
|
experimentId: run.id,
|
||||||
sample_id: sample.sample_id,
|
sample_id: sample.sample_id,
|
||||||
run_number: run.run_number,
|
run_number: run.run_number,
|
||||||
beamline_parameters: run.beamline_parameters,
|
beamline_parameters: run.beamline_parameters,
|
||||||
@ -307,8 +309,10 @@ const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => {
|
|||||||
return (
|
return (
|
||||||
<RunDetails
|
<RunDetails
|
||||||
run={params.row}
|
run={params.row}
|
||||||
|
runId={params.row.experimentId}
|
||||||
|
sample_id={params.row.sample_id}
|
||||||
basePath={basePath}
|
basePath={basePath}
|
||||||
onHeightChange={(height: number) => handleDetailPanelHeightChange(params.row.id, height)} // Pass callback for dynamic height
|
onHeightChange={height => handleDetailPanelHeightChange(params.row.id, height)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,196 +1,279 @@
|
|||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Accordion,
|
Accordion, AccordionSummary, AccordionDetails, Typography, Grid, Modal, Box
|
||||||
AccordionSummary,
|
|
||||||
AccordionDetails,
|
|
||||||
Typography,
|
|
||||||
Grid,
|
|
||||||
Modal,
|
|
||||||
Box
|
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||||
import './SampleImage.css';
|
import './SampleImage.css';
|
||||||
|
import { DataGridPremium, GridColDef } from "@mui/x-data-grid-premium";
|
||||||
|
import { SamplesService } from "../../openapi";
|
||||||
|
|
||||||
interface RunDetailsProps {
|
interface RunDetailsProps {
|
||||||
run: ExperimentParameters;
|
run: TreeRow;
|
||||||
|
runId: number;
|
||||||
|
sample_id: number;
|
||||||
basePath: string;
|
basePath: string;
|
||||||
onHeightChange?: (height: number) => void; // Callback to notify the parent about height changes
|
onHeightChange?: (height: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange, basePath }) => {
|
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null); // Ref to track component height
|
interface ExperimentParameters {
|
||||||
|
run_number: number;
|
||||||
|
id: number;
|
||||||
|
sample_id: number;
|
||||||
|
beamline_parameters: BeamlineParameters;
|
||||||
|
images: Image[];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface ProcessingResults {
|
||||||
|
pipeline: string;
|
||||||
|
resolution: number;
|
||||||
|
unit_cell: string;
|
||||||
|
spacegroup: string;
|
||||||
|
rmerge: number;
|
||||||
|
rmeas: number;
|
||||||
|
isig: number;
|
||||||
|
cc: number;
|
||||||
|
cchalf: number;
|
||||||
|
completeness: number;
|
||||||
|
multiplicity: number;
|
||||||
|
nobs: number;
|
||||||
|
total_refl: number;
|
||||||
|
unique_refl: number;
|
||||||
|
comments?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange, basePath, runId, sample_id }) => {
|
||||||
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const [currentHeight, setCurrentHeight] = useState<number>(0);
|
const [currentHeight, setCurrentHeight] = useState<number>(0);
|
||||||
const [modalOpen, setModalOpen] = useState<boolean>(false); // For modal state
|
const [modalOpen, setModalOpen] = useState<boolean>(false);
|
||||||
const [selectedImage, setSelectedImage] = useState<string | null>(null); // Tracks the selected image for the modal
|
const [selectedImage, setSelectedImage] = useState<string | null>(null);
|
||||||
|
const [expandedResults, setExpandedResults] = useState(false);
|
||||||
|
const [processingResult, setProcessingResult] = useState<ProcessingResults[] | null>(null);
|
||||||
|
|
||||||
const { beamline_parameters, images } = run;
|
const {beamline_parameters, images} = run;
|
||||||
const { synchrotron, beamline, detector } = beamline_parameters;
|
const {synchrotron, beamline, detector} = beamline_parameters;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchResults(sample_id, runId); // fetching based on experimentId
|
||||||
|
}, [runId]);
|
||||||
|
|
||||||
|
const fetchResults = async (sample_id: number, runId: number) => {
|
||||||
|
try {
|
||||||
|
const results = await SamplesService.getResultsForRunAndSampleSamplesProcessingResultsSampleIdRunIdGet(sample_id, runId);
|
||||||
|
|
||||||
|
// Explicitly handle nested results
|
||||||
|
const mappedResults: ProcessingResults[] = results.map((res): ProcessingResults => ({
|
||||||
|
pipeline: res.result?.pipeline || 'N/A',
|
||||||
|
resolution: res.result.resolution ?? 0,
|
||||||
|
unit_cell: res.result?.unit_cell || 'N/A',
|
||||||
|
spacegroup: res.result?.spacegroup || 'N/A',
|
||||||
|
rmerge: res.result?.rmerge ?? 0,
|
||||||
|
rmeas: res.result?.rmeas ?? 0,
|
||||||
|
isig: res.result?.isig ?? 0,
|
||||||
|
cc: res.result?.cc ?? 0,
|
||||||
|
cchalf: res.result?.cchalf ?? 0,
|
||||||
|
completeness: res.result?.completeness ?? 0,
|
||||||
|
multiplicity: res.result?.multiplicity ?? 0,
|
||||||
|
nobs: res.result?.nobs ?? 0,
|
||||||
|
total_refl: res.result?.total_refl ?? 0,
|
||||||
|
unique_refl: res.result?.unique_refl ?? 0,
|
||||||
|
comments: res.result?.comments || null,
|
||||||
|
}));
|
||||||
|
|
||||||
|
setProcessingResult(mappedResults);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching results:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const resultColumns: GridColDef[] = [
|
||||||
|
{field: 'pipeline', headerName: 'Pipeline', flex: 1},
|
||||||
|
{field: 'resolution', headerName: 'Resolution (Å)', flex: 1},
|
||||||
|
{field: 'unit_cell', headerName: 'Unit Cell (Å)', flex: 1.5},
|
||||||
|
{field: 'spacegroup', headerName: 'Spacegroup', flex: 1},
|
||||||
|
{field: 'rmerge', headerName: 'Rmerge', flex: 1},
|
||||||
|
{field: 'rmeas', headerName: 'Rmeas', flex: 1},
|
||||||
|
{field: 'isig', headerName: 'I/sig(I)', flex: 1},
|
||||||
|
{field: 'cc', headerName: 'CC', flex: 1},
|
||||||
|
{field: 'cchalf', headerName: 'CC(1/2)', flex: 1},
|
||||||
|
{field: 'completeness', headerName: 'Completeness (%)', flex: 1},
|
||||||
|
{field: 'multiplicity', headerName: 'Multiplicity', flex: 1},
|
||||||
|
{field: 'nobs', headerName: 'N obs.', flex: 1},
|
||||||
|
{field: 'total_refl', headerName: 'Total Reflections', flex: 1},
|
||||||
|
{field: 'unique_refl', headerName: 'Unique Reflections', flex: 1},
|
||||||
|
{field: 'comments', headerName: 'Comments', flex: 2},
|
||||||
|
];
|
||||||
|
|
||||||
// Calculate and notify the parent about height changes
|
|
||||||
const updateHeight = () => {
|
const updateHeight = () => {
|
||||||
if (containerRef.current) {
|
if (containerRef.current) {
|
||||||
const newHeight = containerRef.current.offsetHeight;
|
const newHeight = containerRef.current.offsetHeight;
|
||||||
if (newHeight !== currentHeight) {
|
if (newHeight !== currentHeight && onHeightChange) {
|
||||||
setCurrentHeight(newHeight);
|
setCurrentHeight(newHeight);
|
||||||
if (onHeightChange) {
|
onHeightChange(newHeight);
|
||||||
onHeightChange(newHeight);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateHeight(); // Update height on initial render
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Update height whenever the component content changes
|
|
||||||
const observer = new ResizeObserver(updateHeight);
|
const observer = new ResizeObserver(updateHeight);
|
||||||
if (containerRef.current) {
|
if (containerRef.current) observer.observe(containerRef.current);
|
||||||
observer.observe(containerRef.current);
|
return () => observer.disconnect();
|
||||||
}
|
}, [containerRef.current, processingResult]);
|
||||||
return () => {
|
|
||||||
observer.disconnect();
|
|
||||||
};
|
|
||||||
}, [containerRef]);
|
|
||||||
|
|
||||||
const handleImageClick = (imagePath: string) => {
|
const handleImageClick = (imagePath: string) => {
|
||||||
setSelectedImage(imagePath);
|
setSelectedImage(imagePath);
|
||||||
setModalOpen(true); // Open the modal when the image is clicked
|
setModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
setSelectedImage(null); // Clear the current image
|
setSelectedImage(null);
|
||||||
setModalOpen(false);
|
setModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="details-panel" // Add the class here
|
className="details-panel"
|
||||||
ref={containerRef} // Attach the ref to the main container
|
ref={containerRef}
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
flexDirection: 'column', // Stack children vertically
|
||||||
gap: '16px',
|
gap: '16px',
|
||||||
padding: '16px',
|
padding: '16px',
|
||||||
border: '1px solid #ccc',
|
border: '1px solid #ccc',
|
||||||
borderRadius: '4px',
|
borderRadius: '4px',
|
||||||
alignItems: 'flex-start',
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
{/* Main Details Section */}
|
{/* Wrap details and images together */}
|
||||||
<div style={{ flexGrow: 1 }}>
|
<div style={{display: 'flex', gap: '16px', alignItems: 'flex-start'}}>
|
||||||
<Typography variant="h6" gutterBottom>
|
{/* Main Details Section */}
|
||||||
Run {run.run_number} Details
|
<div style={{flexGrow: 1}}>
|
||||||
</Typography>
|
<Typography variant="h6" gutterBottom>
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
Run {run.run_number} Details
|
||||||
Beamline: {beamline} | Synchrotron: {synchrotron}
|
</Typography>
|
||||||
</Typography>
|
<Typography variant="subtitle1" gutterBottom>
|
||||||
|
Beamline: {beamline} | Synchrotron: {synchrotron}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
{/* Detector Details Accordion */}
|
{/* Detector Details Accordion */}
|
||||||
<Accordion>
|
<Accordion>
|
||||||
<AccordionSummary
|
<AccordionSummary
|
||||||
expandIcon={<ExpandMoreIcon />}
|
expandIcon={<ExpandMoreIcon/>}
|
||||||
aria-controls="detector-content"
|
aria-controls="detector-content"
|
||||||
id="detector-header"
|
id="detector-header"
|
||||||
>
|
>
|
||||||
<Typography>
|
<Typography><strong>Detector Details</strong></Typography>
|
||||||
<strong>Detector Details</strong>
|
</AccordionSummary>
|
||||||
</Typography>
|
<AccordionDetails>
|
||||||
</AccordionSummary>
|
<Typography>Manufacturer: {detector?.manufacturer || 'N/A'}</Typography>
|
||||||
<AccordionDetails>
|
<Typography>Model: {detector?.model || 'N/A'}</Typography>
|
||||||
<Typography>Manufacturer: {detector?.manufacturer || 'N/A'}</Typography>
|
<Typography>Type: {detector?.type || 'N/A'}</Typography>
|
||||||
<Typography>Model: {detector?.model || 'N/A'}</Typography>
|
<Typography>
|
||||||
<Typography>Type: {detector?.type || 'N/A'}</Typography>
|
Beam Center (px): x: {detector?.beamCenterX_px || 'N/A'},
|
||||||
<Typography>
|
y: {detector?.beamCenterY_px || 'N/A'}
|
||||||
Beam Center (px): x: {detector?.beamCenterX_px || 'N/A'}, y: {detector?.beamCenterY_px || 'N/A'}
|
</Typography>
|
||||||
</Typography>
|
</AccordionDetails>
|
||||||
</AccordionDetails>
|
</Accordion>
|
||||||
</Accordion>
|
|
||||||
|
|
||||||
{/* Beamline Details Accordion */}
|
{/* Beamline Details Accordion */}
|
||||||
<Accordion>
|
<Accordion>
|
||||||
<AccordionSummary
|
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
||||||
expandIcon={<ExpandMoreIcon />}
|
<Typography><strong>Beamline Details</strong></Typography>
|
||||||
aria-controls="beamline-content"
|
</AccordionSummary>
|
||||||
id="beamline-header"
|
<AccordionDetails>
|
||||||
>
|
<Typography>Synchrotron: {beamline_parameters?.synchrotron || 'N/A'}</Typography>
|
||||||
<Typography>
|
<Typography>Ring mode: {beamline_parameters?.ringMode || 'N/A'}</Typography>
|
||||||
<strong>Beamline Details</strong>
|
<Typography>Ring current: {beamline_parameters?.ringCurrent_A || 'N/A'}</Typography>
|
||||||
</Typography>
|
<Typography>Beamline: {beamline_parameters?.beamline || 'N/A'}</Typography>
|
||||||
</AccordionSummary>
|
<Typography>Undulator: {beamline_parameters?.undulator || 'N/A'}</Typography>
|
||||||
<AccordionDetails>
|
<Typography>Undulator gap: {beamline_parameters?.undulatorgap_mm || 'N/A'}</Typography>
|
||||||
<Typography>Synchrotron: {beamline_parameters?.synchrotron || 'N/A'}</Typography>
|
<Typography>Focusing optic: {beamline_parameters?.focusingOptic || 'N/A'}</Typography>
|
||||||
<Typography>Ring mode: {beamline_parameters?.ringMode || 'N/A'}</Typography>
|
<Typography>Monochromator: {beamline_parameters?.monochromator || 'N/A'}</Typography>
|
||||||
<Typography>Ring current: {beamline_parameters?.ringCurrent_A || 'N/A'}</Typography>
|
</AccordionDetails>
|
||||||
<Typography>Beamline: {beamline_parameters?.beamline || 'N/A'}</Typography>
|
</Accordion>
|
||||||
<Typography>Undulator: {beamline_parameters?.undulator || 'N/A'}</Typography>
|
|
||||||
<Typography>Undulator gap: {beamline_parameters?.undulatorgap_mm || 'N/A'}</Typography>
|
|
||||||
<Typography>Focusing optic: {beamline_parameters?.focusingOptic || 'N/A'}</Typography>
|
|
||||||
<Typography>Monochromator: {beamline_parameters?.monochromator || 'N/A'}</Typography>
|
|
||||||
</AccordionDetails>
|
|
||||||
</Accordion>
|
|
||||||
|
|
||||||
{/* Beam Characteristics Accordion */}
|
{/* Beam Characteristics Accordion */}
|
||||||
<Accordion>
|
<Accordion>
|
||||||
<AccordionSummary
|
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
||||||
expandIcon={<ExpandMoreIcon />}
|
<Typography><strong>Beam Characteristics</strong></Typography>
|
||||||
aria-controls="beam-content"
|
</AccordionSummary>
|
||||||
id="beam-header"
|
<AccordionDetails>
|
||||||
>
|
<Typography>Wavelength: {beamline_parameters?.wavelength || 'N/A'}</Typography>
|
||||||
<Typography>
|
<Typography>Energy: {beamline_parameters?.energy || 'N/A'}</Typography>
|
||||||
<strong>Beam Characteristics</strong>
|
<Typography>Transmission: {beamline_parameters?.transmission || 'N/A'}</Typography>
|
||||||
|
<Typography>
|
||||||
|
Beam focus (µm): vertical: {beamline_parameters?.beamSizeHeight || 'N/A'},
|
||||||
|
horizontal:{' '}
|
||||||
|
{beamline_parameters?.beamSizeWidth || 'N/A'}
|
||||||
|
</Typography>
|
||||||
|
<Typography>Flux at sample
|
||||||
|
(ph/s): {beamline_parameters?.beamlineFluxAtSample_ph_s || 'N/A'}</Typography>
|
||||||
|
</AccordionDetails>
|
||||||
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Image Section */}
|
||||||
|
<div style={{width: '900px'}}>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Associated Images
|
||||||
|
</Typography>
|
||||||
|
{images && images.length > 0 ? (
|
||||||
|
<Grid container spacing={1}>
|
||||||
|
{images.map((img) => (
|
||||||
|
<Grid item xs={4} key={img.id}>
|
||||||
|
<div
|
||||||
|
className="image-container"
|
||||||
|
onClick={() => handleImageClick(`${basePath || ''}${img.filepath}`)}
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={`${basePath || ''}${img.filepath}`}
|
||||||
|
alt={img.comment || 'Image'}
|
||||||
|
className="zoom-image"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
maxWidth: '100%',
|
||||||
|
borderRadius: '4px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
) : (
|
||||||
|
<Typography variant="body2" color="textSecondary">
|
||||||
|
No images available.
|
||||||
</Typography>
|
</Typography>
|
||||||
</AccordionSummary>
|
)}
|
||||||
<AccordionDetails>
|
</div>
|
||||||
<Typography>Wavelength: {beamline_parameters?.wavelength || 'N/A'}</Typography>
|
|
||||||
<Typography>Energy: {beamline_parameters?.energy || 'N/A'}</Typography>
|
|
||||||
<Typography>Transmission: {beamline_parameters?.transmission || 'N/A'}</Typography>
|
|
||||||
<Typography>
|
|
||||||
Beam focus (µm): vertical: {beamline_parameters?.beamSizeHeight || 'N/A'}, horizontal:{' '}
|
|
||||||
{beamline_parameters?.beamSizeWidth || 'N/A'}
|
|
||||||
</Typography>
|
|
||||||
<Typography>Flux at sample (ph/s): {beamline_parameters?.beamlineFluxAtSample_ph_s || 'N/A'}</Typography>
|
|
||||||
</AccordionDetails>
|
|
||||||
</Accordion>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Image Section */}
|
{/* Processing Results Accordion - Full Width Below */}
|
||||||
<div style={{ width: '900px' }}>
|
<div style={{width: '100%'}}>
|
||||||
<Typography variant="h6" gutterBottom>
|
<Accordion expanded={expandedResults} onChange={(e, expanded) => setExpandedResults(expanded)}>
|
||||||
Associated Images
|
<AccordionSummary expandIcon={<ExpandMoreIcon/>}>
|
||||||
</Typography>
|
<Typography><strong>Processing Results</strong></Typography>
|
||||||
{images && images.length > 0 ? (
|
</AccordionSummary>
|
||||||
<Grid container spacing={1}>
|
<AccordionDetails style={{width: '100%', overflowX: 'auto'}}>
|
||||||
{images.map((img) => (
|
{processingResult ? (
|
||||||
<Grid item xs={4} key={img.id}>
|
<div style={{width: '100%'}}>
|
||||||
<div
|
<DataGridPremium
|
||||||
className="image-container"
|
rows={processingResult.map((res, idx) => ({id: idx, ...res}))}
|
||||||
onClick={() => handleImageClick(`${basePath || ''}${img.filepath}`)} // Open modal with image
|
columns={resultColumns}
|
||||||
style={{
|
autoHeight
|
||||||
cursor: 'pointer',
|
hideFooter
|
||||||
}}
|
columnVisibilityModel={{id: false}}
|
||||||
>
|
disableColumnResize={false}
|
||||||
<img
|
/>
|
||||||
src={`${basePath || ''}${img.filepath}`} // Ensure basePath
|
</div>
|
||||||
alt={img.comment || 'Image'}
|
) : (
|
||||||
className="zoom-image"
|
<Typography variant="body2" color="textSecondary">Loading results...</Typography>
|
||||||
style={{
|
)}
|
||||||
width: '100%', // Ensure the image takes the full width of its container
|
</AccordionDetails>
|
||||||
maxWidth: '100%', // Prevent any overflow
|
</Accordion>
|
||||||
borderRadius: '4px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
) : (
|
|
||||||
<Typography variant="body2" color="textSecondary">
|
|
||||||
No images available.
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Modal for Zoomed Image */}
|
{/* Modal for Zoomed Image */}
|
||||||
@ -224,5 +307,4 @@ const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange, basePath }
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RunDetails;
|
export default RunDetails;
|
@ -3,8 +3,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-17T10:32:07.119518Z",
|
"end_time": "2025-03-17T15:41:26.497650Z",
|
||||||
"start_time": "2025-03-17T10:32:06.622836Z"
|
"start_time": "2025-03-17T15:41:25.771778Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@ -385,8 +385,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-17T10:32:10.718097Z",
|
"end_time": "2025-03-17T15:41:47.722623Z",
|
||||||
"start_time": "2025-03-17T10:32:10.716192Z"
|
"start_time": "2025-03-17T15:41:47.720727Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@ -736,8 +736,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-03-17T10:46:08.211213Z",
|
"end_time": "2025-03-17T15:42:07.300875Z",
|
||||||
"start_time": "2025-03-17T10:46:08.193139Z"
|
"start_time": "2025-03-17T15:42:07.279495Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@ -750,12 +750,12 @@
|
|||||||
"from aareDBclient.rest import ApiException\n",
|
"from aareDBclient.rest import ApiException\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Your actual sample and experiment IDs\n",
|
"# Your actual sample and experiment IDs\n",
|
||||||
"sample_id = 123 # Replace with valid IDs\n",
|
"sample_id = sample_id # Replace with valid IDs\n",
|
||||||
"run_id = 1 # Replace with valid run_id\n",
|
"run_id = 1 # Replace with valid run_id\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Create random Results payload\n",
|
"# Create random Results payload\n",
|
||||||
"results_data = Results(\n",
|
"results_data = Results(\n",
|
||||||
" pipeline=\"autoproc\",\n",
|
" pipeline=\"fastproc\",\n",
|
||||||
" resolution=round(random.uniform(1.0, 4.0), 2),\n",
|
" resolution=round(random.uniform(1.0, 4.0), 2),\n",
|
||||||
" unit_cell=f\"{random.uniform(20, 120):.2f}, {random.uniform(20, 120):.2f}, \"\n",
|
" unit_cell=f\"{random.uniform(20, 120):.2f}, {random.uniform(20, 120):.2f}, \"\n",
|
||||||
" f\"{random.uniform(20, 120):.2f}, {random.uniform(60, 120):.2f}, \"\n",
|
" f\"{random.uniform(20, 120):.2f}, {random.uniform(60, 120):.2f}, \"\n",
|
||||||
@ -804,9 +804,9 @@
|
|||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): 127.0.0.1:8000\n",
|
"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: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",
|
"/Users/gotthardg/PycharmProjects/aaredb/.venv/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",
|
" warnings.warn(\n",
|
||||||
"DEBUG:urllib3.connectionpool:https://127.0.0.1:8000 \"POST /samples/processing-results HTTP/1.1\" 200 369\n"
|
"DEBUG:urllib3.connectionpool:https://127.0.0.1:8000 \"POST /samples/processing-results HTTP/1.1\" 200 367\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -814,11 +814,11 @@
|
|||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"API call successful:\n",
|
"API call successful:\n",
|
||||||
"ResultResponse(id=2, sample_id=123, run_id=1, result=Results(pipeline='autoproc', resolution=1.94, unit_cell='23.86, 89.07, 37.39, 63.99, 88.77, 81.42', spacegroup='P41212', rmerge=0.072, rmeas=0.07, isig=29.58, cc=0.758, cchalf=0.915, completeness=93.12, multiplicity=6.1, nobs=279922, total_refl=83994, unique_refl=47041, comments='Random auto-generated test entry'))\n"
|
"ResultResponse(id=4, sample_id=247, run_id=1, result=Results(pipeline='fastproc', resolution=3.93, unit_cell='56.27, 40.58, 26.64, 93.74, 90.52, 99.53', spacegroup='C2', rmerge=0.097, rmeas=0.13, isig=21.29, cc=0.989, cchalf=0.802, completeness=98.46, multiplicity=6.35, nobs=273232, total_refl=217336, unique_refl=11189, comments='Random auto-generated test entry'))\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 9
|
"execution_count": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user