ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4TTLDetector.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4TTLDetector.cc
1 #include "PHG4TTLDetector.h"
2 #include "PHG4TTLDisplayAction.h"
3 
4 #include <g4main/PHG4Detector.h> // for PHG4Detector
5 #include <g4main/PHG4DisplayAction.h> // for PHG4DisplayAction
6 #include <g4main/PHG4Subsystem.h> // for PHG4Subsystem
7 
8 #include <phparameter/PHParameters.h>
9 
10 #include <Geant4/G4Box.hh>
11 #include <Geant4/G4Cons.hh>
12 #include <Geant4/G4LogicalVolume.hh>
13 #include <Geant4/G4PVPlacement.hh>
14 #include <Geant4/G4PVReplica.hh>
15 #include <Geant4/G4RotationMatrix.hh> // for G4RotationMatrix
16 #include <Geant4/G4String.hh> // for G4String
17 #include <Geant4/G4SubtractionSolid.hh>
18 #include <Geant4/G4SystemOfUnits.hh>
19 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
20 #include <Geant4/G4Transform3D.hh> // for G4Transform3D
21 #include <Geant4/G4Trd.hh>
22 #include <Geant4/G4Tubs.hh>
23 #include <Geant4/G4Types.hh> // for G4double, G4int
24 #include <Geant4/G4AssemblyVolume.hh> // for G4double, G4int
25 #include <Geant4/G4NistManager.hh>
26 #include <Geant4/G4RotationMatrix.hh>
27 
28 #include <algorithm> // for max
29 #include <cassert>
30 #include <climits>
31 #include <cmath>
32 #include <iostream>
33 #include <map> // for _Rb_tree_iterator, _Rb_tree_co...
34 #include <sstream>
35 #include <utility> // for pair
36 
37 class G4VPhysicalVolume;
38 class PHCompositeNode;
39 
40 //_______________________________________________________________
41 //note this inactive thickness is ~1.5% of a radiation length
43  : PHG4Detector(subsys, Node, dnam)
44  , name_base(dnam)
45  , m_DisplayAction(dynamic_cast<PHG4TTLDisplayAction *>(subsys->GetDisplayAction()))
46  , m_SteppingAction(0)
47  , m_Params(parameters)
48  , overlapcheck_sector(false)
49 {
50 }
51 
52 //_______________________________________________________________
53 //_______________________________________________________________
55 {
56  for (map_phy_vol_t::const_iterator it = map_active_phy_vol.begin();
57  it != map_active_phy_vol.end(); ++it)
58  {
59  if (physvol == (*it).second)
60  {
61  return true;
62  }
63  }
64 
65  return false;
66 }
67 
68 //_______________________________________________________________
70 {
71  if (m_Params->get_int_param("isForward") == 1)
72  {
73  BuildForwardTTL(logicWorld);
74  }
75  else
76  {
77  BuildBarrelTTL(logicWorld);
78  }
79 }
80 
82 {
83  // MATERIALS
84  G4double density, a;
85  G4int ncomponents, z;
86  G4int natoms;
87  G4String symbol;
88 
91 
93  G4Element *elH = new G4Element("Hydrogen", symbol = "H", 1., 1.01 * g / mole);
94  G4Element *elC = new G4Element("Carbon", symbol = "C", 6., 12.01 * g / mole);
95  G4Element *elN = new G4Element("Nitrogen", symbol = "N", 7., 14.01 * g / mole);
96  G4Element *elO = new G4Element("Oxygen", symbol = "O", 8., 16.00 * g / mole);
97  G4Material *mat_Epoxy = GetDetectorMaterial("EpoxyTTL",false);
98  if (!mat_Epoxy)
99  {
100  mat_Epoxy = new G4Material("EpoxyTTL", density = 1.16 * g / cm3, natoms = 4);
101  mat_Epoxy->AddElement(elH, 32); // Hydrogen
102  mat_Epoxy->AddElement(elN, 2); // Nitrogen
103  mat_Epoxy->AddElement(elO, 4); // Oxygen
104  mat_Epoxy->AddElement(elC, 15); // Carbon
105  // G4Material *mat_Epoxy = GetDetectorMaterial("Epoxy");
106  }
107  G4Material *mat_ALN = GetDetectorMaterial("AluminiumNitrate",false);
108  if (!mat_ALN)
109  {
110  mat_ALN = new G4Material("AluminiumNitrate", density = 3.255 * g / cm3, ncomponents = 2);
111  // G4Material *mat_ALN = new G4Material("AluminiumNitrate", density = 3.255 * g / cm3, ncomponents = 2);
112  mat_ALN->AddElement(G4Element::GetElement("Al"), 1);
113  mat_ALN->AddElement(G4Element::GetElement("N"), 1);
114  }
115  G4Material *mat_Solder_Tin = GetDetectorMaterial("Tin",false);
116  if (!mat_Solder_Tin)
117  {
118  mat_Solder_Tin = new G4Material("Tin", z = 50., a = 118.7 * g / mole, density = 7.310 * g / cm3);
119  }
120  G4Material *Air = GetDetectorMaterial("G4_AIR");
121 
122  // Carbon fiber 190 width + 65 microns scotch , overall 255 microns
123  G4Material *CarbonFiber = new G4Material("CarbonFiber", density = 1.750*g/cm3, ncomponents=2);
124  CarbonFiber->AddMaterial(man->FindOrBuildMaterial("G4_C"), 74.5*perCent); // Carbon
125  CarbonFiber->AddMaterial(mat_Epoxy, 25.50*perCent); // Epoxy (scotch)
126 
127  // positions
128  G4double rCenter = m_Params->get_double_param("rMin"); // center location of Al support plate
129  G4double det_height = 2.1 * cm;
131  G4ThreeVector detzvec(0, 0, place_z);
132  G4double detlength = m_Params->get_double_param("length");
133 
134  //Create the envelope = 'world volume' for the calorimeter
135  G4AssemblyVolume* assemblyDetector = new G4AssemblyVolume();
136 
137  // Single module with length based on readout (contains 14 LGADs [counting across both sides] in x-direction and 6 in z-direction)
138  G4double baseplate_length = 43.1 * mm;
139  G4double baseplate_width = 56.5 * mm / 2;
140  G4double segmentlength = 6 * baseplate_length; //(detlength - 10 * cm) / 6;//m_Params->get_double_param("length");
141 
142  G4VSolid *sol_module_envelope = new G4Trd("sol_module_envelope",
143  sin(M_PI / 12.) * (rCenter-det_height/2), sin(M_PI / 12.) * (rCenter + det_height/2),
144  segmentlength / 2, segmentlength / 2,
145  (det_height*1.001) / 2);
146 
147  G4LogicalVolume *log_module_envelope = new G4LogicalVolume(sol_module_envelope, Air, "log_module_envelope");
148 
149  G4double diameter_coolingtube = 5 * mm;
150  G4double cooling_plate_height = 1 * mm;
151  G4VSolid *sol_cooling_plate_top = new G4Box("sol_cooling_plate_top",
152  sin(M_PI / 12.) * (rCenter + diameter_coolingtube / 2 ),
153  segmentlength / 2,
154  cooling_plate_height / 2);
155  G4VSolid *sol_cooling_plate_bottom = new G4Box("sol_cooling_plate_top",
156  sin(M_PI / 12.) * (rCenter - diameter_coolingtube / 2 - cooling_plate_height),
157  segmentlength / 2,
158  cooling_plate_height / 2);
159  // std::cout << "top plate: " << sin(M_PI / 12.) * (rCenter + diameter_coolingtube / 2 + cooling_plate_height / 2) << std::endl;
160  // std::cout << "bottom plate: " << sin(M_PI / 12.) * (rCenter - diameter_coolingtube / 2 - cooling_plate_height / 2) << std::endl;
161  G4LogicalVolume *log_cooling_plate_top = new G4LogicalVolume(sol_cooling_plate_top, GetDetectorMaterial("G4_Al"), "log_cooling_plate_barrel_top");
162  G4LogicalVolume *log_cooling_plate_bottom = new G4LogicalVolume(sol_cooling_plate_bottom, GetDetectorMaterial("G4_Al"), "log_cooling_plate_barrel_bottom");
163 
164  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, 0, diameter_coolingtube/2+cooling_plate_height/2), log_cooling_plate_top,
165  "physical_cooling_plate_top", log_module_envelope, false, 0, overlapcheck_sector),false);
166  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, 0, -(diameter_coolingtube/2+cooling_plate_height/2)), log_cooling_plate_bottom,
167  "physical_cooling_plate_bottom", log_module_envelope, false, 0, overlapcheck_sector),false);
168  RegisterLogicalVolume(log_cooling_plate_top);
169  RegisterLogicalVolume(log_cooling_plate_bottom);
170  m_DisplayAction->AddVolume(log_cooling_plate_top, "CoolingPlate");
171  m_DisplayAction->AddVolume(log_cooling_plate_bottom, "CoolingPlate");
172 
173  G4double wallthickness_coolingtube = 1 * mm;
174  G4VSolid *sol_cutout_tube = new G4Box("sol_cutout_tube",
175  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
176  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
177  (segmentlength * 1.1) / 2);
178  G4VSolid *sol_cooling_tube = new G4Box("sol_cooling_tube_tmp",
179  diameter_coolingtube / 2,
180  diameter_coolingtube / 2,
181  (segmentlength - 0.2 * mm) / 2);
182  sol_cooling_tube = new G4SubtractionSolid(G4String("sol_cooling_tube"), sol_cooling_tube, sol_cutout_tube, 0, G4ThreeVector(0,0,0));
183 
184  G4LogicalVolume *Log_cooling_tube = new G4LogicalVolume(sol_cooling_tube, GetDetectorMaterial("G4_Al"), "Log_cooling_tube");
185  RegisterLogicalVolume(Log_cooling_tube);
186  m_DisplayAction->AddVolume(Log_cooling_tube, "Cooling_tube");
187 
188  G4VSolid *sol_water_cooling = new G4Box("sol_water_cooling",
189  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
190  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
191  (segmentlength - 0.2 * mm) / 2);
192  G4LogicalVolume *Log_water_cooling = new G4LogicalVolume(sol_water_cooling, //
193  GetDetectorMaterial("G4_WATER"), "Log_water_cooling");
194  RegisterLogicalVolume(Log_water_cooling);
195  m_DisplayAction->AddVolume(Log_water_cooling, "Water_cooling");
196 
197  G4VSolid *sol_internal_support_center = new G4Box("sol_internal_support_center",
198  (1.5 * baseplate_width - diameter_coolingtube)/2,
199  diameter_coolingtube / 2,
200  (2* mm) / 2);
201 
202  G4LogicalVolume *Log_internal_support_center = new G4LogicalVolume(sol_internal_support_center, CarbonFiber, "Log_internal_support_center");
203  RegisterLogicalVolume(Log_internal_support_center);
204  m_DisplayAction->AddVolume(Log_internal_support_center, "Carbon_Support");
205  G4VSolid *sol_internal_support_edge = new G4Box("sol_internal_support_edge",
206  (1.5 * baseplate_width - diameter_coolingtube - baseplate_width / 3)/2,
207  diameter_coolingtube / 2,
208  (2* mm) / 2);
209 
210  G4LogicalVolume *Log_internal_support_edge = new G4LogicalVolume(sol_internal_support_edge, CarbonFiber, "Log_internal_support_edge");
211  RegisterLogicalVolume(Log_internal_support_edge);
212  m_DisplayAction->AddVolume(Log_internal_support_edge, "Carbon_Support");
213 
214 
215  G4RotationMatrix *rotcooling = new G4RotationMatrix();
216  rotcooling->rotateX(M_PI / 2);
217  G4double leftedgeCU = sin(M_PI / 12.) * (rCenter + det_height / 2 + cooling_plate_height / 2);
218  int maxicup = 9;
219  for (int icup = 0; icup < maxicup; icup++)
220  {
221  G4double edgeshift = 0;
222  if (icup == 0) edgeshift = baseplate_width / 3;
223  if (icup == (maxicup - 1)) edgeshift = -baseplate_width / 3;
224  RegisterPhysicalVolume(new G4PVPlacement(rotcooling, G4ThreeVector(-leftedgeCU + icup * 1.5 * baseplate_width + edgeshift, 0, 0), Log_cooling_tube,
225  "cooling_tube_Physical_" + std::to_string(icup), log_module_envelope, false, 0, overlapcheck_sector), false);
226  RegisterPhysicalVolume(new G4PVPlacement(rotcooling, G4ThreeVector(-leftedgeCU + icup * 1.5 * baseplate_width + edgeshift, 0, 0), Log_water_cooling,
227  "water_cooling_Physical_" + std::to_string(icup), log_module_envelope, false, 0, overlapcheck_sector), false);
228  if(icup!=0 && icup<(maxicup-2)){
229  RegisterPhysicalVolume(new G4PVPlacement(rotcooling, G4ThreeVector(-leftedgeCU + icup * 1.5 * baseplate_width + edgeshift + 0.75*baseplate_width, 0, 0), Log_internal_support_center,
230  "internal_support_center_" + std::to_string(icup), log_module_envelope, false, 0, overlapcheck_sector), false);
231  RegisterPhysicalVolume(new G4PVPlacement(rotcooling, G4ThreeVector(-leftedgeCU + icup * 1.5 * baseplate_width + edgeshift + 0.75*baseplate_width, 2*baseplate_length, 0), Log_internal_support_center,
232  "internal_support_center_f_" + std::to_string(icup), log_module_envelope, false, 0, overlapcheck_sector), false);
233  RegisterPhysicalVolume(new G4PVPlacement(rotcooling, G4ThreeVector(-leftedgeCU + icup * 1.5 * baseplate_width + edgeshift + 0.75*baseplate_width, -2*baseplate_length, 0), Log_internal_support_center,
234  "internal_support_center_b_" + std::to_string(icup), log_module_envelope, false, 0, overlapcheck_sector), false);
235  } else if(icup==0 || icup==(maxicup-2)){
236  RegisterPhysicalVolume(new G4PVPlacement(rotcooling, G4ThreeVector(-leftedgeCU + icup * 1.5 * baseplate_width + edgeshift + 0.75*baseplate_width - baseplate_width / 6, 0, 0), Log_internal_support_edge,
237  "internal_support_edge_" + std::to_string(icup), log_module_envelope, false, 0, overlapcheck_sector), false);
238  RegisterPhysicalVolume(new G4PVPlacement(rotcooling, G4ThreeVector(-leftedgeCU + icup * 1.5 * baseplate_width + edgeshift + 0.75*baseplate_width - baseplate_width / 6, 2*baseplate_length, 0), Log_internal_support_edge,
239  "internal_support_edge_f_" + std::to_string(icup), log_module_envelope, false, 0, overlapcheck_sector), false);
240  RegisterPhysicalVolume(new G4PVPlacement(rotcooling, G4ThreeVector(-leftedgeCU + icup * 1.5 * baseplate_width + edgeshift + 0.75*baseplate_width - baseplate_width / 6, -2*baseplate_length, 0), Log_internal_support_edge,
241  "internal_support_edge_b_" + std::to_string(icup), log_module_envelope, false, 0, overlapcheck_sector), false);
242  }
243  }
244 
245 
246  // Sensor Module:
247  G4double sensor_width = 21.2 * mm;
248  G4double sensor_length = 42.0 * mm;
249  G4double baseSH_width_top = baseplate_width / 2 - (0.1543*cm/2); //-0.15*mm;
250  G4double baseSH_width = baseplate_width / 2 - (0.232*cm/2); //-0.15*mm;
251 
252  const int nLayers = 8;
253  std::string strLayerName[nLayers] = {
254  "ThermalPad",
255  "ALN",
256  "LairdFilm",
257  "ROC",
258  "Solder",
259  "Sensor",
260  "Epoxy",
261  "AIN"};
262  G4Material *materialLayer[nLayers] = {GetDetectorMaterial("G4_GRAPHITE"),
263  mat_ALN,
264  GetDetectorMaterial("G4_GRAPHITE"),
265  GetDetectorMaterial("G4_PLEXIGLASS"),
266  mat_Solder_Tin,
267  GetDetectorMaterial("G4_Si"),
268  mat_Epoxy,
269  mat_ALN};
270  G4double thicknessLayer[nLayers] = {0.25 * mm, 0.79 * mm, 0.08 * mm, 0.25 * mm, 0.03 * mm, 0.3 * mm, 0.08 * mm, 0.51 * mm};
271  G4double widthLayer[nLayers] = {
272  baseplate_width - 0.3 * mm,
273  baseplate_width,
274  sensor_width + 1 * mm,
275  sensor_width + 1 * mm,
276  sensor_width - 0.2 * mm,
277  sensor_width,
278  sensor_width,
279  baseplate_width - 4 * mm};
280  G4double offsetLayer[nLayers] = {
281  0.3 * mm / 2,
282  0,
283  (baseplate_width - widthLayer[2]) / 2 - 0.2 * mm,
284  (baseplate_width - widthLayer[3]) / 2 - 0.2 * mm,
285  (baseplate_width - widthLayer[4]) / 2 - 0.1 * mm,
286  (baseplate_width - widthLayer[5] - 0.1 * mm) / 2,
287  (baseplate_width - widthLayer[6] - 0.1 * mm) / 2,
288  4 * mm / 2 - 0.2 * mm};
289  G4double lengthLayer[nLayers] = {
290  baseplate_length - 0.2 * mm,
291  baseplate_length,
292  sensor_length + 0.2 * mm,
293  sensor_length + 0.2 * mm,
294  sensor_length - 0.2 * mm,
295  sensor_length,
296  sensor_length,
297  baseplate_length - 0.2 * mm};
298  bool layerActive[nLayers] = {
299  false, false, false, false, false, true, false, false};
300 
301  G4double thicknessDet = 0;
302  for (int ilay = 0; ilay < nLayers; ilay++)
303  {
304  thicknessDet += thicknessLayer[ilay];
305  }
306 
307  // Sensor Ladder (6 Sensors)
308  G4VSolid *sol_sensor_ladder = new G4Box("sol_sensor_ladder",
309  baseplate_width / 2,
310  segmentlength / 2,
311  thicknessDet / 2);
312  G4LogicalVolume *log_sensor_ladder = new G4LogicalVolume(sol_sensor_ladder, Air, "log_sensor_ladder");
313  m_DisplayAction->AddVolume(log_sensor_ladder, "SensorLadder");
314 
315  G4VSolid *sol_sensor_stack = new G4Box("sol_sensor_stack",
316  baseplate_width / 2,
317  baseplate_length / 2,
318  thicknessDet / 2);
319  G4LogicalVolume *log_sensor_stack = new G4LogicalVolume(sol_sensor_stack, Air, "log_sensor_stack");
320  m_DisplayAction->AddVolume(log_sensor_stack, "SensorStack");
321 
322  double z_start = -thicknessDet / 2;
323  for (int ilay = 0; ilay < nLayers; ilay++)
324  {
325  const std::string layer_name = "sensor_stack_" + strLayerName[ilay];
326  const std::string layer_name_Solid = "sol_" + layer_name;
327 
328  G4VSolid *sol_Module_Layer_Raw = new G4Box(layer_name_Solid + "_Raw",
329  widthLayer[ilay] / 2,
330  lengthLayer[ilay] / 2,
331  thicknessLayer[ilay] / 2);
332 
333  G4LogicalVolume *Log_Layer = new G4LogicalVolume(sol_Module_Layer_Raw, //
334  materialLayer[ilay], layer_name + "_Log");
335  RegisterLogicalVolume(Log_Layer);
337  new G4PVPlacement(0, G4ThreeVector(-offsetLayer[ilay], 0, z_start + thicknessLayer[ilay] / 2), Log_Layer,
338  "physical_" + layer_name, log_sensor_stack, false, 0, overlapcheck_sector),
339  layerActive[ilay]);
340  z_start += thicknessLayer[ilay];
341  m_DisplayAction->AddVolume(Log_Layer, "TTLLayers");
342  }
343 
344  new G4PVReplica("TTL_Replicas_Modules", log_sensor_stack, log_sensor_ladder,
345  kYAxis, 6, baseplate_length);
346  G4double offsety = diameter_coolingtube/2 + cooling_plate_height + thicknessDet / 2;
347  G4double leftedge = sin(M_PI / 12.) * (rCenter + diameter_coolingtube/2 + cooling_plate_height );
348  G4double leftedgebottom = sin(M_PI / 12.) * (rCenter - diameter_coolingtube/2 - cooling_plate_height);
349 
350  G4RotationMatrix *rotationSensor = new G4RotationMatrix();
351  rotationSensor->rotateZ(-M_PI);
352  // top side
353  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(-leftedge + baseplate_width / 2, 0, offsety), log_sensor_ladder,
354  "physical_sensor_ladder_t1", log_module_envelope, false, 0, overlapcheck_sector), false);
355 
356  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(-leftedge + baseplate_width / 2 + 2*baseSH_width_top + baseplate_width , 0, offsety), log_sensor_ladder,
357  "physical_sensor_ladder_t2", log_module_envelope, false, 0, overlapcheck_sector), false);
358  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(-leftedge + baseplate_width / 2 + 2*baseSH_width_top + 2* baseplate_width, 0, offsety), log_sensor_ladder,
359  "physical_sensor_ladder_t3", log_module_envelope, false, 0, overlapcheck_sector), false);
360 
361  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(-leftedge + baseplate_width / 2 + 4*baseSH_width_top + 3* baseplate_width, 0, offsety), log_sensor_ladder,
362  "physical_sensor_ladder_t4", log_module_envelope, false, 0, overlapcheck_sector), false);
363  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(-leftedge + baseplate_width / 2 + 4*baseSH_width_top + 4* baseplate_width, 0, offsety), log_sensor_ladder,
364  "physical_sensor_ladder_t5", log_module_envelope, false, 0, overlapcheck_sector), false);
365 
366  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(-leftedge + baseplate_width / 2 + 6*baseSH_width_top + 5* baseplate_width, 0, offsety), log_sensor_ladder,
367  "physical_sensor_ladder_t6", log_module_envelope, false, 0, overlapcheck_sector), false);
368  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(-leftedge + baseplate_width / 2 + 6*baseSH_width_top + 6* baseplate_width, 0, offsety), log_sensor_ladder,
369  "physical_sensor_ladder_t7", log_module_envelope, false, 0, overlapcheck_sector), false);
370 
371  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(-leftedge + baseplate_width / 2 + 8*baseSH_width_top + 7* baseplate_width, 0, offsety), log_sensor_ladder,
372  "physical_sensor_ladder_t8", log_module_envelope, false, 0, overlapcheck_sector), false);
373 
374  // bottom side
375  G4double offsetyDown = diameter_coolingtube/2 + cooling_plate_height + thicknessDet / 2;
376  G4RotationMatrix *rotationSensorDown = new G4RotationMatrix();
377  rotationSensorDown->rotateY(-M_PI);
378  G4RotationMatrix *rotationSensorFlip = new G4RotationMatrix();
379  rotationSensorFlip->rotateY(-M_PI);
380  rotationSensorFlip->rotateZ(-M_PI);
381  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorDown, G4ThreeVector(-leftedgebottom + baseSH_width + baseplate_width/2, 0, -offsetyDown), log_sensor_ladder,
382  "physical_sensor_ladder_b1", log_module_envelope, false, 0, overlapcheck_sector), false);
383  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorFlip, G4ThreeVector(-leftedgebottom + baseSH_width + baseplate_width/2 + baseplate_width, 0, -offsetyDown), log_sensor_ladder,
384  "physical_sensor_ladder_b2", log_module_envelope, false, 0, overlapcheck_sector), false);
385 
386  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorDown, G4ThreeVector(-leftedgebottom + 3*baseSH_width + baseplate_width/2 + 2*baseplate_width, 0, -offsetyDown), log_sensor_ladder,
387  "physical_sensor_ladder_b3", log_module_envelope, false, 0, overlapcheck_sector), false);
388  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorFlip, G4ThreeVector(-leftedgebottom + 3*baseSH_width + baseplate_width/2 + 3*baseplate_width, 0, -offsetyDown), log_sensor_ladder,
389  "physical_sensor_ladder_b4", log_module_envelope, false, 0, overlapcheck_sector), false);
390 
391  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorDown, G4ThreeVector(-leftedgebottom + 5*baseSH_width + baseplate_width/2 + 4*baseplate_width, 0, -offsetyDown), log_sensor_ladder,
392  "physical_sensor_ladder_b5", log_module_envelope, false, 0, overlapcheck_sector), false);
393  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorFlip, G4ThreeVector(-leftedgebottom + 5*baseSH_width + baseplate_width/2 + 5*baseplate_width, 0, -offsetyDown), log_sensor_ladder,
394  "physical_sensor_ladder_b6", log_module_envelope, false, 0, overlapcheck_sector), false);
395  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorDown, G4ThreeVector(-leftedgebottom + 7*baseSH_width + baseplate_width/2 + 6*baseplate_width, 0, -offsetyDown), log_sensor_ladder,
396  "physical_sensor_ladder_b7", log_module_envelope, false, 0, overlapcheck_sector), false);
397  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorFlip, G4ThreeVector(-leftedgebottom + 7*baseSH_width + baseplate_width/2 + 7*baseplate_width, 0, -offsetyDown), log_sensor_ladder,
398  "physical_sensor_ladder_b8", log_module_envelope, false, 0, overlapcheck_sector), false);
399  // SERVICE HYBRID
400  const int nLayers_SH = 4;
401  std::string strLayerName_SH[nLayers_SH] = {
402  "ThermalPad",
403  "HighSpeedBoard",
404  "ConnectorSpace",
405  "Powerboard"};
406  G4Material *materialLayer_SH[nLayers_SH] = {
407  GetDetectorMaterial("G4_GRAPHITE"),
408  GetDetectorMaterial("G4_POLYSTYRENE"),
409  GetDetectorMaterial("G4_AIR"),
410  GetDetectorMaterial("G4_POLYSTYRENE")};
411  G4double thicknessLayer_SH[nLayers_SH] = {
412  0.25 * mm,
413  1.00 * mm,
414  1.50 * mm,
415  3.10 * mm};
416  G4double widthLayer_SH[nLayers_SH] = {
417  baseSH_width - 0.2 * mm,
418  baseSH_width - 0.2 * mm,
419  baseSH_width - 0.35 * mm,
420  baseSH_width};
421  G4double offsetLayer_SH[nLayers_SH] = {
422  0.2 * mm / 2,
423  0.2 * mm / 2,
424  0.35 * mm / 2,
425  0};
426  G4double lengthLayer_SH[nLayers_SH] = {
427  baseplate_length,
428  baseplate_length,
429  baseplate_length,
430  baseplate_length};
431  bool layerActive_SH[nLayers_SH] = {
432  false, false, false, false};
433 
434  G4double thicknessDet_SH = 0;
435  for (int ilay = 0; ilay < nLayers_SH; ilay++)
436  {
437  thicknessDet_SH += thicknessLayer_SH[ilay];
438  }
439 
440  // Sensor Ladder (6 Sensors)
441  G4VSolid *sol_SH_ladder = new G4Box("sol_SH_ladder",
442  baseSH_width / 2,
443  segmentlength / 2,
444  thicknessDet_SH / 2);
445  G4LogicalVolume *log_SH_ladder = new G4LogicalVolume(sol_SH_ladder, Air, "log_SH_ladder");
446  m_DisplayAction->AddVolume(log_SH_ladder, "SHLadder");
447 
448  G4VSolid *sol_SH_stack = new G4Box("sol_SH_stack",
449  baseSH_width / 2,
450  baseplate_length / 2,
451  thicknessDet_SH / 2);
452  G4LogicalVolume *log_SH_stack = new G4LogicalVolume(sol_SH_stack, Air, "log_SH_stack");
453  m_DisplayAction->AddVolume(log_SH_stack, "SHStack");
454 
455  double z_start_SH = -thicknessDet_SH / 2;
456  for (int ilay = 0; ilay < nLayers_SH; ilay++)
457  {
458  const std::string layer_name = "SH_stack_" + strLayerName_SH[ilay];
459  const std::string layer_name_Solid = "sol_" + layer_name;
460 
461  G4VSolid *sol_Module_Layer_Raw = new G4Box(layer_name_Solid + "_Raw",
462  widthLayer_SH[ilay] / 2,
463  lengthLayer_SH[ilay] / 2,
464  thicknessLayer_SH[ilay] / 2);
465 
466  G4LogicalVolume *Log_Layer = new G4LogicalVolume(sol_Module_Layer_Raw,materialLayer_SH[ilay], layer_name + "_Log");
467  RegisterLogicalVolume(Log_Layer);
469  new G4PVPlacement(0, G4ThreeVector(-offsetLayer_SH[ilay], 0, z_start_SH + thicknessLayer_SH[ilay] / 2), Log_Layer,
470  "physical_" + layer_name, log_SH_stack, false, 0, overlapcheck_sector),
471  layerActive_SH[ilay]);
472  z_start_SH += thicknessLayer_SH[ilay];
473  m_DisplayAction->AddVolume(Log_Layer, "SHLayers");
474  }
475 
476  new G4PVReplica("SH_Replicas_Modules", log_SH_stack, log_SH_ladder,
477  kYAxis, 6, baseplate_length);
478 
479  G4double offsety_SH = diameter_coolingtube/2 + cooling_plate_height + thicknessDet_SH / 2;
480  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(-leftedge + 1 * baseplate_width + baseSH_width_top - baseSH_width/2, 0, offsety_SH), log_SH_ladder,
481  "physical_SH_ladder_t1", log_module_envelope, false, 0, overlapcheck_sector), false);
482  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(-leftedge + 1 * baseplate_width + 1 * baseSH_width_top + baseSH_width / 2, 0, offsety_SH), log_SH_ladder,
483  "physical_SH_ladder_t2", log_module_envelope, false, 0, overlapcheck_sector), false);
484 
485  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(-leftedge + 3 * baseplate_width + 3 * baseSH_width_top - baseSH_width / 2, 0, offsety_SH), log_SH_ladder,
486  "physical_SH_ladder_t3", log_module_envelope, false, 0, overlapcheck_sector), false);
487  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(-leftedge + 3 * baseplate_width + 3 * baseSH_width_top + baseSH_width / 2, 0, offsety_SH), log_SH_ladder,
488  "physical_SH_ladder_t4", log_module_envelope, false, 0, overlapcheck_sector), false);
489 
490  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(-leftedge + 5 * baseplate_width + 5 * baseSH_width_top - baseSH_width / 2, 0, offsety_SH), log_SH_ladder,
491  "physical_SH_ladder_t5", log_module_envelope, false, 0, overlapcheck_sector), false);
492  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(-leftedge + 5 * baseplate_width + 5 * baseSH_width_top + baseSH_width / 2, 0, offsety_SH), log_SH_ladder,
493  "physical_SH_ladder_t6", log_module_envelope, false, 0, overlapcheck_sector), false);
494 
495  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(-leftedge + 7 * baseplate_width + 7 * baseSH_width_top - baseSH_width / 2, 0, offsety_SH), log_SH_ladder,
496  "physical_SH_ladder_t7", log_module_envelope, false, 0, overlapcheck_sector), false);
497  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(-leftedge + 7 * baseplate_width + 7 * baseSH_width_top + baseSH_width / 2, 0, offsety_SH), log_SH_ladder,
498  "physical_SH_ladder_t8", log_module_envelope, false, 0, overlapcheck_sector), false);
499 
500  G4double offsetyDown_SH = diameter_coolingtube/2 + cooling_plate_height + thicknessDet_SH / 2;
501  // RegisterPhysicalVolume(new G4PVPlacement(rotationSensorFlip, G4ThreeVector(-leftedgebottom + 0 * baseplate_width + baseSH_width / 2, 0, -offsetyDown_SH), log_SH_ladder,
502  // "physical_SH_ladder_b1", log_module_envelope, false, 0, overlapcheck_sector), false);
503 
504  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorDown, G4ThreeVector(-leftedgebottom + 2 * baseplate_width + 1 * baseSH_width + baseSH_width / 2, 0, -offsetyDown_SH), log_SH_ladder,
505  "physical_SH_ladder_b2", log_module_envelope, false, 0, overlapcheck_sector), false);
506  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorFlip, G4ThreeVector(-leftedgebottom + 2 * baseplate_width + 2 * baseSH_width + baseSH_width / 2, 0, -offsetyDown_SH), log_SH_ladder,
507  "physical_SH_ladder_b3", log_module_envelope, false, 0, overlapcheck_sector), false);
508 
509  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorDown, G4ThreeVector(-leftedgebottom + 4 * baseplate_width + 3 * baseSH_width + baseSH_width / 2, 0, -offsetyDown_SH), log_SH_ladder,
510  "physical_SH_ladder_b4", log_module_envelope, false, 0, overlapcheck_sector), false);
511  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorFlip, G4ThreeVector(-leftedgebottom + 4 * baseplate_width + 4 * baseSH_width + baseSH_width / 2, 0, -offsetyDown_SH), log_SH_ladder,
512  "physical_SH_ladder_b5", log_module_envelope, false, 0, overlapcheck_sector), false);
513 
514  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorDown, G4ThreeVector(-leftedgebottom + 6 * baseplate_width + 5 * baseSH_width + baseSH_width / 2, 0, -offsetyDown_SH), log_SH_ladder,
515  "physical_SH_ladder_b6", log_module_envelope, false, 0, overlapcheck_sector), false);
516 
517  RegisterPhysicalVolume(new G4PVPlacement(rotationSensorFlip, G4ThreeVector(-leftedgebottom + 6 * baseplate_width + 6 * baseSH_width + baseSH_width / 2, 0, -offsetyDown_SH), log_SH_ladder,
518  "physical_SH_ladder_b7", log_module_envelope, false, 0, overlapcheck_sector), false);
519 
520  // RegisterPhysicalVolume(new G4PVPlacement(rotationSensorDown, G4ThreeVector(-leftedgebottom + 8 * baseplate_width + 7 * baseSH_width + baseSH_width / 2, 0, -offsetyDown_SH), log_SH_ladder,
521  // "physical_SH_ladder_b8", log_module_envelope, false, 0, overlapcheck_sector), false);
522 
523 
524  RegisterLogicalVolume(log_module_envelope);
525  m_DisplayAction->AddVolume(log_module_envelope, "ModuleEnvelope");
526  G4double moduleShift = 3 * mm; //to avoid overlaps
527 
528  for (int isec = 0; isec < 12; isec++)
529  {
530  // if(isec!=3 && isec!=4)continue; // NOTE REMOVE
531  // if(isec!=3)continue; // NOTE REMOVE
532  G4RotationMatrix *motherrot = new G4RotationMatrix();
533  motherrot->rotateX(M_PI / 2);
534  motherrot->rotateY(M_PI);
535  motherrot->rotateZ(M_PI + (isec - 3) * 2 * M_PI / 12.);
536  // // central segments
537  G4ThreeVector vec_central_transl((rCenter*cos(M_PI / 12.)+moduleShift) * cos(isec * 2 * M_PI / 12.), (rCenter*cos(M_PI / 12.)+moduleShift) * sin(isec * 2 * M_PI / 12.), place_z);
538  assemblyDetector->AddPlacedVolume( log_module_envelope,vec_central_transl,motherrot);
539  for (int ilen = 1; ilen < ((detlength / 2 - segmentlength / 2) / segmentlength); ilen++)
540  {
541  // forward segments
542  G4ThreeVector vec_det_fwdlayers_transl((rCenter*cos(M_PI / 12.)+moduleShift) * cos(isec * 2 * M_PI / 12.), (rCenter*cos(M_PI / 12.)+moduleShift) * sin(isec * 2 * M_PI / 12.), place_z + ilen * segmentlength);
543  assemblyDetector->AddPlacedVolume(log_module_envelope, vec_det_fwdlayers_transl, motherrot);
544  // backward segments
545  G4ThreeVector vec_det_bcklayers_transl((rCenter*cos(M_PI / 12.)+moduleShift) * cos(isec * 2 * M_PI / 12.), (rCenter*cos(M_PI / 12.)+moduleShift) * sin(isec * 2 * M_PI / 12.), place_z -ilen * segmentlength);
546  assemblyDetector->AddPlacedVolume(log_module_envelope, vec_det_bcklayers_transl, motherrot);
547 
548 
549  }
550 
551 
552  // std::cout << "x : " << (rCenter*cos(M_PI / 12.)+moduleShift) * cos(isec * 2 * M_PI / 12.) << "\ty: " << (rCenter*cos(M_PI / 12.)+moduleShift) * sin(isec * 2 * M_PI / 12.) << "\tdistance: " << sqrt(pow((rCenter*cos(M_PI / 12.)+moduleShift) * cos(isec * 2 * M_PI / 12.),2)+pow((rCenter*cos(M_PI / 12.)+moduleShift) * sin(isec * 2 * M_PI / 12.),2)) << std::endl;
553 
554  // RegisterPhysicalVolume(new G4PVPlacement(motherrot, G4ThreeVector((rCenter*cos(M_PI / 12.)+moduleShift) * cos(isec * 2 * M_PI / 12.), (rCenter*cos(M_PI / 12.)+moduleShift) * sin(isec * 2 * M_PI / 12.), place_z), log_module_envelope, "Mother_Segment_Raw_Physical_Center_" + std::to_string(isec), logicWorld, false, 0, overlapcheck_sector),false);
555  // for (int ilen = 1; ilen < ((detlength / 2 - segmentlength / 2) / segmentlength); ilen++)
556  // {
557  // // // forward segments
558  // RegisterPhysicalVolume(new G4PVPlacement(motherrot, G4ThreeVector((rCenter*cos(M_PI / 12.)+moduleShift) * cos(isec * 2 * M_PI / 12.), (rCenter*cos(M_PI / 12.)+moduleShift) * sin(isec * 2 * M_PI / 12.), place_z + ilen * segmentlength), log_module_envelope, "Mother_Segment_Raw_Physical_Fwd_" + std::to_string(isec) + "_" + std::to_string(ilen), logicWorld, false, 0, overlapcheck_sector), false);
559  // // // backward segments
560  // RegisterPhysicalVolume(new G4PVPlacement(motherrot, G4ThreeVector((rCenter*cos(M_PI / 12.)+moduleShift) * cos(isec * 2 * M_PI / 12.), (rCenter*cos(M_PI / 12.)+moduleShift) * sin(isec * 2 * M_PI / 12.), place_z -ilen * segmentlength), log_module_envelope,"Mother_Segment_Raw_Physical_Bwd_" + std::to_string(isec) + "_" + std::to_string(ilen), logicWorld, false, 0, overlapcheck_sector), false);
561  // }
562  }
563  assemblyDetector->MakeImprint( logicWorld, detzvec,0 );
564 
565  // RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, 0, place_z), DetectorLog_Det,
566  // name_base + "_Physical", logicWorld, false, 0, overlapcheck_sector));
567 }
568 
570 {
571  // MATERIALS
572  G4double density;
573  G4double a;
574  G4int z;
575  G4int ncomponents;
576  G4int natoms;
577  G4String symbol;
578 
581 
582 
583  G4Element *elH = new G4Element("Hydrogen", symbol = "H", 1., 1.01 * g / mole);
584  G4Element *elC = new G4Element("Carbon", symbol = "C", 6., 12.01 * g / mole);
585  G4Element *elN = new G4Element("Nitrogen", symbol = "N", 7., 14.01 * g / mole);
586  G4Element *elO = new G4Element("Oxygen", symbol = "O", 8., 16.00 * g / mole);
587  G4Material *mat_Epoxy = GetDetectorMaterial("EpoxyTTL");
588  if (!mat_Epoxy)
589  {
590  mat_Epoxy = new G4Material("EpoxyTTL", density = 1.16 * g / cm3, natoms = 4);
591  mat_Epoxy->AddElement(elH, 32); // Hydrogen
592  mat_Epoxy->AddElement(elN, 2); // Nitrogen
593  mat_Epoxy->AddElement(elO, 4); // Oxygen
594  mat_Epoxy->AddElement(elC, 15); // Carbon
595  // G4Material *mat_Epoxy = GetDetectorMaterial("Epoxy");
596  }
597  G4Material *mat_ALN = GetDetectorMaterial("AluminiumNitrate");
598  if (!mat_ALN)
599  {
600  mat_ALN = new G4Material("AluminiumNitrate", density = 3.255 * g / cm3, ncomponents = 2);
601  // G4Material *mat_ALN = new G4Material("AluminiumNitrate", density = 3.255 * g / cm3, ncomponents = 2);
602  mat_ALN->AddElement(G4Element::GetElement("Al"), 1);
603  mat_ALN->AddElement(G4Element::GetElement("N"), 1);
604  }
605  G4Material *mat_Solder_Tin = GetDetectorMaterial("Tin");
606  if (!mat_Solder_Tin)
607  {
608  mat_Solder_Tin = new G4Material("Tin", z = 50., a = 118.7 * g / mole, density = 7.310 * g / cm3);
609  }
610 
611  G4double det_height = 2.0 * cm;
612 
613  //Create the envelope = 'world volume' for the calorimeter
614  G4Material *Air = GetDetectorMaterial("G4_AIR");
615 
616  G4double rMin = m_Params->get_double_param("rMin");
617  G4double rMax = m_Params->get_double_param("rMax");
618  G4double xoffset = m_Params->get_double_param("offset_x");
619  // G4double xoffset = 6*cm;
620 
621  G4VSolid *beampipe_cutout = new G4Cons("ttl_beampipe_cutout",
622  0, rMin,
623  0, rMin,
624  det_height * 2 / 2.0,
625  0, 2 * M_PI);
626  G4VSolid *ttl_envelope_solid = new G4Cons("ttl_envelope_solid_cutout",
627  0, rMax,
628  0, rMax,
629  det_height / 2.0,
630  0, 2 * M_PI);
631  ttl_envelope_solid = new G4SubtractionSolid(G4String("ttl_envelope_solid"), ttl_envelope_solid, beampipe_cutout, 0, G4ThreeVector(xoffset, 0, 0.));
632 
633  const G4Transform3D transform_Det_to_Hall =
635  m_Params->get_double_param("place_z") + det_height / 2);
636 
637  m_SteppingAction->SetZPositionFwd(m_Params->get_double_param("place_z") + det_height / 2);
638  G4LogicalVolume *DetectorLog_Det = new G4LogicalVolume(ttl_envelope_solid, Air, name_base + "_Log");
639  RegisterLogicalVolume(DetectorLog_Det);
640 
641  RegisterPhysicalVolume(new G4PVPlacement(G4RotateZ3D(2 * pi) * transform_Det_to_Hall, DetectorLog_Det,
642  name_base + "_Physical", logicWorld, false, 0, overlapcheck_sector));
643  m_DisplayAction->AddVolume(DetectorLog_Det, "DetectorBoxFwd");
644 
645  G4double cooling_plate_height = 1 * mm;
646  G4double diameter_coolingtube = 5*mm;
647  G4double wallthickness_coolingtube = 1 * mm;
648 
649  G4VSolid *sol_module_envelope = new G4Cons("sol_module_envelope_cutout",
650  0, rMax,
651  0, rMax,
652  det_height / 2.0,
653  0, 2 * M_PI);
654  sol_module_envelope = new G4SubtractionSolid(G4String("sol_module_envelope_"), sol_module_envelope, beampipe_cutout, 0, G4ThreeVector(xoffset, 0, 0.));
655  G4LogicalVolume *log_module_envelope = new G4LogicalVolume(sol_module_envelope, Air, "log_module_envelope");
656  m_DisplayAction->AddVolume(log_module_envelope, "ModuleEnvelope");
657  RegisterLogicalVolume(log_module_envelope);
658  // G4RotationMatrix *rot1 = new G4RotationMatrix();
659  // rot1->rotateZ(0.5 * isec * M_PI);
660  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, 0, 0), log_module_envelope,
661  "physical_module_envelope2", DetectorLog_Det, false, 0, overlapcheck_sector));
662 
663  G4VSolid *sol_cooling_plate = new G4Cons("sol_cooling_plate_cutout",
664  0, rMax,
665  0, rMax,
666  cooling_plate_height / 2.0,
667  0, 2 * M_PI);
668  sol_cooling_plate = new G4SubtractionSolid(G4String("sol_cooling_plate"), sol_cooling_plate, beampipe_cutout, 0, G4ThreeVector(xoffset, 0, 0.));
669 
670  G4LogicalVolume *log_cooling_plate = new G4LogicalVolume(sol_cooling_plate, GetDetectorMaterial("G4_Al"), "log_cooling_plate");
671  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, 0, diameter_coolingtube/2+cooling_plate_height/2), log_cooling_plate,
672  "physical_cooling_plate_f", log_module_envelope, false, 0, overlapcheck_sector), false);
673  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, 0, -diameter_coolingtube/2-cooling_plate_height/2), log_cooling_plate,
674  "physical_cooling_plate_b", log_module_envelope, false, 0, overlapcheck_sector), false);
675  RegisterLogicalVolume(log_cooling_plate);
676  m_DisplayAction->AddVolume(log_cooling_plate, "CoolingPlate");
677 
678 
679  // Sensor Module:
680  G4double sensor_width = 21.2 * mm;
681  G4double sensor_length = 42.0 * mm;
682  G4double baseplate_length = 43.1 * mm;
683  G4double baseplate_width = 56.5 * mm / 2;
684 
685  const int nLayers = 8;
686  std::string strLayerName[nLayers] = {
687  "ThermalPad",
688  "ALN",
689  "LairdFilm",
690  "ROC",
691  "Solder",
692  "Sensor",
693  "Epoxy",
694  "AIN"};
695  G4Material *materialLayer[nLayers] = {GetDetectorMaterial("G4_GRAPHITE"), mat_ALN, GetDetectorMaterial("G4_GRAPHITE"), GetDetectorMaterial("G4_PLEXIGLASS"), mat_Solder_Tin, GetDetectorMaterial("G4_Si"), mat_Epoxy, mat_ALN};
696  G4double thicknessLayer[nLayers] = {
697  0.25 * mm, 0.79 * mm, 0.08 * mm, 0.25 * mm, 0.03 * mm, 0.3 * mm, 0.08 * mm, 0.51 * mm};
698  G4double widthLayer[nLayers] = {
699  baseplate_width - 0.3 * mm,
700  baseplate_width,
701  sensor_width + 1 * mm,
702  sensor_width + 1 * mm,
703  sensor_width - 0.2 * mm,
704  sensor_width,
705  sensor_width,
706  baseplate_width - 4 * mm};
707  G4double offsetLayer[nLayers] = {
708  0.3 * mm / 2,
709  0,
710  (baseplate_width - widthLayer[2]) / 2 - 0.2 * mm,
711  (baseplate_width - widthLayer[3]) / 2 - 0.2 * mm,
712  (baseplate_width - widthLayer[4]) / 2 - 0.1 * mm,
713  (baseplate_width - widthLayer[5] - 0.1 * mm) / 2,
714  (baseplate_width - widthLayer[6] - 0.1 * mm) / 2,
715  4 * mm / 2 - 0.2 * mm};
716  G4double lengthLayer[nLayers] = {
717  baseplate_length - 0.2 * mm,
718  baseplate_length,
719  sensor_length + 0.2 * mm,
720  sensor_length + 0.2 * mm,
721  sensor_length - 0.2 * mm,
722  sensor_length,
723  sensor_length,
724  baseplate_length - 0.2 * mm};
725  bool layerActive[nLayers] = {
726  false, false, false, false, false, true, false, false};
727 
728  G4double thicknessDet = 0;
729  for (int ilay = 0; ilay < nLayers; ilay++)
730  {
731  thicknessDet += thicknessLayer[ilay];
732  }
733 
734  G4double segmentlength = baseplate_length; //(detlength - 10 * cm) / 6;//
735  G4VSolid *sol_sensor_stack = new G4Box("sol_sensor_stack",
736  baseplate_length / 2,
737  baseplate_width / 2,
738  thicknessDet / 2);
739  G4LogicalVolume *log_sensor_stack = new G4LogicalVolume(sol_sensor_stack, Air, "log_sensor_stack");
740  m_DisplayAction->AddVolume(log_sensor_stack, "SensorStack");
741 
742  double z_start = -thicknessDet / 2;
743  for (int ilay = 0; ilay < nLayers; ilay++)
744  {
745  const std::string layer_name = "sensor_stack_" + strLayerName[ilay];
746  const std::string layer_name_Solid = "sol_" + layer_name;
747 
748  G4VSolid *sol_Module_Layer_Raw = new G4Box(layer_name_Solid + "_Raw",
749  lengthLayer[ilay] / 2,
750  widthLayer[ilay] / 2,
751  thicknessLayer[ilay] / 2);
752 
753  G4LogicalVolume *Log_Layer = new G4LogicalVolume(sol_Module_Layer_Raw, //
754  materialLayer[ilay], layer_name + "_Log");
755  RegisterLogicalVolume(Log_Layer);
757  new G4PVPlacement(0, G4ThreeVector(0, -offsetLayer[ilay], z_start + thicknessLayer[ilay] / 2), Log_Layer,
758  "physical_" + layer_name, log_sensor_stack, false, 0, overlapcheck_sector),
759  layerActive[ilay]);
760  z_start += thicknessLayer[ilay];
761  m_DisplayAction->AddVolume(Log_Layer, "TTLLayers");
762  }
763 
764  // SERVICE HYBRID
765  G4double baseSH_width = baseplate_width / 2;
766  const int nLayers_SH = 4;
767  std::string strLayerName_SH[nLayers_SH] = {
768  "ThermalPad",
769  "HighSpeedBoard",
770  "ConnectorSpace",
771  "Powerboard"};
772  G4Material *materialLayer_SH[nLayers_SH] = {
773  GetDetectorMaterial("G4_GRAPHITE"),
774  GetDetectorMaterial("G4_POLYSTYRENE"),
775  GetDetectorMaterial("G4_AIR"),
776  GetDetectorMaterial("G4_POLYSTYRENE")};
777  G4double thicknessLayer_SH[nLayers_SH] = {
778  0.25 * mm,
779  1.00 * mm,
780  1.50 * mm,
781  3.10 * mm};
782  G4double widthLayer_SH[nLayers_SH] = {
783  baseSH_width - 0.2 * mm,
784  baseSH_width - 0.2 * mm,
785  baseSH_width - 0.35 * mm,
786  baseSH_width};
787  G4double offsetLayer_SH[nLayers_SH] = {
788  0.2 * mm / 2,
789  0.2 * mm / 2,
790  0.35 * mm / 2,
791  0};
792  G4double lengthLayer_SH[nLayers_SH] = {
793  baseplate_length,
794  baseplate_length,
795  baseplate_length,
796  baseplate_length};
797  bool layerActive_SH[nLayers_SH] = {
798  false, false, false, false};
799 
800  G4double thicknessDet_SH = 0;
801  for (int ilay = 0; ilay < nLayers_SH; ilay++)
802  {
803  thicknessDet_SH += thicknessLayer_SH[ilay];
804  }
805 
806  G4VSolid *sol_SH_stack = new G4Box("sol_SH_stack",
807  baseplate_length / 2,
808  baseSH_width / 2,
809  thicknessDet_SH / 2);
810  G4LogicalVolume *log_SH_stack = new G4LogicalVolume(sol_SH_stack, Air, "log_SH_stack");
811  m_DisplayAction->AddVolume(log_SH_stack, "SHStack");
812 
813  double z_start_SH = -thicknessDet_SH / 2;
814  for (int ilay = 0; ilay < nLayers_SH; ilay++)
815  {
816  const std::string layer_name = "SH_stack_" + strLayerName_SH[ilay];
817  const std::string layer_name_Solid = "sol_" + layer_name;
818 
819  G4VSolid *sol_Module_Layer_Raw = new G4Box(layer_name_Solid + "_Raw",
820  lengthLayer_SH[ilay] / 2,
821  widthLayer_SH[ilay] / 2,
822  thicknessLayer_SH[ilay] / 2);
823 
824  G4LogicalVolume *Log_Layer = new G4LogicalVolume(sol_Module_Layer_Raw, //
825  materialLayer_SH[ilay], layer_name + "_Log");
826  RegisterLogicalVolume(Log_Layer);
828  new G4PVPlacement(0, G4ThreeVector(0,-offsetLayer_SH[ilay], z_start_SH + thicknessLayer_SH[ilay] / 2), Log_Layer,
829  "physical_" + layer_name, log_SH_stack, false, 0, overlapcheck_sector),
830  layerActive_SH[ilay]);
831  z_start_SH += thicknessLayer_SH[ilay];
832  m_DisplayAction->AddVolume(Log_Layer, "SHLayers");
833  }
834 
835  G4double fullsensor_width = baseSH_width+baseplate_width;
836  G4VSolid *sol_sensor_and_readout = new G4Box("sol_sensor_and_readout",
837  segmentlength / 2,
838  fullsensor_width / 2,
839  thicknessDet_SH / 2);
840  G4LogicalVolume *log_sensor_and_readout = new G4LogicalVolume(sol_sensor_and_readout, Air, "log_sensor_and_readout");
841  m_DisplayAction->AddVolume(log_sensor_and_readout, "SensorAndReadoutLadder");
842 
843  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, -fullsensor_width/2 + baseplate_width/2, -thicknessDet_SH/2+thicknessDet/2),
844  log_sensor_stack, "SensorPlacedPhysical", log_sensor_and_readout, false, 0, overlapcheck_sector),false);
845  RegisterPhysicalVolume(new G4PVPlacement(0, G4ThreeVector(0, fullsensor_width/2 - baseplate_width/4, 0),
846  log_SH_stack, "ServiceHybridPlacedPhysical", log_sensor_and_readout, false, 0, overlapcheck_sector),false);
847 
848  G4double offsetzFront = diameter_coolingtube/2 + cooling_plate_height + thicknessDet_SH / 2;
849  G4double offsetzBack = -diameter_coolingtube/2 - cooling_plate_height - thicknessDet_SH / 2;
850  // number of towers in radial direction (on y axis)
851  int rowYdir = (int) ( (rMax-(fullsensor_width/2)) / fullsensor_width);
852  for(int row=rowYdir;row>=-rowYdir;row--){
853  // for(int row=0;row>=-rowYdir;row--){
854  // pythagoras -> get available length in circular mother volume for towers
855  // divide given length by tower width -> get number of towers that can be placed
856  int numSensorsRow = (int) ( ( 2* sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width + fullsensor_width/2) ,2)) ) / segmentlength );
857  if(numSensorsRow==0) continue;
858  // we want an odd number of towers to be symmetrically centered around 0
859  if ( numSensorsRow % 2 == 0) numSensorsRow-=1;
860 
861  if( ( (abs(row)*fullsensor_width) -(fullsensor_width/2)) < rMin ){
862  if(xoffset!=0){
863  // pythagoras -> get available length in circular mother volume for towers
864  // divide given length by tower width -> get number of towers that can be placed
865  // int numSensorsRowInner = ceil( ( 2* sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) ) / segmentlength );
866  int numSensorLeftAdd = ceil( (xoffset -(segmentlength/2) - sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) ) / segmentlength );
867  int numSensorRightAdd = ceil( (xoffset -(segmentlength/2) + sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) ) / segmentlength );
868  // we want an odd number of towers to be symmetrically centered around 0
869  // create mother volume with space for numSensorsRow towers along x-axis
870  auto TTLDetRowLeftSolid = new G4Box("TTLDetRowLeftBox" + std::to_string(row), (((numSensorsRow-1) /2 + numSensorLeftAdd)) * segmentlength / 2.0,fullsensor_width / 2.0,thicknessDet_SH / 2.0);
871  auto TTLDetRowLeftLogical = new G4LogicalVolume(TTLDetRowLeftSolid,Air,"TTLDetRowLeftLogical" + std::to_string(row));
872  // replicate singletower tower design numSensorsRow times along x-axis
873  new G4PVReplica("TTLDetRowLeftPhysical" + std::to_string(row),log_sensor_and_readout,TTLDetRowLeftLogical,
874  kXAxis,((numSensorsRow-1) /2 + numSensorLeftAdd),segmentlength);
875  m_DisplayAction->AddVolume(TTLDetRowLeftLogical, "StripBox");
876 
877  G4RotationMatrix *rotationSensor = new G4RotationMatrix();
878  rotationSensor->rotateZ(-M_PI);
879  new G4PVPlacement(row%2==0 ? rotationSensor : 0, G4ThreeVector( - ( (((numSensorsRow-1) /2 + numSensorLeftAdd)) * segmentlength / 2.0 + segmentlength / 2.0 - (numSensorLeftAdd* segmentlength)), (row*fullsensor_width), offsetzFront),
880  TTLDetRowLeftLogical, "TTLDetRowLeftPlacedFront" + std::to_string(row), log_module_envelope, 0, false, overlapcheck_sector);
881 
882  G4RotationMatrix *rotationSensorBck1 = new G4RotationMatrix();
883  rotationSensorBck1->rotateX(-M_PI);
884  G4RotationMatrix *rotationSensorBck2 = new G4RotationMatrix();
885  rotationSensorBck2->rotateZ(-M_PI);
886  rotationSensorBck2->rotateX(-M_PI);
887  new G4PVPlacement(row%2==0 ? rotationSensorBck2 : rotationSensorBck1, G4ThreeVector( - ( (((numSensorsRow-1) /2 + numSensorLeftAdd)) * segmentlength / 2.0 + segmentlength / 2.0 - (numSensorLeftAdd* segmentlength)), (row*fullsensor_width), offsetzBack),
888  TTLDetRowLeftLogical, "TTLDetRowLeftPlacedBack" + std::to_string(row), log_module_envelope, 0, false, overlapcheck_sector);
889 
890  G4VSolid *sol_cutout_tube_left = new G4Box("sol_cutout_tube_left" + std::to_string(row),
891  1.3*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) + xoffset)/2,
892  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
893  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2);
894  G4VSolid *sol_cooling_tube_left = new G4Box("sol_cooling_tube_left_tmp" + std::to_string(row),
895  0.86*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) + xoffset)/2,
896  diameter_coolingtube / 2,
897  diameter_coolingtube / 2);
898  sol_cooling_tube_left = new G4SubtractionSolid(G4String("sol_cooling_tube_left" + std::to_string(row)), sol_cooling_tube_left, sol_cutout_tube_left, 0, G4ThreeVector(0,0,0));
899  G4LogicalVolume *Log_cooling_tube_left = new G4LogicalVolume(sol_cooling_tube_left, //
900  GetDetectorMaterial("G4_Al"), "Log_cooling_tube_left" + std::to_string(row));
901  RegisterLogicalVolume(Log_cooling_tube_left);
902  m_DisplayAction->AddVolume(Log_cooling_tube_left, "Cooling_tube");
903 
904  G4VSolid *sol_water_cooling_left = new G4Box("sol_water_cooling_left" + std::to_string(row),
905  0.85*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) + xoffset)/2,
906  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
907  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2);
908  G4LogicalVolume *Log_water_cooling_left = new G4LogicalVolume(sol_water_cooling_left, //
909  GetDetectorMaterial("G4_WATER"), "Log_water_cooling_left" + std::to_string(row));
910  RegisterLogicalVolume(Log_water_cooling_left);
911  m_DisplayAction->AddVolume(Log_water_cooling_left, "Water_cooling");
912 
913  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(- ( (((numSensorsRow-1) /2 + numSensorLeftAdd)) * segmentlength / 2.0 + segmentlength / 2.0 - (numSensorLeftAdd* segmentlength)), row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_cooling_tube_left,
914  "cooling_tube_left_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
915  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(- ( (((numSensorsRow-1) /2 + numSensorLeftAdd)) * segmentlength / 2.0 + segmentlength / 2.0 - (numSensorLeftAdd* segmentlength)), row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_water_cooling_left,
916  "cooling_water_left_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
917 
918 
919  // // create mother volume with space for numSensorsRow towers along x-axis
920  auto TTLDetRowRightSolid = new G4Box("TTLDetRowRightBox" + std::to_string(row), (((numSensorsRow-1) /2 - numSensorRightAdd)) * segmentlength / 2.0,fullsensor_width / 2.0,thicknessDet_SH / 2.0);
921  auto TTLDetRowRightLogical = new G4LogicalVolume(TTLDetRowRightSolid,Air,"TTLDetRowRightLogical" + std::to_string(row));
922  m_DisplayAction->AddVolume(TTLDetRowRightLogical, "StripBox");
923  // // replicate singletower tower design numSensorsRow times along x-axis
924  new G4PVReplica("TTLDetRowRightPhysical" + std::to_string(row),log_sensor_and_readout,TTLDetRowRightLogical,
925  kXAxis,((numSensorsRow-1) /2 - numSensorRightAdd ),segmentlength);
926 
927  new G4PVPlacement(row%2==0 ? rotationSensor : 0, G4ThreeVector(( (((numSensorsRow-1) /2 - numSensorRightAdd)) * segmentlength / 2.0 + segmentlength / 2.0 + (numSensorRightAdd* segmentlength)), (row*fullsensor_width), offsetzFront),
928  TTLDetRowRightLogical, "TTLDetRowRightPlacedFront" + std::to_string(row), log_module_envelope, 0, false, overlapcheck_sector);
929 
930  new G4PVPlacement(row%2==0 ? rotationSensorBck2 : rotationSensorBck1, G4ThreeVector(( (((numSensorsRow-1) /2 - numSensorRightAdd)) * segmentlength / 2.0 + segmentlength / 2.0 + (numSensorRightAdd* segmentlength)), (row*fullsensor_width), offsetzBack),
931  TTLDetRowRightLogical, "TTLDetRowRightPlacedBack" + std::to_string(row), log_module_envelope, 0, false, overlapcheck_sector);
932 
933 
934  G4VSolid *sol_cutout_tube_right = new G4Box("sol_cutout_tube_right" + std::to_string(row),
935  1.3*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) - xoffset)/2,
936  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
937  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2);
938  G4VSolid *sol_cooling_tube_right = new G4Box("sol_cooling_tube_right_tmp" + std::to_string(row),
939  0.86*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) - xoffset)/2,
940  diameter_coolingtube / 2,
941  diameter_coolingtube / 2);
942  sol_cooling_tube_right = new G4SubtractionSolid(G4String("sol_cooling_tube_right" + std::to_string(row)), sol_cooling_tube_right, sol_cutout_tube_right, 0, G4ThreeVector(0,0,0));
943  G4LogicalVolume *Log_cooling_tube_right = new G4LogicalVolume(sol_cooling_tube_right, //
944  GetDetectorMaterial("G4_Al"), "Log_cooling_tube_right" + std::to_string(row));
945  RegisterLogicalVolume(Log_cooling_tube_right);
946  m_DisplayAction->AddVolume(Log_cooling_tube_right, "Cooling_tube");
947 
948  G4VSolid *sol_water_cooling_right = new G4Box("sol_water_cooling_right" + std::to_string(row),
949  0.85*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) - xoffset)/2,
950  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
951  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2);
952  G4LogicalVolume *Log_water_cooling_right = new G4LogicalVolume(sol_water_cooling_right, //
953  GetDetectorMaterial("G4_WATER"), "Log_water_cooling_right" + std::to_string(row));
954  RegisterLogicalVolume(Log_water_cooling_right);
955  m_DisplayAction->AddVolume(Log_water_cooling_right, "Water_cooling");
956 
957  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(( (((numSensorsRow-1) /2 - numSensorRightAdd)) * segmentlength / 2.0 + segmentlength / 2.0 + (numSensorRightAdd* segmentlength)), row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_cooling_tube_right,
958  "cooling_tube_right_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
959  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(( (((numSensorsRow-1) /2 - numSensorRightAdd)) * segmentlength / 2.0 + segmentlength / 2.0 + (numSensorRightAdd* segmentlength)), row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_water_cooling_right,
960  "cooling_water_right_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
961 
962  } else {
963  // pythagoras -> get available length in circular mother volume for towers
964  // divide given length by tower width -> get number of towers that can be placed
965  int numSensorsInner = ceil( ( 2* sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2)) ) / segmentlength );
966  // we want an odd number of towers to be symmetrically centered around 0
967  if ( numSensorsInner % 2 == 0) numSensorsInner+=1;
968  // numSensorsInner+=2;
969  // create mother volume with space for numSensors towers along x-axis
970  auto TTLDetRowSolid = new G4Box("TTLDetRowBox" + std::to_string(row), (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0,fullsensor_width / 2.0,thicknessDet_SH / 2.0);
971  auto TTLDetRowLogical = new G4LogicalVolume(TTLDetRowSolid,Air,"TTLDetRowLogical" + std::to_string(row));
972  m_DisplayAction->AddVolume(TTLDetRowLogical, "StripBox");
973  // replicate singletower tower design numSensors times along x-axis
974  new G4PVReplica("TTLDetRowPhysical" + std::to_string(row),log_sensor_and_readout,TTLDetRowLogical,
975  kXAxis,(numSensorsRow - numSensorsInner) / 2,segmentlength);
976 
977  G4RotationMatrix *rotationSensor = new G4RotationMatrix();
978  rotationSensor->rotateZ(-M_PI);
979  RegisterPhysicalVolume(new G4PVPlacement(row%2==0 ? rotationSensor : 0, G4ThreeVector( - ( ( numSensorsInner / 2.0 ) * segmentlength ) - ( (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0 ), (row*fullsensor_width), offsetzFront),
980  TTLDetRowLogical, "TTLDetRowPhysicalPlacedFrontLeft_" + std::to_string(row), log_module_envelope, 0, false, overlapcheck_sector),false);
981 
982  RegisterPhysicalVolume(new G4PVPlacement(row%2==0 ? rotationSensor : 0, G4ThreeVector( ( ( numSensorsInner / 2.0 ) * segmentlength ) + ( (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0 ), (row*fullsensor_width), offsetzFront),
983  TTLDetRowLogical, "TTLDetRowPhysicalPlacedFrontRight_" + std::to_string(row), log_module_envelope, 0, false, overlapcheck_sector),false);
984 
985  G4RotationMatrix *rotationSensorBck1 = new G4RotationMatrix();
986  rotationSensorBck1->rotateX(-M_PI);
987  G4RotationMatrix *rotationSensorBck2 = new G4RotationMatrix();
988  rotationSensorBck2->rotateZ(-M_PI);
989  rotationSensorBck2->rotateX(-M_PI);
990 
991  RegisterPhysicalVolume(new G4PVPlacement(row%2==0 ? rotationSensorBck2 : rotationSensorBck1, G4ThreeVector( - ( ( numSensorsInner / 2.0 ) * segmentlength ) - ( (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0 ), (row*fullsensor_width), offsetzBack),
992  TTLDetRowLogical, "TTLDetRowPhysicalPlacedBckLeft_" + std::to_string(row), log_module_envelope, 0, false, overlapcheck_sector),false);
993 
994  RegisterPhysicalVolume(new G4PVPlacement(row%2==0 ? rotationSensorBck2 : rotationSensorBck1, G4ThreeVector( ( ( numSensorsInner / 2.0 ) * segmentlength ) + ( (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0 ), (row*fullsensor_width), offsetzBack),
995  TTLDetRowLogical, "TTLDetRowPhysicalPlacedBckRight_" + std::to_string(row), log_module_envelope, 0, false, overlapcheck_sector),false);
996 
997  // cooling
998  G4VSolid *sol_cutout_tube_bothsides = new G4Box("sol_cutout_tube_bothsides" + std::to_string(row),
999  1.3*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) )/2,
1000  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
1001  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2);
1002  G4VSolid *sol_cooling_tube_bothsides = new G4Box("sol_cooling_tube_bothsides_tmp" + std::to_string(row),
1003  0.96*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)) )/2,
1004  diameter_coolingtube / 2,
1005  diameter_coolingtube / 2);
1006  sol_cooling_tube_bothsides = new G4SubtractionSolid(G4String("sol_cooling_tube_bothsides" + std::to_string(row)), sol_cooling_tube_bothsides, sol_cutout_tube_bothsides, 0, G4ThreeVector(0,0,0));
1007  G4LogicalVolume *Log_cooling_tube_bothsides = new G4LogicalVolume(sol_cooling_tube_bothsides, //
1008  GetDetectorMaterial("G4_Al"), "Log_cooling_tube_bothsides" + std::to_string(row));
1009  RegisterLogicalVolume(Log_cooling_tube_bothsides);
1010  m_DisplayAction->AddVolume(Log_cooling_tube_bothsides, "Cooling_tube");
1011 
1012  G4VSolid *sol_water_cooling_bothsides = new G4Box("sol_water_cooling_bothsides" + std::to_string(row),
1013  0.95*(sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) ,2))- sqrt(pow(rMin,2)-pow( (abs(row)*fullsensor_width)-(fullsensor_width/2) ,2)))/2,
1014  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
1015  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2);
1016  G4LogicalVolume *Log_water_cooling_bothsides = new G4LogicalVolume(sol_water_cooling_bothsides, //
1017  GetDetectorMaterial("G4_WATER"), "Log_water_cooling_bothsides" + std::to_string(row));
1018  RegisterLogicalVolume(Log_water_cooling_bothsides);
1019  m_DisplayAction->AddVolume(Log_water_cooling_bothsides, "Water_cooling");
1020 
1021  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(- ( ( numSensorsInner / 2.0 ) * segmentlength ) - ( (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0 ), row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_cooling_tube_bothsides,
1022  "cooling_tube_bothsides_l_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
1023  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(( ( numSensorsInner / 2.0 ) * segmentlength ) + ( (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0 ), row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_cooling_tube_bothsides,
1024  "cooling_tube_bothsides_r_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
1025  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(- ( ( numSensorsInner / 2.0 ) * segmentlength ) - ( (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0 ), row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_water_cooling_bothsides,
1026  "cooling_water_bothsides_l_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
1027  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(( ( numSensorsInner / 2.0 ) * segmentlength ) + ( (numSensorsRow - numSensorsInner) / 2 * segmentlength / 2.0 ), row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_water_cooling_bothsides,
1028  "cooling_water_bothsides_r_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
1029  }
1030  } else {
1031  // create mother volume with space for numSensorsRow towers along x-axis
1032  auto TTLDetRowSolid = new G4Box("TTLDetRowBox" + std::to_string(row), numSensorsRow * segmentlength / 2.0,fullsensor_width / 2.0,thicknessDet_SH / 2.0);
1033  auto TTLDetRowLogical = new G4LogicalVolume(TTLDetRowSolid,Air,"TTLDetRowLogical" + std::to_string(row));
1034  m_DisplayAction->AddVolume(TTLDetRowLogical, "StripBox");
1035  // replicate singletower tower design numSensorsRow times along x-axis
1036  new G4PVReplica("TTLDetRowPhysicalReplica" + std::to_string(row),log_sensor_and_readout,TTLDetRowLogical,
1037  kXAxis,numSensorsRow,segmentlength);
1038 
1039  G4RotationMatrix *rotationSensor = new G4RotationMatrix();
1040  rotationSensor->rotateZ(-M_PI);
1041  RegisterPhysicalVolume(new G4PVPlacement(row%2==0 ? rotationSensor : 0, G4ThreeVector(0, (row*fullsensor_width), offsetzFront),
1042  TTLDetRowLogical, "TTLDetRowPhysicalFront" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector),false);
1043 
1044  G4RotationMatrix *rotationSensorBck1 = new G4RotationMatrix();
1045  rotationSensorBck1->rotateX(-M_PI);
1046  G4RotationMatrix *rotationSensorBck2 = new G4RotationMatrix();
1047  rotationSensorBck2->rotateZ(-M_PI);
1048  rotationSensorBck2->rotateX(-M_PI);
1049  RegisterPhysicalVolume(new G4PVPlacement(row%2==0 ? rotationSensorBck2 : rotationSensorBck1, G4ThreeVector(0, (row*fullsensor_width), offsetzBack),
1050  TTLDetRowLogical, "TTLDetRowPhysicalBack" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector),false);
1051 
1052 
1053  G4VSolid *sol_cutout_tube = new G4Box("sol_cutout_tube" + std::to_string(row),
1054  2.5*sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) + diameter_coolingtube ,2))/2,
1055  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
1056  (diameter_coolingtube - 2*wallthickness_coolingtube) / 2);
1057  G4VSolid *sol_cooling_tube = new G4Box("sol_cooling_tube_tmp" + std::to_string(row),
1058  0.98*2*sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) + diameter_coolingtube ,2))/2,
1059  diameter_coolingtube / 2,
1060  diameter_coolingtube / 2);
1061  sol_cooling_tube = new G4SubtractionSolid(G4String("sol_cooling_tube" + std::to_string(row)), sol_cooling_tube, sol_cutout_tube, 0, G4ThreeVector(0,0,0));
1062  G4LogicalVolume *Log_cooling_tube = new G4LogicalVolume(sol_cooling_tube, //
1063  GetDetectorMaterial("G4_Al"), "Log_cooling_tube" + std::to_string(row));
1064  RegisterLogicalVolume(Log_cooling_tube);
1065  m_DisplayAction->AddVolume(Log_cooling_tube, "Cooling_tube");
1066 
1067  G4VSolid *sol_water_cooling = new G4Box("sol_water_cooling" + std::to_string(row),
1068  0.97*2*sqrt(pow(rMax,2)-pow( (abs(row)*fullsensor_width) - (fullsensor_width/2.0) + diameter_coolingtube ,2))/2,
1069  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2,
1070  0.99*(diameter_coolingtube - 2*wallthickness_coolingtube) / 2);
1071  G4LogicalVolume *Log_water_cooling = new G4LogicalVolume(sol_water_cooling, //
1072  GetDetectorMaterial("G4_WATER"), "Log_water_cooling" + std::to_string(row));
1073  RegisterLogicalVolume(Log_water_cooling);
1074  m_DisplayAction->AddVolume(Log_water_cooling, "Water_cooling");
1075 
1076  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(0, row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_cooling_tube,
1077  "cooling_tube_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
1078  RegisterPhysicalVolume(new G4PVPlacement(rotationSensor, G4ThreeVector(0, row>0 ? (row*fullsensor_width) - (fullsensor_width/2.0) : (row*fullsensor_width) + (fullsensor_width/2.0), 0), Log_water_cooling,
1079  "cooling_water_Physical_" + std::to_string(row), log_module_envelope, false, 0, overlapcheck_sector), false);
1080  }
1081  }
1082 }
1083 
1084 
1087 {
1088  if (!v)
1089  {
1090  std::cout
1091  << "PHG4TTLDetector::RegisterVolume - Error - invalid volume!"
1092  << std::endl;
1093  return v;
1094  }
1095  if (map_log_vol.find(v->GetName()) != map_log_vol.end())
1096  {
1097  std::cout << "PHG4TTLDetector::RegisterVolume - Warning - replacing " << v->GetName() << std::endl;
1098  }
1099 
1100  map_log_vol[v->GetName()] = v;
1101 
1102  return v;
1103 }
1104 
1105 G4PVPlacement *
1107  const bool active)
1108 {
1109  if (!v)
1110  {
1111  std::cout
1112  << "PHG4TTLDetector::RegisterPhysicalVolume - Error - invalid volume!"
1113  << std::endl;
1114  return v;
1115  }
1116 
1117  phy_vol_idx_t id(v->GetName(), v->GetCopyNo());
1118 
1119  if (map_phy_vol.find(id) != map_phy_vol.end())
1120  {
1121  std::cout
1122  << "PHG4TTLDetector::RegisterPhysicalVolume - Warning - replacing "
1123  << v->GetName() << "[" << v->GetCopyNo() << "]" << std::endl;
1124  }
1125 
1126  map_phy_vol[id] = v;
1127 
1128  if (active)
1129  map_active_phy_vol[id] = v;
1130 
1131  return v;
1132 }