CachedXShowerRegenerator.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/ParticleCases.h>
39 #include <utl/PhysicalConstants.h>
40 #include <utl/Point.h>
41 #include <utl/RandomEngine.h>
42 #include <utl/TimeStamp.h>
43 #include <utl/Math.h>
44 #include <utl/Reader.h>
45 #include <utl/TabularStream.h>
46 #include <utl/TabulatedFunction.h>
47 
48 #include <CLHEP/Random/RandFlat.h>
49 #include <CLHEP/Random/RandPoisson.h>
50 #include <CLHEP/Random/RandGauss.h>
51 
53 #include "LogXGaussSmearing.h"
54 
55 using namespace CachedXShowerRegeneratorAG;
56 using namespace fwk;
57 using namespace evt;
58 using namespace sevt;
59 using namespace utl;
60 using namespace std;
61 
62 using CLHEP::RandFlat;
63 using CLHEP::RandPoisson;
64 
65 namespace CachedXShowerRegeneratorAG {
66 
67  template<typename Map, typename T>
68  inline
69  void
70  InsertValue(Map& map, const int sId, const T& value)
71  {
72  const typename Map::iterator sIt = map.find(sId);
73  if (sIt != map.end())
74  sIt->second(value);
75  else
76  map.insert(make_pair(sId, typename Map::mapped_type(value)));
77  }
78 
79  inline
80  double
81  Round(const double div, const double val)
82  {
83  return round(div*val)/div;
84  }
85 
87 
92  inline
93  double
94  PlaneFrontTime(const CoordinateSystemPtr showerCS, const Point& corePosition,
95  const Point& position)
96  {
97  return (corePosition.GetZ(showerCS) - position.GetZ(showerCS)) / kSpeedOfLight;
98  }
99 
100 } // namespace CachedXShowerRegeneratorAG
101 
102 
104  fMaxParticles(numeric_limits<unsigned int>::max()),
105  fInnerRadiusCut(0.),
106  fOuterRadiusCut(1.e6*km),
107  fElectronEnergyCut(0),
108  fMuonEnergyCut(0),
109  fPhotonEnergyCut(0),
110  fHadronEnergyCut(0),
111  fMesonEnergyCut(0),
112  fDeltaROverR(0),
113  fDeltaPhi(0),
114  fHorizontalParticleCut(0),
115  fUseStationPositionMatrix(true),
116  fPhiGranularity(0),
117  fRGranularity(0),
118  fMuToVem(0),
119  fEToVem(0),
120  fUseWeightLimiting(false),
121  fWeightThreshold(0),
122  fAccumulatedWeightLimit(0),
123  fMuonWeightScale(1),
124  fRandomEngine(0),
125  fTimeSlotSize(1.*ns),
126  fNOutOfRangeWeight(0),
127  fWeightLimit(0),
128  fSimulateAmiga(false)
129 {
130 }
131 
132 
135 {
136 
137  unityWeightCtr = 0; // temp
138  largeWeightCtr = 0; // temp
139 
140  Branch topB =
141  CentralConfig::GetInstance()->GetTopBranch("CachedXShowerRegenerator");
142 
143  AttributeMap useAtt;
144  useAtt["use"] = string("yes");
145 
146  Branch limitB = topB.GetChild("LimitParticlesPerCycle", useAtt);
147  if (limitB)
148  limitB.GetData(fMaxParticles);
149 
150  Branch distanceCutB = topB.GetChild("DistanceCuts");
151 
152  Branch inB = distanceCutB.GetChild("InnerRadiusCut", useAtt);
153  if (inB)
155 
156  Branch outB = distanceCutB.GetChild("OuterRadiusCut", useAtt);
157  if (outB)
158  outB.GetData(fOuterRadiusCut);
159 
160  Branch energyCutB = topB.GetChild("EnergyCuts");
161  energyCutB.GetChild("ElectronEnergyCut").GetData(fElectronEnergyCut);
162  energyCutB.GetChild("MuonEnergyCut").GetData(fMuonEnergyCut);
163  energyCutB.GetChild("PhotonEnergyCut").GetData(fPhotonEnergyCut);
164  energyCutB.GetChild("HadronEnergyCut").GetData(fHadronEnergyCut);
165  energyCutB.GetChild("MesonEnergyCut").GetData(fMesonEnergyCut);
166 
167  Branch algoB = topB.GetChild("AlgorithmParameters");
168  algoB.GetChild("DeltaROverR").GetData(fDeltaROverR);
169  algoB.GetChild("DeltaPhi").GetData(fDeltaPhi);
170  algoB.GetChild("HorizontalParticleCut").GetData(fHorizontalParticleCut);
171  algoB.GetChild("UseStationPositionMatrix").GetData(fUseStationPositionMatrix);
172  algoB.GetChild("PhiGranularity").GetData(fPhiGranularity);
173  algoB.GetChild("RGranularity").GetData(fRGranularity);
174  algoB.GetChild("LogXGaussSmearingWidth").GetData(fLogXGaussSmearingWidth);
175 
176  Branch limitSwitchB = topB.GetChild("ResamplingWeightLimiting", useAtt);
177  if (limitSwitchB) {
178  fUseWeightLimiting = true;
179  limitSwitchB.GetChild("WeightThreshold").GetData(fWeightThreshold);
180  limitSwitchB.GetChild("AccumulatedWeightLimit").GetData(fAccumulatedWeightLimit);
181  }
182 
183  if (topB.GetChild("MuonWeightScale"))
184  topB.GetChild("MuonWeightScale").GetData(fMuonWeightScale);
185 
186  Branch amigaSimB = topB.GetChild("AmigaSimulation", useAtt);
187  if ( amigaSimB ) {
188  INFO( "AMIGA tank+ground G4 simulation has been activated" );
189  fSimulateAmiga = true;
190  amigaSimB.GetChild("AmigaRadius").GetData(fAmigaRadius);
191  }
192 
193  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector).GetEngine();
194 
196  WARNING("Not using StationPositionMatrix. "
197  "All stations will be searched for injection.");
198 
199  return eSuccess;
200 }
201 
202 
203 bool
205  const double pEnergy)
206  const
207 {
208  switch (pType) {
209  case OFFLINE_PHOTON:
210  return pEnergy < fPhotonEnergyCut;
211  case OFFLINE_ELECTRONS:
212  return pEnergy < fElectronEnergyCut;
213  case OFFLINE_MUONS:
214  return pEnergy < fMuonEnergyCut;
215  case OFFLINE_BARYONS:
216  return pEnergy < fHadronEnergyCut;
217  case OFFLINE_MESONS:
218  return pEnergy < fMesonEnergyCut;
219  default:
220  return true;
221  }
222 }
223 
224 
225 void
227 {
229 
230  fShowerData->fWeightCounterMap.clear();
231 
233  fShowerData->fLogXGauss =
235 
236  ShowerSimData& simShower = event.GetSimShower();
238 
239  if (simShower.GetMinRadiusCut() < fInnerRadiusCut) {
240  ostringstream msg;
241  msg << "Setting new value for fMinRadiusCut: " << fInnerRadiusCut;
242  INFO(msg);
243  simShower.SetMinRadiusCut(fInnerRadiusCut);
244  }
245 
246  fShowerData->fParticleIt = simShower.GroundParticlesBegin();
247  fShowerData->fParticlesEnd = simShower.GroundParticlesEnd();
248 
249  const CoordinateSystemPtr localCS = simShower.GetLocalCoordinateSystem();
250  const double showerZenith = (-simShower.GetDirection()).GetTheta(localCS);
251  const double samplingAreaFactor = 4 * fDeltaPhi * fDeltaROverR / cos(showerZenith);
252 
253  if (!event.HasSEvent())
254  event.MakeSEvent();
255  SEvent& sEvent = event.GetSEvent();
256 
257  const CoordinateSystemPtr showerCS = simShower.GetShowerCoordinateSystem();
258  const Point& corePosition = simShower.GetPosition();
259  const TimeStamp& coreTime = simShower.GetTimeStamp();
260  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
261 
262  int nStations = 0;
263  int nInner = 0;
264  int nOuter = 0;
265 
266  for (sdet::SDetector::StationIterator sdIt = sDetector.StationsBegin();
267  sdIt != sDetector.StationsEnd(); ++sdIt) {
268 
269  ++nStations;
270 
271  const int sId = sdIt->GetId();
272 
273  if (!sEvent.HasStation(sId))
274  sEvent.MakeStation(sId);
275 
276  Station& station = sEvent.GetStation(sId);
277 
278  // clear particle lists for the station. The stuff above
279  // presumably only needs to be called once per shower, but
280  // particle clearing has to happen each time through.
281  if (!station.HasSimData())
282  station.MakeSimData();
283 
284  StationSimData& sSim = station.GetSimData();
285 
286  const Point& sPosition = sdIt->GetPosition();
287 
288  const TimeStamp planeTime =
289  coreTime + TimeInterval(PlaneFrontTime(showerCS, corePosition, sPosition));
290 
291  sSim.SetPlaneFrontTime(planeTime);
292 
293  const double sR = sPosition.GetRho(showerCS);
294 
295  if (sR < fInnerRadiusCut) {
296  ++nInner;
297  sSim.SetIsInsideMinRadius();
298  continue;
299  }
300 
301  if (sR > fOuterRadiusCut) {
302  ++nOuter;
303  continue;
304  }
305 
306  // DV: Particle weights are calculated by the shower simulation according
307  // to the particle densities as measured in the ground-particle plane.
308  // Thus all reweighting area ratios calculated in the resampler have to
309  // have area values expressed in the corresponding ground-particle plane
310  // projections, ie if there is a small missalignement of the tank vertical
311  // and the ground-particle plane vertical, it has to be taken into account
312  // with appropriate cosine of this small angle.
313  // First calculate the ground-particle area of the resampling pie
314  // section of a station:
315  const double samplingArea = samplingAreaFactor * Sqr(sR);
316 
317  // it is best to create station matrix based on log(r^2)
318  const double r1 = 2 * log(sR * (1 - fDeltaROverR));
319  const double r2 = 2 * log(sR * (1 + fDeltaROverR));
320 
321  //cout << "Pushing back station " << sdIt->GetId() << endl;
322  fShowerData->fStationMatrix.PushBack(*sdIt, station,
323  sPosition.GetPhi(showerCS), fDeltaPhi,
324  sR, r1, r2,
325  samplingArea);
326 
327  }
328 
329  fShowerData->fStationMatrix.CreateMatrix(fUseStationPositionMatrix);
330  fShowerData->fMinR2 = exp(fShowerData->fStationMatrix.GetMinR());
331 
332  ostringstream info;
333  info << "Out of " << nStations << " stations: inner cut " << nInner << ", outer " << nOuter;
334  INFO(info);
335 }
336 
337 
340 {
341  INFO("Starting G4XTank simulation...");
342 
343  if (!event.HasSimShower()) {
344  ERROR("Current event does not have a simulated shower.");
345  return eFailure;
346  }
347 
348  const ShowerSimData& simShower = event.GetSimShower();
349 
350  // sim event finished ?
351  if (fShowerData && fShowerData->fParticleIt == fShowerData->fParticlesEnd) {
352  fShowerData = 0;
353  // break inner loop
354  return eBreakLoop;
355  }
356 
357  if (!fShowerData)
358  InitNewShower(event);
359 
360  {
361  ostringstream info;
362  info << "Regenerating batch of "
363  << fMaxParticles << " particles.";
364  INFO(info);
365  }
366 
367  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
368  SEvent& sEvent = event.GetSEvent();
369 
370  // clear particle list for the stations
371  for (sdet::SDetector::StationIterator sdIt = sDetector.StationsBegin();
372  sdIt != sDetector.StationsEnd(); ++sdIt)
373  sEvent.GetStation(sdIt->GetId()).GetSimData().ClearParticleList();
374 
375  const CoordinateSystemPtr showerCS = simShower.GetShowerCoordinateSystem();
376  const Point& corePosition = simShower.GetPosition();
377  const CoordinateSystemPtr grParticleCS = simShower.GetLocalCoordinateSystem();
378 
379  // Based on the cuts read in for the outer and inner radius in Init(), we
380  // build the list of stations that lie within the region of interest in
381  // the shower plane. We then loop only over these stations, since anything
382  // outside the limits defined by the outer and inner radius cuts will never
383  // receive any regenerated particles anyway.
384 
385  // keep count to avoid excessive memory consumption
386  unsigned int nParticlesInjected = 0;
387 
388  ShowerParticleIterator& particleIt = fShowerData->fParticleIt;
389 
390  for (; particleIt != fShowerData->fParticlesEnd; ++particleIt) {
391 
392  // over the cache limit?
393  if (nParticlesInjected >= fMaxParticles) {
394  ostringstream info;
395  info << nParticlesInjected << " particles processed.";
396  INFO(info);
397  return eSuccess;
398  }
399 
400  const Point& pPosition = particleIt->GetPosition();
401  const double pR2ShowerFrame = pPosition.GetRho2(showerCS);
402 
403  // particle time relative to the core time
404  const double pTime = particleIt->GetTime().GetInterval();
405 
406  // due to a bug in CORSIKA (version 6.900) when simulating upward going particles (option UPWARD)
407  // a few particles per shower get negative delays w.r.t. to the plane front, they behave like tachyons.
408  // see http://www-ik.fzk.de/~maurel/corsika_negative_particle_delays for a list
409  // of "superluminal" particles in a library simulated using the UPWARD option.
410  // Negative delays on the order of 0.01 ns are possible due to roundoff errors,
411  // only particles with a delay smaller than -0.1 ns are rejected here.
412  double pPlaneFrontDelay = pTime - PlaneFrontTime(showerCS, corePosition, pPosition);
413  if (pPlaneFrontDelay < -0.1*ns )
414  continue;
415 
416  if (pR2ShowerFrame <= fShowerData->fMinR2)
417  continue;
418 
419  const double pLogR2ShowerFrame = log(pR2ShowerFrame);
420 
421  const double pPhiShowerFrame = pPosition.GetPhi(showerCS);
422 
424  fShowerData->fStationMatrix.GetStationList(pPhiShowerFrame, pLogR2ShowerFrame);
425 
426  if (sList.empty())
427  continue;
428 
429  if (IsParticleEnergyLow(particleIt->GetType(), particleIt->GetKineticEnergy()))
430  continue;
431 
432  for (StationPositionMatrix::StationInfoPtrList::const_iterator sIt = sList.begin();
433  sIt != sList.end(); ++sIt) {
434 
435  const StationInfo& sInfo = **sIt;
436 
437  if (!sInfo.IsIn(pPhiShowerFrame, pLogR2ShowerFrame))
438  continue;
439 
440  const double pWeight =
441  (particleIt->GetType() == utl::Particle::eMuon ||
442  particleIt->GetType() == utl::Particle::eAntiMuon ||
444  fMuonWeightScale*particleIt->GetWeight():
445  particleIt->GetWeight());
446 
447  Particle newParticle(*particleIt);
448  //Set Parent (same particle at this level, keep this for underground propagation backtracking)
449  newParticle.SetParent( newParticle );
450 
451  // This decision should be taken elsewhere, after
452  // calculating AvgN
453  //
454  //original newParticle.SetWeight(1);
455 
456  // all particle positions within the resampling area are equivalent, define
457  // "weight density", ie the probability to find a particle with such properties
458  // within some area
459  const double pWeightDensity = pWeight / sInfo.GetResamplingArea();
460 
461  const sdet::Station& dStation = sInfo.GetDetStation();
462  const double sThickness = dStation.GetThickness();
463  const double sRadius = dStation.GetRadius() + sThickness;
464  const double sHeight = dStation.GetHeight() + sThickness;
465  const CoordinateSystemPtr dStationCS =
466  dStation.GetLocalCoordinateSystem();
467  Station& station = sInfo.GetEvtStation();
468 
469  const unsigned int sId = dStation.GetId();
470 
471  const Vector& pDirection = newParticle.GetDirection();
472  const double pStationCosine = pDirection.GetZ(dStationCS);
473  const double pPlaneCosine = pDirection.GetZ(grParticleCS);
474  const double pPlaneAbsCosine = abs(pPlaneCosine);
475 
476  // top entry
477 
478  // tank top surface seen by the particle?
479  if (pPlaneAbsCosine < fHorizontalParticleCut) {
480  ++fShowerData->fNHorizontalParticles;
481  } else if (pStationCosine < 0 && pPlaneCosine < fHorizontalParticleCut) {
482 
483  // projected top area of a tank
484  const double effArea = kPi*Sqr((fSimulateAmiga?fAmigaRadius:sRadius)) * pStationCosine/pPlaneCosine;
485 
486  const double avgN = pWeightDensity * effArea;
487 
488  InsertValue(fShowerData->fWeightStat, sId, avgN);
489 
490  unsigned int n;
491  double weight;
492 
493  if (fUseWeightLimiting) {
494  boost::tie(n, weight) = ParticleNumberAndWeight(avgN, sId);
495 
496  if (int(weight) == 1)
497  ++unityWeightCtr;
498  else
499  largeWeightCtr += weight;
500 
501  } else {
502  n = RandPoisson::shoot(fRandomEngine, avgN);
503  weight = 1;
504  }
505 
506  newParticle.SetWeight(weight);
507 
508  for (unsigned int i = 0; i < n; ++i) {
509  //Different definition of the radius when simulating for AMIGA
510  //with the tank and the ground beneath simulated simultaneously
511  double r = (fSimulateAmiga?fAmigaRadius:sRadius) * sqrt(RandFlat::shoot(fRandomEngine, 0, 1));
512  const double phi = RandFlat::shoot(fRandomEngine, 0, kTwoPi);
513 
514  const Point pShiftedPosition(r, phi, sHeight, dStationCS, Point::kCylindrical);
515  newParticle.SetPosition(pShiftedPosition);
516 
517  // Shift the time to account for differences in position between the
518  // hit tank and the position the particle was placed at the ground
519  // by the shower simulation. Also, include a shift for multiple
520  // particle entries from regeneration of one weighted particle. So far,
521  // no one has provided any real justification for what distribution
522  // should be used for the energy shifting.
523  // see P. Billoir, Astroparticle Physics 30 (2008) 270–285
524  double pShiftedTime =
525  pTime + PlaneFrontTime(showerCS, pPosition, pShiftedPosition);
526 
527  if (i && fShowerData->fLogXGauss) {
528  const double planeFrontTime =
529  PlaneFrontTime(showerCS, corePosition, pShiftedPosition);
530  pShiftedTime =
531  fShowerData->fLogXGauss->GetSmearedTime(planeFrontTime, pShiftedTime);
532  }
533 
534  newParticle.SetTime(pShiftedTime);
535 
536  InsertValue(fShowerData->fTimeStat, sId, pShiftedTime);
537 
538  station.AddParticle(newParticle);
539 
540  } // for n
541 
542  fShowerData->fTopParticles[sId] += n;
543  nParticlesInjected += n;
544 
545  } // end of for top entries
546 
547  //In the case of AMIGA simulation, side entries have no importance
548  //particles are injected onthe top of a "big" cylinder containing both the
549  //tank and the ground beneath
550  if(!fSimulateAmiga){
551  // side entry
552  const double pStationSine = pDirection.GetRho(dStationCS);
553 
554  if (pPlaneAbsCosine < fHorizontalParticleCut) {
555 
556  ++fShowerData->fNHorizontalParticles;
557 
558  } else if (pStationSine) {
559 
560  // projected side area of a tank
561  const double effArea = 2*sRadius*sHeight * pStationSine/pPlaneAbsCosine;
562  const double avgN = pWeightDensity * effArea;
563  //original const unsigned int n = RandPoisson::shoot(fRandomEngine, avgN);
564  const double pPhi = pDirection.GetPhi(dStationCS) + kPiOnTwo;
565 
566  unsigned int n;
567  double weight;
568 
569  if (fUseWeightLimiting) {
570  boost::tie(n, weight) = ParticleNumberAndWeight(avgN, sId);
571  } else {
572  n = RandPoisson::shoot(fRandomEngine, avgN);
573  weight = 1;
574  }
575 
576  newParticle.SetWeight(weight);
577 
578  for (unsigned int i = 0; i < n; ++i) {
579 
580  // For the X and Y component we need to find the angle made between
581  // the (tank) X-Y axis and the incoming particle direction, then add
582  // an angle sampled from a cosine distribution.
583 
584  const double phi = pPhi + acos(RandFlat::shoot(fRandomEngine, -1, 1));
585  const double z = RandFlat::shoot(fRandomEngine, -sThickness, sHeight);
586  const Point pShiftedPosition(sRadius, phi, z, dStationCS, Point::kCylindrical);
587  newParticle.SetPosition(pShiftedPosition);
588 
589  // Shift the time (read comment above).
590  double pShiftedTime =
591  pTime + PlaneFrontTime(showerCS, pPosition, pShiftedPosition);
592  if (i && fShowerData->fLogXGauss) {
593  const double planeFrontTime =
594  PlaneFrontTime(showerCS, corePosition, pShiftedPosition);
595  pShiftedTime =
596  fShowerData->fLogXGauss->GetSmearedTime(planeFrontTime, pShiftedTime);
597  }
598  newParticle.SetTime(pShiftedTime);
599 
600  InsertValue(fShowerData->fTimeStat, sId, pShiftedTime);
601 
602  station.AddParticle(newParticle);
603  }
604  fShowerData->fSideParticles[sId] += n;
605  nParticlesInjected += n;
606  if (pStationCosine >= 0)
607  fShowerData->fUpwardSideParticles[sId] += n;
608  } // for side entries
609  } // for side entries
610  } // for station info
611  }
612 
613  ostringstream info;
614  info << nParticlesInjected << " particles processed.";
615  INFO(info);
616 
617  if (fShowerData->fParticleIt == fShowerData->fParticlesEnd)
618  OutputStats(event);
619 
620  return eSuccess;
621 }
622 
623 
624 void
626 {
628  fShowerData->fStationMatrix.GetStationList();
629 
630  int nStations = 0;
631 
632  {
633  INFO("\nStation particle statistics:");
634 
635  TabularStream tab("r|.|r|r|r|.|.|.");
636  tab << endc << "Rho" << endc << endc << endc << endc
637  << "wght" << endc << "wght" << endc << "wght" << endr
638 
639  << "station" << endc << "[km]" << endc << "top" << endc << "side" << endc << "up" << endc
640  << "min" << endc << "avg" << endc << "max" << endr << hline;
641 
642  for (StationPositionMatrix::StationInfoList::const_iterator sIt = sList.begin();
643  sIt != sList.end(); ++sIt) {
644 
645  const unsigned sId = sIt->GetDetStation().GetId();
646 
647  if (fShowerData->fTopParticles[sId] ||
648  fShowerData->fSideParticles[sId] ||
649  fShowerData->fUpwardSideParticles[sId]) {
650 
651  ShowerData::WeightStatMap::const_iterator wIt = fShowerData->fWeightStat.find(sId);
652  // ShowerData::TimeStatMap::const_iterator mmIt = fShowerData->fTimeStat.find(sId);
653  tab << sId << ' ' << endc
654  << setprecision(4) << sIt->GetR()/km << endc
655  << ' ' << fShowerData->fTopParticles[sId] << ' ' << endc
656  << ' ' << fShowerData->fSideParticles[sId] << ' ' << endc
657  << ' ' << fShowerData->fUpwardSideParticles[sId] << ' ' << endc
658  << ' ' << setprecision(4) << wIt->second.GetMin() << endc
659  << ' ' << setprecision(4) << wIt->second.GetAverage() << endc
660  << ' ' << setprecision(4) << wIt->second.GetMax() << endr;
661  ++nStations;
662  }
663 
664  }
665 
666  tab << delr;
667 
668  if (nStations)
669  cerr << tab << endl;
670  else
671  cerr << "No stations were hit." << endl;
672  }
673 
674  {
675  INFO("\nStation timing statistics:\n"
676  "abs = absolute time difference to core time\n"
677  "rel = relative time to station plane-front arrival");
678  TabularStream tab("r|.|.|.|.|.");
679  tab << endc << "Rho" << endc << "min abs" << endc << "max abs" << endc
680  << "min rel" << endc << "max rel" << endr
681 
682  << "station" << endc << "[km]" << endc << "time [ns]" << endc << "time [ns]" << endc
683  << "time [ns]" << endc << "time [ns]" << endr << hline;
684 
685  const ShowerSimData& simShower = event.GetSimShower();
686  const TimeStamp& coreTime = simShower.GetTimeStamp();
687 
688  for (StationPositionMatrix::StationInfoList::const_iterator sIt = sList.begin();
689  sIt != sList.end(); ++sIt) {
690 
691  const unsigned sId = sIt->GetDetStation().GetId();
692 
693  if (fShowerData->fTopParticles[sId] ||
694  fShowerData->fSideParticles[sId] ||
695  fShowerData->fUpwardSideParticles[sId]) {
696 
697  const TimeInterval sTime =
698  sIt->GetEvtStation().GetSimData().GetPlaneFrontTime() - coreTime;
699 
700  // ShowerData::WeightStatMap::const_iterator wIt = fShowerData->fWeightStat.find(sId);
701  ShowerData::TimeStatMap::const_iterator mmIt = fShowerData->fTimeStat.find(sId);
702  tab << sId << ' ' << endc
703  << setprecision(4) << sIt->GetR()/km << endc
704  << ' ' << Round(10, mmIt->second.GetMin().GetInterval()/ns) << endc
705  << ' ' << Round(10, mmIt->second.GetMax().GetInterval()/ns) << endc
706  << ' ' << Round(10, (mmIt->second.GetMin() - sTime).GetInterval()/ns) << endc
707  << ' ' << Round(10, (mmIt->second.GetMax() - sTime).GetInterval()/ns) << endr;
708 
709  }
710 
711  }
712 
713  tab << delr;
714 
715  if (nStations)
716  cerr << tab << endl;
717  }
718 
719  if (nStations) {
720  ostringstream info;
721  info << endl << fShowerData->fNHorizontalParticles << " horizontal particles rejected.";
722  INFO(info);
723  }
724 }
725 
726 
729 {
730  if (fNOutOfRangeWeight) {
731  ostringstream warn;
732  warn << "During shower regeneration, a total of " << fNOutOfRangeWeight << " "
733  "weighted particle(s) resulted in generation of unity-weight particles exceeding "
734  << fWeightLimit << " in number.";
735  WARNING(warn);
736  }
737 
738 // cout << "unityWeightCtr = " << unityWeightCtr << endl;
739 // cout << "largeWeightCtr = " << largeWeightCtr << endl;
740 
741  return eSuccess;
742 }
743 
745 
749  boost::tuple<unsigned int, double>
750  CachedXShowerRegenerator::ParticleNumberAndWeight(const double& avgN, const int& sId)
751  {
752  unsigned int n;
753  double weight;
754 
755  if (avgN > fWeightThreshold) {
756 
757  // fShowerData->fWeightCounterMap[sId] += avgN;
758 
759  if (fShowerData->fWeightCounterMap[sId] <= fAccumulatedWeightLimit) {
760 
761 // if (sId == 5669)
762 // cout << "a (avgN = " << avgN << ") ";
763 
764  n = RandPoisson::shoot(fRandomEngine, avgN);
765  weight = 1;
766  } else {
767 
768 // if (sId == 5669)
769 // cout << "b (avgN = " << avgN << ") ";
770 
771  n = 1;
772  weight = avgN;
773  }
774  }
775  else {
776  n = RandPoisson::shoot(fRandomEngine, avgN);
777  weight = 1;
778  }
779 
780  fShowerData->fWeightCounterMap[sId] += n;
781  return boost::make_tuple(n, weight);
782  }
783 
784 // Configure (x)emacs for this file ...
785 // Local Variables:
786 // mode: c++
787 // compile-command: "make -C .. CachedXShowerRegenerator/CachedXShowerRegenerator.o -k"
788 // 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.
bool IsIn(const double phi, const double r) const
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
boost::tuple< unsigned int, double > ParticleNumberAndWeight(const double &, const int &)
(Optional) special handling for particles with very large weights.
std::map< std::string, std::string > AttributeMap
Definition: Branch.h:24
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void InsertValue(Map &map, const int sId, const T &value)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
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.
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
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.
VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
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
double GetHeight() const
Height of the tank (water only)
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
double Round(const double div, const double val)
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
void AddParticle(const utl::Particle &particle)
const sdet::Station & GetDetStation() const
#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
double PlaneFrontTime(const CoordinateSystemPtr showerCS, const Point &corePosition, const Point &position)
Calculate time of arrival of the plan front at point x.
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
VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
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.
void SetParent(Particle &parent)
Definition: Particle.h:150
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
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.