12 #include <fwk/CentralConfig.h>
13 #include <fwk/RunController.h>
14 #include <fwk/CoordinateSystemRegistry.h>
15 #include <fwk/LocalCoordinateSystem.h>
17 #include <utl/Reader.h>
18 #include <utl/ErrorLogger.h>
19 #include <utl/MathConstants.h>
20 #include <utl/Vector.h>
21 #include <utl/PhysicalConstants.h>
22 #include <utl/TabulatedFunctionErrors.h>
24 #include <evt/Event.h>
25 #include <evt/ShowerFRecData.h>
27 #include <fevt/FEvent.h>
29 #include <fevt/Telescope.h>
30 #include <fevt/EyeHeader.h>
31 #include <fevt/EyeRecData.h>
32 #include <fevt/TelescopeRecData.h>
33 #include <fevt/PixelRecData.h>
34 #include <fevt/Pixel.h>
35 #include <fevt/FdConstants.h>
37 #include <det/Detector.h>
39 #include <fdet/FDetector.h>
41 #include <fdet/Pixel.h>
42 #include <fdet/Channel.h>
43 #include <fdet/Telescope.h>
44 #include <fdet/Camera.h>
46 #include <utl/Vector.h>
54 using namespace FdApertureLightFinderKG;
71 ERROR(
"Could not find branch FdApertureLightKG");
101 eyeiter !=
event.GetFEvent().EyesEnd(ComponentSelector::eHasData); ++eyeiter) {
105 if (CalculateShowerGeometryData(eye)) {
106 if (FindLightFlux(eye)) {
107 if (fVerbosity >= 0) {
109 msg <<
"Calculated telescope- and eye-based light at aperture for eye " << eye.
GetId();
114 if (fVerbosity >= 0) {
116 msg <<
"Failed to calculate light at aperture for eye " << eye.
GetId();
126 INFO(
"No good eyes, returning eContinueLoop");
127 return eContinueLoop;
137 fShowerGeometryData.clear();
141 msg <<
"No RecData for eye " << eye.
GetId() <<
" skipping...";
147 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
166 bool firstTime =
true;
172 if (not pixiter->HasRecData())
178 const unsigned int timeoffset = eye.
GetTelescope( pixiter->GetTelescopeId() ).GetTimeOffset();
179 const double t1 = timebinsize * pixiter->
GetRecData().GetPulseStart() + timeoffset;
180 const double t2 = timebinsize * pixiter->GetRecData().GetPulseStop() + timeoffset;
182 if (t2 > maxT_i || firstTime)
184 if (t1 < minT_i || firstTime)
191 if (maxT_i <= minT_i) {
192 INFO(
"shower time length is <= 0, skipping...");
199 teliter != eye.
TelescopesEnd(ComponentSelector::eHasData); ++teliter) {
202 const unsigned int telId = teliter->
GetId();
206 const unsigned int timeoffset = teliter->GetTimeOffset();
214 const Vector coreTelescopeVec = telPos-core;
215 const double cDist = coreTelescopeVec.
GetMag();
216 const double cosBeta =
CosAngle(axis, coreTelescopeVec);
225 vector<ShowerGeometryData> telData;
228 const unsigned int nBaselineBins = 200;
229 for (
unsigned int i = nBaselineBins; i < adcTraceLength; ++i) {
231 const double t1 = i * timeBinSize + timeoffset;
232 const double t2 = (i+1) * timeBinSize + timeoffset;
233 const double tMean = t1 + 0.5 * timeBinSize;
238 const double deltaMean =
239 (meanTimeAtTelescope - coreTime).GetInterval()*
kSpeedOfLight;
240 const double meanDistance =
241 -(cDist*cDist - deltaMean*deltaMean) / (2*(deltaMean + cDist*cosBeta));
242 const utl::Point meanPointOnShower = core - meanDistance*axis;
245 utl::Vector chi_i_vec = meanPointOnShower - telPos;
252 const double angleToTelAxis =
Angle(chi_i_vec, telAxis);
253 if (angleToTelAxis > 25*
deg)
258 tmpShGeoData.
fT1 = t1;
259 tmpShGeoData.
fT2 = t2;
272 telData.push_back(tmpShGeoData);
275 fShowerGeometryData[telId] = telData;
286 double zStep = 0.5 *
degree;
287 double zMin = fminZetaAngle;
288 double zMax = fmaxZetaAngle + zStep;
289 double zeta = FindZeta(eye, zMin, zMax, zStep);
294 zStep = fstepZetaAngle;
298 zeta = FindZeta(eye, zMin, zMax, zStep);
301 INFO(
"Zeta search failed - Bailing out for this eye");
306 zeta += fSafetyMargin;
312 zetaTelIter != eye.
TelescopesEnd(ComponentSelector::eHasData); ++zetaTelIter) {
313 if (!zetaTelIter->HasRecData())
314 zetaTelIter->MakeRecData();
315 zetaTelIter->GetRecData().SetZeta(zeta);
319 FindZeta(eye, zeta, zeta, zStep,
true);
322 vector<LastTelTime> timeOrderedTelescopes;
324 teliter != eye.
TelescopesEnd(ComponentSelector::eHasData); ++teliter) {
325 const unsigned int telId = teliter->GetId();
327 timeOrderedTelescopes.push_back(telTime);
329 const vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
332 for (
int i = telescopeData.size()-1; i >= 0; --i) {
333 if (telescopeData[i].fEyeVarianceSum > 0) {
334 timeOrderedTelescopes.back().fLastTime = telescopeData[i].fT2;
339 sort(timeOrderedTelescopes.begin(), timeOrderedTelescopes.end(), LastTelTime::TelescopeTimeCmp);
341 vector<double> telFluoTime;
342 vector<double> telFluoTimeBin;
343 vector<double> telFluoFlux;
344 vector<double> telVFluoFlux;
345 vector<double> telVBackground;
346 vector<const vector<unsigned int>*> telPixelsInZeta;
347 vector<double> eyeFluoTime;
348 vector<double> eyeFluoTimeBin;
349 vector<double> eyeFluoFlux;
350 vector<double> eyeVFluoFlux;
351 vector<double> eyeVBackground;
354 unsigned int latestFluxTime = 0;
355 for (vector<LastTelTime>::const_iterator telescopeIter = timeOrderedTelescopes.begin();
356 telescopeIter != timeOrderedTelescopes.end(); ++telescopeIter) {
357 const int telId = telescopeIter->fTelId;
359 const vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
360 typedef pair<double, double> FarFromBorderTimeRange;
361 list<FarFromBorderTimeRange> spotFarFromBorderRanges;
363 bool isNearBorder =
true;
364 double rangeStartTime = -1e99;
366 for (
unsigned int i = 0; i < telescopeData.size(); ++i) {
368 const double dT = telDataNow.
fT2 - telDataNow.
fT1;
369 const double t_i = telDataNow.
fT1 + 0.5*dT;
374 isNearBorder =
false;
375 rangeStartTime = telDataNow.
fT1;
383 spotFarFromBorderRanges.push_back(std::make_pair(rangeStartTime, telDataNow.
fT1));
384 if (fVerbosity > 0) {
386 msg <<
"Telescope " << telId <<
": Detected new time range for "
387 <<
"light-collection-efficiency-less profile reconstruction: "
388 << rangeStartTime <<
" ns to " << telDataNow.
fT1 <<
" ns.";
391 rangeStartTime = -1e99;
396 telFluoTime.push_back(t_i);
397 telFluoTimeBin.push_back(dT);
406 eyeFluoTime.push_back(t_i);
407 eyeFluoTimeBin.push_back(dT);
418 if (rangeStartTime >= 0 && !isNearBorder) {
420 spotFarFromBorderRanges.push_back(std::make_pair(rangeStartTime, last.
fT2));
421 if (fVerbosity > 0) {
423 msg <<
"Telescope " << telId <<
": Detected new time range for "
424 "light-collection-efficiency-less profile reconstruction: "
425 << rangeStartTime <<
" ns to " << last.
fT2 <<
" ns. "
426 " This is not expected for normal FD events. BE CAREFUL.";
431 if (!telFluoTime.empty()) {
433 FillTelescopeFluxes(telescope, telFluoTime, telFluoTimeBin, telFluoFlux,
434 telVFluoFlux, telVBackground, telPixelsInZeta,
435 spotFarFromBorderRanges);
440 telFluoTimeBin.clear();
442 telVFluoFlux.clear();
443 telVBackground.clear();
444 telPixelsInZeta.clear();
445 latestFluxTime = telescopeIter->fLastTime;
448 if (eyeFluoTime.empty())
451 FillEyeFluxes(eye, eyeFluoTime, eyeFluoTimeBin, eyeFluoFlux, eyeVFluoFlux, eyeVBackground);
486 const vector<double>& fluoTime,
487 const vector<double>& fluoTimeBin,
488 const vector<double>& fluoFlux,
489 const vector<double>& vfluoFlux,
490 const vector<double>& vBackground)
499 FillFluxes(fluolightprofile, lightprofile, backgroundProfile,
500 fluoTime, fluoTimeBin, fluoFlux, vfluoFlux, vBackground);
508 const vector<double>& fluoTime,
509 const vector<double>& fluoTimeBin,
510 const vector<double>& fluoFlux,
511 const vector<double>& vfluoFlux,
512 const vector<double>& vBackground,
513 const vector<
const vector<unsigned int>*>& pixelsInZeta,
514 const list<pair<double, double>>& farFromBorderTimeRanges)
523 FillFluxes( fluolightprofile, lightprofile, backgroundProfile,
524 fluoTime, fluoTimeBin, fluoFlux, vfluoFlux, vBackground );
529 const unsigned int nBins = pixelsInZeta.size();
531 zetaPixels.resize(nBins);
532 for (
unsigned int iTimeBin = 0; iTimeBin < nBins; ++iTimeBin)
533 zetaPixels[iTimeBin] = *pixelsInZeta[iTimeBin];
542 const vector<double>& fluoTime,
543 const vector<double>& fluoTimeBin,
544 const vector<double>& fluoFlux,
545 const vector<double>& vfluoFlux,
546 const vector<double>& vBackground)
548 for (
unsigned int i = 0, n = fluoTime.size(); i < n; ++i) {
549 const double sigmaFluoFlux =
sqrt(vfluoFlux[i]);
550 const double tMean = fluoTime[i];
551 const double dt = fluoTimeBin[i];
552 lightprofile.
PushBack(tMean, 0.5*dt, fluoFlux[i], sigmaFluoFlux);
553 fluolightprofile.
PushBack(tMean, 0.5*dt, fluoFlux[i], sigmaFluoFlux);
554 backgroundProfile.
PushBack(tMean, 0.5*dt, 0,
sqrt(vBackground[i]));
567 double bestZeta = initZeta;
569 if (fillFlux && (initZeta + 1e-12 < finZeta || initZeta - 1e-12 > finZeta)) {
570 ERROR(
"You called FindZeta with the fillFlux=true argument, but the initial and final guesses "
571 "for zeta are not identical. This is an error. Either call FindZeta for zeta optimization "
572 "(fillFlux=false) or for filling the light fluxes (fillFlux=true, initial zeta==final zeta)");
576 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
582 for (
double zeta = initZeta; zeta <= finZeta; zeta += stepZeta) {
584 const double cosZeta = cos(zeta);
585 double totalSignal = 0;
586 double totalNoise2 = 0;
589 teliter != eye.
TelescopesEnd(ComponentSelector::eHasData); ++teliter) {
591 const unsigned int telId = teliter->GetId();
594 det::Detector::GetInstance().GetFDetector().GetTelescope(*teliter);
598 const double area2 = area*area;
600 vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
603 pixiter != teliter->PixelsEnd(ComponentSelector::eHasData); ++pixiter) {
605 if (!pixiter->HasRecData())
613 const double pixelX = pixeldir.
GetX(localTelCS);
614 const double pixelY = pixeldir.
GetY(localTelCS);
615 const double pixelZ = pixeldir.
GetZ(localTelCS);
618 const TraceD& photontrace = pixiter->GetRecData().GetPhotonTrace();
619 const double RMS2 =
pow(pixiter->GetRecData().GetRMS(), 2);
621 for (
unsigned int i = 0; i < telescopeData.size(); ++i) {
627 const double cosAngle = thisTelData.
fChiVecMean[0] * pixelX
631 if (cosAngle > cosZeta) {
634 const double photonSignal_i = photontrace[idx];
635 const double noise2_i =
636 photonSignal_i < 0 ? RMS2 : RMS2 + photonSignal_i / photon2Pe * (1 + gainVariance);
638 totalSignal += photonSignal_i;
639 totalNoise2 += noise2_i;
652 *teliter, cosZeta)) {
658 }
else if (fOnlyUsedForTimeFit) {
671 const double signalToNoise = totalNoise2 > 0 ? totalSignal /
sqrt(totalNoise2) : 0.;
675 <<
" zeta [deg] " << zeta/
degree
676 <<
" S/N " << signalToNoise <<
" S " << totalSignal
679 if (signalToNoise > maxSN) {
680 maxSN = signalToNoise;
689 cout <<
" Best Zeta " << bestZeta/
degree <<
"\n" << endl;
698 const double cosZeta)
703 if (
CosAngle(direction, *iter) > cosZeta)
Telescope & GetTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Telescope by Id, throw exception if not existent.
unsigned int GetId() const
const utl::Vector & GetDirection() const
pointing direction of this pixel
double GetFADCBinSize() const
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
Description of the electronic channel for the 480 channels of the crate.
void FillEyeFluxes(fevt::Eye &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &)
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
utl::TabulatedFunctionErrors & GetClearedTelescopeLightFlux(fevt::Telescope &tel, const fevt::FdConstants::LightSource source)
Fluorescence Detector Eye Event.
bool FindLightFlux(fevt::Eye &eye)
SizeType GetStop() const
Get valid data stop bin.
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
utl::Vector GetAxis() const
double GetGainVariance() const
#define INFO(message)
Macro for logging informational messages.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Detector description interface for Eye-related data.
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
fevt::TelescopeRecData & GetRecData()
Reconstructed data for this telescope.
double pow(const double x, const unsigned int i)
void FillFluxes(utl::TabulatedFunctionErrors &, utl::TabulatedFunctionErrors &, utl::TabulatedFunctionErrors &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &)
void FillTelescopeFluxes(fevt::Telescope &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< const std::vector< unsigned int > * > &, const std::list< std::pair< double, double >> &)
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
std::vector< utl::Vector >::const_iterator ConstMirrorEventBorderPixelsIterator
Detector description interface for FDetector-related data.
void SetZeta(const double zeta)
A TimeStamp holds GPS second and nanosecond for some event.
boost::indirect_iterator< ConstInternalPixelIterator, const Pixel & > ConstPixelIterator
Const iterator over pixels used in reconstruction.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
ConstMirrorEventBorderPixelsIterator MirrorEventBorderPixelsEnd() const
End of list of pixels just outside the mirror event.
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
Class representing a document branch.
LightSource
Possible light sources.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
unsigned int fADCTraceIndex
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
EyeIterator EyesBegin(const ComponentSelector::Status status)
const Channel & GetChannel(const fevt::Channel &eventChannel) const
Get fdet::Channel from fevt::Channel.
void SetSpotFarFromBorderTimeRanges(const std::list< std::pair< double, double >> &timeRanges)
boost::filter_iterator< ComponentSelector, ConstAllPixelIterator > ConstPixelIterator
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
const std::vector< std::vector< unsigned int > > & GetPixelsInZetaOverTime() const
Returns the time-vector of vectors of pixel ids which are within zeta at the given time...
void PushBack(const double x, const double xErr, const double y, const double yErr)
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
double GetReferenceLambda() const
ConstMirrorEventBorderPixelsIterator MirrorEventBorderPixelsBegin() const
Begin of list of pixels just outside the mirror event.
double FindZeta(fevt::Eye &eye, double initZeta, double finZeta, double stepZeta, bool fillFlux=false)
fevt::FEvent & GetFEvent()
utl::TabulatedFunctionErrors & GetClearedEyeLightFlux(fevt::Eye &eye, const fevt::FdConstants::LightSource source)
bool CalculateShowerGeometryData(const fevt::Eye &eye)
double GetY(const CoordinateSystemPtr &coordinateSystem) const
constexpr double kSpeedOfLight
Detector description interface for Telescope-related data.
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
const Telescope & GetTelescope(const fevt::Telescope &eventTel) const
Get fdet::Telescope from fevt::Telescope.
double GetFADCBinSize() const
double GetDiaphragmArea() const
SizeType GetStart() const
Get valid data start bin.
utl::Point GetPosition() const
PixelIterator TimeFitPixelsEnd()
total (shower and background)
Interface class to access to Fluorescence reconstruction of a Shower.
double CosAngle(const Vector &l, const Vector &r)
Main configuration utility.
void MakeLightFlux(const FdConstants::LightSource source=FdConstants::eTotal)
bool IsNearBorder(const utl::Vector &direction, const fevt::Telescope &telescope, double zeta) const
Fluorescence Detector Telescope Event.
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
std::vector< unsigned int > fPixelsInZeta
PixelIterator TimeFitPixelsBegin()
double GetDiaPhoton2PEFactor(const double wavelength, const std::string &configSignature="") const
#define ERROR(message)
Macro for logging error messages.
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
unsigned int GetId() const
boost::filter_iterator< ComponentSelector, ConstAllTelescopeIterator > ConstTelescopeIterator
int GetFADCTraceLength() const
void MakeLightFlux(const FdConstants::LightSource source=FdConstants::eTotal)
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.