12 #include <fwk/CentralConfig.h>
13 #include <fwk/CoordinateSystemRegistry.h>
15 #include <utl/Reader.h>
16 #include <utl/ErrorLogger.h>
17 #include <utl/MathConstants.h>
18 #include <utl/Vector.h>
19 #include <utl/PhysicalConstants.h>
20 #include <utl/TabulatedFunctionErrors.h>
22 #include <evt/Event.h>
23 #include <evt/ShowerFRecData.h>
25 #include <fevt/FEvent.h>
27 #include <fevt/Telescope.h>
28 #include <fevt/EyeRecData.h>
29 #include <fevt/PixelRecData.h>
30 #include <fevt/Pixel.h>
31 #include <fevt/FdComponentSelector.h>
33 #include <det/Detector.h>
35 #include <fdet/FDetector.h>
37 #include <fdet/Pixel.h>
38 #include <fdet/Channel.h>
39 #include <fdet/Camera.h>
40 #include <fdet/Telescope.h>
42 #include <utl/Vector.h>
47 using namespace FdApertureLightFinderOG;
64 CentralConfig::GetInstance()->
GetTopBranch(
"FdApertureLightFinder");
67 ERROR(
"Could not find branch FdApertureLightFinder");
91 FEvent& fevent =
event.GetFEvent();
96 for (eyeiter = fevent.
EyesBegin(ComponentSelector::eHasData);
97 eyeiter != fevent.
EyesEnd(ComponentSelector::eHasData);
103 INFO(
"T0 must be taken from EyeRecData, skip this Eye");
108 INFO(
"No Geometrical info for this Eye - skip this Eye");
112 if ( FindLightFlux(eye) )
117 if ( nGoodEyes == 0 )
118 return eContinueLoop;
137 if ( !FindSignalTimeRange(eye) )
142 double zMin=fminZetaAngle;
143 double zMax=fmaxZetaAngle+zStep;
144 double zeta=FindZeta(eye,zMin,zMax,zStep);
149 zStep=fstepZetaAngle;
152 zeta=FindZeta(eye,zMin,zMax,zStep);
155 INFO(
"Zeta search failed - Bailing out for this eye");
160 zeta += fSafetyMargin;
164 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
168 const double T0 = eyerecdata.
GetTZero();
170 const double Rp = eyerecdata.
GetRp();
173 const Vector eyeToCore = core - eyePos;
176 const double timeBinSize = 100*
ns;
178 deque <double> fluoTime, fluoFlux, vfluoFlux, vBackground;
181 for (
double time= fTStart;
183 time += timeBinSize) {
186 double fluxVariance_i=0;
187 double backgroundVariance_i=0;
190 const double chi_1 = chi0 - 2*atan(
kSpeedOfLight/Rp *(time - T0) );
191 double l = eyeToCore.
GetMag() * sin(chi_1) / sin(chi0 - chi_1);
194 Vector chi_i_vec1 = eyeToCore + l * axis;
198 const double chi_2 = chi0 - 2*atan(
kSpeedOfLight/Rp *(time - T0+timeBinSize) );
199 l = eyeToCore.
GetMag() * sin(chi_2) / sin(chi0 - chi_2);
202 Vector chi_i_vec2 = eyeToCore + l * axis;
206 Vector chi_i_vec = chi_i_vec1 + chi_i_vec2;
209 if (chi_i_vec.
GetTheta(eyeCS) > kTelescopeMaxTheta ||
210 chi_i_vec.
GetTheta(eyeCS) < kTelescopeMinTheta)
213 unsigned int ntelescopes=0;
224 double telescope_flux_i=0;
225 double telescope_variance_i=0;
226 double telescope_bgVariance_i=0;
228 double telescopeTimeOffset = teliter->GetTimeOffset();
232 const double squaredArea = area*area;
235 bool hasSignal =
false;
236 bool isNearBorder =
false;
239 for (pixiter = teliter->PixelsBegin(ComponentSelector::eHasData);
240 pixiter != teliter->PixelsEnd(ComponentSelector::eHasData);
247 const double alpha=(
Angle(chi_i_vec1, pixeldir) +
Angle(chi_i_vec2, pixeldir))/2.;
253 isNearBorder = IsNearBorder(chi_i_vec, detTel,zeta);
258 telescope_variance_i=0;
259 telescope_bgVariance_i=0;
263 if (not pixiter->HasRecData())
266 const TraceD& photontrace= pixiter->GetRecData().GetPhotonTrace();
268 int idx = int((time - telescopeTimeOffset)/timeBinSize);
270 if(idx>=(
int) photontrace.
GetStart()&&
271 idx<=(int) photontrace.
GetStop()) {
275 telescope_flux_i += photontrace[idx]/area;
277 const double baseLineVariance =
278 pow(pixiter->GetRecData().GetRMS(),2)/squaredArea;
280 telescope_bgVariance_i += baseLineVariance;
282 if (photontrace[idx]<0)
283 telescope_variance_i += baseLineVariance;
285 const double signalVariance =
286 photontrace[idx]/photon2Pe * (1.+gainVariance);
287 telescope_variance_i +=
288 (signalVariance/squaredArea + baseLineVariance);
295 if (!isNearBorder && hasSignal ){
297 flux_i+= telescope_flux_i;
298 fluxVariance_i+= telescope_variance_i;
299 backgroundVariance_i+= telescope_bgVariance_i;
307 fluxVariance_i/=ntelescopes;
308 backgroundVariance_i/=ntelescopes;
313 fluoTime.push_back(time);
314 fluoFlux.push_back(flux_i);
315 vfluoFlux.push_back(fluxVariance_i);
316 vBackground.push_back(backgroundVariance_i);
325 unsigned int nPopFront=0;
326 for (
unsigned int i=0;i<fluoTime.size();i++) {
327 if(fluoFlux[i]>2.*
sqrt(vfluoFlux[i]))
331 for (
unsigned int i=0;i<nPopFront;i++) {
332 fluoTime.pop_front();
333 fluoFlux.pop_front();
334 vfluoFlux.pop_front();
335 vBackground.pop_front();
338 unsigned int nPopBack=0;
339 for (
int i=(
int) fluoTime.size()-1;i>-1;i--) {
340 if(fluoFlux[i]>2.*
sqrt(vfluoFlux[i]))
344 for (
unsigned int i=0;i<nPopBack;i++) {
347 vfluoFlux.pop_back();
348 vBackground.pop_back();
352 if(fluoTime.size()<1)
355 CombineAndFillFluxes(eye, fluoTime, fluoFlux, vfluoFlux, vBackground);
367 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
372 bool firstTime =
true;
378 if (not pixiter->HasRecData())
384 const double timeoffset =
385 eye.
GetTelescope(pixiter->GetTelescopeId()).GetTimeOffset();
387 const double t1 = timeBinSize*pixelRecData.
GetPulseStart()+timeoffset;
388 const double t2 = timeBinSize*pixelRecData.
GetPulseStop()+timeoffset;
390 if (t2 > maxT_i || firstTime)
392 if (t1 < minT_i || firstTime) {
401 if (fTStop <= fTStart)
412 const deque<double>& fluoTime,
413 const deque<double>& fluoFlux,
414 const deque<double>& vfluoFlux,
415 const deque<double>& vBackgroundFlux)
419 const double timeBinSize = 100. *
ns;
444 fluoLightProfile.
Clear();
445 lightProfile.
Clear();
446 backgroundProfile.
Clear();
450 vector<double> c_fluoTime, c_fluoDTime, c_fluoFlux, c_vfluoFlux, c_vbgFlux;
452 double t1=fluoTime[0];
456 double lastTime=fluoTime[0];
461 for (
unsigned int i=0;i<fluoTime.size();i++) {
467 if(fluoTime[i]-lastTime>timeBinSize) {
469 double dt = fluoTime[i-1]-t1+timeBinSize;
470 c_fluoTime.push_back(t1);
471 c_fluoDTime.push_back(dt);
472 c_fluoFlux.push_back(sum);
473 c_vfluoFlux.push_back(sum2);
474 c_vbgFlux.push_back(bgSum2);
475 nBins=0.; sum=0.; sum2=0.; bgSum2=0.; t1=0.;
485 bgSum2+= vBackgroundFlux[i];
486 lastTime=fluoTime[i];
487 double nEquiv=sum*sum/sum2;
488 if( fnEquivMin<=0 || nEquiv>fnEquivMin || i==fluoTime.size()-1 ) {
489 double dt = fluoTime[i]-t1+timeBinSize;
490 c_fluoTime.push_back(t1);
491 c_fluoDTime.push_back(dt);
492 c_fluoFlux.push_back(sum);
493 c_vfluoFlux.push_back(sum2);
494 c_vbgFlux.push_back(bgSum2);
495 nBins=0.; sum=0.; sum2=0.; bgSum2=0.; t1=0.;
500 if(c_fluoTime.size()>(
unsigned int) fnProfMax) {
502 double nCombi=(double) c_fluoTime.size()/ (double) fnProfMax;
511 for (
unsigned int i=0;i<c_fluoTime.size();i++) {
517 if(sum>0.&&c_fluoTime[i]-lastTime>c_fluoDTime[i-1]) {
518 double dt = c_fluoTime[i-1]-t1+c_fluoDTime[i-1];
520 fluoLightProfile.
PushBack (t1+dt/2.,dt/2.,sum,
sqrt(sum2));
521 backgroundProfile.
PushBack(t1+dt/2.,dt/2., 0.,
sqrt(bgSum2));
522 sum=0.; sum2=0.; t1=0.; bgSum2=0.; combined=0;
526 sum += c_fluoFlux[i];
527 sum2+= c_vfluoFlux[i];
528 bgSum2+= c_vbgFlux[i];
529 lastTime=c_fluoTime[i];
533 if(combined>=nCombi||i==c_fluoTime.size()-1) {
534 double dt = c_fluoTime[i]-t1+c_fluoDTime[i];
536 fluoLightProfile.
PushBack (t1+dt/2.,dt/2.,sum,
sqrt(sum2));
537 backgroundProfile.
PushBack(t1+dt/2.,dt/2., 0.,
sqrt(bgSum2));
538 sum=0.; sum2=0.; t1=0.; bgSum2=0.; combined=0;
543 for (
unsigned int i=0;i<c_fluoTime.size();i++) {
545 sum2 = c_vfluoFlux[i];
546 bgSum2 = c_vbgFlux[i];
547 double dt = c_fluoDTime[i];
548 lightProfile.
PushBack (c_fluoTime[i]+dt/2.,dt/2.,sum,
sqrt(sum2));
549 fluoLightProfile.
PushBack (c_fluoTime[i]+dt/2.,dt/2.,sum,
sqrt(sum2));
550 backgroundProfile.
PushBack(c_fluoTime[i]+dt/2.,dt/2., 0.,
sqrt(bgSum2));
568 if (
Angle(direction,*iter) < zeta)
581 unsigned int maxoffset = 0;
588 const unsigned int tmp = teliter->GetTimeOffset();
602 double finZeta,
double stepZeta)
607 info <<
"Eye: " << eye.
GetId() <<
'\n';
609 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
614 const double T0 = eyerecdata.
GetTZero();
616 const double Rp = eyerecdata.
GetRp();
619 const Vector eyeToCore = core - eyePos;
622 const double timeBinSize = 100.*
ns;
625 double bestZeta = initZeta;
629 const int nTimes=(int) ((fTStop-fTStart)/timeBinSize)+1;
631 double * chi_i_vecX =
new double[nTimes];
632 double * chi_i_vecY =
new double[nTimes];
633 double * chi_i_vecZ =
new double[nTimes];
635 const double distEyeToCore = eyeToCore.
GetMag();
640 time+= timeBinSize) {
642 const double chi_i = chi0-2.* atan(
kSpeedOfLight/Rp * (time - T0) );
643 double l = distEyeToCore * sin(chi_i) / sin(chi0 - chi_i);
646 Vector chi_i_vec = eyeToCore + l * axis;
649 if (chi_i_vec.
GetTheta(eyeCS) > kTelescopeMaxTheta ||
650 chi_i_vec.
GetTheta(eyeCS) < kTelescopeMinTheta) {
652 chi_i_vecX[iTime] = 9999;
653 chi_i_vecY[iTime] = 9999;
654 chi_i_vecZ[iTime] = 9999;
658 chi_i_vecX[iTime] = chi_i_vec.
GetX(eyeCS);
659 chi_i_vecY[iTime] = chi_i_vec.
GetY(eyeCS);
660 chi_i_vecZ[iTime] = chi_i_vec.
GetZ(eyeCS);
669 for (
double zeta = initZeta;
673 double signalOverNoise=0;
675 double varianceSum =0;
679 double charge_i=0.,noise2_i=0;
688 const unsigned int telescopeTimeOffset = teliter->GetTimeOffset();
694 teliter->PixelsBegin(ComponentSelector::eHasData);
695 pixiter != teliter->PixelsEnd(ComponentSelector::eHasData);
702 const double pixelX = pixeldir.
GetX(eyeCS);
703 const double pixelY = pixeldir.
GetY(eyeCS);
704 const double pixelZ = pixeldir.
GetZ(eyeCS);
706 if (!pixiter->HasRecData())
709 const TraceD& photontrace = pixiter->GetRecData().GetPhotonTrace();
710 const double baseLineVariance =
pow(pixiter->GetRecData().GetRMS(),2);
716 time+= timeBinSize) {
718 if(*(chi_i_vecX+iTime)<100) {
720 const double angle = acos(*(chi_i_vecX+iTime)*pixelX+
721 *(chi_i_vecY+iTime)*pixelY+
722 *(chi_i_vecZ+iTime)*pixelZ);
726 const int idx = int((time - telescopeTimeOffset)/timeBinSize);
728 if( idx>=(
int) photontrace.
GetStart()&&
729 idx<=(int) photontrace.
GetStop()) {
731 charge_i = photontrace[idx];
733 noise2_i = baseLineVariance;
735 const double signalVariance =
736 charge_i / photon2Pe * (1.+gainVariance);
737 noise2_i = baseLineVariance + signalVariance;
740 signalSum += charge_i;
741 varianceSum += noise2_i;
754 signalOverNoise = signalSum /
sqrt(varianceSum);
757 <<
" zeta [deg] " << setw(5) << zeta/
degree
758 <<
", S/N " << setw(10) << signalOverNoise
759 <<
", S " << setw(9) << signalSum <<
'\n';
761 if (signalOverNoise > maxSN) {
762 maxSN = signalOverNoise;
767 delete [] chi_i_vecX;
768 delete [] chi_i_vecY;
769 delete [] chi_i_vecZ;
773 info <<
" Best Zeta " << bestZeta/
degree;
Telescope & GetTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Telescope by Id, throw exception if not existent.
Branch GetTopBranch() const
unsigned int GetId() const
const utl::Vector & GetDirection() const
pointing direction of this pixel
void CombineAndFillFluxes(fevt::Eye &eye, const std::deque< double > &fluoTime, const std::deque< double > &fluoFlux, const std::deque< double > &vfluoFlux, const std::deque< double > &vBackground)
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
int GetPulseStop() const
pulse stop (to be defined)
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.
Fluorescence Detector Eye Event.
SizeType GetStop() const
Get valid data stop bin.
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
double FindZeta(const fevt::Eye &eye, double initZeta, double finZeta, double stepZeta) const
bool FindLightFlux(fevt::Eye &eye)
double GetChiZero() const
int GetPulseStart() const
pulse start (to be defined)
EyeIterator EyesEnd(const ComponentSelector::Status status)
double GetGainVariance() const
#define INFO(message)
Macro for logging informational messages.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
double pow(const double x, const unsigned int i)
unsigned int GetMaxOffset(const fevt::Eye &eye) const
Get the maximum time offset of the telescopes in the event.
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
Detector description interface for FDetector-related data.
void SetZeta(const double zeta)
static const double kTelescopeMaxTheta
boost::indirect_iterator< ConstInternalPixelIterator, const Pixel & > ConstPixelIterator
Const iterator over pixels used in reconstruction.
OutOfBorderPixelsIterator OutOfBorderPixelsEnd() const
End of pixels out of the border.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
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.
boost::filter_iterator< ComponentSelector, ConstAllPixelIterator > ConstPixelIterator
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
std::vector< utl::Vector >::const_iterator OutOfBorderPixelsIterator
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.
Top of Fluorescence Detector event hierarchy.
Eye-specific shower reconstruction data.
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
double GetReferenceLambda() const
static const double kTelescopeMinTheta
double GetY(const CoordinateSystemPtr &coordinateSystem) const
boost::filter_iterator< ComponentSelector, AllPixelIterator > PixelIterator
selective Pixel iterators
constexpr double kSpeedOfLight
Detector description interface for Telescope-related data.
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.
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
PixelIterator TimeFitPixelsEnd()
bool FindSignalTimeRange(const fevt::Eye &eye)
OutOfBorderPixelsIterator OutOfBorderPixelsBegin() const
Begin of pixels out of the border.
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of 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
PixelIterator TimeFitPixelsBegin()
double GetDiaPhoton2PEFactor(const double wavelength, const std::string &configSignature="") const
#define ERROR(message)
Macro for logging error messages.
bool IsNearBorder(const utl::Vector &direction, const fdet::Telescope &telescope, double zeta) const
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
Fluorescence Detector Pixel Reconstructed Data.
boost::filter_iterator< ComponentSelector, ConstAllTelescopeIterator > ConstTelescopeIterator
utl::Point GetPosition() const
Eye position.
void MakeLightFlux(const FdConstants::LightSource source=FdConstants::eTotal)
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.