4 #include <phparameter/PHParameters.h>
12 #include <Geant4/G4Box.hh>
13 #include <Geant4/G4Cons.hh>
14 #include <Geant4/G4Element.hh>
15 #include <Geant4/G4LogicalBorderSurface.hh>
16 #include <Geant4/G4LogicalSkinSurface.hh>
17 #include <Geant4/G4LogicalVolume.hh>
18 #include <Geant4/G4Material.hh>
19 #include <Geant4/G4MaterialPropertiesTable.hh>
20 #include <Geant4/G4OpticalSurface.hh>
21 #include <Geant4/G4PVPlacement.hh>
22 #include <Geant4/G4Polyhedra.hh>
23 #include <Geant4/G4RotationMatrix.hh>
24 #include <Geant4/G4String.hh>
25 #include <Geant4/G4SubtractionSolid.hh>
26 #include <Geant4/G4SystemOfUnits.hh>
27 #include <Geant4/G4ThreeVector.hh>
28 #include <Geant4/G4Transform3D.hh>
29 #include <Geant4/G4Types.hh>
30 #include <Geant4/G4UnionSolid.hh>
31 #include <Geant4/G4VisAttributes.hh>
49 , m_SuperDetector(
"NONE")
50 , m_Params(parameters)
52 , _towerlogicnameprefix(
"HybridHomogeneousCalorimeterTower")
53 , m_IsActive(m_Params->get_int_param(
"active"))
54 , m_AbsorberActive(m_Params->get_int_param(
"absorberactive"))
55 , m_doLightProp(
false)
84 cout <<
"PHG4HybridHomogeneousCalorimeterDetector: Begin Construction" << endl;
89 cout <<
"ERROR in PHG4HybridHomogeneousCalorimeterDetector: No tower mapping file specified. Abort detector construction." << endl;
90 cout <<
"Please run set_string_param(\"mappingtower\", std::string filename ) first." << endl;
117 const G4int nZSlices = 4;
118 G4double zPosSlice[nZSlices] = {0, 0.001, frame_dz - 0.001, frame_dz};
119 G4double rinPosSlice[nZSlices] = {frame_r_in, frame_r_in, frame_r_in, frame_r_in};
120 G4double routPosSlice[nZSlices] = {frame_r_out, frame_r_out, frame_r_out, frame_r_out};
122 G4VSolid* frame_full_solid =
new G4Polyhedra(G4String(
"frame_full_solid"),
130 G4LogicalVolume* frame_full_logic =
new G4LogicalVolume(frame_full_solid,
GetDetectorMaterial(
"G4_Fe"),
"frame_full_logic", 0, 0, 0);
133 G4RotationMatrix* rotFrame =
new G4RotationMatrix();
134 rotFrame->rotateZ(
M_PI / 12);
135 new G4PVPlacement(rotFrame, G4ThreeVector(0, 0, frame_z_pos - frame_dz / 2),
141 return frame_full_logic;
149 cout <<
"PHG4HybridHomogeneousCalorimeterDetector: Build logical volume for single tower..." << endl;
162 bool doWrapping =
false;
163 if (reflective_foil_thickness > 0 || tedlar_thickness > 0) doWrapping =
true;
168 bool doSensors =
false;
169 if (sensor_dimension > 0 && sensor_count > 0 && sensor_thickness > 0) doSensors =
true;
171 G4double tower_dx = crystal_dx + 2 * (carbon_thickness + airgap_crystal_carbon + reflective_foil_thickness + tedlar_thickness);
172 G4double tower_dy = crystal_dy + 2 * (carbon_thickness + airgap_crystal_carbon + reflective_foil_thickness + tedlar_thickness);
173 G4double tower_dz = crystal_dz + 2 * (carbon_thickness);
174 if (doSensors) tower_dz = crystal_dz + 2 * (carbon_thickness) + sensor_thickness;
185 G4VSolid* single_tower_solid =
new G4Box(G4String(
"single_tower_solid"), tower_dx / 2.0, tower_dy / 2.0, tower_dz / 2.0);
186 G4LogicalVolume* single_tower_logic =
new G4LogicalVolume(single_tower_solid, WorldMaterial,
"single_tower_logic", 0, 0, 0);
189 G4VSolid* solid_crystal =
new G4Box(G4String(
"single_crystal_solid"),
195 if (carbon_frame_style == 0 && carbon_thickness > 0)
198 G4VSolid* Carbon_hunk_solid =
new G4Box(G4String(
"Carbon_hunk_solid"),
201 ((tower_dz / 2.0) - 1 *
mm));
203 G4VSolid* cutout_solid =
new G4Box(G4String(
"lead_solid"), crystal_dx / 2.0, crystal_dy / 2.0, crystal_dz);
205 G4SubtractionSolid* Carbon_shell_solid =
new G4SubtractionSolid(G4String(
"Carbon_Shell_solid"),
209 G4ThreeVector(0.00 *
mm, 0.00 *
mm, 0.00 *
mm));
211 G4LogicalVolume* Carbon_shell_logic =
new G4LogicalVolume(Carbon_shell_solid, material_shell,
"Carbon_shell_logic", 0, 0, 0);
219 G4VPhysicalVolume* physvol_carbon =
new G4PVPlacement(0, G4ThreeVector(0, 0, sensor_thickness / 2), Carbon_shell_logic, name_shell, single_tower_logic, 0, 0,
OverlapCheck());
222 else if (carbon_frame_style == 1)
226 G4VSolid* Carbon_hunk_solid =
new G4Box(G4String(
"Carbon_hunk_solid"),
229 (carbon_frame_depth / 2.0));
230 G4VSolid* cutout_solid =
new G4Box(G4String(
"cutout_solid"), (tower_dx - 2 * (carbon_thickness)) / 2.0, (tower_dy - 2 * (carbon_thickness)) / 2.0, crystal_dz);
232 G4SubtractionSolid* Carbon_gap_solid =
new G4SubtractionSolid(G4String(
"Carbon_gap_solid"),
236 G4ThreeVector(0.00 *
mm, 0.00 *
mm, 0.00 *
mm));
237 G4LogicalVolume* logic_gap =
new G4LogicalVolume(Carbon_gap_solid, material_shell,
"Carbon_gap_logic", 0, 0, 0);
241 G4VPhysicalVolume* physvol_carbon_gap_front =
new G4PVPlacement(0, G4ThreeVector(0, 0, tower_dz / 2 - carbon_frame_depth / 2 - carbon_thickness), logic_gap, name_gap +
"_gap_front", single_tower_logic, 0, 0,
OverlapCheck());
243 G4VPhysicalVolume* physvol_carbon_gap_back =
new G4PVPlacement(0, G4ThreeVector(0, 0, -tower_dz / 2 + carbon_frame_depth / 2 + carbon_thickness + sensor_thickness), logic_gap, name_gap +
"_gap_back", single_tower_logic, 0, 0,
OverlapCheck());
248 G4VSolid* Carbon_hunk_solid_face =
new G4Box(G4String(
"Carbon_hunk_solid_face"),
251 (carbon_thickness / 2.0));
252 G4VSolid* cutout_solid_face =
new G4Box(G4String(
"cutout_solid_face"), (tower_dx - 2.0 * carbon_face_lip) / 2.0, (tower_dy - 2.0 * carbon_face_lip) / 2.0, (tower_dz));
254 G4SubtractionSolid* Carbon_face_solid =
new G4SubtractionSolid(G4String(
"Carbon_face_solid"),
255 Carbon_hunk_solid_face,
258 G4ThreeVector(0.00 *
mm, 0.00 *
mm, 0.00 *
mm));
259 G4LogicalVolume* logic_face =
new G4LogicalVolume(Carbon_face_solid, material_shell,
"Carbon_face_logic", 0, 0, 0);
263 G4VPhysicalVolume* physvol_carbon_face_front =
new G4PVPlacement(0, G4ThreeVector(0, 0, tower_dz / 2 - carbon_thickness / 2), logic_face, name_face +
"_face_front", single_tower_logic, 0, 0,
OverlapCheck());
265 G4VPhysicalVolume* physvol_carbon_face_back =
new G4PVPlacement(0, G4ThreeVector(0, 0, -tower_dz / 2 + carbon_thickness / 2 + sensor_thickness), logic_face, name_face +
"_face_back", single_tower_logic, 0, 0,
OverlapCheck());
271 G4VSolid* VM2000_hunk_solid =
new G4Box(G4String(
"VM2000_hunk_solid"),
272 (crystal_dx + 2 * reflective_foil_thickness) / 2.0,
273 (crystal_dy + 2 * reflective_foil_thickness) / 2.0,
274 ((crystal_dz / 2.0) - 1 *
mm));
276 G4VSolid* cutout_solid_VM2000 =
new G4Box(G4String(
"cutout_solid_VM2000"), crystal_dx / 2.0, crystal_dy / 2.0, crystal_dz);
278 G4SubtractionSolid* VM2000_foil_solid =
new G4SubtractionSolid(G4String(
"VM2000_foil_solid"),
282 G4ThreeVector(0.00 *
mm, 0.00 *
mm, 0.00 *
mm));
284 G4LogicalVolume* VM2000_foil_logic =
new G4LogicalVolume(VM2000_foil_solid,
GetVM2000Material(),
"VM2000_foil_logic", 0, 0, 0);
288 G4VPhysicalVolume* physvol_VM2000 =
new G4PVPlacement(0, G4ThreeVector(0, 0, sensor_thickness / 2), VM2000_foil_logic, name_VM2000foil, single_tower_logic, 0, 0,
OverlapCheck());
292 G4VSolid* Tedlar_hunk_solid =
new G4Box(G4String(
"Tedlar_hunk_solid"),
293 (crystal_dx + 2 * reflective_foil_thickness + 2 * tedlar_thickness) / 2.0,
294 (crystal_dy + 2 * reflective_foil_thickness + 2 * tedlar_thickness) / 2.0,
295 ((crystal_dz / 2.0) - 1 *
mm));
297 G4VSolid* cutout_solid_Tedlar =
new G4Box(G4String(
"cutout_solid_Tedlar"), (crystal_dx + 2 * reflective_foil_thickness) / 2.0, (crystal_dy + 2 * reflective_foil_thickness) / 2.0, crystal_dz);
299 G4SubtractionSolid* Tedlar_foil_solid =
new G4SubtractionSolid(G4String(
"Tedlar_foil_solid"),
303 G4ThreeVector(0.00 *
mm, 0.00 *
mm, 0.00 *
mm));
305 G4LogicalVolume* Tedlar_foil_logic =
new G4LogicalVolume(Tedlar_foil_solid,
GetTedlarMaterial(),
"Tedlar_foil_logic", 0, 0, 0);
309 G4VPhysicalVolume* physvol_Tedlar =
new G4PVPlacement(0, G4ThreeVector(0, 0, sensor_thickness / 2), Tedlar_foil_logic, name_Tedlarfoil, single_tower_logic, 0, 0,
OverlapCheck());
324 G4LogicalVolume* logic_crystal =
new G4LogicalVolume(solid_crystal, material_Scin,
"single_crystal_logic", 0, 0, 0);
335 G4VPhysicalVolume* physvol_crys =
new G4PVPlacement(0, G4ThreeVector(0, 0, sensor_thickness / 2), logic_crystal, name_crystal, single_tower_logic, 0, 0,
OverlapCheck());
340 G4VSolid* single_sensor_solid =
new G4Box(
"single_sensor_solid", sensor_dimension / 2., sensor_dimension / 2., sensor_thickness / 2.);
343 G4LogicalVolume* single_sensor_logic =
new G4LogicalVolume(single_sensor_solid, material_Sensor,
"single_sensor_logic", 0, 0, 0);
348 G4VPhysicalVolume* physvol_sensor_0 =
new G4PVPlacement(0, G4ThreeVector(0, 0, -tower_dz / 2 + carbon_thickness + sensor_thickness / 2), single_sensor_logic, name_sensor, single_tower_logic, 0, 0,
OverlapCheck());
356 cout <<
"PHG4HybridHomogeneousCalorimeterDetector: Building logical volume for single tower done." << endl;
358 return single_tower_logic;
364 typedef std::map<std::string, towerposition>::iterator it_type;
369 cout <<
"PHG4HybridHomogeneousCalorimeterDetector: Place tower " << iterator->first
370 <<
" idx_j = " << iterator->second.idx_j <<
", idx_k = " << iterator->second.idx_k
371 <<
" at x = " << iterator->second.x <<
" , y = " << iterator->second.y <<
" , z = " << iterator->second.z << endl;
373 int copyno = (iterator->second.idx_j << 16) + iterator->second.idx_k;
374 new G4PVPlacement(0, G4ThreeVector(iterator->second.x, iterator->second.y, iterator->second.z),
388 G4Element* ele_O =
new G4Element(
"Oxygen",
"O", 8., 16.00 *
g / mole);
389 G4Element* ele_Si =
new G4Element(
"Silicon",
"Si", 14., 28.09 *
g / mole);
390 G4Element* ele_B =
new G4Element(
"Boron",
"B", 5., 10.811 *
g / mole);
391 G4Element* ele_Na =
new G4Element(
"Sodium",
"Na", 11., 22.99 *
g / mole);
392 G4Element* ele_Mg =
new G4Element(
"Magnesium",
"Mg", 12., 24.30 *
g / mole);
393 G4Element* ele_Pb =
new G4Element(
"Lead",
"Pb", 82., 207.2 *
g / mole);
394 G4Element* ele_Ba =
new G4Element(
"Barium",
"Ba", 56., 137.3 *
g / mole);
395 G4Element* ele_Gd =
new G4Element(
"Gadolinium",
"Gd", 64., 157.3 *
g / mole);
399 if ((setting > 0.) && (setting < 1.))
403 if (
Verbosity()) cout <<
"Set G4_PbWO4..." << endl;
405 else if ((setting > 1.) && (setting < 2.))
408 if (
Verbosity()) cout <<
"Set G4_GLASS_LEAD..." << endl;
410 else if ((setting > 2.) && (setting < 3.))
413 if (
Verbosity()) cout <<
"Set G4_BARIUM_SULFATE..." << endl;
415 else if ((setting > 3.) && (setting < 4.))
418 if (
Verbosity()) cout <<
"Set G4_CESIUM_IODIDE..." << endl;
420 else if ((setting > 4.) && (setting < 5.))
422 material_Scin =
new G4Material(
"material_Scin", 4.5 *
g /
cm3, 5);
423 material_Scin->AddElement(ele_Si, 21.9 * perCent);
424 material_Scin->AddElement(ele_B, 8.8 * perCent);
425 material_Scin->AddElement(ele_Na, 10.4 * perCent);
426 material_Scin->AddElement(ele_Mg, 6.5 * perCent);
427 material_Scin->AddElement(ele_O, 52.4 * perCent);
429 if (
Verbosity()) cout <<
"Set Sciglass..." << endl;
431 else if ((setting > 5.) && (setting < 6.))
433 material_Scin =
new G4Material(
"material_Scin", 9.0 *
g /
cm3, 5);
434 material_Scin->AddElement(ele_Si, 21.9 * perCent);
435 material_Scin->AddElement(ele_B, 8.8 * perCent);
436 material_Scin->AddElement(ele_Na, 10.4 * perCent);
437 material_Scin->AddElement(ele_Mg, 6.5 * perCent);
438 material_Scin->AddElement(ele_O, 52.4 * perCent);
440 if (
Verbosity()) cout <<
"Set heavier Sciglass..." << endl;
442 else if ((setting > 6.) && (setting < 7.))
444 material_Scin =
new G4Material(
"material_Scin", 4.5 *
g /
cm3, 3);
445 material_Scin->AddElement(ele_Si, 21.9 * perCent);
446 material_Scin->AddElement(ele_O, 52.4 * perCent);
447 material_Scin->AddElement(ele_Pb, 25.7 * perCent);
449 if (
Verbosity()) cout <<
"Set Sciglass contained lead..." << endl;
451 else if ((setting > 7.) && (setting < 8.))
453 material_Scin =
new G4Material(
"material_Scin", 4.22 *
g /
cm3, 4);
454 material_Scin->AddElement(ele_O, 0.261);
455 material_Scin->AddElement(ele_Ba, 0.3875);
456 material_Scin->AddElement(ele_Si, 0.1369);
457 material_Scin->AddElement(ele_Gd, 0.2146);
459 if (
Verbosity()) cout <<
"Set Sciglass from Nathaly" << endl;
461 else if ((setting > 8.) && (setting < 9.))
463 material_Scin =
new G4Material(
"material_Scin", 3.8 *
g /
cm3, 3);
464 material_Scin->AddElement(ele_O, 0.293);
465 material_Scin->AddElement(ele_Ba, 0.502);
466 material_Scin->AddElement(ele_Si, 0.205);
468 if (
Verbosity()) cout <<
"Set Sciglass from g4e" << endl;
471 return material_Scin;
480 if (mat->GetMaterialPropertiesTable())
return;
484 const G4int ntab = 2;
485 G4double scin_en[] = {2.9 *
eV, 3. *
eV};
486 G4double scin_fast[] = {1., 1.};
488 G4MaterialPropertiesTable* tab =
new G4MaterialPropertiesTable();
490 tab->AddProperty(
"FASTCOMPONENT", scin_en, scin_fast, ntab);
491 tab->AddConstProperty(
"FASTTIMECONSTANT", 6 *
ns);
492 tab->AddConstProperty(
"SCINTILLATIONYIELD", 200 /
MeV);
493 tab->AddConstProperty(
"RESOLUTIONSCALE", 1.);
495 G4double opt_en[] = {1.551 *
eV, 3.545 *
eV};
496 G4double opt_r[] = {2.4, 2.4};
497 G4double opt_abs[] = {200 *
cm, 200 *
cm};
499 tab->AddProperty(
"RINDEX", opt_en, opt_r, ntab);
500 tab->AddProperty(
"ABSLENGTH", opt_en, opt_abs, ntab);
502 mat->SetMaterialPropertiesTable(tab);
511 G4OpticalSurface*
surface =
new G4OpticalSurface(
"CrystalSurface", unified, polished, dielectric_metal);
513 new G4LogicalSkinSurface(
"CrystalSurfaceL", vol, surface);
516 const G4int ntab = 2;
517 G4double opt_en[] = {1.551 *
eV, 3.545 *
eV};
518 G4double reflectivity[] = {0.8, 0.8};
519 G4double efficiency[] = {0.9, 0.9};
520 G4MaterialPropertiesTable* surfmat =
new G4MaterialPropertiesTable();
521 surfmat->AddProperty(
"REFLECTIVITY", opt_en, reflectivity, ntab);
522 surfmat->AddProperty(
"EFFICIENCY", opt_en, efficiency, ntab);
523 surface->SetMaterialPropertiesTable(surfmat);
533 G4OpticalSurface* surf =
new G4OpticalSurface(
"OpDetS");
535 surf->SetType(dielectric_metal);
537 surf->SetFinish(polished);
539 surf->SetModel(glisur);
541 new G4LogicalBorderSurface(
"OpDetB", crystal, opdet, surf);
543 const G4int ntab = 2;
544 G4double opt_en[] = {1.551 *
eV, 3.545 *
eV};
546 G4double reflectivity[] = {0.1, 0.1};
549 G4double efficiency[] = {1., 1.};
551 G4MaterialPropertiesTable* surfmat =
new G4MaterialPropertiesTable();
552 surfmat->AddProperty(
"REFLECTIVITY", opt_en, reflectivity, ntab);
553 surfmat->AddProperty(
"EFFICIENCY", opt_en, efficiency, ntab);
554 surf->SetMaterialPropertiesTable(surfmat);
560 static string matname =
"HybridHomogeneousTedlar";
564 G4double density_tedlar = 1.43 *
g /
cm3;
565 tedlar =
new G4Material(matname, density_tedlar, 3);
566 tedlar->AddElement(G4Element::GetElement(
"C"), 2);
567 tedlar->AddElement(G4Element::GetElement(
"F"), 2);
568 tedlar->AddElement(G4Element::GetElement(
"H"), 2);
575 static string matname =
"HybridHomogeneousVM2000";
579 G4double density_VM2000 = 1.43 *
g /
cm3;
580 VM2000 =
new G4Material(matname, density_VM2000, 3);
581 VM2000->AddElement(G4Element::GetElement(
"C"), 2);
582 VM2000->AddElement(G4Element::GetElement(
"F"), 2);
583 VM2000->AddElement(G4Element::GetElement(
"H"), 2);
585 G4MaterialPropertiesTable* mptVM2000 =
new G4MaterialPropertiesTable();
586 const G4int nEntriesVM2000 = 31;
588 G4double photonE_VM2000[nEntriesVM2000] =
589 {1.37760 *
eV, 1.45864 *
eV, 1.54980 *
eV, 1.65312 *
eV, 1.71013 *
eV, 1.77120 *
eV, 1.83680 *
eV, 1.90745 *
eV, 1.98375 *
eV, 2.06640 *
eV, 2.10143 *
eV, 2.13766 *
eV, 2.17516 *
eV, 2.21400 *
eV, 2.25426 *
eV, 2.29600 *
eV, 2.33932 *
eV, 2.38431 *
eV, 2.43106 *
eV, 2.47968 *
eV, 2.53029 *
eV, 2.58300 *
eV, 2.63796 *
eV, 2.69531 *
eV, 2.75520 *
eV, 2.81782 *
eV, 2.88335 *
eV, 2.95200 *
eV, 3.09960 *
eV, 3.54241 *
eV, 4.13281 *
eV};
590 G4double refractiveIndex_VM2000[nEntriesVM2000] =
591 {1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42, 1.42};
592 mptVM2000->AddProperty(
"RINDEX", photonE_VM2000, refractiveIndex_VM2000, nEntriesVM2000);
594 VM2000->SetMaterialPropertiesTable(mptVM2000);
608 if (!istream_mapping.is_open())
610 cout <<
"ERROR in PHG4HybridHomogeneousCalorimeterDetector: Failed to open mapping file " <<
m_Params->
get_string_param(
"mappingtower") << endl;
616 while (
getline(istream_mapping, line_mapping))
619 if (line_mapping.find(
"#") != string::npos)
623 cout <<
"PHG4HybridHomogeneousCalorimeterDetector: SKIPPING line in mapping file: " << line_mapping << endl;
628 istringstream iss(line_mapping);
631 if (line_mapping.find(
"Tower ") != string::npos)
633 unsigned idx_j, idx_k, idx_l;
634 G4double pos_x, pos_y, pos_z;
635 G4double size_x, size_y,
size_z;
636 G4double rot_x, rot_y, rot_z;
641 if (!(iss >> dummys >> dummy >> idx_j >> idx_k >> idx_l >> pos_x >> pos_y >> pos_z >> size_x >> size_y >> size_z >> rot_x >> rot_y >> rot_z))
643 cout <<
"ERROR in PHG4HybridHomogeneousCalorimeterDetector: Failed to read line in mapping file " <<
m_Params->
get_string_param(
"mappingtower") << endl;
649 ostringstream towername;
663 tower_new.
idx_j = idx_j;
664 tower_new.
idx_k = idx_k;
665 _map_tower.insert(make_pair(towername.str(), tower_new));
674 if (!(iss >> parname >> parval))
676 cout <<
"ERROR in PHG4HybridHomogeneousCalorimeterDetector: Failed to read line in mapping file " <<
m_Params->
get_string_param(
"mappingtower") << endl;
685 std::map<string, G4double>::iterator parit;
852 static string matname =
"HybridHomogeneousCarbonFiber";
856 G4double density_carbon_fiber = 1.44 *
g /
cm3;
857 carbonfiber =
new G4Material(matname, density_carbon_fiber, 1);
858 carbonfiber->AddElement(G4Element::GetElement(
"C"), 1);