Monte Carlo LYSO
Geant4 simulation for the LYSO calorimeter prototype
construction.cc
Go to the documentation of this file.
1 
5 #include "construction.hh"
6 
8 {
10 
11  // Default settings
12  fIsGrease = true;
14  fIsLightGuide = false;
15  nLightGuideMat = 1;
16  fIsPCB = true;
17  fIsEndcap = true;
18  fIsASiPM = false;
19  fIsCosmicRaysDetectors = true;
20 
22 }
23 
24 
25 
27 {
28  G4NistManager *nist = G4NistManager::Instance();
29 
30  // LYSO
31  fLYSO = new G4Material("LYSO", 7.25*g/cm3, 5, kStateSolid);
32  fLYSO->AddElement(nist->FindOrBuildElement("Lu"), 73.8579*perCent);
33  fLYSO->AddElement(nist->FindOrBuildElement("Y"), 1.9747*perCent);
34  fLYSO->AddElement(nist->FindOrBuildElement("Si"), 6.2418*perCent);
35  fLYSO->AddElement(nist->FindOrBuildElement("O"), 17.77*perCent);
36  fLYSO->AddElement(nist->FindOrBuildElement("Ce"), 0.1556*perCent);
37 
38  G4MaterialPropertiesTable *mptLYSO = new G4MaterialPropertiesTable();
39 
40  std::vector<G4double> Energies = {2.14*eV, 2.95*eV, 3.69*eV};
41  const G4int nEntries = Energies.size();
42  std::vector<G4double> emissionEnergies =
43  {
44  2.14*eV, 2.16*eV, 2.19*eV, 2.22*eV, 2.26*eV,
45  2.29*eV, 2.33*eV, 2.37*eV, 2.41*eV, 2.45*eV,
46  2.49*eV, 2.53*eV, 2.57*eV, 2.6*eV, 2.64*eV,
47  2.67*eV, 2.7*eV, 2.72*eV, 2.74*eV, 2.76*eV,
48  2.78*eV, 2.81*eV, 2.84*eV, 2.86*eV, 2.9*eV,
49  2.95*eV, 3.0*eV, 3.05*eV, 3.07*eV, 3.09*eV,
50  3.12*eV, 3.14*eV, 3.15*eV, 3.18*eV, 3.2*eV,
51  3.21*eV, 3.22*eV, 3.24*eV, 3.25*eV, 3.28*eV,
52  3.3*eV, 3.32*eV, 3.37*eV, 3.43*eV, 3.52*eV,
53  3.6*eV, 3.69*eV
54  };
55 
56  std::vector<G4double> LYSO_RINDEX(nEntries, 1.82);
57  std::vector<G4double> LYSO_ABSLENGTH(nEntries, 50.*cm);
58  std::vector<G4double> LYSO_SCINTILLATIONCOMPONENT1 =
59  {
60  0.0, 0.0231, 0.153, 0.867,
61  1.44, 2.13, 2.99, 4.07,
62  5.17, 7.27, 10.3, 14.3,
63  19.0, 23.2, 28.0, 32.6,
64  36.9, 41.6, 46.4, 51.0,
65  55.5, 60.1, 65.0, 69.5,
66  73.8, 77.7, 78.1, 73.2,
67  68.1, 63.4, 58.9, 54.3,
68  49.6, 45.2, 40.5, 35.8,
69  31.3, 26.5, 21.5, 17.0,
70  12.2, 7.48, 3.39, 0.726,
71  0.705, 0.314, 0.0
72  };
73 
74  mptLYSO->AddProperty("SCINTILLATIONCOMPONENT1", emissionEnergies, LYSO_SCINTILLATIONCOMPONENT1);
75  mptLYSO->AddProperty("RINDEX", Energies, LYSO_RINDEX);
76  mptLYSO->AddProperty("ABSLENGTH", Energies, LYSO_ABSLENGTH);
77  mptLYSO->AddConstProperty("SCINTILLATIONYIELD", 29000./MeV);
78  mptLYSO->AddConstProperty("RESOLUTIONSCALE", 1.0);
79  mptLYSO->AddConstProperty("SCINTILLATIONTIMECONSTANT1", 42.*ns);
80  mptLYSO->AddConstProperty("SCINTILLATIONYIELD1", 1.);
81 
82  fLYSO->SetMaterialPropertiesTable(mptLYSO);
83 
84  // AIR
85  fAir = nist->FindOrBuildMaterial("G4_AIR");
86 
87  G4MaterialPropertiesTable *mptAir = new G4MaterialPropertiesTable();
88 
89  std::vector<G4double> AIR_RINDEX(nEntries, 1.000293);
90  mptAir->AddProperty("RINDEX", Energies, AIR_RINDEX);
91 
92  fAir->SetMaterialPropertiesTable(mptAir);
93 
94  // VACUUM
95  fVacuum = nist->FindOrBuildMaterial("G4_Galactic");
96 
97  G4MaterialPropertiesTable *mptVacuum = new G4MaterialPropertiesTable();
98 
99  std::vector<G4double> VACUUM_RINDEX(nEntries, 1.);
100  mptVacuum->AddProperty("RINDEX", Energies, VACUUM_RINDEX);
101 
102  fVacuum->SetMaterialPropertiesTable(mptVacuum);
103 
104  // SILICON
105  fSilicon = nist->FindOrBuildMaterial("G4_Si");
106  G4MaterialPropertiesTable *mptDetector = new G4MaterialPropertiesTable();
107  std::vector<G4double> DETECTOR_RINDEX(nEntries, 1.55); //should be 3.88, but it is included in the PDE, so it's fixed at the same value of the window (Total transmission)
108  mptDetector->AddProperty("RINDEX", Energies, DETECTOR_RINDEX);
109 
110  fSilicon->SetMaterialPropertiesTable(mptDetector);
111 
112  // EPOXY
113  fEpoxy = new G4Material("Epoxy", 1.2*g/cm3, 2);
114  fEpoxy->AddElement(nist->FindOrBuildElement("C"), 2);
115  fEpoxy->AddElement(nist->FindOrBuildElement("H"), 2);
116  G4MaterialPropertiesTable *mptEpoxy = new G4MaterialPropertiesTable();
117  std::vector<G4double> EPOXY_RINDEX(nEntries, 1.55);
118  mptEpoxy->AddProperty("RINDEX", Energies, EPOXY_RINDEX);
119 
120  fEpoxy->SetMaterialPropertiesTable(mptEpoxy);
121 
122  // FR4
123  fFR4 = new G4Material("FR4", 1.85*g/cm3, 2);
124  fFR4->AddMaterial(nist->FindOrBuildMaterial("G4_SILICON_DIOXIDE"), 52.8*perCent);
125  fFR4->AddMaterial(fEpoxy, 47.2*perCent);
126 
127  // CARBON FIBER
128  fCarbonFiber = new G4Material("Carbon Fiber", 1.5*g/cm3, 1);
129  fCarbonFiber->AddElement(nist->FindOrBuildElement("C"), 1);
130 
131  // PLEXIGLASS
132  fPlexiglass = nist->FindOrBuildMaterial("G4_PLEXIGLASS");
133 
134  G4MaterialPropertiesTable *mptPlexiglass = new G4MaterialPropertiesTable();
135 
136  std::vector<G4double> PLEXIGLASS_RINDEX(nEntries, 1.49);
137  mptPlexiglass->AddProperty("RINDEX", Energies, PLEXIGLASS_RINDEX);
138 
139  fPlexiglass->SetMaterialPropertiesTable(mptPlexiglass);
140 
141  // SAPPHIRE
142  fSapphire = new G4Material("Sapphire", 3.98*g/cm3, 2, kStateSolid);
143  fSapphire->AddElement(nist->FindOrBuildElement("Al"), 2);
144  fSapphire->AddElement(nist->FindOrBuildElement("O"), 3);
145 
146  G4MaterialPropertiesTable *mptSapphire = new G4MaterialPropertiesTable();
147 
148  std::vector<G4double> SAPPHIRE_RINDEX(nEntries, 1.77);
149  mptSapphire->AddProperty("RINDEX", Energies, SAPPHIRE_RINDEX);
150 
151  fSapphire->SetMaterialPropertiesTable(mptSapphire);
152 
153  // OPTICAL GREASE
154  fGrease = new G4Material("OpticalGrease", 1.06*g/cm3, 2);
155  fGrease->AddElement(nist->FindOrBuildElement("C"), 2);
156  fGrease->AddElement(nist->FindOrBuildElement("H"), 6);
157 
158  G4MaterialPropertiesTable *mptGrease = new G4MaterialPropertiesTable();
159 
160  std::vector<G4double> GREASE_RINDEX(nEntries, 1.46);
161  mptGrease->AddProperty("RINDEX", Energies, GREASE_RINDEX);
162 
163  fGrease->SetMaterialPropertiesTable(mptGrease);
164 
165  // Optical Grease surface
167  {
168  fOpGreaseSurface = new G4OpticalSurface("GreaseSurface");
169  fOpGreaseSurface->SetType(dielectric_dielectric);
170  fOpGreaseSurface->SetModel(unified);
171  fOpGreaseSurface->SetFinish(ground);
172  fOpGreaseSurface->SetSigmaAlpha(0.1); // Dummy value indicating the roughness, will be fixed according to experimental data (I hope...)
173  }
174 }
175 
176 
177 
179 {
180  // Construct the World
181  G4Box *solidWorld = new G4Box("solidWorld", GS::halfXsideWorld, GS::halfYsideWorld, GS::halfZsideWorld);
182  logicWorld = new G4LogicalVolume(solidWorld, fAir, "logicWorld");
183  G4VPhysicalVolume *physWorld = new G4PVPlacement(0, G4ThreeVector(0., 0., 0.), logicWorld, "physWorld", 0, false, 0, true);
184 
185  // Option to draw only a SiPM, for debug
186  if(fIsASiPM)
187  {
188  ConstructASiPM();
189  return physWorld;
190  }
191 
192  // Construct the scintillator crystal
193  G4Tubs *solidScintillator = new G4Tubs("solidScintillator", 0.*cm, GS::radiusScintillator, GS::halfheightScintillator, 0.*deg, 360.*deg);
194  logicScintillator = new G4LogicalVolume(solidScintillator, fLYSO, "logicScintillator");
195  G4VPhysicalVolume *physScintillator = new G4PVPlacement(0, G4ThreeVector(GS::xScintillator, GS::yScintillator, GS::zScintillator), logicScintillator, "physScintillator", logicWorld, false, 0, true);
196 
197  // Assign the logic scoring volume to the crystal
199 
200  // Construct a coating for the crystal and the lightguide (if present)
202  logicCoating = new G4LogicalVolume(solidCoating, fCarbonFiber, "logicCoating");
203  G4VPhysicalVolume *physCoating = new G4PVPlacement(0, G4ThreeVector(GS::xScintillator, GS::yScintillator, GS::zScintillator), logicCoating, "physCoating", logicWorld, false, 0, true);
204 
205  // Construct lightguides, PCBs and endcaps -if setted-
208  if(fIsPCB) ConstructPCB();
210 
211  // Construct the package of the SIPM
212  G4Box *solidPackageSiPM = new G4Box("solidPackageSiPM", GS::halfXsidePackageSiPM, GS::halfYsidePackageSiPM, GS::halfZsidePackageSiPM);
213  logicPackageSiPM = new G4LogicalVolume(solidPackageSiPM, fFR4, "logicPackageSiPM");
214 
215  // Construct the window of the SIPM and put it inside the package
216  G4Box *solidWindowSiPM = new G4Box("solidWindowSiPM", GS::halfXsideWindowSiPM, GS::halfYsideWindowSiPM, GS::halfZsideWindowSiPM);
217  logicWindowSiPM = new G4LogicalVolume(solidWindowSiPM, fEpoxy, "logicWindowSiPM");
218  G4VPhysicalVolume *physWindowSiPM = new G4PVPlacement(0, G4ThreeVector(GS::xWindowSiPM, GS::yWindowSiPM, GS::zWindowSiPM), logicWindowSiPM, "physWindowSiPM", logicPackageSiPM, false, 0, true);
219 
220  // Construct the silicon layer and put it inside the window
221  G4Box *solidDetector = new G4Box("solidDetector", GS::halfXsideDetector, GS::halfYsideDetector, GS::halfZsideDetector);
222  logicDetector = new G4LogicalVolume(solidDetector, fSilicon, "logicDetector");
223  G4VPhysicalVolume *physDetector = new G4PVPlacement(0, G4ThreeVector(GS::xDetector, GS::yDetector, GS::zDetector), logicDetector, "physDetector", logicWindowSiPM, false, 0, true);
224 
225  // Define the arrangement of SiPMs
226  G4VPhysicalVolume *physFrontPackageSiPM[GS::nOfSiPMs];
227  G4VPhysicalVolume *physBackPackageSiPM[GS::nOfSiPMs];
228 
229  G4int indexDetector = 0;
230  for(G4int i = 0; i < GS::nRowsSiPMs; i++)
231  {
232  for(G4int j = 0; j < GS::nColsSiPMs; j++)
233  {
234  if(GS::panelSiPMs[i][j])
235  {
236  PositionSiPMs(physFrontPackageSiPM[indexDetector], physBackPackageSiPM[indexDetector], i, j, indexDetector);
237  indexDetector++;
238  }
239  }
240  }
241 
242  // Assign the logic trigger volume to the Si layer
243  fDecayTriggerVolume = logicDetector;
244 
245  // Construct dummy cosmic rays detectors
246  if(fIsCosmicRaysDetectors)
247  ConstructCosmicRaysDetectors();
248 
249  // Add visualization attributes
251 
252  // Always return physWorld
253  return physWorld;
254 }
255 
256 
257 
259 {
260  // Set logic silicon layer as sensitive volume. Use G4SDManager to do it
261  MySensitiveDetector *sensDet = static_cast<MySensitiveDetector*>(G4SDManager::GetSDMpointer()->FindSensitiveDetector("SensitiveDetector"));
262 
263  if(!sensDet)
264  {
265  sensDet = new MySensitiveDetector("SensitiveDetector", "HitsCollection");
266  G4SDManager::GetSDMpointer()->AddNewDetector(sensDet);
267  }
268 
269  SetSensitiveDetector(logicDetector, sensDet);
270 }
271 
272 
273 
275 {
276  // Grease as cilinder
277  G4Tubs *solidGrease = new G4Tubs("solidGrease", 0, GS::radiusScintillator, GS::halfheightGrease, 0.*deg, 360.*deg);
278  logicGrease = new G4LogicalVolume(solidGrease, fGrease, "logicGrease");
279  G4VPhysicalVolume *physFrontGrease = new G4PVPlacement(0, G4ThreeVector(0, 0, GS::zFrontFaceScintillator-GS::halfheightGrease), logicGrease, "physFrontGrease", logicWorld, false, 0, true);
280  G4VPhysicalVolume *physBackGrease = new G4PVPlacement(0, G4ThreeVector(0, 0, GS::zBackFaceScintillator+GS::halfheightGrease), logicGrease, "physBackGrease", logicWorld, false, 1, true);
281 
282  if(fIsLightGuide)
283  {
284  G4VPhysicalVolume *physSecondFrontGrease = new G4PVPlacement(0, G4ThreeVector(0, 0, GS::zFrontFaceScintillator-2*GS::halfheightLightGuide-3*GS::halfheightGrease), logicGrease, "physSecondFrontGrease", logicWorld, false, 0, true);
285  G4VPhysicalVolume *physSecondBackGrease = new G4PVPlacement(0, G4ThreeVector(0, 0, GS::zBackFaceScintillator+2*GS::halfheightLightGuide+3*GS::halfheightGrease), logicGrease, "physSecondBackGrease", logicWorld, false, 1, true);
286  }
287 
288  // Grease as surface
290  G4LogicalSkinSurface *logicGreaseSurface = new G4LogicalSkinSurface("GreaseSurface", logicGrease, fOpGreaseSurface);
291 }
292 
293 
294 
296 {
297  G4Material *fLightGuideMaterial = 0;
298 
299  // Solid light guide as cilinder
300  G4Tubs *solidLightGuide = new G4Tubs("solidLightGuide", 0, GS::radiusLightGuide, GS::halfheightLightGuide, 0.*deg, 360.*deg);
301 
302  // Drill 4 holes in the light guide for LEDs
303  G4Tubs *solidHoleUP = new G4Tubs("solidHoleLightGuide", 0, GS::radiusHole, GS::depthHole, 0.*deg, 360*deg);
304  G4Tubs *solidHoleDOWN = new G4Tubs("solidHoleLightGuide", 0, GS::radiusHole, GS::depthHole, 0.*deg, 360*deg);
305  G4Tubs *solidHoleRIGHT = new G4Tubs("solidHoleLightGuide", 0, GS::radiusHole, GS::depthHole, 0.*deg, 360*deg);
306  G4Tubs *solidHoleLEFT = new G4Tubs("solidHoleLightGuide", 0, GS::radiusHole, GS::depthHole, 0.*deg, 360*deg);
307 
308  G4Rotate3D rotXholeUP(90*deg, G4ThreeVector(1, 0, 0));
309  G4Translate3D transYholeUP(G4ThreeVector(0, GS::radiusLightGuide, 0));
310  G4Transform3D transformHoleUP = (transYholeUP)*(rotXholeUP);
311 
312  G4Rotate3D rotXholeDOWN(90*deg, G4ThreeVector(1, 0, 0));
313  G4Translate3D transYholeDOWN(G4ThreeVector(0, -GS::radiusLightGuide, 0));
314  G4Transform3D transformHoleDOWN = (transYholeDOWN)*(rotXholeDOWN);
315 
316  G4Rotate3D rotYholeRIGHT(90*deg, G4ThreeVector(0, 1, 0));
317  G4Translate3D transYholeRIGHT(G4ThreeVector(GS::radiusLightGuide, 0, 0));
318  G4Transform3D transformHoleRIGHT = (transYholeRIGHT)*(rotYholeRIGHT);
319 
320  G4Rotate3D rotYholeLEFT(90*deg, G4ThreeVector(0, 1, 0));
321  G4Translate3D transYholeLEFT(G4ThreeVector(-GS::radiusLightGuide, 0, 0));
322  G4Transform3D transformHoleLEFT = (transYholeLEFT)*(rotYholeLEFT);
323 
324  G4MultiUnion *solidHoles = new G4MultiUnion("solidHoles");
325  solidHoles->AddNode(*solidHoleUP, transformHoleUP);
326  solidHoles->AddNode(*solidHoleDOWN, transformHoleDOWN);
327  solidHoles->AddNode(*solidHoleRIGHT, transformHoleRIGHT);
328  solidHoles->AddNode(*solidHoleLEFT, transformHoleLEFT);
329  solidHoles->Voxelize();
330 
331  G4VSolid *solidDrilledLightGuide = new G4SubtractionSolid("solidDrilledLightGuide", solidLightGuide, solidHoles);
332 
333  // Options for material
334  switch(nLightGuideMat)
335  {
336  case 1: // Plexiglass
337  fLightGuideMaterial = fPlexiglass;
338  break;
339  case 2: // Sapphire
340  fLightGuideMaterial = fSapphire;
341  break;
342  default:
343  G4cerr << "Option for lightguide's material not valid. \"Plexiglass\" has been setted" << G4endl;
344  fLightGuideMaterial = fPlexiglass;
345  }
346 
347  // Logic and phys volumes for light guides
348  logicLightGuide = new G4LogicalVolume(solidDrilledLightGuide, fLightGuideMaterial, "logicLightGuide");
349  G4VPhysicalVolume *physFrontLightGuide = new G4PVPlacement(0, G4ThreeVector(0., 0., GS::zFrontFaceScintillator-(2*GS::halfheightGrease*fIsGrease)-GS::halfheightLightGuide), logicLightGuide, "physFrontLightGuide", logicWorld, false, 0, true);
350  G4VPhysicalVolume *physBackLightGuide = new G4PVPlacement(0, G4ThreeVector(0., 0., GS::zBackFaceScintillator+(2*GS::halfheightGrease*fIsGrease)+GS::halfheightLightGuide), logicLightGuide, "physBackLightGuide", logicWorld, false, 1, true);
351 }
352 
353 
354 
356 {
357  // PCB as cilinder
358  G4Tubs *solidPCB = new G4Tubs("solidPCB", 0, GS::radiusPCB, GS::halfheightPCB, 0.*deg, 360.*deg);
359  logicPCB = new G4LogicalVolume(solidPCB, fFR4, "logicPCB");
360  G4VPhysicalVolume *physFrontPCB = new G4PVPlacement(0, G4ThreeVector(0, 0, GS::zFrontFaceScintillator-(2*GS::halfheightGrease*fIsGrease)-2*(GS::halfheightLightGuide*fIsLightGuide)-(2*GS::halfheightGrease*fIsLightGuide*fIsGrease)-2*GS::halfZsidePackageSiPM-GS::halfheightPCB), logicPCB, "physFrontPCB", logicWorld, false, 0, true);
361  G4VPhysicalVolume *physBackPCB = new G4PVPlacement(0, G4ThreeVector(0, 0, GS::zBackFaceScintillator+(2*GS::halfheightGrease*fIsGrease)+2*(GS::halfheightLightGuide*fIsLightGuide)+(2*GS::halfheightGrease*fIsLightGuide*fIsGrease)+2*GS::halfZsidePackageSiPM+GS::halfheightPCB), logicPCB, "physBackPCB", logicWorld, false, 1, true);
362 }
363 
364 
365 
367 {
368  // Endcap as cilinder
369  G4Tubs *solidEndcap = new G4Tubs("solidEndcap", 0, GS::radiusEndcap, GS::halfheightEndcap, 0.*deg, 360.*deg);
370  logicEndcap = new G4LogicalVolume(solidEndcap, fCarbonFiber, "logicEndcap");
371  G4VPhysicalVolume *physFrontEndcap = new G4PVPlacement(0, G4ThreeVector(0, 0, GS::zFrontFaceScintillator-(2*GS::halfheightGrease*fIsGrease)-2*(GS::halfheightLightGuide*fIsLightGuide)-(2*GS::halfheightGrease*fIsLightGuide*fIsGrease)-2*GS::halfZsidePackageSiPM-2*(GS::halfheightPCB*fIsPCB)-GS::halfheightEndcap), logicEndcap, "physFrontEndcap", logicWorld, false, 0, true);
372  G4VPhysicalVolume *physBackEndcap = new G4PVPlacement(0, G4ThreeVector(0, 0, GS::zBackFaceScintillator+(2*GS::halfheightGrease*fIsGrease)+2*(GS::halfheightLightGuide*fIsLightGuide)+(2*GS::halfheightGrease*fIsLightGuide*fIsGrease)+2*GS::halfZsidePackageSiPM+2*(GS::halfheightPCB*fIsPCB)+GS::halfheightEndcap), logicEndcap, "physBackEndcap", logicWorld, false, 1, true);
373 }
374 
375 
376 
377 void MyDetectorConstruction::PositionSiPMs(G4VPhysicalVolume *physFrontSiPM, G4VPhysicalVolume *physBackSiPM, G4int row, G4int col, G4int index)
378 {
379  G4double startX = -GS::halfXsidePackageSiPM*(GS::nColsSiPMs -1);
380  G4double startY = GS::halfYsidePackageSiPM*(GS::nRowsSiPMs - 1);
381 
382  // Place the packages. When in back face, need to rotate them of 180°
383  physFrontSiPM = new G4PVPlacement(0, G4ThreeVector(startX + col*2*GS::halfXsidePackageSiPM, startY - row*2*GS::halfYsidePackageSiPM, GS::zFrontFaceScintillator-(2*GS::halfheightGrease*fIsGrease)-2*(GS::halfheightLightGuide*fIsLightGuide)-(2*GS::halfheightGrease*fIsLightGuide*fIsGrease)-GS::halfZsidePackageSiPM), logicPackageSiPM, "physFrontPackageSiPM", logicWorld, false, index, true);
384 
385  G4Rotate3D rotXBackDet(180*deg, G4ThreeVector(1, 0, 0));
387  G4Transform3D transformBackDet = (transBackDet)*(rotXBackDet);
388 
389  physBackSiPM = new G4PVPlacement(transformBackDet, logicPackageSiPM, "physBackPackageSiPM", logicWorld, false, index, true);
390 }
391 
392 
393 
395 {
396  // World
397  G4VisAttributes *visWorld = new G4VisAttributes();
398  visWorld->SetVisibility(false);
399  logicWorld->SetVisAttributes(visWorld);
400 
401  // Endcaps
402  if(fIsEndcap)
403  {
404  G4VisAttributes *visEndcap = new G4VisAttributes();
405  visEndcap->SetColour(0.5, 0.5, 0.5, 0.5);
406  logicEndcap->SetVisAttributes(visEndcap);
407  }
408 
409  // PCBs
410  if(fIsPCB)
411  {
412  G4VisAttributes *visPCB = new G4VisAttributes();
413  visPCB->SetColour(0, 1, 0, 0.65);
414  logicPCB->SetVisAttributes(visPCB);
415  }
416 
417  // Light guides
418  if(fIsLightGuide)
419  {
420  G4VisAttributes *visLightGuide = new G4VisAttributes();
421  visLightGuide->SetColour(1, 1, 1, 0.5);
422  logicLightGuide->SetVisAttributes(visLightGuide);
423  }
424 
425  if(fIsGrease)
426  {
427  G4VisAttributes *visGrease = new G4VisAttributes();
428  visGrease->SetColour(1, 0.5, 0, 0.5);
429  logicGrease->SetVisAttributes(visGrease);
430  }
431 
432  // SiPM packages
433  G4VisAttributes *visPackage = new G4VisAttributes();
434  visPackage->SetColour(1, 1, 0, 0.7);
435  logicPackageSiPM->SetVisAttributes(visPackage);
436 
437  // SiPM windows
438  G4VisAttributes *visWindow = new G4VisAttributes();
439  visWindow->SetColour(1, 1, 1, 0.7);
440  logicWindowSiPM->SetVisAttributes(visWindow);
441 
442  // SiPM silicon layers
443  G4VisAttributes *visDetector = new G4VisAttributes();
444  visDetector->SetColour(0.45, 0.25, 0, 0.7);
445  logicDetector->SetVisAttributes(visDetector);
446 
447  // Scintillator
448  G4VisAttributes *visScintillator = new G4VisAttributes();
449  visScintillator->SetColour(0, 0, 1, 0.98);
450  logicScintillator->SetVisAttributes(visScintillator);
451 
452  // Coating
453  G4VisAttributes *visCoating = new G4VisAttributes();
454  visCoating->SetVisibility(false);
455  logicCoating->SetVisAttributes(visCoating);
456 
457  // Cosmic rays detectors
458  if(fIsCosmicRaysDetectors)
459  {
460  G4VisAttributes *visCosmicDet = new G4VisAttributes();
461  visCosmicDet->SetColour(0, 0.5, 0.6, 0.7);
462  logicCosmicRaysDetector->SetVisAttributes(visCosmicDet);
463  }
464 }
465 
466 
467 
469 {
470  // Define my UD-messenger for the detector construction
471  fMessenger = new G4GenericMessenger(this, "/MC_LYSO/myConstruction/", "Construction settings");
472  fMessenger->DeclareProperty("isOpticalGrease", fIsGrease, "Set if optical grease is present");
473  fMessenger->DeclareProperty("isLightGuide", fIsLightGuide, "Set if the two light guides are present");
474  fMessenger->DeclareProperty("isPCB", fIsPCB, "Set if the two PCBs are present");
475  fMessenger->DeclareProperty("isEndcap", fIsEndcap, "Set if the two endcaps are present");
476  fMessenger->DeclareProperty("MaterialOfLightGuide", nLightGuideMat, "Set the material of light guide: 1 = Plexiglass, 2 = Sapphire");
477  fMessenger->DeclareProperty("isASiPM", fIsASiPM, "Set if construct only a SiPM");
478  fMessenger->DeclareProperty("isCosmicRaysDetectors", fIsCosmicRaysDetectors, "Set if the two cosmic rays detector are present");
479 }
480 
481 
482 
484 {
485  // Construct the package of the SIPM
486  G4Box *solidPackageSiPM = new G4Box("solidPackageSiPM", GS::halfXsidePackageSiPM, GS::halfYsidePackageSiPM, GS::halfZsidePackageSiPM);
487  logicPackageSiPM = new G4LogicalVolume(solidPackageSiPM, fFR4, "logicPackageSiPM");
488 
489  // Construct the window of the SIPM and put it inside the package
490  G4Box *solidWindowSiPM = new G4Box("solidWindowSiPM", GS::halfXsideWindowSiPM, GS::halfYsideWindowSiPM, GS::halfZsideWindowSiPM);
491  logicWindowSiPM = new G4LogicalVolume(solidWindowSiPM, fEpoxy, "logicWindowSiPM");
492  G4VPhysicalVolume *physWindowSiPM = new G4PVPlacement(0, G4ThreeVector(GS::xWindowSiPM, GS::yWindowSiPM, GS::zWindowSiPM), logicWindowSiPM, "physWindowSiPM", logicPackageSiPM, false, 0, true);
493 
494  // Construct the silicon layer and put it inside the window
495  G4Box *solidDetector = new G4Box("solidDetector", GS::halfXsideDetector, GS::halfYsideDetector, GS::halfZsideDetector);
496  logicDetector = new G4LogicalVolume(solidDetector, fSilicon, "logicDetector");
497  G4VPhysicalVolume *physDetector = new G4PVPlacement(0, G4ThreeVector(GS::xDetector, GS::yDetector, GS::zDetector), logicDetector, "physDetector", logicWindowSiPM, false, 0, true);
498 
499  new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logicPackageSiPM, "aSiPM", logicWorld, false, 0, true);
500 
501 
502  // Vis attributes
503  // World
504  G4VisAttributes *visWorld = new G4VisAttributes();
505  visWorld->SetVisibility(false);
506  logicWorld->SetVisAttributes(visWorld);
507 
508  // SiPM packages
509  G4VisAttributes *visPackage = new G4VisAttributes();
510  visPackage->SetColour(1, 1, 0, 0.7);
511  logicPackageSiPM->SetVisAttributes(visPackage);
512 
513  // SiPM windows
514  G4VisAttributes *visWindow = new G4VisAttributes();
515  visWindow->SetColour(1, 1, 1, 0.7);
516  logicWindowSiPM->SetVisAttributes(visWindow);
517 
518  // SiPM silicon layers
519  G4VisAttributes *visDetector = new G4VisAttributes();
520  visDetector->SetColour(0.45, 0.25, 0, 0.7);
521  logicDetector->SetVisAttributes(visDetector);
522 }
523 
524 
525 
526 void MyDetectorConstruction::ConstructCosmicRaysDetectors()
527 {
528  G4Box *solidCosmicRaysDetector = new G4Box("solidCosmicRaysDetector", GS::halfZXsideCosmicRayDetector, GS::halfYsideCosmicRayDetector, GS::halfZXsideCosmicRayDetector);
529  logicCosmicRaysDetector = new G4LogicalVolume(solidCosmicRaysDetector, fAir, "logicCosmicRaysDetector");
530  G4VPhysicalVolume *physUpCosmicRaysDetector = new G4PVPlacement(0, G4ThreeVector(GS::xCosmicRayDetector, GS::yCosmicRayDetector, GS::zCosmicRayDetector), logicCosmicRaysDetector, "physUpCosmicRaysDetector", logicWorld, false, 0, true);
531  G4VPhysicalVolume *physBottomCosmicRaysDetector = new G4PVPlacement(0, G4ThreeVector(GS::xCosmicRayDetector, -GS::yCosmicRayDetector, GS::zCosmicRayDetector), logicCosmicRaysDetector, "physBottomCosmicRaysDetector", logicWorld, false, 1, true);
532 
533  fCosmicTriggerVolume = logicCosmicRaysDetector;
534 }
MyDetectorConstruction()
Constructor of the class.
Definition: construction.cc:7
void ConstructASiPM()
Auxiliary function called by Construct() for building only one SiPM.
void DefineVisAttributes()
Defines the visualization attributes for every component of the apparatus.
G4LogicalVolume * fScoringVolume
Pointer used to define the logical volume of the scoring volume. In the application it is assigned to...
void ConstructGrease()
Auxiliary function called by Construct() for building the optical grease.
G4LogicalVolume * logicGrease
Pointer to optical grease logical volume.
Definition: construction.hh:99
G4LogicalVolume * logicPCB
Pointer to PCB logical volume.
Definition: construction.hh:96
G4Material * fLYSO
Pointer to the LYSO material.
G4int nLightGuideMat
Indicates which material has to be used for light guides; 1 for plexiglass, 2 for sapphire.
G4Material * fAir
Pointer to the air material.
G4LogicalVolume * logicWorld
Pointer to world logical volume.
Definition: construction.hh:90
G4LogicalVolume * logicScintillator
Pointer to crystal logical volume.
Definition: construction.hh:91
G4LogicalVolume * logicDetector
Pointer to silicon layer of SiPM logical volume.
Definition: construction.hh:94
G4Material * fEpoxy
Pointer to the epoxy material.
G4LogicalVolume * logicCoating
Pointer to coating logical volume.
Definition: construction.hh:95
G4Material * fSapphire
Pointer to the sapphire material.
G4Material * fPlexiglass
Pointer to the plexiglass material.
G4bool fIsLightGuide
Flag indicating whether the light guides must be constructed.
G4LogicalVolume * logicPackageSiPM
Pointer to SiPM package logical volume.
Definition: construction.hh:92
G4Material * fFR4
Pointer to the FR4 material.
G4bool fIsEndcap
Flag indicating whether the endcaps must be constructed.
G4Material * fVacuum
Pointer to the vacuum material.
G4LogicalVolume * logicWindowSiPM
Pointer to SiPM window logical volume.
Definition: construction.hh:93
G4Material * fGrease
Pointer to the optical grease material.
G4LogicalVolume * logicEndcap
Pointer to endcap logical volume.
Definition: construction.hh:97
G4GenericMessenger * fMessenger
Generic messenger of the class.
void DefineCommands()
Defines new user commands for detector construction.
void ConstructEndcap()
Auxiliary function called by Construct() for building the endcaps.
void ConstructLightGuide()
Auxiliary function called by Construct() for building the lightguides.
void ConstructPCB()
Auxiliary function called by Construct() for building the PCBs.
G4LogicalVolume * logicLightGuide
Pointer to light guide logical volume.
Definition: construction.hh:98
void PositionSiPMs(G4VPhysicalVolume *physFrontSiPM, G4VPhysicalVolume *physBackSiPM, G4int row, G4int col, G4int index)
Auxiliary function called by Construct() for putting in the right position every SiPM.
G4bool fIsOpticalGreaseSurface
Flag indicating whether the optical grease surface must be constructed.
G4Material * fSilicon
Pointer to the silicon material.
G4Material * fCarbonFiber
Pointer to the carbon fiber material.
void ConstructSDandField() override
It sets all the SiPMs' silicon layers as sensitive detectors.
G4VPhysicalVolume * Construct() override
Construct the detector geometry.
G4bool fIsPCB
Flag indicating whether the PCBs must be constructed.
G4OpticalSurface * fOpGreaseSurface
Pointer to the optical grease surface.
G4bool fIsGrease
Flag indicating whether the optical grease must be constructed.
G4bool fIsASiPM
Flag indicating whether only one SiPM must be constructed.
void DefineMaterials()
Defines all materials.
Definition: construction.cc:26
Concrete class of G4VSensitiveDetector, representing the detector (i.e. the SiPM).
Definition: detector.hh:28
Declaration of the class MyDetectorConstruction.
constexpr G4double zScintillator
z-position of the scintillator crystal.
constexpr G4double halfYsideDetector
Half the y-side length of the SiPM silicon layer.
constexpr G4double depthHole
Depth of the holes drilled in the light guide.
constexpr G4double halfXsideWindowSiPM
Half the x-side length of the SiPM window.
constexpr G4double zWindowSiPM
z-position of the SiPM window referring to package center.
constexpr G4double halfXsidePackageSiPM
Half the x-side length of the SiPM package.
constexpr G4double halfheightPCB
Half the height of the PCB.
constexpr G4double halfXsideDetector
Half the x-side length of the SiPM silicon layer.
constexpr G4double halfZsideWindowSiPM
Half the z-side length of the SiPM window.
constexpr G4double zDetector
z-position of the SiPM silicon layer referring to window center.
constexpr G4double radiusScintillator
Radius of the scintillator crystal.
constexpr G4double zBackFaceScintillator
z-position of the back face of the scintillator crystal.
constexpr G4double halfheightGrease
Half the height of the optical grease layer.
constexpr G4double zFrontFaceScintillator
z-position of the front face of the scintillator crystal.
constexpr G4double halfZsidePackageSiPM
Half the z-side length of the SiPM package.
constexpr G4double halfheightLightGuide
Half the height of the light guide.
constexpr G4double xScintillator
x-position of the scintillator crystal.
constexpr G4double yWindowSiPM
y-position of the SiPM window referring to package center.
constexpr G4double radiusLightGuide
Radius of the light guide.
constexpr G4double halfheightScintillator
Half the height of the scintillator crystal.
constexpr G4double halfYsidePackageSiPM
Half the y-side length of the SiPM package.
constexpr G4double halfYsideWorld
Half the y-side length of the world volume.
constexpr G4double halfYsideWindowSiPM
Half the y-side length of the SiPM window.
constexpr G4double coating_space
Space between the crystal and the coating around it.
constexpr G4double halfheightEndcap
Half the height of the endcap.
constexpr G4double xWindowSiPM
x-position of the SiPM window referring to package center.
constexpr G4double xDetector
x-position of the SiPM silicon layer referring to window center.
constexpr G4double coating_thickness
Thickness of the cylindrical coating.
constexpr G4int nOfSiPMs
The number of SiPMs on a detector face.
constexpr G4double halfZsideWorld
Half the z-side length of the world volume.
constexpr G4double yDetector
y-position of the SiPM silicon layer referring to window center.
constexpr G4double halfZsideDetector
Half the z-side length of the SiPM silicon layer.
constexpr G4double radiusPCB
Radius of the Printed Circuit Board (PCB).
constexpr G4double halfXsideWorld
Half the x-side length of the world volume.
constexpr G4double yScintillator
y-position of the scintillator crystal.
constexpr G4double radiusHole
Radius of the holes drilled in the light guide.
constexpr G4double radiusEndcap
Radius of the endcap.