EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EicFRichDetector.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EicFRichDetector.cc
1 //____________________________________________________________________________..
2 //
3 // This is a working template for the G4 Construct() method which needs to be implemented
4 // We wedge a method between the G4 Construct() to enable volume hierarchies on the macro
5 // so here it is called ConstructMe() but there is no functional difference
6 // Currently this installs a simple G4Box solid, creates a logical volume from it
7 // and places it. Put your own detector in place (just make sure all active volumes
8 // get inserted into the m_PhysicalVolumesSet)
9 //
10 // Rather than using hardcoded values you should consider using the parameter class
11 // Parameter names and defaults are set in EicFRichSubsystem::SetDefaultParameters()
12 // Only parameters defined there can be used (also to override in the macro)
13 // to avoids typos.
14 // IMPORTANT: parameters have no inherent units, there is a convention (cm/deg)
15 // but in any case you need to multiply them here with the correct CLHEP/G4 unit
16 //
17 // The place where you put your own detector is marked with
18 // //begin implement your own here://
19 // //end implement your own here://
20 // Do not forget to include the G4 includes for your volumes
21 //____________________________________________________________________________..
22 
23 #include "EicFRichDetector.h"
24 
25 #include <phparameter/PHParameters.h>
26 
27 #include <g4main/PHG4Detector.h>
28 
29 #include <Geant4/G4Box.hh>
30 #include <Geant4/G4Polycone.hh>
31 #include <Geant4/G4Color.hh>
32 #include <Geant4/G4LogicalVolume.hh>
33 #include <Geant4/G4Material.hh>
34 #include <Geant4/G4PVPlacement.hh>
35 #include <Geant4/G4SystemOfUnits.hh>
36 #include <Geant4/G4VisAttributes.hh>
37 
38 #include <cmath>
39 #include <iostream>
40 
41 class G4VSolid;
42 class PHCompositeNode;
43 
44 using namespace std;
45 double bp_r(double z_cm){return 0.05025461*z_cm-0.180808;}
46 double rmax(double z_cm){return 0.6624*z_cm;}
47 //G4Material * element_material( string identifier );
48 //void addDetectorSection( G4LogicalVolume *logicWorld , string name , double z_pos , double thick , string material , string color);
49 //____________________________________________________________________________..
51  PHCompositeNode *Node,
53  const std::string &dnam)
54  : PHG4Detector(subsys, Node, dnam)
55  , m_Params(parameters)
56 {
57 }
58 
59 //_______________________________________________________________
60 int EicFRichDetector::IsInDetector(G4VPhysicalVolume *volume) const
61 {
62  set<G4VPhysicalVolume *>::const_iterator iter = m_PhysicalVolumesSet.find(volume);
63  if (iter != m_PhysicalVolumesSet.end())
64  {
65  return 1;
66  }
67  return 0;
68 }
69 
70 //_______________________________________________________________
71 void EicFRichDetector::ConstructMe(G4LogicalVolume *logicWorld)
72 {
73  //begin implement your own here://
74  // Do not forget to multiply the parameters with their respective CLHEP/G4 unit !
75 
76  // This class describes the EIC HM RICH detector from information provided by Evaristo Cisbani <evaristo.cisbani@roma1.infn.it>
77  // The length in z for the gas volume is projected to be between 100 - 150 cm
78 
79  // ---------------- // ---------------- // ---------------- // ---------------- // ---------------- // ---------------- // ---------------- //
80  // Parameters
81  double overall_z_pos = 150 * cm;
82  double overall_gas_length = 144 * cm;
83  // ----------------
84  // Mylar entrance
85  double z_m_1 = overall_z_pos;
86  double t_m_1 = 0.02*cm;
87  // ----------------
88  // Aerogel
89  double z_aero = z_m_1+t_m_1;
90  double t_aero = 4.*cm;
91  // ----------------
92  // PMMA
93  double z_PMMA = z_aero+t_aero;
94  double t_PMMA = 2*mm;
95  // ----------------
96  // C2F6
97  double z_C2F6 = z_PMMA+t_PMMA;
98  double t_C2F6 = overall_gas_length;
99  // ----------------
100  // Mirror layer 1
101  double z_mr_1 = z_C2F6+t_C2F6;
102  double t_mr_1 = 0.1*mm;
103  // ----------------
104  // Mirror layer 2
105  double z_mr_2 = z_mr_1+t_mr_1;
106  double t_mr_2 = 0.05*mm;
107  // ----------------
108  // Mylar exit
109  double z_m_2 = z_mr_2+t_mr_2;
110  double t_m_2 = 0.02*cm;
111  // ---------------- // ---------------- // ---------------- // ---------------- // ---------------- // ---------------- // ---------------- //
112  addDetectorSection( logicWorld , "RICH_mylar_ent" , z_m_1 , t_m_1 , "mylar" , "cyan" );
113  addDetectorSection( logicWorld , "RICH_aerogel" , z_aero , t_aero , "aerogel" , "gray" );
114  addDetectorSection( logicWorld , "RICH_PMMA" , z_PMMA , t_PMMA , "PMMA" , "green" );
115  addDetectorSection( logicWorld , "RICH_C2F6" , z_C2F6 , t_C2F6 , "C2F6" , "magenta" );
116  addDetectorSection( logicWorld , "RICH_mirror_l1" , z_mr_1 , t_mr_1 , "SiO2" , "white" );
117  addDetectorSection( logicWorld , "RICH_mirror_l2" , z_mr_2 , t_mr_2 , "cf_epo" , "yellow" );
118  addDetectorSection( logicWorld , "RICH_mylar_ext" , z_m_2 , t_m_2 , "mylar" , "cyan" );
119 
120  //end implement your own here://
121  return;
122 }
123 // ======================================================================================================
124 void EicFRichDetector::Print(const std::string &what) const
125 {
126  cout << "EicFRich Detector:" << endl;
127  if (what == "ALL" || what == "VOLUME")
128  {
129  cout << "Version 0.1" << endl;
130  cout << "Parameters:" << endl;
131  m_Params->Print();
132  }
133  return;
134 }
135 // ======================================================================================================
136 G4Material * EicFRichDetector::element_material( std::string identifier ){
137  G4Material * G4_mat = GetDetectorMaterial("G4_AIR");
138  G4double density;
139  G4int ncomponents, natoms;
140 
141  if(identifier=="mylar"){
142  G4_mat = GetDetectorMaterial("G4_MYLAR");
143  }
144  else if(identifier=="C2F6"){
145  G4_mat = new G4Material("C2F6", density = 0.0057 * g / cm3, ncomponents = 2);
146  G4_mat->AddElement(G4Element::GetElement("C"), natoms = 2);
147  G4_mat->AddElement(G4Element::GetElement("F"), natoms = 6);
148  }
149  else if(identifier=="PMMA"){
150  G4_mat = new G4Material("PMMA", density = 1.18 * g / cm3, ncomponents = 3);
151  G4_mat->AddElement(G4Element::GetElement("C"), 3.6 / (3.6 + 5.7 + 1.4));
152  G4_mat->AddElement(G4Element::GetElement("H"), 5.7 / (3.6 + 5.7 + 1.4));
153  G4_mat->AddElement(G4Element::GetElement("O"), 1.4 / (3.6 + 5.7 + 1.4));
154  }
155  else if(identifier=="SiO2"){
156  G4_mat = new G4Material("SiO2", density = 2.5 * g / cm3 , ncomponents = 2);
157  G4_mat->AddElement(G4Element::GetElement("Si"), natoms = 1);
158  G4_mat->AddElement(G4Element::GetElement("O" ), natoms = 2);
159  }
160  else if(identifier=="aerogel"){
161  G4Material *SiO2Aerogel = new G4Material("aerogel_SiO2", density = 2.5 * g / cm3 , ncomponents = 2);
162  SiO2Aerogel->AddElement(G4Element::GetElement("Si"), 1);
163  SiO2Aerogel->AddElement(G4Element::GetElement("O" ), 2);
164 
165  G4Material *air = GetDetectorMaterial("G4_AIR");
166 
167  G4double fracMass;
168  G4_mat = new G4Material("aerogel", density = 0.094 * g / cm3 , ncomponents = 2);
169  G4_mat->AddMaterial(air , fracMass = 96.*perCent);
170  G4_mat->AddMaterial(SiO2Aerogel, fracMass = 4.*perCent);
171  }
172  else if(identifier=="cf_epo"){
173  G4String symbol;
174  G4Element* elH = new G4Element("Hydrogen",symbol="H" , 1., 1.01*g/mole);
175  G4Element* elC = new G4Element("Carbon" ,symbol="C" , 6., 12.01*g/mole);
176  G4Element* elN = new G4Element("Nitrogen",symbol="N" , 7., 14.01*g/mole);
177  G4Element* elO = new G4Element("Oxygen" ,symbol="O" , 8., 16.00*g/mole);
178 
179  G4Material *Epoxy = new G4Material("Epoxy", density = 1.16*g/cm3, natoms=4);
180  Epoxy->AddElement(elH, 32); // Hydrogen
181  Epoxy->AddElement(elN, 2); // Nitrogen
182  Epoxy->AddElement(elO, 4); // Oxygen
183  Epoxy->AddElement(elC, 15); // Carbon
184 
185  G4_mat = new G4Material("CarbonFiber", density = 1.750*g/cm3, natoms=2);
186  G4_mat->AddMaterial(GetDetectorMaterial("G4_C"), 74.5*perCent); // Carbon
187  G4_mat->AddMaterial(Epoxy, 25.5*perCent); // Epoxy (scotch)
188  }
189  return G4_mat;
190 }
191 // ======================================================================================================
192 void EicFRichDetector::addDetectorSection( G4LogicalVolume *logicWorld , std::string name , double z_pos , double thick , std::string material , std::string color){
193 
194  double z_det [] = {z_pos,z_pos+thick};
195  double rin [2] = {0};
196  double rout[2] = {0};
197 
198  for(int i = 0 ; i < 2 ; i++){
199  rin [i] = bp_r(z_det[i]);
200  rout[i] = rmax(z_det[i]);
201  }
202  G4Material * G4_mat = element_material( material );
203 
204  G4RotationMatrix *rotm = new G4RotationMatrix();
205  rotm->rotateX(0);
206  rotm->rotateY(0);
207  rotm->rotateZ(0);
208 
209  G4Color G4_color = G4Color(G4Colour::White());
210  if (color=="cyan" ) G4_color = G4Color(G4Colour::Cyan());
211  else if(color=="yellow" ) G4_color = G4Color(G4Colour::Yellow());
212  else if(color=="green" ) G4_color = G4Color(G4Colour::Green());
213  else if(color=="gray" ) G4_color = G4Color(G4Colour::Gray());
214  else if(color=="magenta") G4_color = G4Color(G4Colour::Magenta());
215 
216  G4VSolid *G4_polycone = new G4Polycone(name,0,360*degree,2,z_det,rin,rout);
217  G4LogicalVolume *logical = new G4LogicalVolume(G4_polycone,G4_mat, "EicFRichLogical");
218  G4VisAttributes *vis_1 = new G4VisAttributes(G4_color);
219  vis_1->SetForceSolid(true);
220  logical->SetVisAttributes(vis_1);
221 
222  G4VPhysicalVolume *phy_1 = new G4PVPlacement(rotm, G4ThreeVector(0,0,0), logical , "EicFRich", logicWorld, 0, false, OverlapCheck());
223 
224  // add it to the list of placed volumes so the IsInDetector method picks them up
225  m_PhysicalVolumesSet.insert(phy_1);
226 }