3 #include <fwk/CentralConfig.h>
4 #include <fwk/RunController.h>
5 #include <fwk/CoordinateSystemRegistry.h>
6 #include <fwk/LocalCoordinateSystem.h>
8 #include <utl/Reader.h>
9 #include <utl/ErrorLogger.h>
10 #include <utl/MathConstants.h>
11 #include <utl/Vector.h>
12 #include <utl/PhysicalConstants.h>
13 #include <utl/TabulatedFunctionErrors.h>
15 #include <evt/Event.h>
16 #include <evt/ShowerFRecData.h>
18 #include <fevt/FEvent.h>
20 #include <fevt/Telescope.h>
21 #include <fevt/EyeHeader.h>
22 #include <fevt/EyeRecData.h>
23 #include <fevt/TelescopeRecData.h>
24 #include <fevt/PixelRecData.h>
25 #include <fevt/Pixel.h>
26 #include <fevt/FdConstants.h>
28 #include <det/Detector.h>
30 #include <fdet/FDetector.h>
32 #include <fdet/Pixel.h>
33 #include <fdet/Channel.h>
34 #include <fdet/Telescope.h>
35 #include <fdet/Camera.h>
37 #include <utl/Vector.h>
46 using namespace FdProfileConstrainedGeometryFitPG;
86 cout <<
"\n --[PCGF internal ApertureLight]--> " << endl;
93 eyeiter !=
event.GetFEvent().EyesEnd(ComponentSelector::eHasData);
96 Eye& eye = (*eyeiter);
98 if ( CalculateShowerGeometryData(eye) ) {
100 if ( FindLightFlux(eye) ) {
101 msg <<
"Calculated telescope- and eye-based light at aperture for eye " << eye.
GetId();
105 msg <<
"Failed to calculate light at aperture for eye " << eye.
GetId();
112 if ( nGoodEyes == 0 ) {
114 INFO(
"No good eyes, returning false");
125 fShowerGeometryData.clear();
129 msg <<
"No RecData for eye " << eye.
GetId() <<
" skipping...";
135 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
154 bool firstTime =
true;
160 if (not pixiter->HasRecData())
166 const unsigned int timeoffset = eye.
GetTelescope( pixiter->GetTelescopeId() ).GetTimeOffset();
167 const double t1 = timebinsize * pixiter->
GetRecData().GetPulseStart() + timeoffset;
168 const double t2 = timebinsize * pixiter->GetRecData().GetPulseStop() + timeoffset;
170 if (t2 > maxT_i || firstTime)
172 if (t1 < minT_i || firstTime)
179 if (maxT_i <= minT_i) {
180 INFO(
"shower time length is <= 0, skipping...");
191 const unsigned int telId = teliter->
GetId();
195 const unsigned int timeoffset = teliter->GetTimeOffset();
203 const Vector coreTelescopeVec = telPos-core;
204 const double cDist = coreTelescopeVec.
GetMag();
205 const double cosBeta =
CosAngle(axis, coreTelescopeVec);
214 vector<ShowerGeometryData> telData;
217 const unsigned int nBaselineBins = 200;
218 for (
unsigned int i = nBaselineBins; (int)i < adcTraceLength; ++i) {
220 const int t1 = i * timeBinSize + timeoffset;
221 const int t2 = (i+1) * timeBinSize + timeoffset;
222 const double tMean = (double)t1 + 0.5 * (
double)timeBinSize;
227 const double deltaMean =
229 const double meanDistance =
230 -(cDist*cDist-deltaMean*deltaMean)/(2*(deltaMean+cDist*cosBeta));
231 const utl::Point meanPointOnShower = core - meanDistance*axis;
234 utl::Vector chi_i_vec = meanPointOnShower - telPos;
241 const double angleToTelAxis =
Angle(chi_i_vec, telAxis);
242 if (!fStripMode && angleToTelAxis > 25.*
deg)
247 tmpShGeoData.
fT1 = t1;
248 tmpShGeoData.
fT2 = t2;
261 telData.push_back(tmpShGeoData);
264 fShowerGeometryData[telId] = telData;
275 double zStep = .5 *
degree;
276 double zMin = fminZetaAngle;
277 double zMax = fmaxZetaAngle + zStep;
278 double zeta = FindZeta(eye, zMin, zMax, zStep);
283 zStep = fstepZetaAngle;
287 zeta = FindZeta(eye, zMin, zMax, zStep);
290 INFO(
"Zeta search failed - Bailing out for this eye");
295 zeta += fSafetyMargin;
301 zetaTelIter != eye.
TelescopesEnd(ComponentSelector::eHasData);
303 if (!zetaTelIter->HasRecData())
304 zetaTelIter->MakeRecData();
305 zetaTelIter->GetRecData().SetZeta(zeta);
309 FindZeta(eye, zeta, zeta, zStep,
true);
312 vector<LastTelTime> timeOrderedTelescopes;
317 const unsigned int telId = teliter->GetId();
319 timeOrderedTelescopes.push_back(telTime);
321 const vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
324 for (
int i = telescopeData.size()-1; i >= 0; --i ) {
325 if ( telescopeData[i].fEyeVarianceSum > 0. ) {
326 timeOrderedTelescopes.back().fLastTime = telescopeData[i].fT2;
331 sort(timeOrderedTelescopes.begin(), timeOrderedTelescopes.end(), LastTelTime::TelescopeTimeCmp);
333 vector<double> telFluoTime, telFluoTimeBin, telFluoFlux, telVFluoFlux, telVBackground;
334 vector<const vector<unsigned int>*> telPixelsInZeta;
335 vector<double> eyeFluoTime, eyeFluoTimeBin, eyeFluoFlux, eyeVFluoFlux, eyeVBackground;
338 unsigned int latestFluxTime = 0;
339 for (vector<LastTelTime>::const_iterator telescopeIter = timeOrderedTelescopes.begin();
340 telescopeIter != timeOrderedTelescopes.end(); ++telescopeIter )
342 const int telId = telescopeIter->fTelId;
344 const vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
345 typedef pair<double, double> FarFromBorderTimeRange;
346 list<FarFromBorderTimeRange> spotFarFromBorderRanges;
348 bool isNearBorder =
true;
349 double rangeStartTime = -1.e99;
351 for (
unsigned int i = 0; i < telescopeData.size(); ++i ) {
353 const double dT = (double) (telDataNow.
fT2 - telDataNow.
fT1);
354 const double t_i = (double) telDataNow.
fT1 + dT/2.;
359 isNearBorder =
false;
360 rangeStartTime = telDataNow.
fT1;
369 spotFarFromBorderRanges.push_back( std::make_pair(rangeStartTime,
371 if (fVerbosity > 0) {
373 msg <<
"Telescope " << telId <<
": Detected new time range for "
374 <<
"light-collection-efficiency-less profile reconstruction: "
375 << rangeStartTime <<
" ns to " << telDataNow.
fT1 <<
" ns.";
378 rangeStartTime = -1.e99;
383 telFluoTime.push_back(t_i);
384 telFluoTimeBin.push_back(dT);
393 eyeFluoTime.push_back(t_i);
394 eyeFluoTimeBin.push_back(dT);
405 if (rangeStartTime >= 0. && !isNearBorder) {
407 spotFarFromBorderRanges.push_back(std::make_pair(rangeStartTime, last.
fT2));
408 if (fVerbosity > 0) {
410 msg <<
"Telescope " << telId <<
": Detected new time range for "
411 <<
"light-collection-efficiency-less profile reconstruction: "
412 << rangeStartTime <<
" ns to " << last.
fT2 <<
" ns.";
417 if (!telFluoTime.empty()) {
419 FillTelescopeFluxes(telescope, telFluoTime, telFluoTimeBin, telFluoFlux,
420 telVFluoFlux, telVBackground, telPixelsInZeta,
421 spotFarFromBorderRanges);
425 telFluoTime.clear(); telFluoTimeBin.clear(); telFluoFlux.clear();
426 telVFluoFlux.clear(); telVBackground.clear();
427 telPixelsInZeta.clear();
428 latestFluxTime = telescopeIter->fLastTime;
431 if (eyeFluoTime.empty())
434 FillEyeFluxes(eye, eyeFluoTime, eyeFluoTimeBin,
435 eyeFluoFlux, eyeVFluoFlux, eyeVBackground);
471 const vector<double>& fluoTime,
472 const vector<double>& fluoTimeBin,
473 const vector<double>& fluoFlux,
474 const vector<double>& vfluoFlux,
475 const vector<double>& vBackground)
484 FillFluxes( fluolightprofile, lightprofile, backgroundProfile,
485 fluoTime, fluoTimeBin, fluoFlux, vfluoFlux, vBackground );
493 const vector<double>& fluoTime,
494 const vector<double>& fluoTimeBin,
495 const vector<double>& fluoFlux,
496 const vector<double>& vfluoFlux,
497 const vector<double>& vBackground,
498 const vector<
const vector<unsigned int>*>& pixelsInZeta,
499 const list<pair<double, double> >& farFromBorderTimeRanges)
508 FillFluxes( fluolightprofile, lightprofile, backgroundProfile,
509 fluoTime, fluoTimeBin, fluoFlux, vfluoFlux, vBackground );
514 const unsigned int nBins = pixelsInZeta.size();
516 zetaPixels.resize(nBins);
517 for (
unsigned int iTimeBin = 0; iTimeBin < nBins; ++iTimeBin)
518 zetaPixels[iTimeBin] = *(pixelsInZeta[iTimeBin]);
527 const vector<double>& fluoTime,
528 const vector<double>& fluoTimeBin,
529 const vector<double>& fluoFlux,
530 const vector<double>& vfluoFlux,
531 const vector<double>& vBackground)
533 for (
unsigned int i = 0; i < fluoTime.size(); ++i) {
534 const double sigmaFluoFlux =
sqrt(vfluoFlux[i]);
535 const double tMean = fluoTime[i];
536 const double dt = fluoTimeBin[i];
537 lightprofile.
PushBack ( tMean, dt/2., fluoFlux[i], sigmaFluoFlux );
538 fluolightprofile.
PushBack ( tMean, dt/2., fluoFlux[i], sigmaFluoFlux );
539 backgroundProfile.
PushBack( tMean, dt/2., 0.,
sqrt(vBackground[i]) );
552 double bestZeta = initZeta;
554 if (fillFlux && (initZeta+1.e-12 < finZeta || initZeta-1.e-12 > finZeta)) {
556 msg <<
"You called FindZeta with the fillFlux=true argument, but the initial and final guesses"
557 <<
" for zeta are not identical. This is an error. Either call FindZeta for zeta optimization"
558 <<
" (fillFlux=false) or for filling the light fluxes (fillFlux=true, initial zeta==final zeta)";
563 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
572 for (
double zeta = initZeta;
576 const double cosZeta = cos(zeta);
577 double totalSignal = 0.;
578 double totalNoise2 = 0.;
584 const unsigned int telId = teliter->GetId();
586 const Vector&
fSDP = teliter->GetRecData().GetSDP();
589 det::Detector::GetInstance().GetFDetector().GetTelescope(*teliter);
593 const double area2 = area*area;
595 vector<ShowerGeometryData>& telescopeData = fShowerGeometryData[telId];
598 pixiter != teliter->PixelsEnd(ComponentSelector::eHasData);
601 if (!pixiter->HasRecData())
609 const double pixelX = pixeldir.
GetX(localTelCS);
610 const double pixelY = pixeldir.
GetY(localTelCS);
611 const double pixelZ = pixeldir.
GetZ(localTelCS);
614 const TraceD& photontrace = pixiter->GetRecData().GetPhotonTrace();
615 const double RMS2 =
pow(pixiter->GetRecData().GetRMS(), 2);
617 for (
unsigned int i = 0; i < telescopeData.size(); ++i ) {
623 const double cosAngle = thisTelData.
fChiVecMean[0] * pixelX
627 double angleSDP =
Angle(fSDP, pixeldir);
629 if (angleSDP > 90.*
deg) {
630 angleSDP = 180.*
deg - angleSDP;
633 if ((!fStripMode && cosAngle > cosZeta) || (fStripMode &&
abs(angleSDP - 90.*
deg) < zeta)) {
636 const double photonSignal_i = photontrace[idx];
637 const double noise2_i = photonSignal_i < 0
639 : RMS2 + photonSignal_i/photon2Pe * (1.+gainVariance);
641 totalSignal += photonSignal_i;
642 totalNoise2 += noise2_i;
673 const double signalToNoise = totalNoise2 > 0. ? totalSignal /
sqrt(totalNoise2) : 0.;
677 <<
" zeta [deg] " << zeta/
degree
678 <<
" S/N " << signalToNoise <<
" S " << totalSignal
681 if (signalToNoise > maxSN) {
682 maxSN = signalToNoise;
691 cout <<
" Best Zeta " << bestZeta/
degree <<
"\n" << endl;
704 if (fBorderMargin > 0) {
705 cosDeg = cos(fBorderMargin);
711 if (
CosAngle(direction, *iter) > cosDeg)
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
utl::TabulatedFunctionErrors & GetClearedEyeLightFlux(fevt::Eye &eye, const fevt::FdConstants::LightSource source)
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.
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 > &)
std::vector< unsigned int > fPixelsInZeta
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.
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
Fluorescence Detector Eye Event.
SizeType GetStop() const
Get valid data stop bin.
unsigned int fADCTraceIndex
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
bool FindLightFlux(fevt::Eye &eye)
void FillEyeFluxes(fevt::Eye &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &)
utl::Vector GetAxis() const
double GetGainVariance() const
double FindZeta(fevt::Eye &eye, double initZeta, double finZeta, double stepZeta, bool fillFlux=false)
#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)
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.
bool IsNearBorder(const utl::Vector &direction, const fevt::Telescope &telescope, double zeta) const
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.
utl::TabulatedFunctionErrors & GetClearedTelescopeLightFlux(fevt::Telescope &tel, const fevt::FdConstants::LightSource source)
double GetX(const CoordinateSystemPtr &coordinateSystem) const
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.
double abs(const SVector< n, T > &v)
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)
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.
fevt::FEvent & GetFEvent()
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.
const Telescope & GetTelescope(const fevt::Telescope &eventTel) const
Get fdet::Telescope from fevt::Telescope.
double GetFADCBinSize() const
double GetDiaphragmArea() const
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
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)
void MakeLightFlux(const FdConstants::LightSource source=FdConstants::eTotal)
bool Run(evt::Event &event)
Fluorescence Detector Telescope Event.
bool CalculateShowerGeometryData(const fevt::Eye &eye)
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
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
PixelIterator TimeFitPixelsBegin()
double GetDiaPhoton2PEFactor(const double wavelength, const std::string &configSignature="") const
#define ERROR(message)
Macro for logging error messages.
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 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.