Loading...
Searching...
No Matches
SAXSDetectorConstruction.cc
Go to the documentation of this file.
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/// \file SAXSDetectorConstruction.cc
27/// \brief Implementation of the SAXSDetectorConstruction class
28//
29//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
30
33
34#include "G4RunManager.hh"
35
36#include "G4Material.hh"
37#include "G4MaterialTable.hh"
38#include "G4Element.hh"
39#include "G4ElementTable.hh"
40#include "G4NistManager.hh"
41
42#include "G4Box.hh"
43#include "G4Tubs.hh"
44#include "G4Sphere.hh"
45#include "G4Cons.hh"
46#include "G4Polyhedra.hh"
47#include "G4Trd.hh"
48#include "G4SubtractionSolid.hh"
49#include "G4UnionSolid.hh"
50#include "G4AssemblyVolume.hh"
51#include "G4IntersectionSolid.hh"
52
53#include "G4RotationMatrix.hh"
54#include "G4ThreeVector.hh"
55
56#include "G4LogicalVolume.hh"
57#include "G4PVPlacement.hh"
58#include "G4GeometryManager.hh"
59#include "G4PhysicalVolumeStore.hh"
60#include "G4LogicalVolumeStore.hh"
61#include "G4SolidStore.hh"
62#include "G4UniformMagField.hh"
63
64#include "G4VisAttributes.hh"
65#include "G4Colour.hh"
66
67#include "G4SDManager.hh"
68#include "G4VSensitiveDetector.hh"
69
70#include "G4MultiFunctionalDetector.hh"
71#include "G4PSDoseDeposit.hh"
72#include "G4PSEnergyDeposit.hh"
73#include "G4SDParticleFilter.hh"
74
75#include <cmath>
76#include <sstream>
77#include <vector>
78
79#include "G4PhysicalConstants.hh"
80#include "G4SystemOfUnits.hh"
81#include "globals.hh"
82
83#include "G4ExtendedMaterial.hh"
84#include "G4MIData.hh"
85
86//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
87
89 G4VUserDetectorConstruction(), fWorldLogic(0)
90{
91 G4cout << "### DetectorConstruction Instantiated ###" << G4endl;
92
93 //instantiate the messenger (set methods will be called after construct)
95
96 //set geometrical variables
98
99 //Initialization
101
102 fComp0 = 0.0; //components of the "Medical Material (MedMat)"
103 fComp1 = 1.0; //Through macro I can set one Medical Material only
104 fComp2 = 0.0;
105 fComp3 = 0.0;
106
107 fCustomMatDensity = 1.00; //g/mol
108 fCustomMatHmassfract = 0.1119;
111 fCustomMatOmassfract = 0.8881;
118
119 fCustomMatFF = ""; //MIFF filename for a custom (extended) material
120
122
123 fIWantSlits = false;
124}
125
126//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
127
129
130//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
131
133{
134 //Define the NIST manager
135 G4NistManager* NistMan = G4NistManager::Instance();
136
137 //Define the required elements for compounds
138 G4Element* elH = NistMan->FindOrBuildElement("H");
139 G4Element* elC = NistMan->FindOrBuildElement("C");
140 G4Element* elN = NistMan->FindOrBuildElement("N");
141 G4Element* elO = NistMan->FindOrBuildElement("O");
142 G4Element* elNa = NistMan->FindOrBuildElement("Na");
143 G4Element* elP = NistMan->FindOrBuildElement("P");
144 G4Element* elS = NistMan->FindOrBuildElement("S");
145 G4Element* elCl = NistMan->FindOrBuildElement("Cl");
146 G4Element* elK = NistMan->FindOrBuildElement("K");
147 G4Element* elCa = NistMan->FindOrBuildElement("Ca");
148
149 //variable definition
150 G4double d; //density
151 G4int nel; //number of elements
152 G4String matname;
153
154 //Air
155 d = 1.29*mg/cm3;
156 nel = 2;
157 G4double tAir = 293.15 * CLHEP::kelvin; //20° Celsius
158 G4double pAir = 1.*CLHEP::atmosphere; //1 atm
159 fAir = new G4Material("Air", d, nel, kStateGas, tAir, pAir);
160 fAir->AddElement(elN, 0.7);
161 fAir->AddElement(elO, 0.3);
162
163 //Fat (Tartari2002) (FF from Tartari2002)
164 G4double d_Fat = 0.923*g/cm3;
165 nel = 3;
166 matname = "Fat_MI";
167 fFat = new G4Material(matname, d_Fat, nel);
168 fFat->AddElement(elH, 0.119);
169 fFat->AddElement(elC, 0.772);
170 fFat->AddElement(elO, 0.109);
171
172 //Water (FF from Tartari2002)
173 G4double d_Water = 1.*g/cm3;
174 nel = 2;
175 matname = "Water_MI";
176 fWater = new G4Material(matname, d_Water, nel);
177 fWater->AddElement(elH, 2);
178 fWater->AddElement(elO, 1);
179
180 //BoneMatrix (Collagen) (FF from Tartari2002)
181 G4double d_BoneMatrix = 1.263*g/cm3;
182 nel = 4;
183 matname = "BoneMatrix_MI";
184 fBoneMatrix = new G4Material(matname, d_BoneMatrix, nel);
185 fBoneMatrix->AddElement(elH, 0.0344);
186 fBoneMatrix->AddElement(elC, 0.7140);
187 fBoneMatrix->AddElement(elN, 0.1827);
188 fBoneMatrix->AddElement(elO, 0.0689);
189
190 //Mineral (Hydroxyapatite) (Tartari2002) (FF from Tartari2002)
191 G4double d_Mineral = 2.74*g/cm3;
192 nel = 4;
193 matname = "Mineral_MI";
194 fMineral = new G4Material(matname, d_Mineral, nel);
195 fMineral->AddElement(elH, 0.002);
196 fMineral->AddElement(elO, 0.414);
197 fMineral->AddElement(elP, 0.185);
198 fMineral->AddElement(elCa, 0.399);
199
200 //Medical Material (compostion of Water, Fat, BoneMatrix and Mineral)
201 G4double comp[] = {fComp0, fComp1, fComp2, fComp3};
202 G4double d_MedMat =
203 1/(comp[0]/d_Fat+comp[1]/d_Water+comp[2]/d_BoneMatrix+comp[3]/d_Mineral);
204 G4int n_MedMat = 0;
205 for (size_t i=0; i<4; i++) {
206 if (comp[i]>0) n_MedMat++;
207 if (comp[i]<0 || comp[i]>1) {
208 G4String excep =
209 "Error in Medical Material composition: comp[i]<0 or comp[i]>1";
210 G4Exception("DetectorConstuction::DefineMaterials()","dc0001",
211 FatalException,excep);
212 return;
213 }
214 }
215 std::stringstream ss0,ss1,ss2,ss3;
216 ss0 << comp[0];
217 ss1 << comp[1];
218 ss2 << comp[2];
219 ss3 << comp[3];
220 if (comp[0]==0 || comp[0]==1) ss0 << ".00";
221 if (comp[1]==0 || comp[1]==1) ss1 << ".00";
222 if (comp[2]==0 || comp[2]==1) ss2 << ".00";
223 if (comp[3]==0 || comp[3]==1) ss3 << ".00";
224 if (ss0.str().size()<4) ss0 << "0";
225 if (ss1.str().size()<4) ss1 << "0";
226 if (ss2.str().size()<4) ss2 << "0";
227 if (ss3.str().size()<4) ss3 << "0";
228 if (ss0.str().size()!=4 || ss1.str().size()!=4 || ss2.str().size()!=4
229 || ss3.str().size()!=4) {
230 G4String excep =
231 "Error in MedMaterial composition: check the digits of the elements of comp";
232 G4Exception("DetectorConstuction::DefineMaterials()","dc0002",
233 FatalException,excep);
234 return;
235 }
236 matname = "MedMat_"+ss0.str()+"_"+ss1.str()+"_"+ss2.str()+"_"+ss3.str();
237 fMedMat = new G4Material(matname, d_MedMat, n_MedMat);
238 if (comp[0]) fMedMat->AddMaterial(fFat, comp[0]);
239 if (comp[1]) fMedMat->AddMaterial(fWater, comp[1]);
240 if (comp[2]) fMedMat->AddMaterial(fBoneMatrix, comp[2]);
241 if (comp[3]) fMedMat->AddMaterial(fMineral, comp[3]);
242 if (comp[0]+comp[1]+comp[2]+comp[3] != 1) {
243 G4String excep = "Error in Medical Material composition: sum(comp) != 1";
244 G4Exception("DetectorConstuction::DefineMaterials()",
245 "dc0003",FatalException,excep);
246 return;
247 }
248 //If the user wants to use more than one MedMat, he has to create the mix
249 //and label the material properly, such as "MedMat_0.55_0.25_0.05_0.15".
250 //Such a name enables the automatic form factor calculation.
251
252 //PMMA (FF from Tartari2002)
253 d = 1.18*g/cm3;
254 nel = 3;
255 matname = "PMMA_MI";
256 fPMMA = new G4Material(matname, d, nel);
257 fPMMA->AddElement(elH, 8);
258 fPMMA->AddElement(elC, 5);
259 fPMMA->AddElement(elO, 2);
260
261 //Adipose (Poletti2002) (FF from Poletti2002)
262 d = 0.92*g/cm3;
263 nel = 4;
264 matname = "adipose_MI";
265 fAdipose = new G4Material(matname, d, nel);
266 fAdipose->AddElement(elH, 0.124);
267 fAdipose->AddElement(elC, 0.765);
268 fAdipose->AddElement(elN, 0.004);
269 fAdipose->AddElement(elO, 0.107);
270
271 //Glandular (Poletti2002) (FF from Poletti2002)
272 d = 1.04*g/cm3;
273 nel = 4;
274 matname = "glandular_MI";
275 fGlandular = new G4Material(matname, d, nel);
276 fGlandular->AddElement(elH, 0.093);
277 fGlandular->AddElement(elC, 0.184);
278 fGlandular->AddElement(elN, 0.044);
279 fGlandular->AddElement(elO, 0.679);
280
281 //human breast 50/50 (ICRU44) (FF from Peplow1998)
282 d = 0.96*g/cm3;
283 nel = 3;
284 matname = "breast5050_MI";
285 fBreast5050 = new G4Material(matname, d, nel);
286 fBreast5050->AddElement(elH, 0.115);
287 fBreast5050->AddElement(elC, 0.387);
288 fBreast5050->AddElement(elO, 0.498);
289
290 //Liver (ICRU46) (FF_pork_liver_Peplow1998)
291 d = 1.06*g/cm3;
292 nel = 9;
293 matname = "liver_MI";
294 fliver = new G4Material(matname, d, nel);
295 fliver->AddElement(elH, 0.102);
296 fliver->AddElement(elC, 0.139);
297 fliver->AddElement(elN, 0.030);
298 fliver->AddElement(elO, 0.716);
299 fliver->AddElement(elNa, 0.002);
300 fliver->AddElement(elP, 0.003);
301 fliver->AddElement(elS, 0.003);
302 fliver->AddElement(elCl, 0.002);
303 fliver->AddElement(elK, 0.003);
304
305 //Kidney (ICRU46) (FF_pork_kidney_Peplow1998)
306 d = 1.05*g/cm3;
307 nel = 10;
308 matname = "kidney_MI";
309 fkidney = new G4Material(matname, d, nel);
310 fkidney->AddElement(elH, 0.103);
311 fkidney->AddElement(elC, 0.132);
312 fkidney->AddElement(elN, 0.030);
313 fkidney->AddElement(elO, 0.724);
314 fkidney->AddElement(elNa, 0.002);
315 fkidney->AddElement(elP, 0.002);
316 fkidney->AddElement(elS, 0.002);
317 fkidney->AddElement(elCl, 0.002);
318 fkidney->AddElement(elK, 0.002);
319 fkidney->AddElement(elCa, 0.001);
320
321 //Lexan (Polycarbonate) (FF from Peplow1998)
322 d = 1.221*g/cm3;
323 nel = 3;
324 matname = "Lexan_MI";
325 fLexan = new G4Material(matname, d, nel);
326 fLexan->AddElement(elH, 14);
327 fLexan->AddElement(elC, 16);
328 fLexan->AddElement(elO, 3);
329
330 //Kapton (FF from Peplow1998)
331 d = 1.42*g/cm3;
332 nel = 4;
333 matname = "Kapton_MI";
334 fKapton = new G4Material(matname, d, nel);
335 fKapton->AddElement(elH, 28);
336 fKapton->AddElement(elC, 35);
337 fKapton->AddElement(elN, 2);
338 fKapton->AddElement(elO, 7);
339
340 //Carcinoma (muscle ICRU44) (FF from Kidane1999)
341 d = 1.05*g/cm3; //check the density
342 nel = 9;
343 matname = "carcinoma_MI";
344 fcarcinoma = new G4Material(matname, d, nel);
345 fcarcinoma->AddElement(elH, 0.102);
346 fcarcinoma->AddElement(elC, 0.143);
347 fcarcinoma->AddElement(elN, 0.034);
348 fcarcinoma->AddElement(elO, 0.710);
349 fcarcinoma->AddElement(elNa, 0.001);
350 fcarcinoma->AddElement(elP, 0.002);
351 fcarcinoma->AddElement(elS, 0.003);
352 fcarcinoma->AddElement(elCl, 0.001);
353 fcarcinoma->AddElement(elK, 0.004);
354
355 //Nylon (FF from Kosanetzky1987)
356 d = 1.15*g/cm3;
357 nel = 4;
358 matname = "Nylon_MI";
359 fNylon = new G4Material(matname, d, nel);
360 fNylon->AddElement(elH, 11);
361 fNylon->AddElement(elC, 6);
362 fNylon->AddElement(elN, 1);
363 fNylon->AddElement(elO, 1);
364
365 //Polyethylene (FF from Kosanetzky1987)
366 d = 0.94*g/cm3; //MDPE => 0.92*g/cm3, HDPE => 0.94*g/cm3
367 nel = 2;
368 matname = "Polyethylene_MI";
369 fPolyethylene = new G4Material(matname, d, nel);
370 fPolyethylene->AddElement(elH, 4);
371 fPolyethylene->AddElement(elC, 2);
372
373 //Polystyrene (FF from Kosanetzky1987)
374 d = 1.05*g/cm3;
375 nel = 2;
376 matname = "Polystyrene_MI";
377 fPolystyrene = new G4Material(matname, d, nel);
378 fPolystyrene->AddElement(elH, 8);
379 fPolystyrene->AddElement(elC, 8);
380
381 //GrayMatter (DeFelici2008) (FF from DeFelici2008)
382 d = 0.991*g/cm3;
383 nel = 3;
384 matname = "grayMatter_MI";
385 fGrayMatter = new G4Material(matname, d, nel);
386 fGrayMatter->AddElement(elH, 0.1127);
387 fGrayMatter->AddElement(elC, 0.0849);
388 fGrayMatter->AddElement(elO, 0.8024);
389
390 //WhiteMatter (DeFelici2008) (FF from DeFelici2008)
391 d = 0.983*g/cm3;
392 nel = 3;
393 matname = "whiteMatter_MI";
394 fWhiteMatter = new G4Material(matname, d, nel);
395 fWhiteMatter->AddElement(elH, 0.1134);
396 fWhiteMatter->AddElement(elC, 0.1621);
397 fWhiteMatter->AddElement(elO, 0.7245);
398
399 //Blood (beef) (ICRU46) (FF from Peplow1998)
400 d = 1.06*g/cm3;
401 nel = 9;
402 matname = "blood_MI";
403 fbeefBlood = new G4Material(matname, d, nel);
404 fbeefBlood->AddElement(elH, 0.102);
405 fbeefBlood->AddElement(elC, 0.11);
406 fbeefBlood->AddElement(elN, 0.033);
407 fbeefBlood->AddElement(elO, 0.746);
408 fbeefBlood->AddElement(elNa, 0.001);
409 fbeefBlood->AddElement(elP, 0.001);
410 fbeefBlood->AddElement(elS, 0.002);
411 fbeefBlood->AddElement(elCl, 0.003);
412 fbeefBlood->AddElement(elK, 0.002);
413
414 //Formaline (FF from Peplow1998)
415 d = 1.083*g/cm3;
416 nel = 3;
417 matname = "Formaline_MI";
418 fFormaline = new G4Material(matname, d, nel);
419 fFormaline->AddElement(elH, 2);
420 fFormaline->AddElement(elC, 1);
421 fFormaline->AddElement(elO, 1);
422
423 //Acetone (FF from Cozzini2010)
424 d = 0.7845*g/cm3;
425 nel = 3;
426 matname = "Acetone_MI";
427 fAcetone = new G4Material(matname, d, nel);
428 fAcetone->AddElement(elH, 6);
429 fAcetone->AddElement(elC, 3);
430 fAcetone->AddElement(elO, 1);
431
432 //Hperoxide (FF from Cozzini2010)
433 d = 1.11*g/cm3;
434 nel = 2;
435 matname = "Hperoxide_MI";
436 fHperoxide = new G4Material(matname, d, nel);
437 fHperoxide->AddElement(elH, 2);
438 fHperoxide->AddElement(elO, 2);
439
440 //CIRS30-70 (Poletti2002) (FF from Poletti2002)
441 d = 0.97*g/cm3;
442 nel = 5;
443 matname = "CIRS30-70_MI";
444 fCIRS3070 = new G4Material(matname, d, nel);
445 fCIRS3070->AddElement(elH, 0.1178);
446 fCIRS3070->AddElement(elC, 0.7512);
447 fCIRS3070->AddElement(elN, 0.0066);
448 fCIRS3070->AddElement(elO, 0.1214);
449 fCIRS3070->AddElement(elCa, 0.0030);
450
451 //CIRS50-50 (Poletti2002) (FF from Poletti2002)
452 d = 0.98*g/cm3;
453 nel = 5;
454 matname = "CIRS50-50_MI";
455 fCIRS5050 = new G4Material(matname, d, nel);
456 fCIRS5050->AddElement(elH, 0.1110);
457 fCIRS5050->AddElement(elC, 0.7274);
458 fCIRS5050->AddElement(elN, 0.0104);
459 fCIRS5050->AddElement(elO, 0.1482);
460 fCIRS5050->AddElement(elCa, 0.0030);
461
462 //CIRS70-30 (Poletti2002) (FF from Poletti2002)
463 d = 1.01*g/cm3;
464 nel = 5;
465 matname = "CIRS70-30_MI";
466 fCIRS7030 = new G4Material(matname, d, nel);
467 fCIRS7030->AddElement(elH, 0.1172);
468 fCIRS7030->AddElement(elC, 0.7378);
469 fCIRS7030->AddElement(elN, 0.0130);
470 fCIRS7030->AddElement(elO, 0.1244);
471 fCIRS7030->AddElement(elCa, 0.0076);
472
473 //RMI454 (Poletti2002) (FF from Poletti2002)
474 d = 0.98*g/cm3;
475 nel = 4;
476 matname = "RMI454_MI";
477 fRMI454 = new G4Material(matname, d, nel);
478 fRMI454->AddElement(elH, 0.0924);
479 fRMI454->AddElement(elC, 0.6935);
480 fRMI454->AddElement(elN, 0.0198);
481 fRMI454->AddElement(elO, 0.1943);
482
483 //Bone (King2011 decomposition) (FF from King2011)
484 d = 1.344*g/cm3;
485 nel = 6;
486 matname = "bone_MI";
487 fBone = new G4Material(matname, d, nel);
488 fBone->AddElement(elH, 0.0582);
489 fBone->AddElement(elC, 0.3055);
490 fBone->AddElement(elN, 0.0347);
491 fBone->AddElement(elO, 0.3856);
492 fBone->AddElement(elP, 0.0684);
493 fBone->AddElement(elCa, 0.1476);
494
495 //FatLowX (Tartari2002) (FF_fat_Tartari2002_joint_lowXdata_ESRF2003)
496 nel = 3;
497 matname = "FatLowX_MI";
498 ffatLowX = new G4Material(matname, d_Fat, nel);
499 ffatLowX->AddElement(elH, 0.119);
500 ffatLowX->AddElement(elC, 0.772);
501 ffatLowX->AddElement(elO, 0.109);
502
503 //BonematrixLowX (Collagen)
504 //(Tartari2002) (FF_bonematrix_Tartari2002_joint_lowXdata)
505 nel = 4;
506 matname = "BoneMatrixLowX_MI";
507 fbonematrixLowX = new G4Material(matname, d_BoneMatrix, nel);
508 fbonematrixLowX->AddElement(elH, 0.0344);
509 fbonematrixLowX->AddElement(elC, 0.7140);
510 fbonematrixLowX->AddElement(elN, 0.1827);
511 fbonematrixLowX->AddElement(elO, 0.0689);
512
513 //dryBoneLowX
514 //(Tartari2002) (FF_dryBone_Tartari2002_joint_lowXdata_ESRF2003)
515 d = 2.06*g/cm3;
516 nel = 6;
517 matname = "dryBoneLowX_MI";
518 fdryBoneLowX = new G4Material(matname, d, nel);
519 fdryBoneLowX->AddElement(elH, 0.0112);
520 fdryBoneLowX->AddElement(elC, 0.2013);
521 fdryBoneLowX->AddElement(elN, 0.0515);
522 fdryBoneLowX->AddElement(elO, 0.3148);
523 fdryBoneLowX->AddElement(elP, 0.1327);
524 fdryBoneLowX->AddElement(elCa, 0.2885);
525
526 //CustomMat (FF read from file)
527 nel = 0;
528 G4double sumMF = 0.;
529 G4cout << "CustomMat composition: " << G4endl;
531 G4cout << "CustomMatHmassfract: " << fCustomMatHmassfract << G4endl;
532 nel++;
533 sumMF += fCustomMatHmassfract;
534 }
536 G4cout << "CustomMatCmassfract: " << fCustomMatCmassfract << G4endl;
537 nel++;
538 sumMF += fCustomMatCmassfract;
539 }
541 G4cout << "CustomMatNmassfract: " << fCustomMatNmassfract << G4endl;
542 nel++;
543 sumMF += fCustomMatNmassfract;
544 }
546 G4cout << "CustomMatOmassfract: " << fCustomMatOmassfract << G4endl;
547 nel++;
548 sumMF += fCustomMatOmassfract;
549 }
551 G4cout << "CustomMatNamassfract: " << fCustomMatNamassfract << G4endl;
552 nel++;
553 sumMF += fCustomMatNamassfract;
554 }
556 G4cout << "CustomMatPmassfract: " << fCustomMatPmassfract << G4endl;
557 nel++;
558 sumMF += fCustomMatPmassfract;
559 }
561 G4cout << "CustomMatSmassfract: " << fCustomMatSmassfract << G4endl;
562 nel++;
563 sumMF += fCustomMatSmassfract;
564 }
566 G4cout << "CustomMatClmassfract: " << fCustomMatClmassfract << G4endl;
567 nel++;
568 sumMF += fCustomMatClmassfract;
569 }
571 G4cout << "CustomMatKmassfract: " << fCustomMatKmassfract << G4endl;
572 nel++;
573 sumMF += fCustomMatKmassfract;
574 }
576 G4cout << "CustomMatCamassfract: " << fCustomMatCamassfract << G4endl;
577 nel++;
578 sumMF += fCustomMatCamassfract;
579 }
580 if (sumMF == 0.) {
581 //set a default material (water),
582 //otherwiswe an error appears in the interactive mode
583 fCustomMatDensity = 1.00; //g/cm3
584 fCustomMatHmassfract = 0.1119;
585 G4cout << "CustomMat set, but not used!" << G4endl;
586 G4cout << "CustomMatHmassfract: " << fCustomMatHmassfract << G4endl;
587 fCustomMatOmassfract = 0.8881;
588 G4cout << "CustomMatOmassfract: " << fCustomMatOmassfract << G4endl;
589 nel = 2;
590 sumMF = 1;
591 }
592 if (sumMF != 1.) {
593 G4String excep =
594 "Error in Custom Material composition: check elemental mass fractions";
595 G4Exception("DetectorConstuction::DefineMaterials()",
596 "dc0004",FatalException,excep);
597 return;
598 }
599
600 d = fCustomMatDensity*g/cm3;
601 matname = "CustomMat";
602 //Notice: this is an extended material
603 fCustomMat = new G4ExtendedMaterial(matname, d, nel);
605 fCustomMat->AddElement(elH, fCustomMatHmassfract);
607 fCustomMat->AddElement(elC, fCustomMatCmassfract);
609 fCustomMat->AddElement(elN, fCustomMatNmassfract);
611 fCustomMat->AddElement(elO, fCustomMatOmassfract);
613 fCustomMat->AddElement(elNa, fCustomMatNamassfract);
615 fCustomMat->AddElement(elP, fCustomMatPmassfract);
617 fCustomMat->AddElement(elS, fCustomMatSmassfract);
619 fCustomMat->AddElement(elCl, fCustomMatClmassfract);
621 fCustomMat->AddElement(elK, fCustomMatKmassfract);
623 fCustomMat->AddElement(elCa, fCustomMatCamassfract);
624 //Register MI extension
625 fCustomMat->RegisterExtension
626 (std::unique_ptr<G4MIData>(new G4MIData("MI")));
627 G4MIData* dataMICustomMat = (G4MIData*)fCustomMat->RetrieveExtension("MI");
628 dataMICustomMat->SetFilenameFF(fCustomMatFF);
629
630 //Nist Materials
631 fLead = NistMan->FindOrBuildMaterial("G4_Pb");
632 fTungsten = NistMan->FindOrBuildMaterial("G4_W");
633 fGe = NistMan->FindOrBuildMaterial("G4_Ge");
634}
635
636//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
637
639{
640 //World
641 fWorldSize = 10000.*mm;
642
643 //Phantom
644 fPhantomDiameter = 50.*mm;
645 fPhantomHeight = 15.*mm;
646 fPhantomZ = 0.*mm;
647
648 //setup angle (rad)
649 fthetaSetup = 0.;
650
651 //Slits
652 fSlitSize = 50.*mm;
653 fSlit1Thickness = 5.*mm;
654 fSlit2Thickness = 5.*mm;
655 fSlit3Thickness = 5.*mm;
656 fSlit4Thickness = 5.*mm;
657 fSlit1SampleDistance = 350.*mm;
658 fSlit2SampleDistance = 50.*mm;
659 fSlit3SampleDistance = 50.*mm;
660 fSlit4SampleDistance = 450.*mm;
661 fSlit1xAperture = 4.*mm;
662 fSlit2xAperture = 4.*mm;
663 fSlit3xAperture = 4.*mm;
664 fSlit4xAperture = 4.*mm;
665 fSlit1yAperture = 4.*mm;
666 fSlit2yAperture = 4.*mm;
667 fSlit3yAperture = 4.*mm;
668 fSlit4yAperture = 4.*mm;
669
670 //Detector
671 fDetectorSize = 20.*mm;
672 fDetectorThickness = 20.*mm;
673 fDetectorSampleDistance = 500.*mm;
674
675 //Shielding
676 fShieldingThickness = 4.*mm;
677}
678
679//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
680
682{
683 //define custom materials
685
686 //World
687 fWorldSolid = new G4Box("WorldSolid",
688 fWorldSize*0.5,
689 fWorldSize*0.5,
690 fWorldSize*0.5);
691
692 fWorldLogic = new G4LogicalVolume(fWorldSolid, fAir, "WorldLogic");
693
694 fWorldLogic->SetVisAttributes(G4VisAttributes::GetInvisible());
695
697 G4ThreeVector(0., 0., 0.),
699 "WorldPhysical",
700 0,
701 false,
702 0);
703
704 //choose the phantom material
705 switch (fPhantomMaterialIndex) {
706 case (1):
708 break;
709 case (2):
711 break;
712 case (3):
714 break;
715 case (4):
717 break;
718 case (5):
720 break;
721 case (6):
723 break;
724 case (7):
726 break;
727 case (8):
729 break;
730 case (9):
732 break;
733 case (10):
735 break;
736 case (11):
738 break;
739 case (12):
741 break;
742 case (13):
744 break;
745 case (14):
747 break;
748 case (15):
750 break;
751 case (16):
753 break;
754 case (17):
756 break;
757 case (18):
759 break;
760 case (19):
762 break;
763 case (20):
765 break;
766 case (21):
768 break;
769 case (22):
771 break;
772 case (23):
774 break;
775 case (24):
777 break;
778 case (25):
780 break;
781 case (26):
783 break;
784 case (27):
786 break;
787 case (28):
789 break;
790 case (29):
792 break;
793 case (30):
795 break;
796 }
797
798 //Phantom (cylinder with axis orthogonal to the X-ray beam axis)
799 G4Tubs* PhantomSolid = new G4Tubs("PhantomSolid",
800 0.,
801 fPhantomDiameter*0.5,
802 fPhantomHeight*0.5,
803 0.*deg,
804 360.*deg);
805
806 fPhantomLogic = new G4LogicalVolume(PhantomSolid,
808 "PhantomLogic");
809
810 G4VisAttributes* PhantomVisAttribute =
811 new G4VisAttributes(G4Colour(1., 1., 1.));
812 PhantomVisAttribute->SetForceSolid(true);
813 fPhantomLogic->SetVisAttributes(PhantomVisAttribute);
814
815 G4cout << "Phantom material: " << fPhantomMaterial->GetName() << G4endl;
816 G4cout << "Phantom density: " << fPhantomMaterial->GetDensity()/(g/cm3)
817 << " g/cm3" << G4endl;
818 G4cout << "Phantom mass: " << fPhantomLogic->GetMass()/g << " g" << G4endl;
819
820 G4double rotAngle = 90.*CLHEP::deg;
821 G4RotationMatrix* PhantomRotationMatrix =
822 new G4RotationMatrix(0., 0., 0.);
823 PhantomRotationMatrix->rotateX(rotAngle);
824
825 fPhantomPhysical = new G4PVPlacement(PhantomRotationMatrix,
826 G4ThreeVector(0., 0., fPhantomZ),
828 "PhantomPhysical",
830 false,
831 0);
832
833 //setup rotation matrix (downstream of the phantom/sample)
834 G4RotationMatrix* SetupRotationMatrix = new G4RotationMatrix();
835 SetupRotationMatrix->rotateY(-fthetaSetup);
836
837 //Slits
838 G4Box* Slit1OutSolid = new G4Box("Slit1OutSolid",
839 fSlitSize*0.5,
840 fSlitSize*0.5,
841 fSlit1Thickness*0.5);
842
843 G4Box* Slit2OutSolid = new G4Box("Slit2OutSolid",
844 fSlitSize*0.5,
845 fSlitSize*0.5,
846 fSlit2Thickness*0.5);
847
848 G4Box* Slit3OutSolid = new G4Box("Slit3OutSolid",
849 fSlitSize*0.5,
850 fSlitSize*0.5,
851 fSlit3Thickness*0.5);
852
853 G4Box* Slit4OutSolid = new G4Box("Slit4OutSolid",
854 fSlitSize*0.5,
855 fSlitSize*0.5,
856 fSlit4Thickness*0.5);
857
858 G4Box* Hole1Solid = new G4Box("Hole1Solid",
859 fSlit1xAperture*0.5,
860 fSlit1yAperture*0.5,
861 fSlit1Thickness*0.51);
862
863 G4Box* Hole2Solid = new G4Box("Hole2Solid",
864 fSlit2xAperture*0.5,
865 fSlit2yAperture*0.5,
866 fSlit2Thickness*0.51);
867
868 G4Box* Hole3Solid = new G4Box("Hole3Solid",
869 fSlit3xAperture*0.5,
870 fSlit3yAperture*0.5,
871 fSlit3Thickness*0.51);
872
873 G4Box* Hole4Solid = new G4Box("Hole4Solid",
874 fSlit4xAperture*0.5,
875 fSlit4yAperture*0.5,
876 fSlit4Thickness*0.51);
877
878 G4SubtractionSolid* Slit1Solid = new G4SubtractionSolid("Slit1Solid",
879 Slit1OutSolid,
880 Hole1Solid);
881
882 G4SubtractionSolid* Slit2Solid = new G4SubtractionSolid("Slit1Solid",
883 Slit2OutSolid,
884 Hole2Solid);
885
886 G4SubtractionSolid* Slit3Solid = new G4SubtractionSolid("Slit3Solid",
887 Slit3OutSolid,
888 Hole3Solid);
889
890 G4SubtractionSolid* Slit4Solid = new G4SubtractionSolid("Slit4Solid",
891 Slit4OutSolid,
892 Hole4Solid);
893
894 fSlit1Logic = new G4LogicalVolume(Slit1Solid, fTungsten, "Slit1Logic");
895 fSlit2Logic = new G4LogicalVolume(Slit2Solid, fTungsten, "Slit2Logic");
896 fSlit3Logic = new G4LogicalVolume(Slit3Solid, fTungsten, "Slit3Logic");
897 fSlit4Logic = new G4LogicalVolume(Slit4Solid, fTungsten, "Slit4Logic");
898
899 if (fIWantSlits) {
900 G4cout << "Slit material: Tungsten" << G4endl;
901 G4cout << "Slit1 thickness: " << fSlit1Thickness/mm << " mm" << G4endl;
902 G4cout << "Slit2 thickness: " << fSlit2Thickness/mm << " mm" << G4endl;
903 G4cout << "Slit3 thickness: " << fSlit3Thickness/mm << " mm" << G4endl;
904 G4cout << "Slit4 thickness: " << fSlit4Thickness/mm << " mm" << G4endl;
905 G4cout << "Slit1 aperture: " << fSlit1xAperture/mm << " x "
906 << fSlit1yAperture/mm << " mm2" << G4endl;
907 G4cout << "Slit2 aperture: " << fSlit2xAperture/mm << " x "
908 << fSlit2yAperture/mm << " mm2" << G4endl;
909 G4cout << "Slit3 aperture: " << fSlit3xAperture/mm << " x "
910 << fSlit3yAperture/mm << " mm2" << G4endl;
911 G4cout << "Slit4 aperture: " << fSlit4xAperture/mm << " x "
912 << fSlit4yAperture/mm << " mm2" << G4endl;
913 }
914
915 G4VisAttributes* SlitlVisAttribute =
916 new G4VisAttributes(G4Colour(0.5, 0.5, 0.5));
917 SlitlVisAttribute->SetForceSolid(true);
918 fSlit1Logic->SetVisAttributes(SlitlVisAttribute);
919 fSlit2Logic->SetVisAttributes(SlitlVisAttribute);
920 fSlit3Logic->SetVisAttributes(SlitlVisAttribute);
921 fSlit4Logic->SetVisAttributes(SlitlVisAttribute);
922
923 G4double Slit1z = fPhantomZ - fSlit1SampleDistance;
924 G4ThreeVector Slit1PositionVector = G4ThreeVector(0., 0., Slit1z);
925
926 G4double Slit2z = fPhantomZ - fSlit2SampleDistance;
927 G4ThreeVector Slit2PositionVector = G4ThreeVector(0., 0., Slit2z);
928
929 G4double Slit3x = fSlit3SampleDistance*std::sin(fthetaSetup);
930 G4double Slit3z = fPhantomZ + fSlit3SampleDistance*std::cos(fthetaSetup);
931 G4ThreeVector Slit3PositionVector = G4ThreeVector(Slit3x, 0., Slit3z);
932
933 G4double Slit4x = fSlit4SampleDistance*std::sin(fthetaSetup);
934 G4double Slit4z = fPhantomZ + fSlit4SampleDistance*std::cos(fthetaSetup);
935 G4ThreeVector Slit4PositionVector = G4ThreeVector(Slit4x, 0., Slit4z);
936
937 if (fIWantSlits) {
939 Slit1PositionVector,
941 "Slit1Physical",
943 false,
944 0);
945
947 Slit2PositionVector,
949 "Slit2Physical",
951 false,
952 0);
953
954 fSlit3Physical = new G4PVPlacement(SetupRotationMatrix,
955 Slit3PositionVector,
957 "Slit3Physical",
959 false,
960 0);
961
962 fSlit4Physical = new G4PVPlacement(SetupRotationMatrix,
963 Slit4PositionVector,
965 "Slit4Physical",
967 false,
968 0);
969 }
970
971 //Detector (with shielding)
972 G4Tubs* DetectorSolid = new G4Tubs("DetectorSolid",
973 0.,
974 fDetectorSize*0.5,
976 0.*deg,
977 360.*deg);
978
979 fDetectorLogic = new G4LogicalVolume(DetectorSolid, fGe, "DetectorLogic");
980
981 G4VisAttributes* DetectorVisAttribute =
982 new G4VisAttributes(G4Colour(0., 0.5, 0.));
983 DetectorVisAttribute->SetForceSolid(true);
984 fDetectorLogic->SetVisAttributes(DetectorVisAttribute);
985
986 G4double Detx = fDetectorSampleDistance*std::sin(fthetaSetup);
987 G4double Detz = fPhantomZ + fDetectorSampleDistance*std::cos(fthetaSetup);
988 G4ThreeVector DetectorPositionVector = G4ThreeVector(Detx, 0., Detz);
989
990 fDetectorPhysical = new G4PVPlacement(SetupRotationMatrix,
991 DetectorPositionVector,
993 "DetectorPhysical",
995 false,
996 0);
997
998 //Shielding
999 G4double ShieldingSize = fDetectorSize+2*fShieldingThickness;
1000
1001 G4double margin = 2.;
1002 G4double ShieldingLength = fDetectorThickness+fShieldingThickness*margin;
1003
1004 G4double ShieldingSampleDistance = fDetectorSampleDistance+
1007 ShieldingLength*0.5;
1008
1009 G4Tubs* ShieldingSolid = new G4Tubs("ShieldingSolid",
1010 fDetectorSize*0.5,
1011 ShieldingSize*0.5,
1012 ShieldingLength*0.5,
1013 0.*deg,
1014 360.*deg);
1015
1016 fShieldingLogic = new G4LogicalVolume(ShieldingSolid,
1017 fLead,
1018 "ShieldingLogic");
1019
1020 G4cout << "Shielding material: Lead" << G4endl;
1021 G4cout << "Shielding thickness: " << fShieldingThickness/mm
1022 << " mm" << G4endl;
1023
1024 G4VisAttributes* ShieldingVisAttribute =
1025 new G4VisAttributes(G4Colour(0.3, 0.3, 0.3));
1026 ShieldingVisAttribute->SetForceSolid(true);
1027 fShieldingLogic->SetVisAttributes(ShieldingVisAttribute);
1028
1029 G4double Shieldx = ShieldingSampleDistance*std::sin(fthetaSetup);
1030 G4double Shieldz = fPhantomZ +
1031 ShieldingSampleDistance*std::cos(fthetaSetup);
1032 G4ThreeVector ShieldingPositionVector =
1033 G4ThreeVector(Shieldx, 0., Shieldz);
1034
1035 G4double ShieldingBackSampleDistance = fDetectorSampleDistance+
1038
1039 G4Tubs* ShieldingBackSolid = new G4Tubs("ShieldingBackSolid",
1040 0.,
1041 fDetectorSize*0.5,
1043 0.*deg,
1044 360.*deg);
1045
1046 fShieldingBackLogic = new G4LogicalVolume(ShieldingBackSolid,
1047 fLead,
1048 "ShieldingBackLogic");
1049
1050 fShieldingBackLogic->SetVisAttributes(ShieldingVisAttribute);
1051
1052 G4double ShieldBackx = ShieldingBackSampleDistance*std::sin(fthetaSetup);
1053 G4double ShieldBackz = fPhantomZ +
1054 ShieldingBackSampleDistance*std::cos(fthetaSetup);
1055 G4ThreeVector ShieldingBackPositionVector =
1056 G4ThreeVector(ShieldBackx, 0., ShieldBackz);
1057
1058 fShieldingPhysical = new G4PVPlacement(SetupRotationMatrix,
1059 ShieldingPositionVector,
1061 "ShieldingPhysical",
1062 fWorldLogic,
1063 false,
1064 0);
1065
1066 fShieldingBackPhysical = new G4PVPlacement(SetupRotationMatrix,
1067 ShieldingBackPositionVector,
1069 "ShieldingBackPhysical",
1070 fWorldLogic,
1071 false,
1072 0);
1073
1074 return fWorldPhysical;
1075
1076}
1077
1078//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1079
1081{
1082 //Sensitive Volume
1083 G4VSensitiveDetector* vDetector = new SAXSSensitiveDetector("det");
1084 G4SDManager::GetSDMpointer()->AddNewDetector(vDetector);
1086 fSensitiveVolume->SetSensitiveDetector(vDetector);
1087}
1088
1089//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Implementation of the SAXSDetectorConstruction class.
Definition of the SAXSSensitiveDetector class.
DetectorConstruction messenger.
virtual G4VPhysicalVolume * Construct()
G4VPhysicalVolume * fShieldingBackPhysical
SAXSDetectorConstructionMessenger * fMessenger

Applications | User Support | Publications | Collaboration