ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DicomFilePlan.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DicomFilePlan.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 #include "DicomFilePlan.hh"
27 #include "DicomBeam.hh"
28 #include "DicomBeamDeviceRef.hh"
29 #include "DicomBeamDevicePos.hh"
30 #include "DicomBeamControlPoint.hh"
31 #include "DicomBeamCompensator.hh"
32 #include "DicomBeamBlock.hh"
33 #include "DicomBeamWedge.hh"
34 
35 #include "G4ThreeVector.hh"
36 
37 #include "dcmtk/dcmdata/dcfilefo.h"
38 #include "dcmtk/dcmdata/dcdeftag.h"
39 #include "dcmtk/dcmrt/drtplan.h"
40 #include "dcmtk/dcmrt/seq/drtfgs.h" // DRTFractionGroupSequence
41 #include "dcmtk/dcmrt/seq/drtrbs8.h" // DRTReferencedBeamSequenceInRTFractionSchemeModule
42 #include "dcmtk/dcmrt/seq/drtbs.h" // for BeamSequence
43 #include "dcmtk/dcmrt/seq/drtblds1.h" // for BeamLimitingDeviceSequence
44 #include "dcmtk/dcmrt/seq/drtcps.h" // for ControlPointSequence
45 #include "dcmtk/dcmrt/seq/drtbldps.h" // for BeamLimitingDevicePositionSequence
46 #include "dcmtk/dcmrt/seq/drtcos.h" // for CompensatorSequence
47 #include "dcmtk/dcmrt/seq/drtbl2.h" // for BlockSequence
48 #include "dcmtk/dcmrt/seq/drtws.h" // for WedgeSequence
49 
50 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
51 DicomFilePlan::DicomFilePlan(DcmDataset* dset) : DicomVFile(dset)
52 {
53 }
54 
55 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
57 {
58  DRTPlanIOD rtplan;
59  OFCondition result = rtplan.read(*theDataset);
60  if (!result.good()) {
61  G4Exception("DicomFilePlan::ReadData",
62  "DFS001",
64  result.text());
65  }
66  OFString fstr;
67  Sint32 fint;
68  Float64 ffloat;
69  OFVector<Float64> fvfloat;
70 
71  DRTFractionGroupSequence frgSeq = rtplan.getFractionGroupSequence();
72  if( frgSeq.isEmpty() ) {
73  G4Exception("DicomFilePlan::ReadData",
74  "DFS002",
76  "DRTFractionGroupSequence is empty");
77  }
78  G4cout << "@@@@@ NUMBER OF FractionSequences " << frgSeq.getNumberOfItems() << G4endl;
79  frgSeq.gotoFirstItem();
80  for( size_t i1 = 0; i1 < frgSeq.getNumberOfItems(); i1++ ) {
81  DRTFractionGroupSequence::Item &rfgItem = frgSeq.getCurrentItem();
82  rfgItem.getBeamDoseMeaning(fstr);
83  G4cout << " " << i1 << " BeamDoseMeaning " << fstr << G4endl;
84  rfgItem.getFractionGroupDescription(fstr);
85  G4cout << " " << i1 << " FractionGroupDescription " << fstr << G4endl;
86  rfgItem.getFractionGroupNumber(fint);
87  G4cout << " " << i1 << " FractionGroupNumber " << fint << G4endl;
88  rfgItem.getFractionPattern(fstr);
89  G4cout << " " << i1 << " FractionPattern " << fstr << G4endl;
90  rfgItem.getNumberOfBeams(fint);
91  G4cout << " " << i1 << " NumberOfBeams " << fint << G4endl;
92  theNumberOfBeams = fint;
93  rfgItem.getNumberOfBrachyApplicationSetups(fint);
94  G4cout << " " << i1 << " NumberOfBrachyApplicationSetups " << fint << G4endl;
95  CheckData0(" NumberOfBrachyApplicationSetups ", fint);
96  rfgItem.getNumberOfFractionPatternDigitsPerDay(fint);
97  G4cout << " " << i1 << " NumberOfFractionPatternDigitsPerDay " << fint << G4endl;
98  rfgItem.getNumberOfFractionsPlanned(fint);
99  G4cout << " " << i1 << " NumberOfFractionsPlanned " << fint << G4endl;
100  rfgItem.getRepeatFractionCycleLength(fint);
101  G4cout << " " << i1 << " RepeatFractionCycleLength " << fint << G4endl;
102  DRTReferencedBeamSequenceInRTFractionSchemeModule refBeamSeq =
103  rfgItem.getReferencedBeamSequence();
104  G4cout << " @@@ NUMBER OF ReferencedBeamSequences " << refBeamSeq.getNumberOfItems() << G4endl;
105 
106  refBeamSeq.gotoFirstItem();
107  for( size_t i2 = 0; i2 < refBeamSeq.getNumberOfItems(); i2++ ) {
108  DicomBeam* db = new DicomBeam();
109  theBeams.push_back(db);
110  DRTReferencedBeamSequenceInRTFractionSchemeModule::Item &rbsItem =
111  refBeamSeq.getCurrentItem();
112  rbsItem.getBeamDeliveryDurationLimit(ffloat);
113  G4cout << " " << i2 << " BeamDeliveryDurationLimit " << ffloat << G4endl;
114  rbsItem.getBeamDose(ffloat);
115  G4cout << " " << i2 << " BeamDose " << ffloat << G4endl; // dose at dose point
116  rbsItem.getBeamDoseSpecificationPoint(fvfloat);
117  G4cout << " " << i2 << " BeamDoseSpecificationPoint (" << fvfloat[0] << "," << fvfloat[1]
118  << "," << fvfloat[2] << ")" << G4endl;
119  db->SetDoseSpecificationPoint(G4ThreeVector(fvfloat[0],fvfloat[1],fvfloat[2]));
120  rbsItem.getBeamMeterset(ffloat);
121  G4cout << " " << i2 << " BeamMeterset " << ffloat << G4endl;
122  db->SetMeterset(ffloat);
123  rbsItem.getReferencedBeamNumber(fint);
124  G4cout << " " << i2 << " ReferencedBeamNumber " << fint << G4endl;
125 
126  refBeamSeq.gotoNextItem();
127  }
128 
129  frgSeq.gotoNextItem();
130  }
131 
132 
133  DRTBeamSequence beamSeq = rtplan.getBeamSequence();
134  if( beamSeq.isEmpty() ) {
135  G4Exception("DicomFilePlan::ReadData",
136  "DFS002",
137  JustWarning,
138  "DRTBeamSequence is empty");
139  }
140  G4cout << "@@@@@ NUMBER OF BeamSequences " << beamSeq.getNumberOfItems() << G4endl;
141  beamSeq.gotoFirstItem();
142  for( size_t i1 = 0; i1 < beamSeq.getNumberOfItems(); i1++ ) {
143  DicomBeam* db = theBeams[i1];
144  DRTBeamSequence::Item &beamItem = beamSeq.getCurrentItem();
145 
146  beamItem.getManufacturer(fstr);
147  G4cout << " " << i1 << " Manufacturer " << fstr << G4endl;
148  beamItem.getManufacturerModelName(fstr);
149  G4cout << " " << i1 << " ManufacturerModelName " << fstr << G4endl;
150  beamItem.getTreatmentMachineName(fstr);
151  G4cout << " " << i1 << " TreatmentMachineName " << fstr << G4endl;
152  beamItem.getPrimaryDosimeterUnit(fstr);
153  G4cout << " " << i1 << " PrimaryDosimeterUnit " << fstr << G4endl;
154  beamItem.getSourceAxisDistance(ffloat);
155  G4cout << " " << i1 << " SourceAxisDistance " << ffloat << G4endl;
156  db->SetSourceAxisDistance(ffloat);
157 
158  DRTBeamLimitingDeviceSequenceInRTBeamsModule beamLDS = beamItem.getBeamLimitingDeviceSequence();
159  G4cout << " @@@ NUMBER OF BeamLimitingDeviceSequence " << beamLDS.getNumberOfItems() << G4endl;
160  beamLDS.gotoFirstItem();
161  for( size_t i2 = 0; i2 < beamLDS.getNumberOfItems(); i2++ ) {
162  DRTBeamLimitingDeviceSequenceInRTBeamsModule::Item bldsItem = beamLDS.getCurrentItem();
163  DicomBeamDeviceRef* dbd = new DicomBeamDeviceRef(bldsItem);
164  db->AddDevice(dbd);
165 
166  beamLDS.gotoNextItem();
167  }
168 
169  beamItem.getBeamNumber(fint);
170  G4cout << " " << i1 << " BeamNumber " << fint << G4endl;
171  db->SetNumber(fint);
172  beamItem.getBeamName(fstr);
173  G4cout << " " << i1 << " BeamName " << fstr << G4endl;
174  beamItem.getBeamDescription(fstr);
175  G4cout << " " << i1 << " BeamDescription " << fstr << G4endl;
176  beamItem.getBeamType(fstr);
177  G4cout << " " << i1 << " BeamType " << fstr << G4endl;
178  beamItem.getRadiationType(fstr);
179  G4cout << " " << i1 << " RadiationType " << fstr << G4endl;
180  db->SetRadiationType(fstr);
181  beamItem.getTreatmentDeliveryType(fstr);
182  G4cout << " " << i1 << " TreatmentDeliveryType " << fstr << G4endl;
183  beamItem.getNumberOfWedges(fint);
184  G4cout << " " << i1 << " NumberOfWedges " << fint << G4endl;
185  DRTWedgeSequence beamWedge = beamItem.getWedgeSequence();
186  beamWedge.gotoFirstItem();
187  for( size_t i2 = 0; i2 < beamWedge.getNumberOfItems(); i2++ ) {
188  DRTWedgeSequence::Item bwedItem = beamWedge.getCurrentItem();
189  DicomBeamWedge* dbwed = new DicomBeamWedge( bwedItem );
190  db->AddWedge( dbwed );
191  beamWedge.gotoNextItem();
192  }
193 
194  beamItem.getNumberOfCompensators(fint);
195  G4cout << " " << i1 << " NumberOfCompensators " << fint << G4endl;
196  DRTCompensatorSequence beamCompens = beamItem.getCompensatorSequence();
197  beamCompens.gotoFirstItem();
198  for( size_t i2 = 0; i2 < beamCompens.getNumberOfItems(); i2++ ) {
199  DRTCompensatorSequence::Item bcompItem = beamCompens.getCurrentItem();
200  DicomBeamCompensator* dbcomp = new DicomBeamCompensator( bcompItem );
201  db->AddCompensator( dbcomp );
202  beamCompens.gotoNextItem();
203  }
204 
205  beamItem.getNumberOfBoli(fint);
206  G4cout << " " << i1 << " NumberOfBoli " << fint << G4endl;
207  //Bolus has no relevant info (see drtrbos1.h)
208 
209  beamItem.getNumberOfBlocks(fint);
210  G4cout << " " << i1 << " NumberOfBlocks " << fint << G4endl;
211  DRTBlockSequenceInRTBeamsModule beamBlock = beamItem.getBlockSequence();
212  beamBlock.gotoFirstItem();
213  for( size_t i2 = 0; i2 < beamBlock.getNumberOfItems(); i2++ ) {
214  DRTBlockSequenceInRTBeamsModule::Item bblItem = beamBlock.getCurrentItem();
215  DicomBeamBlock* dbbl = new DicomBeamBlock( bblItem );
216  db->AddBlock( dbbl );
217  beamBlock.gotoNextItem();
218  }
219 
220  beamItem.getFinalCumulativeMetersetWeight(fstr);
221  G4cout << " " << i1 << " FinalCumulativeMetersetWeight " << fstr << G4endl;
222  beamItem.getDeviceSerialNumber(fstr);
223  G4cout << " " << i1 << " DeviceSerialNumber " << fstr << G4endl;
224  beamItem.getHighDoseTechniqueType(fstr);
225  G4cout << " " << i1 << " HighDoseTechniqueType " << fstr << G4endl;
226  beamItem.getInstitutionAddress(fstr);
227  G4cout << " " << i1 << " InstitutionAddress " << fstr << G4endl;
228  beamItem.getInstitutionName(fstr);
229  G4cout << " " << i1 << " InstitutionName " << fstr << G4endl;
230  beamItem.getInstitutionalDepartmentName(fstr);
231  G4cout << " " << i1 << " InstitutionalDepartmentName " << fstr << G4endl;
232  beamItem.getReferencedPatientSetupNumber(fint);
233  G4cout << " " << i1 << " ReferencedPatientSetupNumber " << fint << G4endl;
234  beamItem.getReferencedToleranceTableNumber(fint);
235  G4cout << " " << i1 << " ReferencedToleranceTableNumber " << fint << G4endl;
236  beamItem.getTotalBlockTrayFactor(ffloat);
237  G4cout << " " << i1 << " TotalBlockTrayFactor " << ffloat << G4endl;
238  beamItem.getTotalCompensatorTrayFactor(ffloat);
239  G4cout << " " << i1 << " TotalCompensatorTrayFactor " << ffloat << G4endl;
240 
241  beamItem.getNumberOfControlPoints(fint);
242  DRTControlPointSequence controlPSeq = beamItem.getControlPointSequence();
243  G4cout << " @@@ NUMBER OF ControlPointSequences " << controlPSeq.getNumberOfItems() << " = "
244  << fint << G4endl;
245  controlPSeq.gotoFirstItem();
246  DicomBeamControlPoint* dbcp0 = 0;
247  // Only first ControlPoint has some info if it does not change
248  for( size_t i2 = 0; i2 < controlPSeq.getNumberOfItems(); i2++ ) {
249  DRTControlPointSequence::Item &cpItem = controlPSeq.getCurrentItem();
250  if( db->GetNControlPoints() != 0 ) dbcp0 = db->GetControlPoint(0);
251  DicomBeamControlPoint* dbcp = new DicomBeamControlPoint( cpItem, dbcp0 );
252  db->AddControlPoint( dbcp );
253  controlPSeq.gotoNextItem();
254 
255  }
256 
257  beamSeq.gotoNextItem();
258  }
259 
260  //(300a,0180) SQ (Sequence with explicit length #=1) # 30, 1 PatientSetupSequence
261  //(300c,0060) SQ (Sequence with explicit length #=1) # 112, 1 ReferencedStructureSetSequence
262  //(300e,0002) CS [UNAPPROVED] # 10, 1 ApprovalStatus
263  //(7fe0,0010) OW (no value available) # 0, 1 PixelData
264 
265 }
266 
267 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
268 void DicomFilePlan::CheckData0(OFString title, Sint32 val )
269 {
270  if( val != 0 ){
271  G4Exception("DicomFilePlan::CheckData",
272  "DFP003",
274  (title + " exists, and code is not ready ").c_str());
275  }
276 }
277 
278 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
280 {
281  for( size_t ii = 0; ii < theBeams.size(); ii++ ){
282  theBeams[ii]->SetControlPointMetersets();
283  }
284 }
285 
286 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
288 {
289  for( size_t ii = 0; ii < theBeams.size(); ii++ ){
290  theBeams[ii]->DumpToFile();
291  }
292 }