/// <summary> /// Read the structure set from a DICOM dataset. /// </summary> /// <param name="ds"></param> /// <returns></returns> public static RadiotherapyStruct Read(DicomDataset ds) { var patient = DicomPatient.Read(ds); var study = DicomStudy.Read(ds); var series = DicomRTSeries.Read(ds); var equipment = DicomEquipment.Read(ds); var structureSet = DicomRTStructureSet.Read(ds); // DicomRTStructureSetROI.RoiNumber is the primary key. We try and locate the first observation and roiContour data for eaach // RoiNumber encountered. var structures = DicomRTStructureSetROI.Read(ds); var contoursData = DicomRTContour.Read(ds); var observations = DicomRTObservation.Read(ds); var allContours = new List <RadiotherapyContour>(); foreach (var s in structures) { var roiContours = contoursData.FirstOrDefault(c => c.ReferencedRoiNumber == s.Key); var roiObservation = observations.FirstOrDefault(o => o.ReferencedRoiNumber == s.Key); // we insist both must exist if (roiContours != null && roiObservation != null) { allContours.Add(new RadiotherapyContour(roiContours, s.Value, roiObservation)); } } return(new RadiotherapyStruct(structureSet, patient, equipment, study, series, allContours)); }
/// <summary> /// returns true if the given seriesUID is not null and not referenced in the structure set specified /// </summary> /// <param name="structureSet"></param> /// <param name="seriesUID"></param> /// <returns></returns> private static bool CheckUnreferencedSeries(DicomRTStructureSet structureSet, string seriesUID) { return(seriesUID != null && !structureSet.ReferencedFramesOfRef.Any( x => x.ReferencedStudies.Any( y => y.ReferencedSeries.Any( z => z.SeriesInstanceUID == seriesUID)))); }
/// <summary> /// Called when we open an existing structure set. Note we preserve the SeriesUID and the Series Description. (this is arguable if it /// did not originate from us) /// </summary> /// <param name="structureSet"></param> /// <param name="patient"></param> /// <param name="equipment"></param> /// <param name="study"></param> /// <param name="series"></param> /// <param name="contours"></param> public RadiotherapyStruct( DicomRTStructureSet structureSet, DicomPatient patient, DicomEquipment equipment, DicomStudy study, DicomRTSeries series, IList <RadiotherapyContour> contours) { RTSeries = series; Patient = patient; Equipment = equipment; Study = study; StructureSet = structureSet; Contours = contours; }
/// <summary> /// Called when we are creating a new structure set from an existing 3D scan. /// </summary> /// <param name="identifiers">The identifiers from 1 of the images of the 3D scan</param> /// <returns>A new structure set with a new SeriesUID</returns> public static RadiotherapyStruct CreateDefault(IReadOnlyList <DicomIdentifiers> identifiers) { var firstIdentifier = identifiers.First(); var newSeriesUID = DicomUID.Generate().UID; return(new RadiotherapyStruct( DicomRTStructureSet.CreateDefault(identifiers), firstIdentifier.Patient, DicomEquipment.CreateEmpty(), firstIdentifier.Study, new DicomRTSeries(DicomRTSeries.RtModality, newSeriesUID, string.Empty), new List <RadiotherapyContour>())); }
/// <summary> /// Serialize the structure set to a DICOM dataset. /// </summary> /// <param name="ds"></param> /// <param name="s"></param> public static void Write(DicomDataset ds, RadiotherapyStruct s) { DicomPatient.Write(ds, s.Patient); DicomStudy.Write(ds, s.Study); DicomRTSeries.Write(ds, s.RTSeries); DicomEquipment.Write(ds, s.Equipment); DicomRTStructureSet.Write(ds, s.StructureSet); // For each ROI, gather the contours, observations and roi details into seperate arrays and serialize var rois = s.Contours.Select(c => c.StructureSetRoi); var contours = s.Contours.Select(c => c.DicomRtContour); var observations = s.Contours.Select(c => c.DicomRtObservation); DicomRTStructureSetROI.Write(ds, rois); DicomRTContour.Write(ds, contours); DicomRTObservation.Write(ds, observations); }
public static DicomFolderContents Build(IReadOnlyList <DicomFileAndPath> fileAndPaths) { // Changed for new OSS fo-dicom-desktop // Extract the RT structs and group by referenced SeriesUID var rtStructs = fileAndPaths.Where((fp) => fp.File.Dataset.GetSingleValue <DicomUID>(DicomTag.SOPClassUID) == DicomUID.RTStructureSetStorage); //var rtStructs = fileAndPaths.Where((fp) => fp.File.Dataset.Get(DicomTag.SOPClassUID, DicomExtensions.EmptyUid) == DicomUID.RTStructureSetStorage); // We assume there is 1 and only 1 referenced series var parsedReferencedFoR = rtStructs.GroupBy( (rt) => DicomRTStructureSet.Read(rt.File.Dataset). ReferencedFramesOfRef.FirstOrDefault()?. ReferencedStudies?.FirstOrDefault()?. ReferencedSeries.FirstOrDefault()?. SeriesInstanceUID ?? string.Empty ); // Changed for new OSS fo-dicom-desktop // Filter out the CT and MR SOPClasses var ctMR = fileAndPaths.Where((fp) => IsSupportedImageSOPClass(fp.File.Dataset.GetSingleValue <DicomUID>(DicomTag.SOPClassUID))); // Group by seriesUID var ctMRGroups = ctMR.GroupBy((fp) => fp.File.Dataset.GetSingleValue <DicomUID>(DicomTag.SeriesInstanceUID)); //// Filter out the CT and MR SOPClasses //var ctMR = fileAndPaths.Where((fp) => IsSupportedImageSOPClass(fp.File.Dataset.Get(DicomTag.SOPClassUID, DicomExtensions.EmptyUid))); //// Group by seriesUID //var ctMRGroups = ctMR.GroupBy((fp) => fp.File.Dataset.Get<DicomUID>(DicomTag.SeriesInstanceUID)); // construct output var seriesContent = ctMRGroups.Select((g) => new DicomSeriesContent(g.Key, g.ToList())); // RT structs without frame of reference information will be group into a null DicomUID entry, var rtContent = parsedReferencedFoR.Select((g) => new DicomSeriesContent(DicomUID.Parse(g.Key), g.ToList())); return(new DicomFolderContents(seriesContent.ToList(), rtContent.ToList())); }