Deprecated/UpgradeASCIITests/CachedShowerRegeneratorASCII/CachedShowerRegenerator.cc
Go to the documentation of this file.
1 
12 #include <utl/config.h>
13 
14 #include <cmath>
15 #include <sstream>
16 #include <vector>
17 #include <limits>
18 
19 #include <fwk/CentralConfig.h>
20 #include <fwk/CoordinateSystemRegistry.h>
21 #include <fwk/RandomEngineRegistry.h>
22 
23 #include <evt/Event.h>
24 #include <evt/ShowerSimData.h>
25 
26 #include <sevt/SEvent.h>
27 #include <sevt/Station.h>
28 #include <sevt/StationSimData.h>
29 
30 #include <det/Detector.h>
31 #include <sdet/SDetector.h>
32 #include <sdet/Station.h>
33 
34 #include <utl/ErrorLogger.h>
35 #include <utl/GeometryUtilities.h>
36 #include <utl/MathConstants.h>
37 #include <utl/Particle.h>
38 #include <utl/PhysicalConstants.h>
39 #include <utl/Point.h>
40 #include <utl/RandomEngine.h>
41 #include <utl/TimeStamp.h>
42 #include <utl/Math.h>
43 #include <utl/Reader.h>
44 #include <utl/TabularStream.h>
45 #include <utl/TabulatedFunction.h>
46 
47 #include <CLHEP/Random/RandFlat.h>
48 #include <CLHEP/Random/RandPoisson.h>
49 #include <CLHEP/Random/RandGauss.h>
50 
52 #include "LogGaussSmearing.h"
53 
54 using namespace CachedShowerRegeneratorASCII;
55 using namespace fwk;
56 using namespace evt;
57 using namespace sevt;
58 using namespace utl;
59 using namespace std;
60 
61 using CLHEP::RandFlat;
62 using CLHEP::RandPoisson;
63 
64 // defs for particle type switch
65 #define PHOTONS utl::Particle::ePhoton
66 #define ELECTRONS utl::Particle::eElectron: \
67  case utl::Particle::ePositron
68 #define MUONS utl::Particle::eMuon: \
69  case utl::Particle::eAntiMuon
70 #define BARYONS utl::Particle::eProton: \
71  case utl::Particle::eAntiProton: \
72  case utl::Particle::eNeutron: \
73  case utl::Particle::eAntiNeutron: \
74  case utl::Particle::eLambda: \
75  case utl::Particle::eAntiLambda
76 #define MESONS utl::Particle::ePiZero: \
77  case utl::Particle::ePiPlus: \
78  case utl::Particle::ePiMinus: \
79  case utl::Particle::eEta: \
80  case utl::Particle::eKaon0L: \
81  case utl::Particle::eKaon0S: \
82  case utl::Particle::eKaonPlus: \
83  case utl::Particle::eKaonMinus
84 
85 
86 namespace CachedShowerRegeneratorASCII {
87 
88  template<typename Map, typename T>
89  inline
90  void
91  InsertValue(Map& map, const int sId, const T& value)
92  {
93  const typename Map::iterator sIt = map.find(sId);
94  if (sIt != map.end())
95  sIt->second(value);
96  else
97  map.insert(make_pair(sId, typename Map::mapped_type(value)));
98  }
99 
100  inline
101  double
102  Round(const double div, const double val)
103  {
104  return round(div*val)/div;
105  }
106 
108 
113  inline
114  double
115  PlaneFrontTime(const CoordinateSystemPtr showerCS, const Point& corePosition,
116  const Point& position)
117  {
118  return (corePosition.GetZ(showerCS) - position.GetZ(showerCS)) / kSpeedOfLight;
119  }
120 
121 } // namespace CachedShowerRegeneratorASCII
122 
123 
125  fMaxParticles(numeric_limits<unsigned int>::max()),
126  fInnerRadiusCut(0.),
127  fOuterRadiusCut(1.e6*km),
128  fElectronEnergyCut(0),
129  fMuonEnergyCut(0),
130  fPhotonEnergyCut(0),
131  fHadronEnergyCut(0),
132  fMesonEnergyCut(0),
133  fDeltaROverR(0),
134  fDeltaPhi(0),
135  fHorizontalParticleCut(0),
136  fUseStationPositionMatrix(true),
137  fPhiGranularity(0),
138  fRGranularity(0),
139  fMuToVem(0),
140  fEToVem(0),
141  fUseWeightLimiting(false),
142  fWeightThreshold(0),
143  fAccumulatedWeightLimit(0),
144  fMuonWeightScale(1),
145  fRandomEngine(0),
146  fTimeSlotSize(1.*ns),
147  fNOutOfRangeWeight(0),
148  fWeightLimit(0)
149 {
150 }
151 
152 
155 {
156 
157  unityWeightCtr = 0; // temp
158  largeWeightCtr = 0; // temp
159 
160  Branch topB =
161  CentralConfig::GetInstance()->GetTopBranch("CachedShowerRegeneratorASCII");
162 
163  topB.GetChild("CylinderHeight_m").GetData(fCylinderHeight);
164 
165 
166  AttributeMap useAtt;
167  useAtt["use"] = string("yes");
168 
169  Branch limitB = topB.GetChild("LimitParticlesPerCycle", useAtt);
170  if (limitB)
171  limitB.GetData(fMaxParticles);
172 
173  Branch distanceCutB = topB.GetChild("DistanceCuts");
174 
175  Branch inB = distanceCutB.GetChild("InnerRadiusCut", useAtt);
176  if (inB)
178 
179  Branch outB = distanceCutB.GetChild("OuterRadiusCut", useAtt);
180  if (outB)
181  outB.GetData(fOuterRadiusCut);
182 
183  Branch energyCutB = topB.GetChild("EnergyCuts");
184  energyCutB.GetChild("ElectronEnergyCut").GetData(fElectronEnergyCut);
185  energyCutB.GetChild("MuonEnergyCut").GetData(fMuonEnergyCut);
186  energyCutB.GetChild("PhotonEnergyCut").GetData(fPhotonEnergyCut);
187  energyCutB.GetChild("HadronEnergyCut").GetData(fHadronEnergyCut);
188  energyCutB.GetChild("MesonEnergyCut").GetData(fMesonEnergyCut);
189 
190  Branch algoB = topB.GetChild("AlgorithmParameters");
191  algoB.GetChild("DeltaROverR").GetData(fDeltaROverR);
192  algoB.GetChild("DeltaPhi").GetData(fDeltaPhi);
193  algoB.GetChild("HorizontalParticleCut").GetData(fHorizontalParticleCut);
194  algoB.GetChild("UseStationPositionMatrix").GetData(fUseStationPositionMatrix);
195  algoB.GetChild("PhiGranularity").GetData(fPhiGranularity);
196  algoB.GetChild("RGranularity").GetData(fRGranularity);
197  algoB.GetChild("LogGaussSmearingWidth").GetData(fLogGaussSmearingWidth);
198 
199  Branch limitSwitchB = topB.GetChild("ResamplingWeightLimiting", useAtt);
200  if (limitSwitchB) {
201  fUseWeightLimiting = true;
202  limitSwitchB.GetChild("WeightThreshold").GetData(fWeightThreshold);
203  limitSwitchB.GetChild("AccumulatedWeightLimit").GetData(fAccumulatedWeightLimit);
204  }
205 
206  if (topB.GetChild("MuonWeightScale"))
207  topB.GetChild("MuonWeightScale").GetData(fMuonWeightScale);
208 
209  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector).GetEngine();
210 
212  WARNING("Not using StationPositionMatrix. "
213  "All stations will be searched for injection.");
214 
215  return eSuccess;
216 }
217 
218 
219 bool
221  const double pEnergy)
222  const
223 {
224  switch (pType) {
225  case PHOTONS:
226  return pEnergy < fPhotonEnergyCut;
227  case ELECTRONS:
228  return pEnergy < fElectronEnergyCut;
229  case MUONS:
230  return pEnergy < fMuonEnergyCut;
231  case BARYONS:
232  return pEnergy < fHadronEnergyCut;
233  case MESONS:
234  return pEnergy < fMesonEnergyCut;
235  default:
236  return true;
237  }
238 }
239 
240 
241 void
243 {
245 
246  fShowerData->fWeightCounterMap.clear();
247 
249  fShowerData->fLogGauss =
251 
252  ShowerSimData& simShower = event.GetSimShower();
254 
255  if (simShower.GetMinRadiusCut() < fInnerRadiusCut) {
256  ostringstream msg;
257  msg << "Setting new value for fMinRadiusCut: " << fInnerRadiusCut;
258  INFO(msg);
259  simShower.SetMinRadiusCut(fInnerRadiusCut);
260  }
261 
262  fShowerData->fParticleIt = simShower.GroundParticlesBegin();
263  fShowerData->fParticlesEnd = simShower.GroundParticlesEnd();
264 
265  const double showerZenith = simShower.GetZenith();
266  const double samplingAreaFactor =
267  4 * fDeltaPhi * fDeltaROverR / cos(showerZenith);
268 
269  if (!event.HasSEvent())
270  event.MakeSEvent();
271  SEvent& sEvent = event.GetSEvent();
272 
273  const CoordinateSystemPtr showerCS = simShower.GetShowerCoordinateSystem();
274  const Point& corePosition = simShower.GetPosition();
275  const TimeStamp& coreTime = simShower.GetTimeStamp();
276  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
277 
278  int nStations = 0;
279  int nInner = 0;
280  int nOuter = 0;
281 
282  for (sdet::SDetector::StationIterator sdIt = sDetector.StationsBegin();
283  sdIt != sDetector.StationsEnd(); ++sdIt) {
284 
285  ++nStations;
286 
287  const int sId = sdIt->GetId();
288 
289  if (!sEvent.HasStation(sId))
290  sEvent.MakeStation(sId);
291 
292  Station& station = sEvent.GetStation(sId);
293 
294  // clear particle lists for the station. The stuff above
295  // presumably only needs to be called once per shower, but
296  // particle clearing has to happen each time through.
297  if (!station.HasSimData())
298  station.MakeSimData();
299  StationSimData& sSim = station.GetSimData();
300 
301  const Point& sPosition = sdIt->GetPosition();
302 
303  const TimeStamp planeTime =
304  coreTime + TimeInterval(PlaneFrontTime(showerCS, corePosition, sPosition));
305  sSim.SetPlaneFrontTime(planeTime);
306 
307  const double sR = sPosition.GetRho(showerCS);
308 
309  if (sR < fInnerRadiusCut) {
310  ++nInner;
311  sSim.SetIsInsideMinRadius();
312  continue;
313  }
314 
315  if (sR > fOuterRadiusCut) {
316  ++nOuter;
317  continue;
318  }
319 
320  // DV: Particle weights are calculated by the shower simulation according
321  // to the particle densities as measured in the ground-particle plane.
322  // Thus all reweighting area ratios calculated in the resampler have to
323  // have area values expressed in the corresponding ground-particle plane
324  // projections, ie if there is a small missalignement of the tank vertical
325  // and the ground-particle plane vertical, it has to be taken into account
326  // with appropriate cosine of this small angle.
327  // First calculate the ground-particle area of the resampling pie
328  // section of a station:
329  const double samplingArea = samplingAreaFactor * Sqr(sR);
330 
331  // it is best to create station matrix based on log(r^2)
332  const double r1 = 2 * log(sR * (1 - fDeltaROverR));
333  const double r2 = 2 * log(sR * (1 + fDeltaROverR));
334 
335  fShowerData->fStationMatrix.PushBack(*sdIt, station,
336  sPosition.GetPhi(showerCS), fDeltaPhi,
337  sR, r1, r2,
338  samplingArea);
339 
340  }
341 
342  fShowerData->fStationMatrix.CreateMatrix(fUseStationPositionMatrix);
343  fShowerData->fMinR2 = exp(fShowerData->fStationMatrix.GetMinR());
344 
345  ostringstream info;
346  info << "Out of " << nStations << " stations: inner cut " << nInner << ", outer " << nOuter;
347  INFO(info);
348 }
349 
350 
353 {
354  if (!event.HasSimShower()) {
355  ERROR("Current event does not have a simulated shower.");
356  return eFailure;
357  }
358 
359  const ShowerSimData& simShower = event.GetSimShower();
360 
361  // sim event finished ?
362  if (fShowerData && fShowerData->fParticleIt == fShowerData->fParticlesEnd) {
363  fShowerData = 0;
364  // break inner loop
365  return eBreakLoop;
366  }
367 
368  if (!fShowerData)
369  InitNewShower(event);
370 
371  {
372  ostringstream info;
373  info << "Cached Shower Regenerator ASCII : Regenerating batch of "
374  << fMaxParticles << " particles.";
375  INFO(info);
376  }
377 
378  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
379  SEvent& sEvent = event.GetSEvent();
380 
381  // clear particle list for the stations
382  for (sdet::SDetector::StationIterator sdIt = sDetector.StationsBegin();
383  sdIt != sDetector.StationsEnd(); ++sdIt)
384  sEvent.GetStation(sdIt->GetId()).GetSimData().ClearParticleList();
385 
386  const CoordinateSystemPtr showerCS = simShower.GetShowerCoordinateSystem();
387  const Point& corePosition = simShower.GetPosition();
388  const CoordinateSystemPtr grParticleCS = simShower.GetLocalCoordinateSystem();
389 
390  // Based on the cuts read in for the outer and inner radius in Init(), we
391  // build the list of stations that lie within the region of interest in
392  // the shower plane. We then loop only over these stations, since anything
393  // outside the limits defined by the outer and inner radius cuts will never
394  // receive any regenerated particles anyway.
395 
396  // keep count to avoid excessive memory consumption
397  unsigned int nParticlesInjected = 0;
398 
399  ShowerParticleIterator& particleIt = fShowerData->fParticleIt;
400 
401  for (; particleIt != fShowerData->fParticlesEnd; ++particleIt) {
402 
403  // over the cache limit?
404  if (nParticlesInjected >= fMaxParticles) {
405  ostringstream info;
406  info << nParticlesInjected << " particles processed.";
407  INFO(info);
408  return eSuccess;
409  }
410 
411  const Point& pPosition = particleIt->GetPosition();
412  const double pR2ShowerFrame = pPosition.GetRho2(showerCS);
413 
414  // particle time relative to the core time
415  const double pTime = particleIt->GetTime().GetInterval();
416 
417  // due to a bug in CORSIKA (version 6.900) when simulating upward going particles (option UPWARD)
418  // a few particles per shower get negative delays w.r.t. to the plane front, they behave like tachyons.
419  // see http://www-ik.fzk.de/~maurel/corsika_negative_particle_delays for a list
420  // of "superluminal" particles in a library simulated using the UPWARD option.
421  // Negative delays on the order of 0.01 ns are possible due to roundoff errors,
422  // only particles with a delay smaller than -0.1 ns are rejected here.
423  double pPlaneFrontDelay = pTime - PlaneFrontTime(showerCS, corePosition, pPosition);
424  if (pPlaneFrontDelay < -0.1*ns )
425  continue;
426 
427  if (pR2ShowerFrame <= fShowerData->fMinR2)
428  continue;
429 
430  const double pLogR2ShowerFrame = log(pR2ShowerFrame);
431 
432  const double pPhiShowerFrame = pPosition.GetPhi(showerCS);
433 
435  fShowerData->fStationMatrix.GetStationList(pPhiShowerFrame, pLogR2ShowerFrame);
436 
437  if (sList.empty())
438  continue;
439 
440  if (IsParticleEnergyLow(particleIt->GetType(), particleIt->GetKineticEnergy()))
441  continue;
442 
443  for (StationPositionMatrix::StationInfoPtrList::const_iterator sIt = sList.begin();
444  sIt != sList.end(); ++sIt) {
445 
446  const StationInfo& sInfo = **sIt;
447 
448  if (!sInfo.IsIn(pPhiShowerFrame, pLogR2ShowerFrame))
449  continue;
450 
451  const double pWeight =
452  (particleIt->GetType() == utl::Particle::eMuon ||
453  particleIt->GetType() == utl::Particle::eAntiMuon ||
455  fMuonWeightScale*particleIt->GetWeight():
456  particleIt->GetWeight());
457 
458  Particle newParticle(*particleIt);
459 
460  // This decision should be taken elsewhere, after
461  // calculating AvgN
462  //
463  //original newParticle.SetWeight(1);
464 
465  // all particle positions within the resampling area are equivalent, define
466  // "weight density", ie the probability to find a particle with such properties
467  // within some area
468  const double pWeightDensity = pWeight / sInfo.GetResamplingArea();
469 
470  const sdet::Station& dStation = sInfo.GetDetStation();
471  const double sThickness = dStation.GetThickness();
472  const double sRadius = dStation.GetRadius() + sThickness;
473  const double sHeight = fCylinderHeight;
474 
475 
476  const CoordinateSystemPtr dStationCS =
477  dStation.GetLocalCoordinateSystem();
478  StationSimData& sSim = sInfo.GetEvtStation().GetSimData();
479 
480  const unsigned int sId = dStation.GetId();
481 
482  const Vector& pDirection = newParticle.GetDirection();
483  const double pStationCosine = pDirection.GetZ(dStationCS);
484  const double pPlaneCosine = pDirection.GetZ(grParticleCS);
485  const double pPlaneAbsCosine = abs(pPlaneCosine);
486 
487  // top entry
488 
489  // tank top surface seen by the particle?
490 
491  if (pPlaneAbsCosine < fHorizontalParticleCut) {
492  ++fShowerData->fNHorizontalParticles;
493  }
494 
495  else if (pStationCosine < 0 && pPlaneCosine < fHorizontalParticleCut) {
496 
497  // projected top area of a tank
498  const double effArea = kPi*Sqr(sRadius) * pStationCosine/pPlaneCosine;
499 
500  const double avgN = pWeightDensity * effArea;
501 
502  InsertValue(fShowerData->fWeightStat, sId, avgN);
503 
504 // if (sId == 5669) {
505 // cout << "\n ============ TOP ENTRY ========== \n";
506 // cout << "avgN = " << avgN << endl;
507 // }
508 
509  unsigned int n;
510  double weight;
511 
512  if (fUseWeightLimiting) {
513  boost::tie(n, weight) = ParticleNumberAndWeight(avgN, sId);
514 
515  if (int(weight) == 1)
516  ++unityWeightCtr;
517  else
518  largeWeightCtr += weight;
519 
520  } else {
521  n = RandPoisson::shoot(fRandomEngine, avgN);
522  weight = 1;
523  }
524 
525  newParticle.SetWeight(weight);
526 
527 // if (sId == 5669) {
528 // cout << "station, fWeightCounter " << sId << ", " << fShowerData->fWeightCounterMap[sId] << " : ";
529 // cout << "( " << n << ", " << newParticle.GetWeight() << ") \n" ;
530 // }
531 
532  for (unsigned int i = 0; i < n; ++i) {
533 
534  const double r =
535  sRadius * sqrt(RandFlat::shoot(fRandomEngine, 0, 1));
536  const double phi =
537  RandFlat::shoot(fRandomEngine, 0, kTwoPi);
538  const Point pShiftedPosition(r, phi, sHeight, dStationCS, Point::kCylindrical);
539  newParticle.SetPosition(pShiftedPosition);
540 
541  // Shift the time to account for differences in position between the
542  // hit tank and the position the particle was placed at the ground
543  // by the shower simulation. Also, include a shift for multiple
544  // particle entries from regeneration of one weighted particle. So far,
545  // no one has provided any real justification for what distribution
546  // should be used for the energy shifting.
547  // see P. Billoir, Astroparticle Physics 30 (2008) 270–285
548  double pShiftedTime =
549  pTime + PlaneFrontTime(showerCS, pPosition, pShiftedPosition);
550  if (i && fShowerData->fLogGauss) {
551  const double planeFrontTime =
552  PlaneFrontTime(showerCS, corePosition, pShiftedPosition);
553  pShiftedTime =
554  fShowerData->fLogGauss->GetSmearedTime(planeFrontTime, pShiftedTime);
555  }
556  newParticle.SetTime(pShiftedTime);
557 
558  InsertValue(fShowerData->fTimeStat, sId, pShiftedTime);
559 
560  sSim.AddParticle(newParticle);
561 
562  } // for n
563 
564  fShowerData->fTopParticles[sId] += n;
565  nParticlesInjected += n;
566 
567  } // for top entries
568 
569  // side entry
570 
571  const double pStationSine = pDirection.GetRho(dStationCS);
572 
573  if (pPlaneAbsCosine < fHorizontalParticleCut) {
574 
575  ++fShowerData->fNHorizontalParticles;
576 
577  }
578 
579  else if (pStationSine) {
580 
581  // projected side area of a tank
582  const double effArea = 2*sRadius*sHeight * pStationSine/pPlaneAbsCosine;
583  const double avgN = pWeightDensity * effArea;
584  //original const unsigned int n = RandPoisson::shoot(fRandomEngine, avgN);
585  const double pPhi = pDirection.GetPhi(dStationCS) + kPiOnTwo;
586 
587 // if (sId == 5669) {
588 // cout << "\n ============ SIDE ENTRY ========== \n";
589 // cout << "avgN = " << avgN << endl;
590 // }
591 
592  unsigned int n;
593  double weight;
594 
595  if (fUseWeightLimiting) {
596  boost::tie(n, weight) = ParticleNumberAndWeight(avgN, sId);
597  } else {
598  n = RandPoisson::shoot(fRandomEngine, avgN);
599  weight = 1;
600  }
601 
602 // if (weight > 2) {
603 // cout << "new part with weight = " << weight << endl;
604 // }
605 
606  newParticle.SetWeight(weight);
607 
608 // if (sId == 5669) {
609 // cout << "station, fWeightCounter " << sId << ", " << fShowerData->fWeightCounterMap[sId] << " : ";
610 // cout << "( " << n << ", " << newParticle.GetWeight() << ") \n" ;
611 // }
612 
613  for (unsigned int i = 0; i < n; ++i) {
614 
615  // For the X and Y component we need to find the angle made between
616  // the (tank) X-Y axis and the incoming particle direction, then add
617  // an angle sampled from a cosine distribution.
618 
619  const double phi = pPhi + acos(RandFlat::shoot(fRandomEngine, -1, 1));
620  const double z = RandFlat::shoot(fRandomEngine, -sThickness, sHeight);
621  const Point pShiftedPosition(sRadius, phi, z, dStationCS, Point::kCylindrical);
622  newParticle.SetPosition(pShiftedPosition);
623 
624  // Shift the time (read comment above).
625  double pShiftedTime =
626  pTime + PlaneFrontTime(showerCS, pPosition, pShiftedPosition);
627  if (i && fShowerData->fLogGauss) {
628  const double planeFrontTime =
629  PlaneFrontTime(showerCS, corePosition, pShiftedPosition);
630  pShiftedTime =
631  fShowerData->fLogGauss->GetSmearedTime(planeFrontTime, pShiftedTime);
632  }
633  newParticle.SetTime(pShiftedTime);
634 
635  InsertValue(fShowerData->fTimeStat, sId, pShiftedTime);
636 
637  sSim.AddParticle(newParticle);
638  }
639  fShowerData->fSideParticles[sId] += n;
640  nParticlesInjected += n;
641  if (pStationCosine >= 0)
642  fShowerData->fUpwardSideParticles[sId] += n;
643  } // for side entries
644  } // for station info
645  }
646 
647  ostringstream info;
648  info << nParticlesInjected << " particles processed.";
649  INFO(info);
650 
651  if (fShowerData->fParticleIt == fShowerData->fParticlesEnd)
652  OutputStats(event);
653 
654  return eSuccess;
655 }
656 
657 
658 void
660 {
662  fShowerData->fStationMatrix.GetStationList();
663 
664  int nStations = 0;
665 
666  {
667  INFO("\nStation particle statistics:");
668 
669  TabularStream tab("r|.|r|r|r|.|.|.");
670  tab << endc << "Rho" << endc << endc << endc << endc
671  << "wght" << endc << "wght" << endc << "wght" << endr
672 
673  << "station" << endc << "[km]" << endc << "top" << endc << "side" << endc << "up" << endc
674  << "min" << endc << "avg" << endc << "max" << endr << hline;
675 
676  for (StationPositionMatrix::StationInfoList::const_iterator sIt = sList.begin();
677  sIt != sList.end(); ++sIt) {
678 
679  const unsigned sId = sIt->GetDetStation().GetId();
680 
681  if (fShowerData->fTopParticles[sId] ||
682  fShowerData->fSideParticles[sId] ||
683  fShowerData->fUpwardSideParticles[sId]) {
684 
685  ShowerData::WeightStatMap::const_iterator wIt = fShowerData->fWeightStat.find(sId);
686  // ShowerData::TimeStatMap::const_iterator mmIt = fShowerData->fTimeStat.find(sId);
687  tab << sId << ' ' << endc
688  << setprecision(4) << sIt->GetR()/km << endc
689  << ' ' << fShowerData->fTopParticles[sId] << ' ' << endc
690  << ' ' << fShowerData->fSideParticles[sId] << ' ' << endc
691  << ' ' << fShowerData->fUpwardSideParticles[sId] << ' ' << endc
692  << ' ' << setprecision(4) << wIt->second.GetMin() << endc
693  << ' ' << setprecision(4) << wIt->second.GetAverage() << endc
694  << ' ' << setprecision(4) << wIt->second.GetMax() << endr;
695  ++nStations;
696  }
697 
698  }
699 
700  tab << delr;
701 
702  if (nStations)
703  cerr << tab;
704  else
705  cerr << "No stations were hit." << endl;
706  }
707 
708  {
709  INFO("\nStation timing statistics:\n"
710  "abs = absolute time difference to core time\n"
711  "rel = relative time to station plane-front arrival");
712  TabularStream tab("r|.|.|.|.|.");
713  tab << endc << "Rho" << endc << "min abs" << endc << "max abs" << endc
714  << "min rel" << endc << "max rel" << endr
715 
716  << "station" << endc << "[km]" << endc << "time [ns]" << endc << "time [ns]" << endc
717  << "time [ns]" << endc << "time [ns]" << endr << hline;
718 
719  const ShowerSimData& simShower = event.GetSimShower();
720  const TimeStamp& coreTime = simShower.GetTimeStamp();
721 
722  for (StationPositionMatrix::StationInfoList::const_iterator sIt = sList.begin();
723  sIt != sList.end(); ++sIt) {
724 
725  const unsigned sId = sIt->GetDetStation().GetId();
726 
727  if (fShowerData->fTopParticles[sId] ||
728  fShowerData->fSideParticles[sId] ||
729  fShowerData->fUpwardSideParticles[sId]) {
730 
731  const TimeInterval sTime =
732  sIt->GetEvtStation().GetSimData().GetPlaneFrontTime() - coreTime;
733 
734  // ShowerData::WeightStatMap::const_iterator wIt = fShowerData->fWeightStat.find(sId);
735  ShowerData::TimeStatMap::const_iterator mmIt = fShowerData->fTimeStat.find(sId);
736  tab << sId << ' ' << endc
737  << setprecision(4) << sIt->GetR()/km << endc
738  << ' ' << Round(10, mmIt->second.GetMin().GetInterval()/ns) << endc
739  << ' ' << Round(10, mmIt->second.GetMax().GetInterval()/ns) << endc
740  << ' ' << Round(10, (mmIt->second.GetMin() - sTime).GetInterval()/ns) << endc
741  << ' ' << Round(10, (mmIt->second.GetMax() - sTime).GetInterval()/ns) << endr;
742 
743  }
744 
745  }
746 
747  tab << delr;
748 
749  if (nStations)
750  cerr << tab;
751  }
752 
753  if (nStations) {
754  ostringstream info;
755  info << fShowerData->fNHorizontalParticles << " horizontal particles rejected.";
756  INFO(info);
757  }
758 }
759 
760 
763 {
764  if (fNOutOfRangeWeight) {
765  ostringstream warn;
766  warn << "During shower regeneration, a total of " << fNOutOfRangeWeight << " "
767  "weighted particle(s) resulted in generation of unity-weight particles exceeding "
768  << fWeightLimit << " in number.";
769  WARNING(warn);
770  }
771 
772 // cout << "unityWeightCtr = " << unityWeightCtr << endl;
773 // cout << "largeWeightCtr = " << largeWeightCtr << endl;
774 
775  return eSuccess;
776 }
777 
779 
783  boost::tuple<unsigned int, double>
784  CachedShowerRegenerator::ParticleNumberAndWeight(const double& avgN, const int& sId)
785  {
786  unsigned int n;
787  double weight;
788 
789  if (avgN > fWeightThreshold) {
790 
791  // fShowerData->fWeightCounterMap[sId] += avgN;
792 
793  if (fShowerData->fWeightCounterMap[sId] <= fAccumulatedWeightLimit) {
794 
795 // if (sId == 5669)
796 // cout << "a (avgN = " << avgN << ") ";
797 
798  n = RandPoisson::shoot(fRandomEngine, avgN);
799  weight = 1;
800  } else {
801 
802 // if (sId == 5669)
803 // cout << "b (avgN = " << avgN << ") ";
804 
805  n = 1;
806  weight = avgN;
807  }
808  }
809  else {
810  n = RandPoisson::shoot(fRandomEngine, avgN);
811  weight = 1;
812  }
813 
814  fShowerData->fWeightCounterMap[sId] += n;
815  return boost::make_tuple(n, weight);
816  }
817 
818 // Configure (x)emacs for this file ...
819 // Local Variables:
820 // mode: c++
821 // compile-command: "make -C .. CachedShowerRegenerator/CachedShowerRegenerator.o -k"
822 // End:
void SetTime(const TimeInterval &time)
Definition: Particle.h:123
Branch GetTopBranch() const
Definition: Branch.cc:63
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger coordinate system associated to the shower core position.
Iterator to retrieve particles from utl::VShowerParticlList.
Station Level Simulated Data
constexpr T Sqr(const T &x)
Point object.
Definition: Point.h:32
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
bool HasStation(const int stationId) const
Check whether station exists.
Definition: SEvent.cc:81
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
utl::ShowerParticleIterator GroundParticlesEnd() const
const TimeInterval & GetTime() const
Arrival time delay at the ground.
Definition: Particle.h:122
Detector description interface for Station-related data.
Report success to RunController.
Definition: VModule.h:62
double GetMinRadiusCut() const
Get the minimum radius from shower axis for which there are valid particles in the shower...
void MakeSimData()
Make station simulated data object.
boost::tuple< unsigned int, double > ParticleNumberAndWeight(const double &, const int &)
(Optional) special handling for particles with very large weights.
void SetPosition(const utl::Point &position)
Definition: Particle.h:111
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
Describes a particle for Simulation.
Definition: Particle.h:26
bool HasSimShower() const
std::map< std::string, std::string > AttributeMap
Definition: Branch.h:24
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
Break current loop. It works for nested loops too!
Definition: VModule.h:66
class to hold data at Station level
bool HasSimData() const
Check whether station simulated data exists.
static const CCylindrical kCylindrical
Definition: BasicVector.h:334
const double ns
constexpr double kPi
Definition: MathConstants.h:24
double abs(const SVector< n, T > &v)
const utl::Point & GetPosition() const
Get the position of the shower core.
const EndRow endr
const int tab
Definition: SdInspector.cc:35
constexpr double kTwoPi
Definition: MathConstants.h:27
StationIterator StationsEnd() const
End of the collection of pointers to commissioned stations.
Definition: SDetector.h:102
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger reference system centered on the tank.
double GetRadius() const
Radius of the tank (water only)
constexpr double kPiOnTwo
Definition: MathConstants.h:25
const double km
void SetWeight(const double weight)
Definition: Particle.h:127
StationIterator StationsBegin() const
Beginning of the collection of pointers to commissioned stations.
Definition: SDetector.h:97
void SetPlaneFrontTime(const utl::TimeStamp &time)
Set shower front plane arrival time.
class to format data in tabular form
void MakeStation(const int stationId)
make a station with specifying Id, throw if invalid stationId
Definition: SEvent.cc:65
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
Definition: SEvent.h:116
double GetInterval() const
Get the time interval as a double (in Auger base units)
Definition: TimeInterval.h:69
double GetRho(const CoordinateSystemPtr &coordinateSystem) const
radius r in cylindrical coordinates (distance to z axis)
Definition: BasicVector.h:263
double GetKineticEnergy() const
Get kinetic energy of the particle.
Definition: Particle.h:130
constexpr double kSpeedOfLight
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
double GetWeight() const
Particle weight (assigned by shower generator thinning algorithms)
Definition: Particle.h:126
const DeleteRow delr
double GetThickness() const
Thickness of the tank walls.
Source GetSource() const
Source of the particle (eg. shower or background)
Definition: Particle.h:107
double PlaneFrontTime(const CoordinateSystemPtr showerCS, const Point &corePosition, const Point &position)
Calculate time of arrival of the plan front at point x.
void SetMinRadiusCut(const double minR)
Set the minimum radius cut.
Vector object.
Definition: Vector.h:30
double GetRho2(const CoordinateSystemPtr &coordinateSystem) const
radius r^2 in cylindrical coordinates (distance to z axis)^2
Definition: BasicVector.h:266
int GetType() const
Definition: Particle.h:101
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
const Point & GetPosition() const
Position of the particle.
Definition: Particle.h:110
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
void SetMuonWeightScale(const double scale)
Set the muon weight scale.
sevt::StationSimData & GetSimData()
Get simulated data at station level.
VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
void AddParticle(const utl::Particle &particle)
void SetIsInsideMinRadius(const bool isIn=true)
Set flag indicating whether station is in the shower hole.
int GetId() const
Station ID.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
const Vector & GetDirection() const
Unit vector giving particle direction.
Definition: Particle.h:114
const HLine hline('-')
utl::ShowerParticleIterator GroundParticlesBegin() const
const EndColumn endc
bool HasSEvent() const
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const

, generated on Tue Sep 26 2023.