CMS 3D CMS Logo

CastorSD.cc
Go to the documentation of this file.
1 // File: CastorSD.cc
3 // Date: 02.04
4 // UpDate: 07.04 - C3TF & C4TF semi-trapezoid added
5 // Description: Sensitive Detector class for Castor
7 
10 
12 //#include "SimDataFormats/CaloHit/interface/CastorShowerEvent.h"
14 
15 #include "G4SDManager.hh"
16 #include "G4Step.hh"
17 #include "G4Track.hh"
18 #include "G4VProcess.hh"
19 
20 #include "G4ios.hh"
21 #include "G4Cerenkov.hh"
22 #include "G4LogicalVolumeStore.hh"
23 
24 #include "CLHEP/Units/GlobalSystemOfUnits.h"
25 #include "CLHEP/Units/GlobalPhysicalConstants.h"
26 #include "Randomize.hh"
27 #include "G4Poisson.hh"
28 
29 //#define debugLog
30 
31 CastorSD::CastorSD(G4String name, const DDCompactView & cpv,
32  const SensitiveDetectorCatalog & clg,
33  edm::ParameterSet const & p,
34  const SimTrackManager* manager) :
35  CaloSD(name, cpv, clg, p, manager), numberingScheme(nullptr), lvC3EF(nullptr),
36  lvC3HF(nullptr), lvC4EF(nullptr), lvC4HF(nullptr), lvCAST(nullptr) {
37 
38  edm::ParameterSet m_CastorSD = p.getParameter<edm::ParameterSet>("CastorSD");
39  useShowerLibrary = m_CastorSD.getParameter<bool>("useShowerLibrary");
40  energyThresholdSL = m_CastorSD.getParameter<double>("minEnergyInGeVforUsingSLibrary");
41  energyThresholdSL = energyThresholdSL*GeV; // Convert GeV => MeV
42 
43  non_compensation_factor = m_CastorSD.getParameter<double>("nonCompensationFactor");
44 
45  if (useShowerLibrary) showerLibrary = new CastorShowerLibrary(name, p);
46 
48 
49  edm::LogInfo("ForwardSim")
50  << "***************************************************\n"
51  << "* *\n"
52  << "* Constructing a CastorSD with name " << GetName() << "\n"
53  << "* *\n"
54  << "***************************************************";
55 
56  const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
57  std::vector<G4LogicalVolume*>::const_iterator lvcite;
58  for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) {
59  if (strcmp(((*lvcite)->GetName()).c_str(),"C3EF") == 0) lvC3EF = (*lvcite);
60  if (strcmp(((*lvcite)->GetName()).c_str(),"C3HF") == 0) lvC3HF = (*lvcite);
61  if (strcmp(((*lvcite)->GetName()).c_str(),"C4EF") == 0) lvC4EF = (*lvcite);
62  if (strcmp(((*lvcite)->GetName()).c_str(),"C4HF") == 0) lvC4HF = (*lvcite);
63  if (strcmp(((*lvcite)->GetName()).c_str(),"CAST") == 0) lvCAST = (*lvcite);
64  if (lvC3EF != nullptr && lvC3HF != nullptr && lvC4EF != nullptr && lvC4HF != nullptr && lvCAST != nullptr) break;
65  }
66  edm::LogInfo("ForwardSim") << "CastorSD:: LogicalVolume pointers\n"
67  << lvC3EF << " for C3EF; " << lvC3HF
68  << " for C3HF; " << lvC4EF << " for C4EF; "
69  << lvC4HF << " for C4HF; "
70  << lvCAST << " for CAST. " << std::endl;
71 
72  // if(useShowerLibrary) edm::LogInfo("ForwardSim") << "\n Using Castor Shower Library \n";
73 
74 }
75 
76 //=============================================================================================
77 
79  if (useShowerLibrary) delete showerLibrary;
80 }
81 
82 //=============================================================================================
83 
85  if (useShowerLibrary) {
86  // showerLibrary = new CastorShowerLibrary(name, cpv, p);
87  G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
88  showerLibrary->initParticleTable(theParticleTable);
89  edm::LogInfo("ForwardSim") << "CastorSD::initRun: Using Castor Shower Library \n";
90  }
91 }
92 
93 //=============================================================================================
94 
95 double CastorSD::getEnergyDeposit(G4Step * aStep) {
96 
97  double NCherPhot = 0.;
98 
99  if (aStep == nullptr)
100  return 0;
101 
102  // Get theTrack
103  G4Track* theTrack = aStep->GetTrack();
104 
105  // preStepPoint information *********************************************
106 
107  G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
108  G4VPhysicalVolume* currentPV = preStepPoint->GetPhysicalVolume();
109  G4LogicalVolume* currentLV = currentPV->GetLogicalVolume();
110 
111 #ifdef debugLog
112  G4String name = currentPV->GetName();
113  std::string nameVolume;
114  nameVolume.assign(name,0,4);
115 
116  G4SteppingControl stepControlFlag = aStep->GetControlFlag();
117  if (aStep->IsFirstStepInVolume())
118  LogDebug("ForwardSim") << "CastorSD::getEnergyDeposit:"
119  << "\n IsFirstStepInVolume " ;
120 #endif
121 
122 
123 
124 #ifdef debugLog
125  if (useShowerLibrary && currentLV==lvCAST) {
126  LogDebug("ForwardSim") << "CastorSD::getEnergyDeposit:"
127  << "\n TrackID , ParentID , ParticleName ,"
128  << " eta , phi , z , time ,"
129  << " K , E , Mom "
130  << "\n TRACKINFO: "
131  << theTrack->GetTrackID()
132  << " , "
133  << theTrack->GetParentID()
134  << " , "
135  << theTrack->GetDefinition()->GetParticleName()
136  << " , "
137  << theTrack->GetPosition().eta()
138  << " , "
139  << theTrack->GetPosition().phi()
140  << " , "
141  << theTrack->GetPosition().z()
142  << " , "
143  << theTrack->GetGlobalTime()
144  << " , "
145  << theTrack->GetKineticEnergy()
146  << " , "
147  << theTrack->GetTotalEnergy()
148  << " , "
149  << theTrack->GetMomentum().mag() ;
150  if(theTrack->GetTrackID() != 1)
151  LogDebug("ForwardSim") << "CastorSD::getEnergyDeposit:"
152  << "\n CurrentStepNumber , TrackID , Particle , VertexPosition ,"
153  << " LogicalVolumeAtVertex , CreatorProcess"
154  << "\n TRACKINFO2: "
155  << theTrack->GetCurrentStepNumber()
156  << " , "
157  << theTrack->GetTrackID()
158  << " , "
159  << theTrack->GetDefinition()->GetParticleName()
160  << " , "
161  << theTrack->GetVertexPosition()
162  << " , "
163  << theTrack->GetLogicalVolumeAtVertex()->GetName()
164  << " , "
165  << theTrack->GetCreatorProcess()->GetProcessName() ;
166  } // end of if(useShowerLibrary)
167 #endif
168 
169  // if particle moves from interaction point or "backwards (halo)
170  bool backward = false;
171  const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
172  const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
173  double zint = hitPoint.z();
174  double pz = hit_mom.z();
175 
176  // Check if theTrack moves backward
177  if (pz * zint < 0.) backward = true;
178 
179  // Check that theTrack is above the energy threshold to use Shower Library
180  bool aboveThreshold = false;
181  if(theTrack->GetKineticEnergy() > energyThresholdSL) aboveThreshold = true;
182 
183  // Check if theTrack is a muon (if so, DO NOT use Shower Library)
184  bool notaMuon = true;
185  G4int mumPDG = 13;
186  G4int mupPDG = -13;
187  G4int parCode = theTrack->GetDefinition()->GetPDGEncoding();
188  if (parCode == mupPDG || parCode == mumPDG ) notaMuon = false;
189 
190  // angle condition
191  double theta_max = M_PI - 3.1305; // angle in radians corresponding to -5.2 eta
192  double R_mom=sqrt(hit_mom.x()*hit_mom.x() + hit_mom.y()*hit_mom.y());
193  double theta = atan2(R_mom,std::abs(pz));
194  bool angleok = false;
195  if ( theta < theta_max) angleok = true;
196 
197  // OkToUse
198  double R = sqrt(hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
199  bool dot = false;
200  if ( zint < -14450. && R < 45.) dot = true;
201  bool inRange = true;
202  if ( zint < -14700. || R > 193.) inRange = false;
203  bool OkToUse = false;
204  if ( inRange && !dot) OkToUse = true;
205 
206  const bool particleWithinShowerLibrary = aboveThreshold &&
207  notaMuon && (!backward) && OkToUse && angleok && currentLV == lvCAST;
208 
209  if (useShowerLibrary && particleWithinShowerLibrary) {
210  // Use Castor shower library if energy is above threshold, is not a muon
211  // and is not moving backward
212  getFromLibrary(aStep);
213 
214 #ifdef debugLog
215  LogDebug("ForwardSim") << " Current logical volume is " << nameVolume ;
216 #endif
217 
218  // track is killed in getFromLibrary...
219 
220  return 0;
221  }
222 
223 
224  // Full - Simulation starts here
225 
226  double meanNCherPhot=0;
227 
228  // remember primary particle hitting the CASTOR detector
229 
230  TrackInformationExtractor TIextractor;
231  TrackInformation& trkInfo = TIextractor(theTrack);
232  if (!trkInfo.hasCastorHit()) {
233  trkInfo.setCastorHitPID(parCode);
234  }
235  const int castorHitPID = trkInfo.getCastorHitPID();
236 
237  // Check whether castor hit track is HAD
238  const bool isHad = !(castorHitPID==emPDG || castorHitPID==epPDG || castorHitPID==gammaPDG || castorHitPID == mupPDG || castorHitPID == mumPDG);
239 
240 
241  // Usual calculations
242  // G4ThreeVector hitPoint = preStepPoint->GetPosition();
243  // G4ThreeVector hit_mom = preStepPoint->GetMomentumDirection();
244  G4double stepl = aStep->GetStepLength()/cm;
245  G4double beta = preStepPoint->GetBeta();
246  G4double charge = preStepPoint->GetCharge();
247  // G4VProcess* curprocess = preStepPoint->GetProcessDefinedStep();
248  // G4String namePr = preStepPoint->GetProcessDefinedStep()->GetProcessName();
249  // std::string nameProcess;
250  // nameProcess.assign(namePr,0,4);
251 
252  // G4LogicalVolume* lv = currentPV->GetLogicalVolume();
253  // G4Material* mat = lv->GetMaterial();
254  // G4double rad = mat->GetRadlen();
255 
256 
257 #ifdef debugLog
258  // postStepPoint information *********************************************
259  G4StepPoint* postStepPoint= aStep->GetPostStepPoint();
260  G4VPhysicalVolume* postPV= postStepPoint->GetPhysicalVolume();
261 
262  G4String postname = postPV->GetName();
263  std::string postnameVolume;
264  postnameVolume.assign(postname,0,4);
265 
266  // theTrack information *************************************************
267  // G4Track* theTrack = aStep->GetTrack();
268  //G4double entot = theTrack->GetTotalEnergy();
269  G4ThreeVector vert_mom = theTrack->GetVertexMomentumDirection();
270 
271  G4ThreeVector localPoint = theTrack->GetTouchable()->GetHistory()->
272  GetTopTransform().TransformPoint(hitPoint);
273 
274  G4String particleType = theTrack->GetDefinition()->GetParticleName();
275 
276  // calculations... *************************************************
277  double phi = -100.;
278  if (vert_mom.x() != 0) phi = atan2(vert_mom.y(),vert_mom.x());
279  if (phi < 0.) phi += twopi;
280 
281 
282  double costheta =vert_mom.z()/sqrt(vert_mom.x()*vert_mom.x()+
283  vert_mom.y()*vert_mom.y()+
284  vert_mom.z()*vert_mom.z());
285  double theta = acos(std::min(std::max(costheta,double(-1.)),double(1.)));
286  double eta = -log(tan(theta/2));
287  G4int primaryID = theTrack->GetTrackID();
288  // *************************************************
289 
290 
291  // *************************************************
292  double edep = aStep->GetTotalEnergyDeposit();
293 #endif
294 
295  // *************************************************
296 
297 
298  // *************************************************
299  // take into account light collection curve for plate
300  // double weight = curve_Castor(nameVolume, preStepPoint);
301  // double edep = aStep->GetTotalEnergyDeposit() * weight;
302  // *************************************************
303 
304 
305  // *************************************************
306  /* comments for sensitive volumes:
307  C001 ...-... CP06,CBU1 ...-...CALM --- > fibres and bundle
308  for first release of CASTOR
309  CASF --- > quartz plate for first and second releases of CASTOR
310  GF2Q, GFNQ, GR2Q, GRNQ
311  for tests with my own test geometry of HF (on ask of Gavrilov)
312  C3TF, C4TF - for third release of CASTOR
313  */
314  if (currentLV == lvC3EF || currentLV == lvC4EF || currentLV == lvC3HF ||
315  currentLV == lvC4HF) {
316  // if(nameVolume == "C3EF" || nameVolume == "C4EF" || nameVolume == "C3HF" || nameVolume == "C4HF") {
317 
318  double bThreshold = 0.67;
319  double nMedium = 1.4925;
320  // double photEnSpectrDL = (1./400.nm-1./700.nm)*10000000.cm/nm; /* cm-1 */
321  // double photEnSpectrDL = 10714.285714;
322 
323  double photEnSpectrDE = 1.24; /* see below */
324  /* E = 2pi*(1./137.)*(eV*cm/370.)/lambda = */
325  /* = 12.389184*(eV*cm)/lambda */
326  /* Emax = 12.389184*(eV*cm)/400nm*10-7cm/nm = 3.01 eV */
327  /* Emin = 12.389184*(eV*cm)/700nm*10-7cm/nm = 1.77 eV */
328  /* delE = Emax - Emin = 1.24 eV --> */
329  /* */
330  /* default for Castor nameVolume == "CASF" or (C3TF & C4TF) */
331 
332  double thFullRefl = 23.; /* 23.dergee */
333  double thFullReflRad = thFullRefl*pi/180.;
334 
335  /* default for Castor nameVolume == "CASF" or (C3TF & C4TF) */
336  double thFibDir = 45.; /* .dergee */
337  /* for test HF geometry volumes:
338  if(nameVolume == "GF2Q" || nameVolume == "GFNQ" ||
339  nameVolume == "GR2Q" || nameVolume == "GRNQ")
340  thFibDir = 0.0; // .dergee
341  */
342  double thFibDirRad = thFibDir*pi/180.;
343  /* */
344  /* */
345 
346  // at which theta the point is located:
347  // double th1 = hitPoint.theta();
348 
349  // theta of charged particle in LabRF(hit momentum direction):
350  double costh =hit_mom.z()/sqrt(hit_mom.x()*hit_mom.x()+
351  hit_mom.y()*hit_mom.y()+
352  hit_mom.z()*hit_mom.z());
353  if (zint < 0) costh = -costh;
354  double th = acos(std::min(std::max(costh,double(-1.)),double(1.)));
355 
356  // just in case (can do bot use):
357  if (th < 0.) th += twopi;
358 
359 
360 
361  // theta of cone with Cherenkov photons w.r.t.direction of charged part.:
362  double costhcher =1./(nMedium*beta);
363  double thcher = acos(std::min(std::max(costhcher,double(-1.)),double(1.)));
364 
365  // diff thetas of charged part. and quartz direction in LabRF:
366  double DelFibPart = fabs(th - thFibDirRad);
367 
368  // define real distances:
369  double d = fabs(tan(th)-tan(thFibDirRad));
370 
371  // double a = fabs(tan(thFibDirRad)-tan(thFibDirRad+thFullReflRad));
372  // double r = fabs(tan(th)-tan(th+thcher));
373 
374  double a = tan(thFibDirRad)+tan(fabs(thFibDirRad-thFullReflRad));
375  double r = tan(th)+tan(fabs(th-thcher));
376 
377 
378  // define losses d_qz in cone of full reflection inside quartz direction
379  double d_qz;
380 #ifdef debugLog
381  double variant;
382 #endif
383  if(DelFibPart > (thFullReflRad + thcher) ) {
384  d_qz = 0.;
385 #ifdef debugLog
386  variant=0.;
387 #endif
388  }
389  // if(d > (r+a) ) {d_qz = 0.; variant=0.;}
390  else {
391  if((th + thcher) < (thFibDirRad+thFullReflRad) &&
392  (th - thcher) > (thFibDirRad-thFullReflRad)) {
393  d_qz = 1.;
394 #ifdef debugLog
395  variant=1.;
396 #endif
397  }
398  // if((DelFibPart + thcher) < thFullReflRad ) {d_qz = 1.; variant=1.;}
399  // if((d+r) < a ) {d_qz = 1.; variant=1.;}
400  else {
401  if((thFibDirRad + thFullReflRad) < (th + thcher) &&
402  (thFibDirRad - thFullReflRad) > (th - thcher) ) {
403  // if((thcher - DelFibPart ) > thFullReflRad )
404  // if((r-d ) > a )
405  d_qz = 0.;
406 #ifdef debugLog
407  variant=2.;
408 #endif
409  } else {
410  // if((thcher + DelFibPart ) > thFullReflRad &&
411  // thcher < (DelFibPart+thFullReflRad) )
412  // {
413 #ifdef debugLog
414  variant=3.;
415 #endif
416 
417  // use crossed length of circles(cone projection)
418  // dC1/dC2 :
419  double arg_arcos = 0.;
420  double tan_arcos = 2.*a*d;
421  if(tan_arcos != 0.) arg_arcos =(r*r-a*a-d*d)/tan_arcos;
422  arg_arcos = fabs(arg_arcos);
423  double th_arcos = acos(std::min(std::max(arg_arcos,double(-1.)),double(1.)));
424  d_qz = fabs(th_arcos/pi/2.);
425 
426  // }
427  // else
428  // {
429  // d_qz = 0.; variant=4.;
430  //#ifdef debugLog
431  // std::cout <<" ===============>variant 4 information: <===== " <<std::endl;
432  // std::cout <<" !!!!!!!!!!!!!!!!!!!!!! variant = " << variant <<std::endl;
433  //#endif
434  //
435  // }
436  }
437  }
438  }
439 
440 
441  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
442 
443  if(charge != 0. && beta > bThreshold ) {
444 
445  meanNCherPhot = 370.*charge*charge*
446  ( 1. - 1./(nMedium*nMedium*beta*beta) )*
447  photEnSpectrDE*stepl;
448 
449  const double scale = (isHad ? non_compensation_factor : 1.0);
450  G4int poissNCherPhot = (G4int) G4Poisson(meanNCherPhot * scale);
451 
452  if(poissNCherPhot < 0) poissNCherPhot = 0;
453 
454  double effPMTandTransport = 0.19;
455  double ReflPower = 0.1;
456  double proba = d_qz + (1-d_qz)*ReflPower;
457  NCherPhot = poissNCherPhot*effPMTandTransport*proba*0.307;
458 
459 
460 #ifdef debugLog
461  double thgrad = th*180./pi;
462  double thchergrad = thcher*180./pi;
463  double DelFibPartgrad = DelFibPart*180./pi;
464  LogDebug("ForwardSim") << " ==============================> start all "
465  << "information:<========= \n" << " =====> for "
466  << "test:<=== \n" << " variant = " << variant
467  << "\n thgrad = " << thgrad << "\n thchergrad "
468  << "= " << thchergrad << "\n DelFibPartgrad = "
469  << DelFibPartgrad << "\n d_qz = " << d_qz
470  << "\n =====> Start Step Information <=== \n"
471  << " ===> calo preStepPoint info <=== \n"
472  << " hitPoint = " << hitPoint << "\n"
473  << " hitMom = " << hit_mom << "\n"
474  << " stepControlFlag = " << stepControlFlag
475  // << "\n curprocess = " << curprocess << "\n"
476  // << " nameProcess = " << nameProcess
477  << "\n charge = " << charge << "\n"
478  << " beta = " << beta << "\n"
479  << " bThreshold = " << bThreshold << "\n"
480  << " thgrad =" << thgrad << "\n"
481  << " effPMTandTransport=" << effPMTandTransport
482  // << "\n volume = " << name
483  << "\n nameVolume = " << nameVolume << "\n"
484  << " nMedium = " << nMedium << "\n"
485  // << " rad length = " << rad << "\n"
486  // << " material = " << mat << "\n"
487  << " stepl = " << stepl << "\n"
488  << " photEnSpectrDE = " << photEnSpectrDE <<"\n"
489  << " edep = " << edep << "\n"
490  << " ===> calo theTrack info <=== " << "\n"
491  << " particleType = " << particleType << "\n"
492  << " primaryID = " << primaryID << "\n"
493  << " entot= " << theTrack->GetTotalEnergy() << "\n"
494  << " vert_eta= " << eta << "\n"
495  << " vert_phi= " << phi << "\n"
496  << " vert_mom= " << vert_mom << "\n"
497  << " ===> calo hit preStepPointinfo <=== "<<"\n"
498  << " local point = " << localPoint << "\n"
499  << " ==============================> final info"
500  << ": <=== \n"
501  << " meanNCherPhot = " << meanNCherPhot << "\n"
502  << " poissNCherPhot = " << poissNCherPhot <<"\n"
503  << " NCherPhot = " << NCherPhot;
504 #endif
505 
506  // Included by WC
507  // std::cout << "\n volume = " << name
508  // << "\n nameVolume = " << nameVolume << "\n"
509  // << "\n postvolume = " << postname
510  // << "\n postnameVolume = " << postnameVolume << "\n"
511  // << "\n particleType = " << particleType
512  // << "\n primaryID = " << primaryID << "\n";
513 
514  }
515  }
516 
517 
518 #ifdef debugLog
519  LogDebug("ForwardSim") << "CastorSD:: " << nameVolume
520  // << " Light Collection Efficiency " << weight
521  << " Weighted Energy Deposit " << edep/MeV
522  << " MeV\n";
523 #endif
524  // Temporary member for testing purpose only...
525  // unit_id = setDetUnitId(aStep);
526  // if(NCherPhot != 0) std::cout << "\n UnitID = " << unit_id << " ; NCherPhot = " << NCherPhot ;
527 
528  return NCherPhot;
529 }
530 
531 //=======================================================================================
532 
533 uint32_t CastorSD::setDetUnitId(G4Step* aStep) {
534  return (numberingScheme == nullptr ? 0 : numberingScheme->getUnitID(aStep));
535 }
536 
537 //=======================================================================================
538 
540 
541  if (scheme != nullptr) {
542  edm::LogInfo("ForwardSim") << "CastorSD: updates numbering scheme for "
543  << GetName();
544  if (numberingScheme) delete numberingScheme;
545  numberingScheme = scheme;
546  }
547 }
548 
549 //=======================================================================================
550 
551 int CastorSD::setTrackID (G4Step* aStep) {
552 
553  theTrack = aStep->GetTrack();
554 
555  TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
556  int primaryID = trkInfo->getIDonCaloSurface();
557  if (primaryID == 0) {
558 #ifdef debugLog
559  edm::LogWarning("ForwardSim") << "CastorSD: Problem with primaryID **** set by force "
560  << "to TkID **** " << theTrack->GetTrackID();
561 #endif
562  primaryID = theTrack->GetTrackID();
563  }
564 
565  if (primaryID != previousID.trackID()) {
566  double etrack = preStepPoint->GetKineticEnergy();
567  resetForNewPrimary(preStepPoint->GetPosition(), etrack);
568  }
569 
570  return primaryID;
571 }
572 
573 //=======================================================================================
574 
575 uint32_t CastorSD::rotateUnitID(uint32_t unitID, G4Track* track, const CastorShowerEvent& shower) {
576 // ==============================================================
577 //
578 // o Exploit Castor phi symmetry to return newUnitID for
579 // shower hits based on track phi coordinate
580 //
581 // ==============================================================
582 
583  // Get 'track' phi:
584  double trackPhi = track->GetPosition().phi();
585  if(trackPhi<0) trackPhi += 2*M_PI ;
586  // Get phi from primary that gave rise to SL 'shower':
587  double showerPhi = shower.getPrimPhi();
588  if(showerPhi<0) showerPhi += 2*M_PI ;
589  // Delta phi:
590 
591  // Find the OctSector for which 'track' and 'shower' belong
592  int trackOctSector = (int) ( trackPhi / (M_PI/4) ) ;
593  int showerOctSector = (int) ( showerPhi / (M_PI/4) ) ;
594 
595  uint32_t newUnitID;
596  uint32_t sec = ( ( unitID>>4 ) & 0xF ) ;
597  uint32_t complement = ( unitID & 0xFFFFFF0F ) ;
598 
599  // edm::LogInfo("ForwardSim") << "\n CastorSD::rotateUnitID: "
600  // << "\n unitID = " << unitID
601  // << "\n sec = " << sec
602  // << "\n complement = " << complement ;
603 
604  // Get 'track' z:
605  double trackZ = track->GetPosition().z();
606 
607  int aux ;
608  int dSec = 2*(trackOctSector - showerOctSector) ;
609  // if(trackZ<0) // Good for revision 1.8 of CastorNumberingScheme
610  if(trackZ>0) // Good for revision 1.9 of CastorNumberingScheme
611  {
612  int sec1 = sec-dSec;
613  // sec -= dSec ;
614  if(sec1<0) sec1 += 16;
615  if(sec1>15) sec1 -= 16;
616  sec = (uint32_t)(sec1);
617  } else {
618  if( dSec<0 ) sec += 16 ;
619  sec += dSec ;
620  aux = (int) (sec/16) ;
621  sec -= aux*16 ;
622  }
623  sec = sec<<4 ;
624  newUnitID = complement | sec ;
625 
626 #ifdef debugLog
627  if(newUnitID != unitID) {
628  LogDebug("ForwardSim") << "\n CastorSD::rotateUnitID: "
629  << "\n unitID = " << unitID
630  << "\n newUnitID = " << newUnitID ;
631  }
632 #endif
633 
634  return newUnitID ;
635 
636 }
637 
638 //=======================================================================================
639 
640 void CastorSD::getFromLibrary (G4Step* aStep) {
641 
643 //
644 // Method to get hits from the Shower Library
645 //
646 // CastorShowerEvent hits returned by getShowerHits are used to
647 // replace the full simulation of the shower from theTrack
648 //
649 // "updateHit" save the Hits to a CaloG4Hit container
650 //
652 
653  preStepPoint = aStep->GetPreStepPoint();
654  theTrack = aStep->GetTrack();
655  bool ok;
656 
657  // **** Call method to retrieve hits from the ShowerLibrary ****
659 
660  double etrack = preStepPoint->GetKineticEnergy();
661  int primaryID = setTrackID(aStep);
662  // int primaryID = theTrack->GetTrackID();
663 
664  // Reset entry point for new primary
665  posGlobal = preStepPoint->GetPosition();
666  resetForNewPrimary(posGlobal, etrack);
667 
668  // Check whether track is EM or HAD
669  G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
670  bool isEM , isHAD ;
671  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG) {
672  isEM = true ; isHAD = false;
673  } else {
674  isEM = false; isHAD = true ;
675  }
676 
677 #ifdef debugLog
678  // edm::LogInfo("ForwardSim") << "\n CastorSD::getFromLibrary: "
679  LogDebug("ForwardSim") << "\n CastorSD::getFromLibrary: "
680  << hits.getNhit() << " hits for " << GetName() << " from "
681  << theTrack->GetDefinition()->GetParticleName() << " of "
682  << preStepPoint->GetKineticEnergy()/GeV << " GeV and trackID "
683  << theTrack->GetTrackID() ;
684 #endif
685 
686  // Scale to correct energy
687  double E_track = preStepPoint->GetTotalEnergy() ;
688  double E_SLhit = hits.getPrimE() * GeV ;
689  double scale = E_track/E_SLhit ;
690 
691  //Non compensation
692  if (isHAD){
693  scale=scale*non_compensation_factor; // if hadronic extend the scale with the non-compensation factor
694  } else {
695  scale=scale; // if electromagnetic, don't do anything
696  }
697 
698 
699 /* double theTrackEnergy = theTrack->GetTotalEnergy() ;
700 
701  if(fabs(theTrackEnergy-E_track)>10.) {
702  edm::LogInfo("ForwardSim") << "\n TrackID = " << theTrack->GetTrackID()
703  << "\n theTrackEnergy = " << theTrackEnergy
704  << "\n preStepPointEnergy = " << E_track ;
705  G4TrackVector tsec = *(aStep->GetSecondary());
706  for (unsigned int kk=0; kk<tsec.size(); kk++) {
707  edm::LogInfo("ForwardSim") << "CastorSD::getFromLibrary:"
708  << "\n tsec[" << kk << "]->GetTrackID() = "
709  << tsec[kk]->GetTrackID()
710  << " with energy "
711  << tsec[kk]->GetTotalEnergy() ;
712  }
713  }
714 */
715  // Loop over hits retrieved from the library
716  for (unsigned int i=0; i<hits.getNhit(); i++) {
717 
718  // Get nPhotoElectrons and set edepositEM / edepositHAD accordingly
719  double nPhotoElectrons = hits.getNphotons(i);
720  // Apply scaling
721  nPhotoElectrons *= scale ;
722  if(isEM) {
723  // edepositEM = nPhotoElectrons*GeV;
724  edepositEM = nPhotoElectrons;
725  edepositHAD = 0.;
726  } else if(isHAD) {
727  edepositEM = 0.;
728  edepositHAD = nPhotoElectrons;
729  // edepositHAD = nPhotoElectrons*GeV;
730  }
731 
732  // Get hit position and time
733  double time = hits.getTime(i);
734  // math::XYZPoint position = hits.getHitPosition(i);
735 
736  // Get hit detID
737  unsigned int unitID = hits.getDetID(i);
738 
739  // Make the detID "rotation" from one sector to another taking into account the
740  // sectors of the impinging particle (theTrack) and of the particle that produced
741  // the 'hits' retrieved from shower library
742  unsigned int rotatedUnitID = rotateUnitID(unitID , theTrack , hits);
743  currentID.setID(rotatedUnitID, time, primaryID, 0);
744  // currentID.setID(unitID, time, primaryID, 0);
745 
746  // check if it is in the same unit and timeslice as the previous one
747  if (currentID == previousID) {
749  } else {
750  if (!checkHit()) currentHit = createNewHit();
751  }
752  } // End of loop over hits
753 
754  //Now kill the current track
755  if (ok) {
756  theTrack->SetTrackStatus(fStopAndKill);
757 #ifdef debugLog
758  LogDebug("ForwardSim") << "CastorSD::getFromLibrary:"
759  << "\n \"theTrack\" with TrackID() = "
760  << theTrack->GetTrackID()
761  << " and with energy "
762  << theTrack->GetTotalEnergy()
763  << " has been set to be killed" ;
764 #endif
765  G4TrackVector tv = *(aStep->GetSecondary());
766  for (unsigned int kk=0; kk<tv.size(); kk++) {
767  if (tv[kk]->GetVolume() == preStepPoint->GetPhysicalVolume()) {
768  tv[kk]->SetTrackStatus(fStopAndKill);
769 #ifdef debugLog
770  LogDebug("ForwardSim") << "CastorSD::getFromLibrary:"
771  << "\n tv[" << kk << "]->GetTrackID() = "
772  << tv[kk]->GetTrackID()
773  << " with energy "
774  << tv[kk]->GetTotalEnergy()
775  << " has been set to be killed" ;
776 #endif
777  }
778  }
779  }
780 }
781 
#define LogDebug(id)
float edepositEM
Definition: CaloSD.h:121
const double beta
T getParameter(std::string const &) const
void initParticleTable(G4ParticleTable *)
G4int emPDG
Definition: CaloSD.h:136
int getCastorHitPID() const
const double GeV
Definition: MathUtil.h:16
void updateHit(CaloG4Hit *)
Definition: CaloSD.cc:440
int getIDonCaloSurface() const
Definition: CaloSD.h:42
double getEnergyDeposit(G4Step *) override
Definition: CastorSD.cc:95
Geom::Theta< T > theta() const
double non_compensation_factor
Definition: CastorSD.h:53
G4ThreeVector posGlobal
Definition: CaloSD.h:113
CastorNumberingScheme * numberingScheme
Definition: CastorSD.h:46
bool useShowerLibrary
Definition: CastorSD.h:51
uint32_t rotateUnitID(uint32_t, G4Track *, const CastorShowerEvent &)
Definition: CastorSD.cc:575
#define nullptr
type of data representation of DDCompactView
Definition: DDCompactView.h:90
void getFromLibrary(G4Step *)
Definition: CastorSD.cc:640
unsigned int getDetID(int i)
G4bool checkHit()
Definition: CaloSD.cc:331
static TrackerG4SimHitNumberingScheme & numberingScheme(const DDCompactView &cpv, const GeometricDet &det)
G4LogicalVolume * lvC4HF
Definition: CastorSD.h:48
const Double_t pi
void setCastorHitPID(const int pid)
const double MeV
void resetForNewPrimary(const G4ThreeVector &, double)
Definition: CaloSD.cc:454
float edepositHAD
Definition: CaloSD.h:121
T sqrt(T t)
Definition: SSEVec.h:18
int trackID() const
Definition: CaloHitID.h:25
G4int epPDG
Definition: CaloSD.h:136
float getTime(int i)
void initRun() override
Definition: CastorSD.cc:84
G4int gammaPDG
Definition: CaloSD.h:136
int setTrackID(G4Step *)
Definition: CastorSD.cc:551
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float getNphotons(int i)
G4LogicalVolume * lvC3HF
Definition: CastorSD.h:48
T min(T a, T b)
Definition: MathUtil.h:58
CaloHitID previousID
Definition: CaloSD.h:117
CaloG4Hit * currentHit
Definition: CaloSD.h:128
bool hasCastorHit() const
uint32_t setDetUnitId(G4Step *step) override
Definition: CastorSD.cc:533
G4Track * theTrack
Definition: CaloSD.h:118
double energyThresholdSL
Definition: CastorSD.h:52
#define M_PI
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:44
G4StepPoint * preStepPoint
Definition: CaloSD.h:120
G4LogicalVolume * lvC4EF
Definition: CastorSD.h:48
static const G4LogicalVolume * GetVolume(const std::string &name)
CastorSD(G4String, const DDCompactView &, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &, const SimTrackManager *)
Definition: CastorSD.cc:31
CaloHitID currentID
Definition: CaloSD.h:117
float getPrimPhi() const
~CastorSD() override
Definition: CastorSD.cc:78
G4LogicalVolume * lvCAST
Definition: CastorSD.h:49
CastorShowerLibrary * showerLibrary
Definition: CastorSD.h:47
CastorShowerEvent getShowerHits(G4Step *, bool &)
void setNumberingScheme(CastorNumberingScheme *scheme)
Definition: CastorSD.cc:539
G4LogicalVolume * lvC3EF
Definition: CastorSD.h:48
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
double a
Definition: hdecay.h:121
virtual uint32_t getUnitID(const G4Step *aStep) const
CaloG4Hit * createNewHit()
Definition: CaloSD.cc:363
unsigned int getNhit()