ACTARSim
ACTAR TPC Simulation Reference Guide
ActarSimSilDetectorConstruction.cc
Go to the documentation of this file.
1 // - AUTHOR: Hector Alvarez-Pol 04/2008
2 /******************************************************************
3  * Copyright (C) 2005-2016, Hector Alvarez-Pol *
4  * All rights reserved. *
5  * *
6  * License according to GNU LESSER GPL (see lgpl-3.0.txt). *
7  * For the list of contributors see CREDITS. *
8  ******************************************************************/
9 //////////////////////////////////////////////////////////////////
10 /// \class ActarSimSilDetectorConstruction
11 /// Silicon detector description
12 /////////////////////////////////////////////////////////////////
13 
18 #include "ActarSimROOTAnalysis.hh"
19 #include "ActarSimSilSD.hh"
20 
21 #include "G4Material.hh"
22 #include "G4Box.hh"
23 #include "G4Cons.hh"
24 #include "G4LogicalVolume.hh"
25 #include "G4PVPlacement.hh"
26 #include "G4RotationMatrix.hh"
27 #include "G4VisAttributes.hh"
28 #include "G4Colour.hh"
29 #include "G4RunManager.hh"
30 #include "G4Transform3D.hh"
31 
32 #include "G4PhysicalConstants.hh"
33 #include "G4SystemOfUnits.hh"
34 
35 #include "globals.hh"
36 
37 //////////////////////////////////////////////////////////////////
38 /// Constructor. Sets the material and the pointer to the Messenger
41  : silBulkMaterial(0),detConstruction(det) {
42  SetSilBulkMaterial("Silicon");
43 
44  //Options for Silicon and scintillator coverage:
45  // 6 bits to indicate which sci wall is present (1) or absent (0)
46  // order is:
47  // bit1 (lsb) beam output wall
48  // bit2 lower (gravity based) wall
49  // bit3 upper (gravity based) wall
50  // bit4 left (from beam point of view) wall
51  // bit5 right (from beam point of view) wall
52  // bit6 (msb) beam entrance wall
53  SetSideCoverage(1);
54 
55  SetXBoxSilHalfLength(100*cm);
56  SetYBoxSilHalfLength(100*cm);
57  SetZBoxSilHalfLength(100*cm);
58 
59  // create commands for interactive definition of the calorimeter
61 }
62 
63 //////////////////////////////////////////////////////////////////
64 /// Destructor.
66  delete silMessenger;
67 }
68 
69 
70 //////////////////////////////////////////////////////////////////
71 /// Wrap for the construction function within the Silicon
72 G4VPhysicalVolume* ActarSimSilDetectorConstruction::Construct(G4LogicalVolume* chamberLog) {
73  //Introduce here other constructors for materials around the TOF (windows, frames...)
74  //which can be controlled by the calMessenger
75  //ConstructTOFWorld(chamberLog);
76  return ConstructSil(chamberLog);
77 }
78 
79 //////////////////////////////////////////////////////////////////
80 /// Constructs the scintillator detector elements
81 ///
82 /// - Introduce Silicon and CsI(Tl) detectors all around. Use MUST style:
83 /// Si: 300 microns thick, 100x100mm2, with 128 strides per side
84 /// (horizontal on one side and vertical in the opposite).
85 /// CsI(Tl): 25x25mm2, 30mm thick, so 16 per Silicon detector.
86 /// <pre>
87 /// < -- 50mm -- >
88 /// ------ -- | x
89 /// | | || | x wires shaping the field
90 /// | | || | x
91 /// |CsI | || | x
92 /// | | || | x
93 /// ------ -- | Gas x Gas
94 /// Si | x
95 /// | x
96 /// Al layer (~1 microm)
97 /// </pre>
98 G4VPhysicalVolume* ActarSimSilDetectorConstruction::ConstructSil(G4LogicalVolume* chamberLog) {
99  //MUST-like silicon detectors (half-sides)
100  //I left some "air" in between silicons. Half-length are defectHalfLength shorter.
101  // G4double silBulk_x = 49.5*mm;
102  // G4double silBulk_y = 49.5*mm;
103  // G4double silBulk_z = 0.15*mm;
104 
105  G4double silBulk_x = 24.5*mm;
106  G4double silBulk_y = 24.5*mm;
107  G4double silBulk_z = 0.3575*mm;
108 
109  G4double silDSSDBulk_x = 31.5*mm;
110  G4double silDSSDBulk_y = 31.5*mm;
111  G4double silDSSDBulk_z = 0.75*mm;
112 
113  G4double defectHalfLength = 0.5*mm;
114  G4double separationFromBox = 3*mm;
115 
116  // Printing the final settings...
117  G4cout << "##################################################################"
118  << G4endl
119  << "########### ActarSimSilDetectorConstruction::ConstructSil() #########"
120  << G4endl
121  << " Note that only a thin (1 micron) Al window is defined in front "
122  << G4endl
123  << " of the silicons. No other box around the silicon volume is described."
124  << G4endl
125  << " MAYA detector characteristics: "
126  << G4endl
127  << " x dimension (half-side) of silicon: " << silBulk_x/mm << " mm"
128  << G4endl
129  << " y dimension (half-side) of silicon: " << silBulk_y/mm << " mm"
130  << G4endl
131  << " z dimension (half-side) of silicon: " << silBulk_z/mm << " mm"
132  << G4endl
133  << " DSSD detector characteristics: "
134  << G4endl
135  << " x dimension (half-side) of silicon: " << silDSSDBulk_x/mm << " mm"
136  << G4endl
137  << " y dimension (half-side) of silicon: " << silDSSDBulk_y/mm << " mm"
138  << G4endl
139  << " z dimension (half-side) of silicon: " << silDSSDBulk_z/mm << " mm"
140  << G4endl
141  << " Detector material: "
142  << silBulkMaterial
143  << G4endl;
144  G4cout << "##################################################################"
145  << G4endl;
146 
147  G4LogicalVolume* silLog(0);
148  G4VPhysicalVolume* silPhys(0);
149 
150  G4Box* silBox =
151  new G4Box("silBox", silBulk_x, silBulk_y, silBulk_z);
152 
153  silLog =
154  new G4LogicalVolume(silBox, silBulkMaterial, "silLog");
155 
156  //DSSD detector
157  G4LogicalVolume* silDSSDLog(0);
158  G4VPhysicalVolume* silDSSDPhys(0);
159 
160  G4Box* silDSSDBox =
161  new G4Box("silDSSDBox", silDSSDBulk_x, silDSSDBulk_y, silDSSDBulk_z);
162 
163  silDSSDLog =
164  new G4LogicalVolume(silDSSDBox, silBulkMaterial, "silDSSDLog");
165 
166  //As a function of the lateral coverage
167  // 6 bits to indicate which sci wall is present (1) or absent (0)
168  // order is:
169  // bit1 (lsb) beam output wall
170  // bit2 lower (gravity based) wall
171  // bit3 upper (gravity based) wall
172  // bit4 left (from beam point of view) wall
173  // bit5 right (from beam point of view) wall
174  // bit6 (msb) beam entrance wall
175 
176  //for the moment, let's assume square silicon...
177  //if not, more sophisticated approach needed!
178  G4int numberOfRowsX = ((G4int) (2*xBoxSilHalfLength/(2*(silBulk_x+defectHalfLength)))) - 1;
179  if( (numberOfRowsX+1)*silBulk_x < 2*xBoxSilHalfLength ) numberOfRowsX++;
180  G4int numberOfRowsY = ((G4int) (2*yBoxSilHalfLength/(2*(silBulk_x+defectHalfLength)))) - 1;
181  if( (numberOfRowsY+1)*silBulk_x < 2*yBoxSilHalfLength ) numberOfRowsY++;
182  G4int numberOfRowsZ = ((G4int) (2*zBoxSilHalfLength/(2*(silBulk_x+defectHalfLength)))) - 1;
183  if( (numberOfRowsZ+1)*silBulk_x < 2*zBoxSilHalfLength ) numberOfRowsZ++;
184 
185  //G4cout << numberOfRowsX << " " << numberOfRowsY << " " << numberOfRowsZ << G4endl;
186 
187  G4int iterationNumber = 0;
188 
189  //By a reason I do not know the correct rotation using Euler angles does not match with standards...
190  // I would call rotLeft to rotTop, and so on...
191  G4RotationMatrix* rotBack = //beam entrance
192  new G4RotationMatrix(0,pi,pi); //if y direction is up and x is right
193  //new G4RotationMatrix(0,pi,0); //if x direction is left and y down
194  G4RotationMatrix* rotBottom = //ZX planes (bottom)
195  new G4RotationMatrix(0,pi/2,0);
196  G4RotationMatrix* rotTop = //ZX planes (top)
197  new G4RotationMatrix(0,-pi/2,0);
198  G4RotationMatrix* rotLeft = //ZY planes
199  new G4RotationMatrix(pi/2,pi/2,-pi/2);
200  G4RotationMatrix* rotRight = //ZY planes
201  new G4RotationMatrix(-pi/2,pi/2,pi/2);
202 
203  // G4int checker = sideCoverage;
204  /*
205  G4PVPlacement(G4RotationMatrix *pRot,
206  const G4ThreeVector &tlate,
207  G4LogicalVolume *pCurrentLogical,
208  const G4String& pName,
209  G4LogicalVolume *pMotherLogical,
210  G4bool pMany,
211  G4int pCopyNo,
212  G4bool pSurfChk=false);
213  // Initialise a single volume, positioned in a frame which is rotated by
214  // *pRot and traslated by tlate, relative to the coordinate system of the
215  // mother volume pMotherLogical.
216  // If pRot=0 the volume is unrotated with respect to its mother.
217  // The physical volume is added to the mother's logical volume.
218  // Arguments particular to G4PVPlacement:
219  // pMany Currently NOT used. For future use to identify if the volume
220  // is meant to be considered an overlapping structure, or not.
221  // pCopyNo should be set to 0 for the first volume of a given type.
222  // pSurfChk if true activates check for overlaps with existing volumes.
223  // This is a very natural way of defining a physical volume, and is
224  // especially useful when creating subdetectors: the mother volumes are
225  // not placed until a later stage of the assembly program.
226  */
227 
228  // if(!gasDetector) {
230  //ActarSimGasDetectorConstruction gasDetector = detConstruction->GetGasDetector();
231  G4double xGasBox = gasDetector->GetGasBoxSizeX();
232  G4double zGasBox = gasDetector->GetGasBoxSizeZ();
233  // }
234 
235 
236  //An aluminium plate to see the Pads active area
237  //G4double plateSizeX = 32*mm;
238  //G4double plateSizeY = yPadSize/2*mm;
239  //G4double layerSizeZ = 0.00015*mm;
240  G4double layerSizeZ = 0.00012*mm;//I don't have the size of strips so I assume it is 80% of the pitch
241  G4double z,a,density;
242 
243  G4Box *DSSD_Al_Layer=new G4Box("DSSD_Al_layer",silDSSDBulk_x,silDSSDBulk_y,layerSizeZ);
244  //G4Box *MAYA_Al_Layer=new G4Box("MAYA_Al_layer",silBulk_x,silBulk_y,layerSizeZ);
245 
246  G4Material* Al =
247  new G4Material("Aluminum", z= 13., a= 26.98*g/mole, density= 2.7*g/cm3);
248 
249  G4LogicalVolume* DSSD_Al_LayerLog=new G4LogicalVolume(DSSD_Al_Layer,Al,"DSSD_Al_layer");
250  //G4LogicalVolume* MAYA_Al_LayerLog=new G4LogicalVolume(MAYA_Al_Layer,Al,"MAYA_Al_layer");
251 
252  G4int DSSDAlIterationNumber = 0;
253  //G4int MAYAAlIterationNumber = 0;
254 
255  // AlLayerPhys=new G4PVPlacement(0,G4ThreeVector( platePosX,platePosY,platePosZ),
256  // AlLayerLog,"Al_layer",chamberLog,false,0);
257 
258  if(sideCoverage & 0x0001){ // bit1 (lsb) beam output wall
259  //iteration on Silicon elements
260  /*
261  for(G4int rowX=0;rowX<numberOfRowsX;rowX++){ //maybe is rowX=1 the first??
262  for(G4int rowY=0;rowY<numberOfRowsY;rowY++){
263  iterationNumber++;
264  silPhys =
265  new G4PVPlacement(0,G4ThreeVector(-xBoxSilHalfLength + ((rowX+1)*2-1)*(silBulk_x+defectHalfLength),
266  -yBoxSilHalfLength + ((rowY+1)*2-1)*(silBulk_x+defectHalfLength),
267  2*zBoxSilHalfLength + separationFromBox + silBulk_z),
268  silLog, "silPhys", chamberLog, false, iterationNumber);
269  }
270  }
271  */
272 
273  for(G4int rowX=0;rowX<2;rowX++){ //maybe is rowX=1 the first??
274  for(G4int rowY=0;rowY<2;rowY++){
275  /*
276  iterationDSSDNumber++;
277  silDSSDPhys =
278  new G4PVPlacement(0,G4ThreeVector( (rowX-0.5)*2*(silDSSDBulk_x+defectHalfLength),
279  (rowY-0.5)*2*(silDSSDBulk_x+defectHalfLength),
280  //2*zBoxSilHalfLength + separationFromBox + silBulk_z),
281  zBoxSilHalfLength - separationFromBox - silDSSDBulk_z),
282  silDSSDLog, "silDSSDPhys", chamberLog, false, iterationDSSDNumber);
283  */
284  iterationNumber++;
285  silPhys =
286  new G4PVPlacement(0,G4ThreeVector( (rowX-0.5)*2*(silDSSDBulk_x+defectHalfLength),
287  (rowY-0.5)*2*(silDSSDBulk_x+defectHalfLength),
288  //zBoxSilHalfLength - separationFromBox - silDSSDBulk_z),
289  zGasBox + zBoxSilHalfLength),
290  silDSSDLog, "silPhys", chamberLog, false, iterationNumber);
291 
292  DSSDAlIterationNumber++;
293  //Al Layers
294  DSSD_Al_LayerPhys = new G4PVPlacement(0,G4ThreeVector( (rowX-0.5)*2*(silDSSDBulk_x+defectHalfLength),
295  (rowY-0.5)*2*(silDSSDBulk_x+defectHalfLength),
296  zGasBox + zBoxSilHalfLength - (silDSSDBulk_z+layerSizeZ)),
297  DSSD_Al_LayerLog,"DSSD_Al_layer",chamberLog,false,DSSDAlIterationNumber);
298 
299  DSSDAlIterationNumber++;
300  DSSD_Al_LayerPhys = new G4PVPlacement(0,G4ThreeVector( (rowX-0.5)*2*(silDSSDBulk_x+defectHalfLength),
301  (rowY-0.5)*2*(silDSSDBulk_x+defectHalfLength),
302  zGasBox + zBoxSilHalfLength + (silDSSDBulk_z+layerSizeZ)),
303  DSSD_Al_LayerLog,"DSSD_Al_layer",chamberLog,false,DSSDAlIterationNumber);
304 
305  }
306  }
307 
308  /*
309  iterationNumber++;
310  silPhys =
311  new G4PVPlacement(0,G4ThreeVector(0,
312  0,
313  2*zBoxSilHalfLength + separationFromBox + silBulk_z),
314  silLog, "silPhys", chamberLog, false, iterationNumber);
315  */
316  }
317 
318  //PLANES ZX
319  //a different rotation has to be introduced on each side...
320  if((sideCoverage >> 1) & 0x0001){ // bit2 lower [bottom] (gravity based) wall
321  for(G4int rowZ=0;rowZ<numberOfRowsZ;rowZ++){
322  for(G4int rowX=0;rowX<numberOfRowsX;rowX++){
323  iterationNumber++;
324  silPhys =
325  new G4PVPlacement(rotBottom,G4ThreeVector(-xBoxSilHalfLength + ((rowX+1)*2-1)*(silBulk_x+defectHalfLength),
326  -(yBoxSilHalfLength + separationFromBox + silBulk_z),
327  ((rowZ+1)*2-1)*(silBulk_x+defectHalfLength)),
328  silLog, "silPhys", chamberLog, false, iterationNumber);
329  }
330  }
331  }
332  if((sideCoverage >> 2) & 0x0001){ // bit3 upper [top] (gravity based) wall
333  for(G4int rowZ=0;rowZ<numberOfRowsZ;rowZ++){
334  for(G4int rowX=0;rowX<numberOfRowsX;rowX++){
335  iterationNumber++;
336  silPhys =
337  new G4PVPlacement(rotTop,G4ThreeVector(-xBoxSilHalfLength + ((rowX+1)*2-1)*(silBulk_x+defectHalfLength),
338  yBoxSilHalfLength + separationFromBox + silBulk_z,
339  ((rowZ+1)*2-1)*(silBulk_x+defectHalfLength)),
340  silLog, "silPhys", chamberLog, false, iterationNumber);
341  }
342  }
343  }
344 
345  //PLANES ZY
346  if((sideCoverage >> 3) & 0x0001){ // bit4 left (from beam point of view) wall
347 
348  for(G4int rowZ=0;rowZ<3;rowZ++){
349  for(G4int rowY=0;rowY<2;rowY++){
350  iterationNumber++;
351  silPhys =
352  //new G4PVPlacement(rotLeft,G4ThreeVector(xBoxSilHalfLength - separationFromBox - silBulk_z,
353  new G4PVPlacement(rotLeft,G4ThreeVector(xGasBox + xBoxSilHalfLength,
354  (rowY-0.5)*2*(silBulk_y+defectHalfLength),
355  (rowZ-1)*2*(silBulk_x+defectHalfLength)),
356  silLog, "silPhys", chamberLog, false, iterationNumber);
357  /*
358  MAYAAlIterationNumber++;
359  //Al Layers
360  MAYA_Al_LayerPhys
361  =new G4PVPlacement(rotLeft,G4ThreeVector(xGasBox + xBoxSilHalfLength - (silBulk_z+layerSizeZ),
362  (rowY-0.5)*2*(silBulk_y+defectHalfLength),
363  (rowZ-1)*2*(silBulk_x+defectHalfLength)),
364  MAYA_Al_LayerLog,"MAYA_Al_layer",chamberLog,false,MAYAAlIterationNumber);
365  */
366  }
367  }
368  }
369 
370  if((sideCoverage >> 4) & 0x0001){ // bit5 right (from beam point of view) wall
371  /*
372  iterationNumber++;
373  silPhys = new G4PVPlacement(rotRight,G4ThreeVector(-(xBoxSilHalfLength - separationFromBox - silBulk_z),
374  0,
375  0),
376  silLog, "silPhys", chamberLog, false, iterationNumber);
377  */
378  for(G4int rowZ=0;rowZ<3;rowZ++){
379  for(G4int rowY=0;rowY<2;rowY++){
380  iterationNumber++;
381  silPhys =
382  //new G4PVPlacement(rotRight,G4ThreeVector(-(xBoxSilHalfLength - separationFromBox - silBulk_z),
383  new G4PVPlacement(rotRight,G4ThreeVector(-(xGasBox + xBoxSilHalfLength),
384  (rowY-0.5)*2*(silBulk_y+defectHalfLength),
385  (rowZ-1)*2*(silBulk_x+defectHalfLength)),
386  silLog, "silPhys", chamberLog, false, iterationNumber);
387  /*
388  MAYAAlIterationNumber++;
389  //Al Layers
390  MAYA_Al_LayerPhys
391  =new G4PVPlacement(rotRight,G4ThreeVector(-(xGasBox + xBoxSilHalfLength) + (silBulk_z+layerSizeZ),
392  (rowY-0.5)*2*(silBulk_y+defectHalfLength),
393  (rowZ-1)*2*(silBulk_x+defectHalfLength)),
394  MAYA_Al_LayerLog,"MAYA_Al_layer",chamberLog,false,MAYAAlIterationNumber);
395  */
396  }
397  }
398  }
399 
400  if((sideCoverage >> 5) & 0x0001){ // bit6 (msb) beam entrance wall
401  for(G4int rowX=0;rowX<numberOfRowsX;rowX++){
402  for(G4int rowY=0;rowY<numberOfRowsY;rowY++){
403  iterationNumber++;
404  silPhys =
405  new G4PVPlacement(rotBack,G4ThreeVector(-xBoxSilHalfLength + ((rowX+1)*2-1)*(silBulk_y+defectHalfLength),
406  -yBoxSilHalfLength + ((rowY+1)*2-1)*(silBulk_x+defectHalfLength),
407  -separationFromBox - silBulk_z),
408  silLog, "silPhys", chamberLog, false, iterationNumber);
409  }
410  }
411  }
412 
413  //------------------------------------------------
414  // Sensitive detectors
415  //------------------------------------------------
416  silLog->SetSensitiveDetector( detConstruction->GetSilSD() );
417  silDSSDLog->SetSensitiveDetector( detConstruction->GetSilSD() );
418 
419  //------------------------------------------------------------------
420  // Visualization attributes
421  //------------------------------------------------------------------
422  G4VisAttributes* silVisAtt1 = new G4VisAttributes(G4Colour(0,1,0));
423  silVisAtt1->SetVisibility(true);
424  silLog->SetVisAttributes(silVisAtt1);
425  G4VisAttributes* silDSSDVisAtt1 = new G4VisAttributes(G4Colour(0,0.75,0));
426  silDSSDVisAtt1->SetVisibility(true);
427  silDSSDLog->SetVisAttributes(silDSSDVisAtt1);
428 
429  G4VisAttributes* DSSD_Al_LayerVisAtt= new G4VisAttributes(G4Colour(1.0,0.,1.0));
430  DSSD_Al_LayerVisAtt->SetVisibility(false);
431  DSSD_Al_LayerLog->SetVisAttributes(DSSD_Al_LayerVisAtt);
432  /*
433  G4VisAttributes* MAYA_Al_LayerVisAtt= new G4VisAttributes(G4Colour(1.0,0.333,1.0));
434  MAYA_Al_LayerVisAtt->SetVisibility(false);
435  MAYA_Al_LayerLog->SetVisAttributes(MAYA_Al_LayerVisAtt);
436  */
437 
438  return silPhys;
439  return silDSSDPhys;
440 }
441 
442 //////////////////////////////////////////////////////////////////
443 /// Set the material the scintillator bulk is made of
445  G4Material* pttoMaterial = G4Material::GetMaterial(mat);
446  if (pttoMaterial) silBulkMaterial = pttoMaterial;
447 }
448 
449 //////////////////////////////////////////////////////////////////
450 /// Updates Scintillator detector
453  G4RunManager::GetRunManager()->
454  DefineWorldVolume(detConstruction->GetWorldPhysicalVolume());
455 }
456 
457 //////////////////////////////////////////////////////////////////
458 /// Prints Scintillator detector parameters.
460  G4cout << "##################################################################"
461  << G4endl
462  << "#### ActarSimSilDetectorConstruction::PrintDetectorParameters() ####"
463  << G4endl
464  << " The silicon coverage is " << sideCoverage << G4endl
465  << "Reminder: 6 bits to indicate which sil wall is present (1) or absent (0)" << G4endl
466  << "bit1 (lsb) beam output wall, bit2 lower (gravity based) wall" << G4endl
467  << "bit3 upper (gravity based) wall, bit4 left (from beam point of view) wall" << G4endl
468  << "bit5 right (from beam point of view) wall, bit6 (msb) beam entrance wall" << G4endl << G4endl;
469  G4cout << " The silicon material is: " << silBulkMaterial << G4endl;
470  G4cout << " The silicon parameters are: " << G4endl
471  << " xBoxSilHalfLength = " << xBoxSilHalfLength/mm
472  << "mm, yBoxSilHalfLength = " << yBoxSilHalfLength/mm
473  << "mm, zBoxSilHalfLength = " << zBoxSilHalfLength/mm << " mm" << G4endl ;
474  G4cout << "##################################################################"
475  << G4endl;
476 }
G4VPhysicalVolume * ConstructSil(G4LogicalVolume *)
ActarSimDetectorConstruction * detConstruction
Pointer to the global detector.
G4double yBoxSilHalfLength
Silicon box half length along Y (Y is vertical)
G4VPhysicalVolume * Construct(G4LogicalVolume *)
Wrap for the construction function within the Silicon.
ActarSimSilDetectorMessenger * silMessenger
Pointer to the Messenger.
void SetSilBulkMaterial(G4String)
Set the material the scintillator bulk is made of.
ActarSimGasDetectorConstruction * GetGasDetector()
G4Material * silBulkMaterial
Pointer to the material the Silicon is made of.
void PrintDetectorParameters()
Prints Scintillator detector parameters.
void UpdateGeometry()
Updates Scintillator detector.
G4double zBoxSilHalfLength
Silicon box half length along Z (Z is along beam)
G4double xBoxSilHalfLength
Silicon box half length along X (X is horizontal)
ActarSimSilDetectorConstruction(ActarSimDetectorConstruction *)
Constructor. Sets the material and the pointer to the Messenger.