EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Cell.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Cell.cxx
1 
2 //_____________________________________________________________________________
3 //
4 // cell in composite calorimeter,
5 // crystal of PbWO4 in carbon fiber casing,
6 // optical photon detector is on its end
7 //_____________________________________________________________________________
8 
9 //local headers
10 #include "Cell.h"
11 #include "CompCal.h"
12 #include "OpTable.h"
13 #include "OpDet.h"
14 #include "RootOut.h"
15 
16 //ROOT
17 #include <TTree.h>
18 
19 //Geant
20 #include <Geant4/G4LogicalVolume.hh>
21 #include <Geant4/G4Box.hh>
22 #include <Geant4/G4SubtractionSolid.hh>
23 #include <Geant4/G4SystemOfUnits.hh>
24 #include <Geant4/G4NistManager.hh>
25 #include <Geant4/G4VisAttributes.hh>
26 #include <Geant4/G4PVPlacement.hh>
27 #include <Geant4/G4VPhysicalVolume.hh>
28 #include <Geant4/G4OpticalPhoton.hh>
29 #include <Geant4/G4Scintillation.hh>
30 #include <Geant4/G4Cerenkov.hh>
31 
32 #include <Geant4/G4Step.hh>
33 #include <Geant4/G4TouchableHistory.hh>
34 
35 #include <TTree.h>
36 
37 //C++
38 #include <vector>
39 
40 
41 //_____________________________________________________________________________
42 Cell::Cell(const G4String& nam, G4int ix, G4int iy, G4int ncells, G4double zpos, G4double ypos, G4LogicalVolume *top, CompCal& d, RootOut *rout):
43  fNam(nam), det(d) {
44 
45 // G4cout << " Cell::Cell: " << fNam << G4endl;
46 
47  //alveole size
48  G4double asiz = 3*cm;
49 
50  //crystal size
51  G4double csiz = 2.6*cm; //for alveole thickness 0.2 cm
52 
53  //cell length
54  G4double zlen = 35*cm;
55 
56  //cell alveole shape
57  G4String alv_nam = fNam+"_alv";
58  G4Box *alv_out = new G4Box(alv_nam+"_out", asiz/2., asiz/2, zlen/2.);
59  G4Box *alv_in = new G4Box(alv_nam+"_in", csiz/2., csiz/2, zlen/2.);
60  G4SubtractionSolid *alv_s = new G4SubtractionSolid(alv_nam, alv_out, alv_in);
61 
62  //Carbon fiber for the alveole, according to TestEm10 example, Materials.cc
63  if( !G4Material::GetMaterial("CarbonFiber", false) ) {
64  G4Element *elC = new G4Element("Carbon", "C", 6., 12.01*g/mole);
65  G4Material *alv_m = new G4Material("CarbonFiber", 0.145*g/cm3, 1);
66  alv_m->AddElement(elC, 1);
67  //G4cout << *(G4Material::GetMaterialTable()) << G4endl;
68  }
69 
70  //alveole volume
71  G4LogicalVolume *alv_l = new G4LogicalVolume(alv_s, G4Material::GetMaterial("CarbonFiber"), alv_nam);
72 
73  //do not show the alveole
74  alv_l->SetVisAttributes( G4VisAttributes::GetInvisible() );
75 
76  //crystal material
77  G4Material *crystal_m = G4NistManager::Instance()->FindOrBuildMaterial("G4_PbWO4");
78 
79  //scintillation and optical properties for the crystal
80  OpTable *optab = new OpTable();
81  optab->CrystalTable(crystal_m);
82 
83  //crystal shape and volume, same name as the cell for sensitive volume
84  G4Box *crystal_s = new G4Box(fNam, csiz/2., csiz/2, zlen/2.);
85  G4LogicalVolume *crystal_l = new G4LogicalVolume(crystal_s, crystal_m, fNam);
86 
87  //crystal optical surface
88  optab->SurfaceTable(crystal_l);
89 
90  //drawing the crystal
91  G4VisAttributes *vis = new G4VisAttributes();
92  vis->SetColor(1, 0, 0, 0.5);
93  //vis->SetForceSolid(true);
94  crystal_l->SetVisAttributes(vis);
95 
96  //cell x and y center points
97  G4double xcen = -asiz/2. * (ncells-1.) + ix*asiz;
98 
99  G4double y0 = asiz/2. * (ncells-1.);
100  if(ypos > 0.01) {
101  y0 = y0 + ncells*asiz/2. + ypos;
102  } else if (ypos < -0.01) {
103  y0 = y0 - ncells*asiz/2. + ypos;
104  }
105 
106  G4double ycen = y0 - iy*asiz;
107 
108  //cell alveole in top volume
109  G4VPhysicalVolume *alvvol = new G4PVPlacement(nullptr, G4ThreeVector(xcen, ycen, zpos-zlen/2.), alv_l, alv_nam, top, false, 0);
110  m_PhysicalVolumes.insert(alvvol);
111 
112  //crystal in top volume
113  G4VPhysicalVolume *csens = new G4PVPlacement(nullptr, G4ThreeVector(xcen, ycen, zpos-zlen/2.), crystal_l, fNam, top, false, 0);
114  m_PhysicalVolumes.insert(csens);
115 
116  //attach optical photon detector, 1.7x1.7 cm
117  fOpDet = new OpDet(fNam+"_OpDet", 1.7*cm, zpos-zlen, xcen, ycen, top);
118  optab->MakeBoundary(csens, fOpDet->GetPhysicalVolume());
119  fOpDet->CreateOutput(rout->GetTree());
120  //indices to identify scintillation and Cerenkov processes
121  G4Scintillation scin;
122  fScinType = scin.GetProcessType();
123  fScinSubType = scin.GetProcessSubType();
124  G4Cerenkov cer;
125  fCerenkovType = cer.GetProcessType();
126  fCerenkovSubType = cer.GetProcessSubType();
127 
128  ClearEvent();
129 
130 }//Cell
131 
132 //_____________________________________________________________________________
133 G4bool Cell::ProcessHits(const G4Step *step, G4TouchableHistory*) {
134 
135  G4TouchableHandle touch = step->GetPreStepPoint()->GetTouchableHandle();
136  G4VPhysicalVolume* volume = touch->GetVolume();
137  if (m_PhysicalVolumes.find(volume) == m_PhysicalVolumes.end())
138  {
139  return false;
140  }
141  //hit in this cell
142 
143  //G4cout << "Cell::ProcessHits, " << fNam << G4endl;
144 
145  //increment deposited energy in the cell
146  fE += step->GetTotalEnergyDeposit();
147 
148  //do not consider optical photon hits since now
149  if(step->GetTrack()->GetDynamicParticle()->GetParticleDefinition() == G4OpticalPhoton::OpticalPhotonDefinition()) {
150  return true;
151  }
152 
153  //first point in the detector in the event
154  if(det.fZ > 9998.) {
155  if(step->GetTrack()->GetTotalEnergy() > 100) {
156  //if(1) {
157 
158  const G4ThreeVector point = step->GetPreStepPoint()->GetPosition();
159 
160  det.fX = point.x();
161  det.fY = point.y();
162  det.fZ = point.z();
163 
164  det.fXyzE = step->GetTrack()->GetTotalEnergy();
165  }
166  }
167 
168  //number of optical photons in the event from secondary tracks
169  const std::vector<const G4Track*> *sec = step->GetSecondaryInCurrentStep();
170  std::vector<const G4Track*>::const_iterator i;
171  for(i = sec->begin(); i != sec->end(); i++) {
172  if((*i)->GetParentID() <= 0) continue;
173 
174  //all optical photons
175  if((*i)->GetDynamicParticle()->GetParticleDefinition() != G4OpticalPhoton::OpticalPhotonDefinition()) continue;
176  fNphot++;
177 
178  //identify the process
179  G4int ptype = (*i)->GetCreatorProcess()->GetProcessType();
180  G4int pstype = (*i)->GetCreatorProcess()->GetProcessSubType();
181  //scintillation photons
182  if(ptype == fScinType && pstype == fScinSubType) fNscin++;
183  //Cerenkov photons
184  if(ptype == fCerenkovType && pstype == fCerenkovSubType) fNcerenkov++;
185 
186  }//secondary tracks loop
187 
188  return true;
189 
190 }//ProcessHits
191 
192 //_____________________________________________________________________________
193 void Cell::CreateOutput(TTree *tree) {
194 
195  AddBranch("_en", &fE, tree);
196 
197  AddBranch("_nphot", &fNphot, tree);
198  AddBranch("_nscin", &fNscin, tree);
199  AddBranch("_ncerenkov", &fNcerenkov, tree);
200 
201 }//WriteHeader
202 
203 //_____________________________________________________________________________
205 
206  fE = 0.;
207 
208  fNphot = 0;
209  fNscin = 0;
210  fNcerenkov = 0;
211 
212 }//ClearEvent
213 
214 //_____________________________________________________________________________
215 /*
216 void Cell::Add(std::vector<Detector*> *vec) {
217 
218  //add this cell and its parts to sensitive detectors
219  vec->push_back(this);
220  vec->push_back(fOpDet);
221 
222 }//Add
223 */
224 //_____________________________________________________________________________
225 void Cell::AddBranch(const std::string& nam, Double_t *val, TTree *tree) {
226 
227  //add branch for one Double_t variable
228 
229  std::string name = fNam + nam; // branch name from detector name and variable name
230  std::string leaf = name + "/D"; // leaflist for Double_t
231  tree->Branch(name.c_str(), val, leaf.c_str()); // create the branch
232 
233 }//AddBranch
234 
235 //_____________________________________________________________________________
236 void Cell::AddBranch(const std::string& nam, ULong64_t *val, TTree *tree) {
237 
238  //add branch for one ULong64_t variable
239 
240  std::string name = fNam + nam; // branch name from detector name and variable name
241  std::string leaf = name + "/l"; // leaflist for Double_t
242  tree->Branch(name.c_str(), val, leaf.c_str()); // create the branch
243 
244 }//AddBranch
245 
246 
247 
248 
249 
250 
251 
252 
253 
254 
255 
256 
257 
258 
259 
260 
261 
262 
263 
264 
265 
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280