3 #include <utl/ErrorLogger.h>
4 #include <utl/RandomEngine.h>
6 #include <det/Detector.h>
9 #include <fdet/FDetector.h>
10 #include <fdet/Telescope.h>
12 #include <atm/InclinedAtmosphericProfile.h>
13 #include <atm/ProfileResult.h>
15 #include <utl/TimeStamp.h>
16 #include <utl/Reader.h>
18 #include <evt/Event.h>
19 #include <evt/ShowerSimData.h>
21 #include <fevt/FEvent.h>
22 #include <fevt/Header.h>
24 #include <fevt/Telescope.h>
25 #include <fevt/EyeHeader.h>
27 #include <fwk/CentralConfig.h>
28 #include <fwk/RunController.h>
29 #include <fwk/RandomEngineRegistry.h>
30 #include <fwk/LocalCoordinateSystem.h>
31 #include <fwk/CoordinateSystemRegistry.h>
33 #include <utl/UTMPoint.h>
35 #include <CLHEP/Random/Randomize.h>
48 using CLHEP::RandFlat;
56 using namespace FdSimEventCheckerOG;
68 ERROR(
"Could not find branch FdSimEventChecker");
79 topB.
GetChild(
"geometryCherenkovHEAT").
GetData(fGeometryCheckCherenkoHEAT);
80 topB.
GetChild(
"geometryCherenkovHECO").
GetData(fGeometryCheckCherenkoHECO);
86 if (fGeometryCheckCherenkoHECO && topB.
GetChild(
"maxVAfileHECO")) {
89 TFile* f_eff =
new TFile(f.c_str());
90 hMaxVA = (TH2D*)f_eff->Get(
"hMaxVA");
91 hMaxVA->SetDirectory(0);
95 fMinViewingAngle = 1e10;
96 if (topB.
GetChild(
"minViewingAngle"))
99 fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
105 << GetVersionInfo(VModule::eRevisionNumber) <<
"\n"
107 info <<
" -- shower mode -- \n"
108 " up-time check: " << fUpTimeCheck <<
"\n"
109 " geometry check (std FD): " << fGeometryCheck <<
"\n"
110 "geometry check (PCGF, HEAT): " << fGeometryCheckCherenkoHEAT <<
"\n"
111 "geometry check (PCGF, HECO): " << fGeometryCheckCherenkoHECO <<
"\n"
112 " fastSkip: " << fFastSkip <<
" (to issue eBreakLoop) \n"
113 " fastRepeat: " << fFastRepeat <<
" (to issue eContinueLoop) \n"
114 " useCDAS: " << fUseCDAS <<
"\n";
115 if (fMinViewingAngle<180*
degree) {
116 info <<
" viewing angle cut: " << fMinViewingAngle/
degree <<
" deg\n";
120 if (fFastSkip && fFastRepeat) {
121 ERROR(
"It is not possible to isse at the same time eBreakLoop and eContinueLoop. Fix xml configuration.");
128 TH2D* hDebug =
new TH2D(
"debug",
"threshold;lgE;dist/m", nE, 14.5, 17.5, nD, 0, 12000);
129 for (
int i=0; i<nE; ++i) {
130 for (
int j=0; j<nD; ++j) {
131 double lgE = 14.5 + (17.5-14.5) / (nE-1) * i;
132 double dist = 0. + 12000. / (nD-1) * j;
133 hDebug->Fill(lgE, dist, InterpolatePCGFAcceptanceMap(lgE, dist));
136 hDebug->SaveAs(
"debug.root");
145 FdSimEventChecker::Run(
Event& event)
148 return eContinueLoop;
151 ERROR (
"Event has no simulated shower.");
157 Point showerPos(0, 0, 0, showerCS);
158 Vector showerAxis(0, 0, -1, showerCS);
161 bool skipAny =
false;
162 bool minViewingAngleRejected =
false;
168 WARNING(
"Running in Laser simulation mode. Skipping geometry cuts.");
171 Detector& detector = Detector::GetInstance();
174 if (fVerbosity >= 1) {
180 if (fUpTimeCheck && fUseCDAS) {
184 double r = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
186 if (cdasDaqStatus == 0)
187 cdasUpTimeFraction = 0;
189 if (r > cdasUpTimeFraction) {
191 info <<
"Skipping event beacuse of CDAS up time cdasTimeFraction=" << cdasUpTimeFraction;
200 iEye != detFD.
EyesEnd() ; ++iEye){
202 const unsigned int eyeId = iEye->GetId();
207 double eyeUpTimeFraction = iEye->GetUpTimeFraction();
208 int eyeDaqStatus = iEye->GetDAQStatus();
209 double fdasVetoFraction = iEye->GetFDASVetoFraction();
210 double cdasVetoFraction = fUseCDAS ? iEye->GetCDASVetoFraction() : 1.;
211 double r = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
213 if (eyeDaqStatus == 0)
214 eyeUpTimeFraction = 0;
216 if (r > eyeUpTimeFraction*fdasVetoFraction*cdasVetoFraction) {
218 info <<
"Skipping eye=" << eyeId <<
" because of upTimeFraction *fdasVetoFraction * cdasVetoFraction =" << eyeUpTimeFraction*fdasVetoFraction*cdasVetoFraction;
226 ERROR(
"EYE missing!");
233 bool geometryRejected =
false;
234 if (fGeometryCheck && !isLaser) {
236 const Point eyePosition = iEye->GetPosition();
237 const double dist = (showerPos - eyePosition).GetMag();
239 const double lgE = log10(simShower.
GetEnergy()/
eV);
240 const double Rcut = Rcutoff(lgE);
245 info <<
"Skipping eye=" << eyeId
246 <<
" because of geometry cut (distance=" << dist/
km <<
"km > R_cut=" << Rcut/
km <<
"km)";
249 geometryRejected =
true;
255 if (fGeometryCheckCherenkoHEAT && !isLaser) {
257 const Point eyePosition = iEye->GetPosition();
258 const double dist = (showerPos - eyePosition).GetMag();
260 const double lgE = log10(simShower.
GetEnergy()/
eV);
261 const double XmaxAngle = CalculateXmaxViewingAngle(*iEye, simShower);
262 const bool cut = PCGFTriggerProbabilityCut(lgE, dist, XmaxAngle);
266 info <<
"Skipping eye=" << eyeId
267 <<
" because of PCGF HEAT geometry cut (distance=" << dist/
km <<
"km, lgE=" << lgE <<
", angle=" << XmaxAngle/
deg <<
"deg)";
270 geometryRejected =
true;
276 if (fGeometryCheckCherenkoHECO && !isLaser) {
280 const double distHE = (showerPos - HEPosition).GetMag();
281 const double distCO = (showerPos - COPosition).GetMag();
283 const double lgE = log10(simShower.
GetEnergy()/
eV);
284 const double XmaxAngleHE = CalculateXmaxViewingAngle(detFD.
GetEye(5), simShower);
285 const double XmaxAngleCO = CalculateXmaxViewingAngle(detFD.
GetEye(4), simShower);
286 const bool cutHE = PCGFTriggerProbabilityCutHECO(lgE, distHE, XmaxAngleHE);
287 const bool cutCO = PCGFTriggerProbabilityCutHECO(lgE, distCO, XmaxAngleCO);
288 const bool cut = cutHE || cutCO;
292 info <<
"Skipping eye=" << eyeId
293 <<
" because of PCGF HECO geometry cut (distHE=" << distHE/
km <<
"km, distCO=" << distCO/
km <<
"km, lgE=" << lgE
294 <<
", angleHE=" << XmaxAngleHE/
deg <<
"deg, angleCO=" << XmaxAngleCO/
deg <<
"deg)";
297 geometryRejected =
true;
306 iTel != iEye->TelescopesEnd(); ++iTel) {
308 const unsigned int telId = iTel->GetId();
314 double telUpTimeFraction = iTel->GetUpTimeFraction();
315 int telDaqStatus = iTel->GetDAQStatus();
316 double r = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
318 if (telDaqStatus == 0)
319 telUpTimeFraction = 0;
321 if (r > telUpTimeFraction) {
323 info <<
"Skipping eye=" << eyeId <<
" tel=" << telId
324 <<
" because of upTimeFraction=" << telUpTimeFraction;
332 if (fMinViewingAngle < 180*
deg) {
333 if (CalculateMinViewingAngle(*iTel, simShower)>fMinViewingAngle) {
334 minViewingAngleRejected =
true;
341 ERROR(
"Telescope does not exists");
346 ostringstream pointing;
347 pointing <<
"sim: " << iTel->GetTelescopePointingId();
350 if (!geometryRejected) {
357 if (minViewingAngleRejected) {
358 ++RunController::GetInstance().GetRunData().GetNamedCounters()[
"FdSimEventChecker/rejectedDueToMinViewingAngle"];
359 INFO(
"At least one telescope was rejected because of minimum viewing angle cut.");
363 INFO(
"No telescopes/eyes left for simulation.");
367 ++RunController::GetInstance().GetRunData().GetNamedCounters()[
"FdSimEventChecker/eventsWithSkippedTelescopes"];
368 INFO(
"Some telescopes/eyes have been removed from DAQ.");
372 ++RunController::GetInstance().GetRunData().GetNamedCounters()[
"FdSimEventChecker/NoFdSim"];
376 return eContinueLoop;
402 FdSimEventChecker::Finish()
409 FdSimEventChecker::DumpDB()
412 cout <<
" ************** dumpDB ************* " << endl;
414 Detector& detector = Detector::GetInstance();
417 cout <<
" ******* time = " << detector.
GetTime() <<
" ********* " << endl;
423 cout <<
" CDAS uptime : " << cdasUpTimeFraction
424 <<
" status: " << cdasDaqStatus << endl;
427 iEye != detFD.
EyesEnd() ; ++iEye){
429 unsigned int eyeId = iEye->GetId();
431 double eyeUpTimeFraction = iEye->GetUpTimeFraction();
432 int eyeDaqStatus = iEye->GetDAQStatus();
434 cout <<
" eye id=" << eyeId
435 <<
" uptime: " << eyeUpTimeFraction
436 <<
" status: " << eyeDaqStatus << endl;
439 iTel != iEye->TelescopesEnd(); ++iTel) {
441 unsigned int telId = iTel->GetId();
443 double telUpTimeFraction = iTel->GetUpTimeFraction();
444 int telDaqStatus = iTel->GetDAQStatus();
446 cout <<
" tel id=" << telId
447 <<
" uptime: " << telUpTimeFraction
448 <<
" status: " << telDaqStatus << endl;
458 FdSimEventChecker::Rcutoff(
const double lgE)
461 const double x = fmax(16.5, fmin(21., lgE));
463 const double p1 = 4.86267e+05;
464 const double p2 = -6.72442e+04;
465 const double p3 = 2.31169e+03;
467 return p1 + p2*x + p3*x*x;
473 FdSimEventChecker::PCGFTriggerProbabilityCutHECO(
const double lgE,
const double dist,
const double angle)
481 hMaxVA->GetBinXYZ(hMaxVA->FindBin(lgE, dist), binLogE, binDist, dz);
482 if (binLogE < 1 || binLogE > hMaxVA->GetNbinsX() || binDist < 1 || binDist > hMaxVA->GetNbinsY())
484 const double thresholdAngle = hMaxVA->GetBinContent(binLogE, binDist) *
degree;
485 return angle > thresholdAngle;
490 FdSimEventChecker::PCGFTriggerProbabilityCut(
const double lgE,
const double dist,
const double angle)
493 const double thresholdAngle = InterpolatePCGFAcceptanceMap(lgE, dist) *
degree;
494 return angle > thresholdAngle;
504 FdSimEventChecker::InterpolatePCGFAcceptanceMap(
const double lgE,
const double dist)
509 const int nEbins = 5;
510 const double lgEmin = 15;
511 const double lgEmax = 17;
512 const int nDbins = 12;
513 const double dmin = 0;
514 const double dmax = 10000;
518 const double angleMax[60] = {
581 const double ebin = (lgE - lgEmin) / (lgEmax - lgEmin) * nEbins;
582 const double dbin = (dist/
m - dmin) / (dmax - dmin) * nDbins;
584 const int iebin = int(ebin);
585 const int idbin = int(dbin);
590 if (iebin < 0 || idbin < 0 || idbin >= nDbins)
595 const double dE = ebin - iebin;
596 const double dD = dbin - idbin;
598 double vecTemp[nDbins];
599 for (
int idbin = 0; idbin < nDbins; ++idbin)
600 vecTemp[idbin] = angleMax[iebin + idbin * nEbins];
605 for (
int idbin = 0; idbin < nDbins; ++idbin)
606 vecTemp[idbin] += (dE-0.5) * (angleMax[iebin + idbin * nEbins] - angleMax[iebin-1 + idbin * nEbins]);
610 if (iebin < nEbins-1) {
611 for (
int idbin = 0; idbin < nDbins; ++idbin)
612 vecTemp[idbin] += (dE-0.5) * (angleMax[iebin+1 + idbin * nEbins] - angleMax[iebin + idbin * nEbins]);
616 double result = vecTemp[idbin];
621 result += (dD-0.5) * (vecTemp[idbin] - vecTemp[idbin-1]);
624 if (idbin < nDbins-1) {
626 result += (dD-0.5) * (vecTemp[idbin+1] - vecTemp[idbin]);
645 double theMinAngle = 1e20;
646 const int nBins = 20000;
647 for (
int i = 0; i < nBins; ++i) {
649 double length = 20.0*
meter * (i - nBins/2);
651 utl::Point pSh = shower_core + length * shower_axis;
655 double theAngleFOV = acos(view*telescope_axis/view.
GetMag());
660 theMinAngle = min(theMinAngle, (acos(shower_axis*view/view.
GetMag())));
668 FdSimEventChecker::CalculateXmaxViewingAngle(
const fdet::Eye& eye,
677 Vector showerAxis = showerAxisReal;
684 const Vector eyeToCore = showerCore-eyePos;
689 const Vector vertical(0, 0, 1, localCS);
693 const double chi0 =
Angle(horizontalInSDP, showerAxis) - (upward ? 180.*
deg : 0.*
deg);
707 const double deltaX = 10.*
g/
cm2;
715 if (distVsSlantDepth.
MinX() < XmaxSim && XmaxSim < distVsSlantDepth.
MaxX())
716 distance = -distVsSlantDepth.
Y(XmaxSim);
719 const utl::Point& xPoint = showerCore + distance*showerAxis;
724 const Vector vertical(0, 0, 1, localCS);
727 XmaxChi =
Angle((xPoint-eyePos), horizontal);
737 return chi0 - XmaxChi;
AxialVector cross(const Vector &l, const Vector &r)
vector cross product
Telescope & GetTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Telescope by Id, throw exception if not existent.
bool HasLaserData() const
Check initialization of the LaserData.
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
double GetFieldOfView() const
Fluorescence Detector Eye Event.
const evt::VGaisserHillasParameter & GetGHParameters() const
Get the Gaisser-Hillas parameters of the shower.
void SetStatus(const ComponentSelector::Status status)
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
utl::TimeStamp GetTime() const
Get time pertaining to the detector description.
bool HasSimShower() const
utl::Vector GetAxis() const
#define INFO(message)
Macro for logging informational messages.
void Init()
Initialise the registry.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
EyeIterator EyesBegin(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to first eye of given type (ePhysical, eVirtual, eAll)
Detector description interface for Eye-related data.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
static const ReferenceEllipsoid & Get(const EllipsoidID theID)
Get known ellipsoid by registered ID.
void SetStatus(const ComponentSelector::Status status)
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
Detector description interface for FDetector-related data.
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
Exception for reporting variable out of valid range.
Interface class to access Shower Simulated parameters.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Reference ellipsoids for UTM transformations.
boost::filter_iterator< FDetComponentSelector, AllEyeIterator > EyeIterator
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
Class describing the Atmospheric profile.
const utl::Point & GetPosition() const
Get the position of the shower core.
double GetCDASUpTimeFraction() const
Top of the hierarchy of the detector description interface.
const fdet::FDetector & GetFDetector() const
void SetRawTelPointing(const std::string &pointing)
double GetEnergy() const
Get the energy of the shower primary particle.
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
Provides translational services for inclined profile.
boost::filter_iterator< TelIsCommissioned, InternalConstTelescopeIterator > TelescopeIterator
An iterator over telescopes.
fevt::FEvent & GetFEvent()
bool HasEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Detector description interface for Telescope-related data.
double MinX() const
Return the minimum value for X (ordinate) stored in the profile.
ResultFlag
Flag returned by module methods to the RunController.
unsigned long GetGPSSecond() const
GPS second.
bool HasGHParameters() const
Check initialization of the Gaisser-Hillas parameters.
bool HasTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Check if the telescope is in the event.
utl::Point GetPosition() const
execption handling for calculation/access for inclined atmosphere model
Main configuration utility.
Fluorescence Detector Telescope Event.
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
#define ERROR(message)
Macro for logging error messages.
int GetCDASDAQStatus() const
utl::Point GetPosition() const
Eye position.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
EyeIterator EyesEnd(const FDetComponentSelector::Type type=FDetComponentSelector::ePhysical) const
iterator pointing to end of available eyes of given type (ePhysical, eVirtual, eAll) ...