ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CCalG4Ecal.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CCalG4Ecal.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
27 // File: CCalG4Ecal.cc
28 // Description: CCalG4Ecal Factory class to construct the G4 geometry of the
29 // electromagnetic calorimeter
31 
32 #include <cmath>
33 
34 #include "CCalG4Ecal.hh"
35 
36 #include "CCalMaterialFactory.hh"
39 
40 #include "CCalutils.hh"
41 
42 #include "G4SystemOfUnits.hh"
43 #include "G4ThreeVector.hh"
44 #include "G4Box.hh"
45 #include "G4Trd.hh"
46 
47 #include "G4LogicalVolume.hh"
48 #include "G4PVPlacement.hh"
49 
50 //#define debug
51 //#define ddebug
52 //#define pdebug
53 //#define sdebug
54 
55 //Initialize static logical volumes
57 
58 //Initialize static prefix name
59 G4String CCalG4Ecal::idName = "CrystalMatrix";
60 
62 // CCalG4Ecal constructor & destructor...
64 
66  CCalEcal(name), CCalG4Able(name), type(module1) {}
67 
69 
71 // CCalG4Ecal methods...
73 
75  G4cout << "==>> Constructing CCalG4Ecal..." << G4endl;
76 
78  // Construction of global volume as a Box
79 
80  if (!crystalmatrixLog) {
82  }
84 
85  G4double x, y, z;
86  if (mother != 0) {
87  x = getXpos()*mm;
88  y = getYpos()*mm;
89  z = getZpos()*mm;
90  } else {
91  x = y = z = 0;
92  }
93 
94  int num;
95  if (type == module2) {
96  num = 2;
97  } else {
98  num = 1;
99  }
100 #ifdef pdebug
101  G4String name("Null");
102  if (mother != 0) name = mother->GetName();
103  G4cout << crystalmatrixLog->GetName() << " Number " << num << " positioned in "
104  << name << " at (" << x << ", " << y << ", " << z << ")";
105 #endif
106 
107  G4RotationMatrix* cmrot = 0;
108  if (mother != 0) {
109  G4String rotstr = idName + num;
110  cmrot = rotfact->findMatrix(rotstr);
111  if (!cmrot) {
112 #ifdef ddebug
113  G4cout << "Creating a new rotation: " << rotstr << tab
114  << getThetaX()*deg << "," << getPhiX()*deg << ","
115  << getThetaY()*deg << "," << getPhiY()*deg << ","
116  << getThetaZ()*deg << "," << getPhiZ()*deg << G4endl;
117 #endif
118  cmrot = rotfact->AddMatrix(rotstr, getThetaX()*deg, getPhiX()*deg,
119  getThetaY()*deg, getPhiY()*deg,
120  getThetaZ()*deg, getPhiZ()*deg);
121  } // if !cmrot
122 #ifdef pdebug
123  G4cout << " rotation by (" << getThetaX() << ", " << getPhiX() << ", "
124  << getThetaY() << "," << getPhiY() << ", " << getThetaZ() << ", "
125  << getPhiZ() << ")" << G4endl;
126 #endif
127  } else {
128 #ifdef pdebug
129  G4cout << " without rotation..." << G4endl;
130 #endif
131  }
132 
133  G4PVPlacement* crystalmatrix;
134  if (mother != 0) {
135  crystalmatrix = new G4PVPlacement(cmrot, G4ThreeVector(x,y,z),
137  mother->GetLogicalVolume(), false, num);
138  } else {
139  crystalmatrix = new G4PVPlacement(cmrot, G4ThreeVector(x,y,z),
141  mother, false, num);
142  }
143  G4cout << "<<== End of CCalG4Ecal construction ..." << G4endl;
144 
145  return crystalmatrix;
146 }
147 
148 
150 
151  //Pointers to the Materials and Rotation Matrix factory
154 
155  G4Material* matter = matfact->findMaterial(getGenMat());
156  G4VSolid* solid = new G4Box (idName, 0.5*getWidBox()*mm, 0.5*getWidBox()*mm,
157  0.5*getLengBox()*mm);
158 #ifdef debug
159  G4cout << tab << idName << " Box made of " << getGenMat() << " of dimension "
160  << 0.5*getWidBox()*mm << ", " << 0.5*getWidBox()*mm << ", "
161  << 0.5*getLengBox()*mm << G4endl;
162 #endif
163  G4LogicalVolume* glog = new G4LogicalVolume (solid, matter, idName);
165 
166  //Now the layers
167  G4String name = idName + "Layer";
168  matter = matfact->findMaterial(getLayMat());
169  solid = new G4Trd(name, getLayPar(0)*mm, getLayPar(1)*mm, getLayPar(2)*mm,
170  getLayPar(3)*mm, getLayPar(4)*mm);
171 #ifdef debug
172  G4cout << tab << name << " Trd made of " << getLayMat() << " of dimension "
173  << getLayPar(0)*mm << ", " << getLayPar(1)*mm << ", " << getLayPar(2)*mm
174  << ", " << getLayPar(3)*mm << ", " << getLayPar(4)*mm << G4endl;
175 #endif
176  G4LogicalVolume* laylog = new G4LogicalVolume (solid, matter, name);
178 
179  G4int i = 0;
180  G4String rotstr;
181  G4double xp, yp, zp, angle;
182  G4double zshift = -0.5 * (getLengBox() - getCrystLength()) + getLengFront();
183  G4RotationMatrix* rot = 0;
184  for (i = 0; i < getLayNum(); i++) {
185  angle = 0.5 * getLayAngle() * (2*i + 1 - getLayNum());
186  xp = angle * (getLayPar(4) + getLayRadius()) * mm;
187  zp = (zshift + getLayPar(0)*std::abs(std::sin(angle))) * mm;
188  rotstr = idName + "Layer" + i;
189  rot = rotfact->findMatrix(rotstr);
190  if (!rot) {
191 #ifdef ddebug
192  G4cout << "Creating a new rotation: " << rotstr << tab
193  << (90.0*deg+angle) << "," << 0.0*deg << "," << 90.0*deg << ","
194  << 90.0*deg << "," << angle << "," << 0.0*deg << G4endl;
195 #endif
196  rot = rotfact->AddMatrix(rotstr, (90.0*deg+angle), 0.0*deg, 90.0*deg,
197  90.0*deg, angle, 0.0*deg);
198  }
199  new G4PVPlacement(rot, G4ThreeVector(xp,0.,zp), laylog, name, glog,
200  false, i+1);
201 #ifdef pdebug
202  G4cout << laylog->GetName() << " number " << i+1 << " positioned in "
203  << glog->GetName() << " at (" << xp << ", 0," << zp
204  << ") with rotation angle " << angle/deg << G4endl;
205 #endif
206  }
207 
208  //Now the crystals
209  name = idName + "Crystal";
210  matter = matfact->findMaterial(getCrystMat());
211  solid = new G4Trd(name, getCrystPar(0)*mm, getCrystPar(1)*mm,
213 #ifdef debug
214  G4cout << tab << name << " Trd made of " << getCrystMat() << " of dimension "
215  << getCrystPar(0)*mm << ", " << getCrystPar(1)*mm << ", "
216  << getCrystPar(2)*mm << ", " << getCrystPar(3)*mm << ", "
217  << getCrystPar(4)*mm << G4endl;
218 #endif
219 
220  G4LogicalVolume* detLog = new G4LogicalVolume (solid, matter, name);
222  sensitiveLogs.push_back(detLog);
223  for (i = 0; i < getCrystNum(); i++) {
224  angle = 0.5 * getLayAngle() * (2*i + 1 - getCrystNum());
225  yp = angle * (getCrystPar(4) + getLayRadius()) * mm;
226  zp = (getCrystPar(0)*std::abs(std::sin(angle)) - getCrystTol()) * mm;
227  rotstr = idName + "Crystal" + i;
228  rot = rotfact->findMatrix(rotstr);
229  if (!rot) {
230 #ifdef ddebug
231  G4cout << "Creating a new rotation: " << rotstr << tab << 90.0*deg << ","
232  << 0.0*deg << "," << (90.0*deg+angle) << "," << 0.0*deg << ","
233  << angle << "," << 90.0*deg << G4endl;
234 #endif
235  rot = rotfact->AddMatrix(rotstr, 90.0*deg, 0.0*deg, (90.0*deg+angle),
236  90.0*deg, angle, 90.0*deg);
237  }
238  new G4PVPlacement(rot, G4ThreeVector(0,yp,zp), detLog, name, laylog,
239  false, i+1);
240 #ifdef pdebug
241  G4cout << detLog->GetName() << " number " << i+1 << " positioned in "
242  << laylog->GetName() << " at (0," << yp << "," << zp
243  << ") with rotation angle " << angle/deg << G4endl;
244 #endif
245  }
246 
247  //Support boxes
248  name = idName + "Support";
249  matter = matfact->findMaterial(getSuppMat());
250  solid = new G4Box (name, 0.5*getDxSupp()*mm, 0.5*getDySupp()*mm,
251  0.5*getDzSupp()*mm);
252 #ifdef debug
253  G4cout << tab << name << " Box made of " << getSuppMat() << " of dimension "
254  << 0.5*getDxSupp()*mm << ", " << 0.5*getDySupp()*mm << ", "
255  << 0.5*getDzSupp()*mm << G4endl;
256 #endif
257  G4LogicalVolume* slog = new G4LogicalVolume (solid, matter, name);
259 
260  zp = (-0.5 * getLengBox() + getCrystLength() + getLengFront() +
261  0.5 * getDzSupp() + getDistSupp()) * mm;
262  for (i = 0; i < getCrystNum(); i++) {
263  yp = getLayPar(1) * (2*i + 1 - getCrystNum()) * mm;
264  new G4PVPlacement(0, G4ThreeVector(0,yp,zp), slog, name, glog,
265  false, i+1);
266 #ifdef pdebug
267  G4cout << slog->GetName() << " number " << i+1 << " positioned in "
268  << glog->GetName() << " at (0," << yp << "," << zp
269  << ") with no rotation" << G4endl;
270 #endif
271  }
272 
273  return glog;
274 }
275 
277 
278 #ifdef debug
279  G4cout << "Now registering CrystalMatrix LogicalVolume's to SD's:" << G4endl;
280 #endif
281  if (sensitiveLogs.size()>0) {
283  G4String SDname = idName;
284  for(std::vector<ptrG4Log>::iterator iter=sensitiveLogs.begin();
285  iter<sensitiveLogs.end(); iter++) {
286  sensDets->registerVolume(SDname, (*iter));
287 #ifdef sdebug
288  G4cout << "Register volume " << (*iter)->GetName() << " for" << SDname
289  << G4endl;
290 #endif
291  }
292  }
293 
294 }
295