EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EICG4dRICHDetector.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EICG4dRICHDetector.cc
1 #include "EICG4dRICHDetector.h"
2 #include "EICG4dRICHConfig.hh"
3 #include "EICG4dRICHOptics.hh"
4 
5 #include <fun4all/Fun4AllBase.h>
6 
7 #include <phparameter/PHParameters.h>
8 
9 #include <g4main/PHG4Detector.h>
10 
11 #include <G4Box.hh>
12 #include <G4Color.hh>
13 #include <G4LogicalVolume.hh>
14 #include <G4Material.hh>
15 #include <G4PVPlacement.hh>
16 #include <G4SystemOfUnits.hh>
17 #include <G4VisAttributes.hh>
18 #include <G4tgbVolumeMgr.hh>
19 
20 #include <cmath>
21 #include <iostream>
22 
23 class G4VSolid;
24 class PHCompositeNode;
25 
26 // ---------------------------------------------------
28  PHParameters *parameters, const std::string &dnam)
29  : PHG4Detector(subsys, Node, dnam)
30  , m_Params(parameters)
31 {
32 }
33 
34 // ---------------------------------------------------
35 int EICG4dRICHDetector::IsInDetector(G4VPhysicalVolume *volume) const
36 {
37  std::set<G4VPhysicalVolume *>::const_iterator iter =
38  m_PhysicalVolumesSet.find(volume);
39  if (iter != m_PhysicalVolumesSet.end())
40  {
41  return 1;
42  }
43  return 0;
44 }
45 
46 // ---------------------------------------------------
47 void EICG4dRICHDetector::ConstructMe(G4LogicalVolume *logicWorld)
48 {
49  EICG4dRICHConfig cfg;
50  cfg.model_file = m_Params->get_string_param("mapping_file");
51  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << "[+] MODEL TEXT FILE: " << cfg.model_file << std::endl;
52  // - check existence
53  std::ifstream mf(cfg.model_file.data());
54  if (!mf.is_open())
55  {
56  std::cerr << "[+] ERROR in " << __FILE__ << ": cannot find MODEL TEXT FILE" << std::endl;
57  return;
58  }
59  mf.close();
60 
61  // graphics
62  G4VisAttributes *vis = new G4VisAttributes(G4Color(0., 0., 0.9, 0.5));
63  vis->SetForceSolid(true);
64  vis->SetVisibility(true);
65  vis->SetLineWidth(1);
66  vis->SetForceSolid(true);
67  logicWorld->SetVisAttributes(G4VisAttributes::Invisible);
68  // logicWorld->SetVisAttributes(vis);
69 
70  // build detector by text file
71  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << "[+] read model text file" << std::endl;
72  G4tgbVolumeMgr *volmgr = G4tgbVolumeMgr::GetInstance();
73  volmgr->AddTextFile(cfg.model_file);
74  if (Verbosity() >= Fun4AllBase::VERBOSITY_MORE) std::cout << "[+] construct detector from text file" << std::endl;
75  G4VPhysicalVolume *vesselPhysVol = volmgr->ReadAndConstructDetector();
77  {
78  std::cout << "[+] detector summary" << std::endl;
79  volmgr->DumpSummary();
80  std::cout << "[+] detector G4Solid list" << std::endl;
81  volmgr->DumpG4SolidList();
82  }
83 
84  // material optical properties (see shared header EICG4dRICHOptics.hh)
85  // - aerogel
86  auto aeroPO = new EICG4dRICHAerogel("EICG4dRICHaerogelMat");
87  aeroPO->setOpticalParams(cfg.aerOptModel); // mode=3: use experimental data
88  // - acrylic filter
90  {
91  std::cout << "[+] Acrylic Wavelength Threshold : " << cfg.filter_thr / (nm) << " nm\n"
92  << std::endl;
93  }
94  auto acryPO = new EICG4dRICHFilter("EICG4dRICHfilterMat");
95  acryPO->setOpticalParams(cfg.filter_thr);
96  // - gas radiator
97  auto gasPO = new EICG4dRICHGas("EICG4dRICHgasMat");
98  gasPO->setOpticalParams();
99  // - photo sensors
100  auto photoSensor = new EICG4dRICHPhotosensor("EICG4dRICHpsst");
101  photoSensor->setOpticalParams("EICG4dRICH");
102  // - mirror (simular to photosensor, but different params)
103  auto mirror = new EICG4dRICHMirror("EICG4dRICHmirror");
104  mirror->setOpticalParams("EICG4dRICH");
105 
106  G4RotationMatrix *rotation = new G4RotationMatrix(m_Params->get_double_param("rot_x") * deg,
107  m_Params->get_double_param("rot_y") * deg,
108  m_Params->get_double_param("rot_z") * deg);
109 
110  const G4ThreeVector *position = new G4ThreeVector(m_Params->get_double_param("place_x") * cm,
111  m_Params->get_double_param("place_y") * cm,
112  m_Params->get_double_param("place_z") * cm);
113 
114  vesselPhysVol->SetRotation(rotation);
115  vesselPhysVol->SetTranslation(*position);
116 
117  // add to logical world
118  logicWorld->AddDaughter(vesselPhysVol);
119 
120  // activate volumes, for hit readout
121  this->ActivateVolumeTree(vesselPhysVol);
122 
123  return;
124 }
125 
126 // ---------------------------------------------------
127 // recursively add detectors to active volume list, descending the tree
128 // from `volu`
129 // - use the "activation filter" to decide for which volumes to save hits
130 // - the petal number is added to `m_PetalMap`, which together
131 // with the copy number, provides a unique ID for each photo sensor
132 void EICG4dRICHDetector::ActivateVolumeTree(G4VPhysicalVolume *volu, G4int petal)
133 {
134  // get objects
135  G4String voluName = volu->GetName();
136  G4int voluCopyNo = volu->GetCopyNo();
137  G4LogicalVolume *logi = volu->GetLogicalVolume();
138 
139  // obtain petal number
140  if (voluName.contains("petal"))
141  {
142  petal = voluCopyNo;
143  }
144 
145  // activation filter: use this to decide which volumes to save
146  // hits for, i.e., which volumes are "active"
147  // TODO: need to decide what volume we want to be active
148  G4bool activate = true; // voluName.contains("psst") || voluName.contains("vessel");
149  if (activate)
150  {
152  {
153  std::cout << "[+] activate " << voluName << " petal " << petal << " copy "
154  << voluCopyNo << std::endl;
155  }
156  m_PhysicalVolumesSet.insert(volu);
157  m_PetalMap.insert(std::pair<G4VPhysicalVolume *, G4int>(volu, petal));
158  }
159 
160  // loop over daughters
161  G4int nd = logi->GetNoDaughters();
162  for (int d = 0; d < nd; d++)
163  {
164  this->ActivateVolumeTree(logi->GetDaughter(d), petal);
165  }
166 }
167 
168 // ---------------------------------------------------
169 // get petal number
170 int EICG4dRICHDetector::GetPetal(G4VPhysicalVolume *volu)
171 {
172  int petalNum;
173  try
174  {
175  petalNum = m_PetalMap.at(volu);
176  }
177  catch (const std::out_of_range &ex)
178  {
179  std::cerr << "ERROR in EICG4dRICHDetector: cannot find petal associated with volume"
180  << std::endl;
181  return -1;
182  }
183  return petalNum;
184 }
185 
186 // ---------------------------------------------------
187 // get PSST number
188 int EICG4dRICHDetector::GetPSST(G4VPhysicalVolume *volu)
189 {
190  return volu->GetName().contains("psst") ? volu->GetCopyNo() : 0;
191 }
192 
193 // ---------------------------------------------------
194 void EICG4dRICHDetector::Print(const std::string &what) const
195 {
196  std::cout << "EICG4dRICH Detector:" << std::endl;
197  if (what == "ALL" || what == "VOLUME")
198  {
199  std::cout << "Version 0.1" << std::endl;
200  std::cout << "Parameters:" << std::endl;
201  m_Params->Print();
202  }
203  return;
204 }