16 #include <phparameter/PHParameters.h>
22 #include <Geant4/G4Color.hh>
23 #include <Geant4/G4Box.hh>
24 #include <Geant4/G4LogicalVolume.hh>
25 #include <Geant4/G4Material.hh>
26 #include <Geant4/G4PVPlacement.hh>
27 #include <Geant4/G4SubtractionSolid.hh>
28 #include <Geant4/G4SystemOfUnits.hh>
29 #include <Geant4/G4Tubs.hh>
30 #include <Geant4/G4Box.hh>
31 #include <Geant4/G4Para.hh>
32 #include <Geant4/G4RotationMatrix.hh>
33 #include <Geant4/G4SystemOfUnits.hh>
34 #include <Geant4/G4ThreeVector.hh>
35 #include <Geant4/G4Transform3D.hh>
36 #include <Geant4/G4Types.hh>
37 #include <Geant4/G4VPhysicalVolume.hh>
39 #include <Geant4/G4UnionSolid.hh>
40 #include <Geant4/G4VisAttributes.hh>
41 #include <Geant4/G4TwoVector.hh>
42 #include <Geant4/G4ExtrudedSolid.hh>
43 #include <Geant4/G4Trd.hh>
68 const std::string &dnam,
const int lyr)
70 , m_Params(parameters)
119 std::cout <<
"EICG4LumiDetector: Begin Construction" << std::endl;
163 double factorV1 = 1.0;
164 double factorV2 = 1.0;
165 double factorV3 = 1.0;
171 std::string TrianTrapMaterial =
"G4_AIR";
172 std::string CuboidMaterial =
"G4_AIR";
173 std::string MagCoreMaterial =
"G4_AIR";
174 std::string RecConeMaterial =
"G4_AIR";
175 std::string ExitWinV2Material =
"G4_AIR";
176 std::string ExitWinV3Material =
"G4_AIR";
185 case 2: TrianTrapMaterial =
"G4_Galactic";
186 CuboidMaterial =
"G4_Galactic";
187 MagCoreMaterial =
"G4_Galactic";
189 ExitWinV2Material = LumiWin_Material;
193 case 3: TrianTrapMaterial =
"G4_Galactic";
194 CuboidMaterial =
"G4_Galactic";
195 MagCoreMaterial =
"G4_Galactic";
196 RecConeMaterial =
"G4_Galactic";
197 ExitWinV2Material =
"G4_Galactic";
199 ExitWinV3Material = LumiWin_Material;
203 default : std::cout<<
"WRONG CHOICE (ONLY 1, 2 & 3)"<<endl;
210 G4ThreeVector size_lw = G4ThreeVector( LumiWin_Length, LumiWin_Height, factorV1*LumiWin_Thickness );
211 G4ThreeVector pos_lw = G4ThreeVector( LumiWin_X, LumiWin_Y, LumiWin_Z );
214 G4ThreeVector size_ov = G4ThreeVector( LumiMag_inner, LumiMag_outer, LumiMag_DZ );
215 G4ThreeVector pos_ov = G4ThreeVector( LumiWin_X, LumiWin_Y, LumiMag_Z );
218 G4ThreeVector size_mc = G4ThreeVector( 0., LumiMag_inner, LumiMag_DZ );
222 G4ThreeVector size_ewV2 = G4ThreeVector( LumiWin_Length, LumiWin_Height, factorV2*LumiWin_Thickness );
223 G4ThreeVector size_ewV3 = G4ThreeVector( LumiWin_Length, LumiWin_Height, factorV3*LumiWin_Thickness );
226 G4ThreeVector size_tr2 = G4ThreeVector( LumiTracker2_XY, LumiTracker2_XY, LumiTracker2_DZ );
227 G4ThreeVector pos_tr2 = G4ThreeVector( LumiWin_X, pos_lw.y() + LumiPhotonCAL_XY/2.0 + size_tr2.y()/2.0 + 0.01*
cm,
228 LumiSpec_Z + LumiSpecTower_DZ/2.0 + LumiWin_Thickness + LumiTracker2_DZ/2.0 );
231 double LumiTracker1_XY = pos_tr2.y() - size_ewV2.y()/2.;
232 G4ThreeVector size_tr1 = G4ThreeVector( LumiTracker1_XY, LumiTracker1_XY, LumiTracker2_DZ );
235 G4ThreeVector size_st = G4ThreeVector(
236 TotalLumiSpecTower*LumiSpecTower_XY, TotalLumiSpecTower*LumiSpecTower_XY, LumiSpecTower_DZ );
239 double dz_tr2_daughter = -1*pos_tr2.z() - (-1*pos_ov.z() + size_ov.z()/2.0);
240 G4ThreeVector pos_ewV2_daughter = G4ThreeVector( 0.0, 0.0, dz_tr2_daughter/2.0 - size_ewV2.z()/2.0);
242 G4ThreeVector pos_tr2_top = G4ThreeVector( 0.0, LumiPhotonCAL_XY/2.0 + size_tr2.y()/2.0,
243 -1*(dz_tr2_daughter/2.0) + size_tr2.z()/2.0 );
244 G4ThreeVector pos_tr2_bot = G4ThreeVector( pos_tr2_top.x(), -1*pos_tr2_top.y(), pos_tr2_top.z() );
246 G4ThreeVector pos_tr1_top = G4ThreeVector( 0.0, pos_tr2.y()/2.0, 0.0 );
247 G4ThreeVector pos_tr1_bot = G4ThreeVector( pos_tr1_top.x() , -1*pos_tr1_top.y(), pos_tr1_top.z() );
252 AddLumiWindow( size_lw, pos_lw, LumiWin_Tilt, LumiWin_Material, logicWorld);
254 AddCuboid( size_lw, pos_lw, size_ov, pos_ov, LumiWin_Tilt, CuboidMaterial, logicWorld);
259 G4LogicalVolume* logicRecCone =
AddRecCone( size_lw, pos_lw, size_ov, pos_ov,
260 size_tr2, pos_tr2, LumiWin_Tilt, RecConeMaterial, logicWorld );
262 AddExitWindowForV2( size_ewV2, pos_ewV2_daughter, LumiWin_Tilt, ExitWinV2Material, logicRecCone );
266 AddLumiTracker(
"TopSpecTracker1", 0, size_tr1, pos_tr1_top, logicRecCone);
267 AddLumiTracker(
"BotSpecTracker1", 1, size_tr1, pos_tr1_bot, logicRecCone);
268 AddLumiTracker(
"TopSpecTracker2", 2, size_tr2, pos_tr2_top, logicRecCone);
269 AddLumiTracker(
"BotSpecTracker2", 3, size_tr2, pos_tr2_bot, logicRecCone);
271 AddExitWindowForV3( size_ewV3, pos_lw, size_tr2, pos_tr2, ExitWinV3Material, logicWorld );
275 AddCAL(
"TopSpecTower", size_st, G4ThreeVector(LumiWin_X, pos_tr2.y(), LumiSpec_Z), TotalLumiSpecTower, logicWorld );
276 AddCAL(
"BotSpecTower", size_st, G4ThreeVector(LumiWin_X, -1*pos_tr2.y(), LumiSpec_Z), TotalLumiSpecTower, logicWorld );
284 std::cout <<
"EICG4Lumi Detector:" << std::endl;
285 if (what ==
"ALL" || what ==
"VOLUME")
287 std::cout <<
"Version 0.1" << std::endl;
288 std::cout <<
"Parameters:" << std::endl;
304 std::string
name =
"LumiWindow";
305 G4Box *
solid =
new G4Box(name +
"_solid", (size.x()/2.0) + 0.3*
cm, size.y()/2.0, size.z()/2.0 );
308 G4LogicalVolume *logical =
new G4LogicalVolume( solid,
GetDetectorMaterial(material), name +
"_logical");
309 G4VisAttributes *vis =
new G4VisAttributes( G4Color(1, 0, 0, 1) );
310 vis->SetForceSolid(
true );
311 logical->SetVisAttributes(vis);
313 G4ThreeVector rot_axis = G4ThreeVector(0,1,0);
314 G4RotationMatrix *rot_matrix =
new G4RotationMatrix(rot_axis , angle);
316 G4ThreeVector pos_new = G4ThreeVector(pos.x() - (size.z()/(2.0*TMath::Sin(angle)) ), pos.y(), pos.z() );
317 G4VPhysicalVolume *physical =
new G4PVPlacement(rot_matrix, pos_new, logical, name+
"_physical", logicWorld, 0,
false,
OverlapCheck());
327 std::string
name =
"LumiExitWindow";
331 G4Box *
solid =
new G4Box(name +
"_solid", size.x(), size.y(), size.z());
333 G4LogicalVolume *logical =
new G4LogicalVolume( solid,
GetDetectorMaterial(material), name +
"_logical");
334 G4VisAttributes *vis =
new G4VisAttributes( G4Color(0, 1, 0, 1) );
335 vis->SetForceSolid(
true );
336 logical->SetVisAttributes(vis);
338 G4ThreeVector rot_axis = G4ThreeVector(0,1,0);
339 G4RotationMatrix *rot_matrix =
new G4RotationMatrix(rot_axis , angle);
340 G4ThreeVector pos_new = G4ThreeVector(pos.x(), pos.y(), pos.z() - size.z() - factor);
341 G4VPhysicalVolume *physical =
new G4PVPlacement(rot_matrix, pos_new, logical, name+
"_physical", logicWorld, 0,
false,
OverlapCheck());
351 std::string
name =
"LumiMag_OuterVessel";
354 G4Tubs *
solid =
new G4Tubs(name+
"_solid", size.x(), size.y(), size.z()/2., 0., 360.*deg);
356 G4LogicalVolume *logical =
new G4LogicalVolume(solid,
GetDetectorMaterial(material), name+
"_logical");
357 G4VisAttributes *vis =
new G4VisAttributes( G4Color(0, 1, 0, 0.5) );
358 vis->SetForceSolid(
true );
359 logical->SetVisAttributes( vis );
361 G4VPhysicalVolume *physical =
new G4PVPlacement( 0, pos, logical, name+
"_physical", logicWorld, 0,
false,
OverlapCheck() );
369 std::string
name =
"LumiMag_MagCore";
372 G4Tubs *
solid =
new G4Tubs(name, size.x(), size.y() - 0.01*
cm, size.z()/2.0, 0., 360.*deg);
374 G4LogicalVolume *logical =
new G4LogicalVolume( solid,
GetDetectorMaterial(material), name);
375 logical->SetVisAttributes( G4VisAttributes::GetInvisible() );
377 G4UniformMagField *field =
new G4UniformMagField( G4ThreeVector(Bx, 0, 0 ) );
378 G4FieldManager *fman =
new G4FieldManager();
379 fman->SetDetectorField( field );
380 fman->CreateChordFinder( field );
381 logical->SetFieldManager(fman,
true);
383 G4VPhysicalVolume *physical =
new G4PVPlacement( 0, pos, logical, name, logicWorld, 0,
false,
OverlapCheck() );
394 std::string
name =
"LumiTrainTrap";
395 std::vector<G4TwoVector> polygon;
397 double x1 = -1*(size.x()/2.0)*TMath::Cos(angle);
398 double y1 = -1*(size.x()/2.0)*TMath::Sin(angle);
400 double x2 = (size.x()/2.0)*TMath::Cos(angle);
401 double y2 = -1*(size.x()/2.0)*TMath::Sin(angle);
403 double x3 = (size.x()/2.0)*TMath::Cos(angle);
404 double y3 = (size.x()/2.0)*TMath::Sin(angle);
406 polygon.push_back({x1, y1});
407 polygon.push_back({
x2, y2});
408 polygon.push_back({
x3, y3});
411 std::vector<G4ExtrudedSolid::ZSection> zsections = {
412 {-1*size.y()/2.0, {0,0}, 1.0}, {size.y()/2.0, {0,0}, 1.0} };
414 G4ExtrudedSolid *
solid =
new G4ExtrudedSolid(name+
"_ExtrudedSolid", polygon, zsections);
418 G4LogicalVolume *logical =
new G4LogicalVolume(solid,
GetDetectorMaterial(material), name+
"_logical");
421 G4VisAttributes *vis =
new G4VisAttributes( G4Color(0, 1, 1, 0.3) );
422 vis->SetForceSolid(
true);
423 logical->SetVisAttributes(vis);
426 G4RotationMatrix *rot_matrix =
new G4RotationMatrix( G4ThreeVector(1, 0, 0), -1*TMath::Pi()/2.0 );
428 G4VPhysicalVolume *physical =
new G4PVPlacement( rot_matrix, pos, logical, name+
"_physical", logicWorld, 0,
false,
OverlapCheck());
439 std::string
name =
"LumiCuboid";
440 double dz_cuboid = -1*Mpos.z() - (Msize.z()/2.0) - ( -1*Wpos.z() + ((Wsize.x()/2.0)*TMath::Sin(angle)));
441 G4Box *
solid =
new G4Box(name +
"_solid",(Wsize.x()/2.0)*TMath::Cos(angle), Wsize.y()/2.0, dz_cuboid/2.0);
443 G4LogicalVolume *logical =
new G4LogicalVolume(solid,
GetDetectorMaterial(material),name +
"_logic");
444 G4VisAttributes *vis =
new G4VisAttributes( G4Color(0, 1, 1, 0.3) );
445 vis->SetForceSolid(
true );
446 logical->SetVisAttributes( vis );
448 double zpos_cuboid = Wpos.z() - (Wsize.x()/2.0)*TMath::Sin(angle) - dz_cuboid/2.0 ;
449 G4ThreeVector pos_cuboid = G4ThreeVector( Wpos.x(), Wpos.y(), zpos_cuboid);
450 G4VPhysicalVolume *physical =
new G4PVPlacement(0, pos_cuboid, logical, name +
"_physical", logicWorld, 0,
false,
OverlapCheck());
459 G4LogicalVolume*
EICG4LumiDetector::AddRecCone(G4ThreeVector Wsize, G4ThreeVector Wpos, G4ThreeVector Msize, G4ThreeVector Mpos, G4ThreeVector Tr2size, G4ThreeVector Tr2pos,
double angle, std::string
material, G4LogicalVolume *logicWorld)
462 double dz_rec_cone = ( -1*Tr2pos.z() + Tr2size.z()/2.0 ) - (-1*Mpos.z() + Msize.z()/2.0);
463 G4Trd *
solid =
new G4Trd(
"solid", Tr2size.x()/2.0 + 1*
cm,(Wsize.x()/2.0)*TMath::Cos(angle), Tr2pos.y() + Tr2size.y()/2.0 + 2.0*
cm, Wsize.y()/2.0, dz_rec_cone/2.0);
465 G4LogicalVolume *logical =
new G4LogicalVolume(solid,
GetDetectorMaterial(
"G4_Galactic"),
"Lumi_RectangularCone");
466 G4VisAttributes *vis =
new G4VisAttributes( G4Color(0, 1, 1, 0.3) );
467 vis->SetForceSolid(
true );
468 logical->SetVisAttributes( vis);
470 G4ThreeVector pos_rec_cone = G4ThreeVector(Wpos.x(), Wpos.y(), Mpos.z() - Msize.z()/2.0 - dz_rec_cone/2.0);
471 G4VPhysicalVolume *physical =
new G4PVPlacement(0, pos_rec_cone, logical,
"Lumi_RectangularCone", logicWorld, 0,
false,
OverlapCheck());
480 std::string
name =
"LumiExitWinV2";
481 G4Box *
solid =
new G4Box(name+
"solid",(Wsize.x()/2.0)*TMath::Cos(angle), Wsize.y()/2.0, Wsize.z()/2.0);
483 G4LogicalVolume *logical =
new G4LogicalVolume( solid,
GetDetectorMaterial(material), name+
"logical");
484 G4VisAttributes *vis =
new G4VisAttributes( G4Color(1, 0, 0, 1) );
485 vis->SetForceSolid(
true );
486 logical->SetVisAttributes( vis );
488 G4VPhysicalVolume *physical =
new G4PVPlacement(0, pos_daug, logical, name+
"physical", logicWorld, 0,
false,
OverlapCheck());
496 G4Box *
solid =
new G4Box(name +
"_solid", size.x()/2.0 , size.y()/2.0 , size.z()/2.0);
498 G4LogicalVolume *logical =
new G4LogicalVolume( solid, G4NistManager::Instance()->FindOrBuildMaterial(
"G4_Si"), name +
"_logical");
500 G4VisAttributes *vis =
new G4VisAttributes( G4Color(1.0, 1.0, 0.0, 1.0) );
501 vis->SetForceSolid(
true);
502 logical->SetVisAttributes(vis);
504 G4VPhysicalVolume *physical =
new G4PVPlacement( 0, pos, logical, name +
"_physical", logicWorld,
false, copyNum,
OverlapCheck() );
514 std::string
name =
"LumiExitWinV3";
515 G4Box *
solid =
new G4Box(name+
"_solid",Tr2size.x()/2.0 + 1*
cm, Tr2size.y() + Tr2pos.y()/2.0 + 2.0*
cm, Wsize.z()/2.0);
517 G4LogicalVolume *logical =
new G4LogicalVolume( solid,
GetDetectorMaterial(material),name+
"logical");
518 G4VisAttributes *vis =
new G4VisAttributes( G4Color(1, 0, 0, 1) );
519 vis->SetForceSolid(
true );
520 logical->SetVisAttributes( vis );
522 G4ThreeVector
pos = G4ThreeVector(Wpos.x(), Wpos.y(), Tr2pos.z() - Tr2size.z()/2.0 - Wsize.z()/2.0);
523 G4VPhysicalVolume *physical =
new G4PVPlacement(0,pos, logical, name+
"physical", logicWorld, 0,
false,
OverlapCheck());
533 G4int nxy = total_tower;
535 G4double towerSizeXY = size.x()/nxy;
537 G4double towerEMZ = size.z();
546 G4double modxy = size.x();
547 G4double modz = size.z();
553 G4Box *mods =
new G4Box(name+
"_mod", modxy/2, modxy/2, modz/2);
554 G4LogicalVolume *modv =
new G4LogicalVolume(mods, G4NistManager::Instance()->FindOrBuildMaterial(
"G4_Galactic"), name+
"_mod");
555 new G4PVPlacement(0, G4ThreeVector(pos.x(), pos.y(), pos.z()), modv, name+
"_mod", logicWorld,
false, 0,
OverlapCheck());
557 modv->SetVisAttributes( G4VisAttributes::GetInvisible() );
560 G4LogicalVolume *towv =
MakeTower(towerSizeXY, towerEMZ);
563 G4double xypos0 = -(nxy*towerSizeXY)/2 + towerSizeXY/2;
564 for(G4int ix=0; ix<nxy; ix++) {
565 for(G4int iy=0; iy<nxy; iy++) {
566 G4double xpos = xypos0 + ix*towerSizeXY;
567 G4double ypos = xypos0 + iy*towerSizeXY;
568 new G4PVPlacement(0, G4ThreeVector(xpos, ypos, 0), towv, towv->GetName(), modv,
false, tcnt++,
OverlapCheck());
578 const double dist=1.0;
579 const double tot_len=calorSizeXY;
580 const double h=0.5*sqrt(3)*dist;
582 const int nx1=int((tot_len-2*offset)/(dist/2))+1;
583 const int ny1=int((tot_len-offset)/(2*h))+1;
584 const int ny2=int((tot_len-offset-h)/(2*h))+1;
586 const double x0=-((tot_len/2.0)-
offset);
587 const double y01=((tot_len/2.0)-
offset);
588 const double y02=((tot_len/2.0)-offset-
h);
590 G4Material* defaultMaterial = G4NistManager::Instance()->FindOrBuildMaterial(
"G4_Galactic");
591 G4Material* gapMaterial2 = G4NistManager::Instance()->FindOrBuildMaterial(
"G4_POLYSTYRENE");
592 G4double a = 183.85*
g/mole;
593 G4Element* elW =
new G4Element(
"Tungsten",
"W", 74., a);
596 if( ! EMCal_abs_mat ) {
597 EMCal_abs_mat =
new G4Material(
"EMCal_fiber_mat", 12.4*
g/
cm3, 2);
598 EMCal_abs_mat->AddElement(elW, 96.0*perCent);
599 EMCal_abs_mat->AddMaterial(gapMaterial2, 4.0*perCent);
603 G4LogicalVolume* calorEM;
604 G4VSolid* calorimeterEM =
new G4Box(
"CalorimeterEM_", calorSizeXY/2, calorSizeXY/2, calorEMZ/2);
605 calorEM=
new G4LogicalVolume(calorimeterEM,defaultMaterial,
m_Name+
"_CalorEM");
608 G4LogicalVolume* absorberEMLV;
609 G4VSolid* absorberEM =
new G4Box(
m_Name+
"_AbsoEM_solid",
610 calorSizeXY/2, calorSizeXY/2, calorEMZ/2);
611 absorberEMLV =
new G4LogicalVolume(absorberEM,EMCal_abs_mat,
m_Name+
"_AbsoEM");
612 G4VPhysicalVolume *physical_absorber =
new G4PVPlacement(0,G4ThreeVector(0.,0.,0.),absorberEMLV,
m_Name+
"_AbsoEM_p",calorEM,
false,0,
OverlapCheck());
615 G4VSolid* gapEM =
new G4Tubs(
m_Name+
"_GapEM",
616 0.0, 0.235*
mm, calorEMZ/2,0.0,360.0 * deg);
619 G4LogicalVolume* gapEMLV;
620 gapEMLV =
new G4LogicalVolume(gapEM,gapMaterial2,
m_Name);
622 double step_x=(dist/2.0)*
mm;
623 double step_y=(2.0*
h)*
mm;
626 for(
int i=0;i<nx1;i++){
627 G4double pos_x=x0*
mm+i*step_x;
633 int jend=(i%2==0) ? ny1 : ny2;
634 for(
int j=0;j<jend;j++){
637 if(i%2==0) pos_y=y01*
mm-j*step_y;
638 if(i%2!=0) pos_y=y02*
mm-j*step_y;
639 G4VPhysicalVolume *physical_scint =
new G4PVPlacement(0,G4ThreeVector(pos_x,pos_y, 0.),gapEMLV,
m_Name+
"_EMGapPhysical",absorberEMLV,
false,copynono,
OverlapCheck());
651 absorberEMLV->SetVisAttributes( G4VisAttributes::GetInvisible() );
652 gapEMLV->SetVisAttributes( G4VisAttributes::GetInvisible() );
654 G4VisAttributes* calorEMvis=
new G4VisAttributes(G4Colour(1,0,1));
655 calorEMvis->SetForceAuxEdgeVisible(
true);
656 calorEM->SetVisAttributes(calorEMvis);