12 #include <evt/Event.h>
14 #include <fevt/FEvent.h>
16 #include <fevt/EyeRecData.h>
17 #include <fevt/Pixel.h>
18 #include <fevt/Telescope.h>
19 #include <fevt/TelescopeRecData.h>
20 #include <fevt/PixelRecData.h>
22 #include <fwk/CentralConfig.h>
24 #include <utl/AxialVector.h>
25 #include <utl/ErrorLogger.h>
26 #include <utl/MathConstants.h>
27 #include <utl/Reader.h>
29 #include <det/Detector.h>
31 #include <fdet/FDetector.h>
33 #include <fdet/Pixel.h>
34 #include <fdet/Channel.h>
41 using namespace FdSDPFinderOG;
51 double FdSDPFinder::fChi2=0;
52 unsigned int FdSDPFinder::fNDof=0;
57 CentralConfig::GetInstance()->
GetTopBranch(
"FdSDPFinder");
60 ERROR(
"Could not find branch FdSDPFinder");
71 " Version: " << GetVersionInfo(VModule::eRevisionNumber) <<
"\n"
73 " min no. pixels: " << fMinPixels <<
"\n"
74 " max distance: " << fMaxDistance <<
"\n"
75 " first guess from track bed "
76 << (fFirstGuessFromCharge?
"charge":
"pixels") <<
'\n';
90 FEvent& fevent =
event.GetFEvent();
94 unsigned int neyes =0;
96 for (eyeiter = fevent.
EyesBegin(ComponentSelector::eHasData);
97 eyeiter != fevent.
EyesEnd(ComponentSelector::eHasData);
103 if (det::Detector::GetInstance().GetFDetector().GetEye(eye).IsVirtual())
116 warn <<
" **** too few pixels with signal (minNPixels=" << fMinPixels <<
"). Skipping eye. **** ";
126 fSDPFirstGuess = FindSDPFirstGuess(eye);
128 if (!fGoodEvent )
continue;
138 <<
" pixels remaining after removing noise";
152 <<
" pixels remaining after removing outliers";
161 unsigned int PixelsReadmited =
true;
162 while ( PixelsReadmited ) {
163 PixelsReadmited =
false;
169 fSDPFirstGuess =
fSDP;
174 info << nReadmitted <<
" pixels readmitted.";
182 info << nRemoved <<
" pixels removed.";
185 if ( nReadmitted != 0 || nRemoved != 0) {
187 PixelsReadmited =
true;
202 telIt != eye.
TelescopesEnd(ComponentSelector::eHasData); ++telIt)
204 if (!telIt->HasRecData())
205 telIt->MakeRecData();
215 if (!neyes)
return eContinueLoop;
233 const double trackbed = 2.0 *
degree;
234 const double trackbedCut = cos(trackbed)*cos(trackbed);
237 det::Detector::GetInstance().GetFDetector().GetEye(eye);
247 const FDetector& fdetector = Detector::GetInstance().GetFDetector();
252 std::vector<double> candidatePixelTimes;
253 std::vector<Vector > candidatePixelDirections;
254 std::vector<std::vector<double> > candidatePixDirComponents;
255 std::vector<double> candidatePixelCharge;
263 if ( ! IsIsolated(*pixeliter,eye) ) {
270 const double pixelTime = pixeliter->GetRecData().GetCentroid() +
272 const double charge = pixeliter->GetRecData().GetTotalCharge();
275 pixelDirection.TransformTo(eyeCS);
277 vector<double> components;
278 components.push_back(pixelDirection.
GetX(eyeCS));
279 components.push_back(pixelDirection.
GetY(eyeCS));
280 components.push_back(pixelDirection.
GetZ(eyeCS));
282 candidatePixDirComponents.push_back(components);
283 candidatePixelDirections.push_back(pixelDirection);
284 candidatePixelCharge.push_back(charge);
285 candidatePixelTimes.push_back(pixelTime);
292 if( candidatePixelTimes.size() < 3) {
295 warn <<
" ************* This event has less than 3 good pixels. Skip! ****************";
302 std::vector <utl::AxialVector> crossProducts;
304 for (
unsigned int i=0;i<candidatePixelTimes.size(); i++ ) {
306 const double t_1 = candidatePixelTimes[i];
307 const Vector& dir1 = candidatePixelDirections[i];
309 for (
unsigned int j = i; j < candidatePixelTimes.size(); ++j) {
313 const double t_2 = candidatePixelTimes[j];
314 const Vector& dir2 = candidatePixelDirections[j];
322 if ( crossprod.
GetMag() != 0. )
323 crossProducts.push_back(crossprod);
334 info <<
" track bed maximization (N=" << crossProducts.size() <<
"*"
335 << candidatePixelTimes.size() <<
")="
336 << crossProducts.size()*candidatePixelTimes.size();
339 double maxTrackBed=-1.;
342 for(
unsigned int k=0;k<crossProducts.size(); k++) {
344 double thisTrackBed=0.;
348 const double x1 = tmpSDP.
GetX(eyeCS);
349 const double y1 = tmpSDP.
GetY(eyeCS);
350 const double z1 = tmpSDP.
GetZ(eyeCS);
352 for (
unsigned int i=0;i<candidatePixelTimes.size(); i++ ) {
354 const double * pixDir = &(candidatePixDirComponents[i].front());
355 const double cosTheta = x1*(*(pixDir))
358 const double sin2Theta = 1. - cosTheta*cosTheta;
365 if ( sin2Theta > trackbedCut ) {
366 if ( fFirstGuessFromCharge )
367 thisTrackBed+=candidatePixelCharge[i];
374 if (thisTrackBed > maxTrackBed) {
375 maxTrackBed = thisTrackBed;
381 if( maxTrackBed <=0. ) {
384 warn <<
" ************* no signal/pixels in track bed!!! Skip! ****************";
401 Detector::GetInstance().GetFDetector().GetEye(eye);
410 TMinuit theMinuit(npar);
412 theMinuit.SetPrintLevel(-1);
413 theMinuit.SetFCN(FdSDPFinder::MinuitFitFunc);
419 theMinuit.mnexcm(
"SET ERR", arglist,1,ierflag);
421 if (ierflag)
ERROR (
"Minuit SET ERR failed");
427 vstart[0] = fSDPFirstGuess.GetTheta(CS);
428 vstart[1] = fSDPFirstGuess.GetPhi(CS);
431 info <<
"SDPn Initial guess (theta, phi): ("
438 theMinuit.mnparm(0,
"Theta",vstart[0], step[0],0,0,ierflag);
439 theMinuit.mnparm(1,
"Phi", vstart[1], step[1],0,0,ierflag);
443 theMinuit.mnexcm(
"MIGRAD", arglist ,2,ierflag);
445 if (ierflag)
ERROR (
"Minuit MIGRAD failed");
447 theMinuit.mnexcm(
"HESSE", arglist, 2, ierflag);
451 double fmin, fedm, errdef;
454 theMinuit.mnstat(fmin, fedm, errdef, npari, nparx, istat);
456 theMinuit.mnexcm(
"MINOS", arglist, 2, ierflag);
457 theMinuit.mnstat(fmin, fedm, errdef, npari, nparx, istat);
459 WARNING(
"Neither HESSE nor MINOS found accurate covariance matrix");
462 double sdpTheta, sdpThetaErr;
463 double sdpPhi,sdpPhiErr;
465 theMinuit.GetParameter(0,sdpTheta,sdpThetaErr);
466 theMinuit.GetParameter(1,sdpPhi,sdpPhiErr);
469 info <<
"Fitted SDPn (theta,phi): (" << sdpTheta/
degree
470 <<
"," << sdpPhi/
degree <<
")";
473 fSDP =
Vector(1,sdpTheta,sdpPhi,CS, Vector::kSpherical);
479 theMinuit.mnemat( &covMatrix[0][0], npar );
480 fSDPCorrThetaPhi = covMatrix[0][1]/sdpThetaErr/sdpPhiErr;
482 fChi2 = theMinuit.fAmin;
503 Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
506 const double d =
abs(
kPi/2 -
Angle(dir, fSDPFirstGuess));
507 if (d > fMaxDistance )
531 Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
532 const unsigned int pixel_id = evtpixel.
GetId();
536 bool SDPfit_pixel =
false;
539 if (pixel_id == iter->GetId()) {
547 const double d =
abs(
kPi/2 -
Angle(dir, fSDPFirstGuess));
548 if (d < fMaxDistance && !IsIsolated(evtpixel, eye))
559 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
587 const int nbins = 400;
588 int timediff_bin_population[nbins]={0};
589 const double timediff_bin_size = 500.0;
591 if ( fIsolationLimit == 0 ) {
593 std::vector<double> candidatePixelTimes;
602 const double pixelTime = pixeliter->GetRecData().GetCentroid()*detChannel.
GetFADCBinSize()
605 candidatePixelTimes.push_back(pixelTime);
609 for (
unsigned int i=0;i<candidatePixelTimes.size(); i++ ) {
611 const double t1 = candidatePixelTimes[i];
613 for (
unsigned int j=0;j<candidatePixelTimes.size(); j++ ) {
618 const double t2 = candidatePixelTimes[j];
622 int timediff_bin = int(timediff / timediff_bin_size );
623 if (timediff_bin >= nbins )
625 timediff_bin_population[timediff_bin]++ ;
631 int max_population = 0;
632 int bin_with_maximum = 0;
633 for (
int i = 0 ; i < nbins ; i++ ) {
634 if ( timediff_bin_population[i] > max_population) {
635 bin_with_maximum = i;
636 max_population = timediff_bin_population[i];
639 fIsolationLimit = (bin_with_maximum+6) * timediff_bin_size ;
658 if (*pixeliter==pixel)
666 const double pixelTime2 = pixeliter->GetRecData().GetCentroid()*detChannel2.
GetFADCBinSize()
669 const double timediff =
673 const double angdiff =
Angle (PixelDir1, PixelDir2);
677 if (timediff < fIsolationLimit && angdiff < 5*
degree)
695 double TrackBed= 1.5 *
degree;
700 vector<double> slope;
701 vector<double> intcpt;
706 for (iter2= iter + 1;
718 double tmpSlope = (t1-t2) / (chi1-chi2);
719 double tmpIntcpt = t1 - tmpSlope*chi1;
720 slope.push_back(tmpSlope);
721 intcpt.push_back(tmpIntcpt);
726 if (! slope.size())
return;
730 unsigned int maxNPixels=0;
731 unsigned int bestIndex=0;
733 for (
unsigned int i=0; i<slope.size(); i++){
735 unsigned int tmpNPixels=0;
747 double dchi = chi_i - (t_i - intcpt[i])/slope[i];
749 if (
std::abs(dchi) < TrackBed * 2) tmpNPixels++;
754 if (tmpNPixels> maxNPixels) {bestIndex=i; maxNPixels= tmpNPixels;}
759 const double theSlope = slope[bestIndex];
760 const double theIntcpt = intcpt[bestIndex];
762 if ( theSlope > 0 ) fSDPFirstGuess *= -1;
773 double dchi = chi_i - (t_i - theIntcpt)/theSlope;
801 FdSDPFinder::MinuitFitFunc(
int& ,
double* ,
double& f,
806 const EyeRecData& recdata = fCurEye->GetRecData();
813 Detector::GetInstance().GetFDetector().GetEye(*fCurEye);
818 double& sdpTheta = par[0];
819 double& sdpPhi = par[1];
822 Vector sdp (1,sdpTheta ,sdpPhi ,CS, Vector::kSpherical);
825 unsigned int ndof =0;
826 double total_charge=0;
834 Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
840 double tmp =
kPi/2. -
Angle( dir , sdp) ;
846 chisq += tmp*tmp * charge /(0.35 *
degree * 0.35 *
degree);
848 total_charge += charge;
852 chisq /= total_charge;
865 det::Detector::GetInstance().GetFDetector().GetEye(eye);
876 det::Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
878 det::Detector::GetInstance().GetFDetector().GetChannel(evtpixel);
892 pixeldir.TransformTo(cs);
894 Vector vertical(0,0,1, cs, Vector::kCartesian);
895 Vector horizontalWithinSDP =
cross(fSDPFirstGuess, vertical);
896 horizontalWithinSDP /= horizontalWithinSDP.
GetR(cs);
900 Vector chi_i_vector = pixeldir - (fSDPFirstGuess * pixeldir) * fSDPFirstGuess;
901 chi_i_vector.TransformTo(cs);
903 chi_i_vector /= chi_i_vector.
GetR(cs);
904 const double chi_i =
Angle(chi_i_vector, horizontalWithinSDP);
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.
Branch GetTopBranch() const
unsigned int GetId() const
const utl::Vector & GetDirection() const
pointing direction of this pixel
void SetSDPFitChiSquare(const double sdpChi2, const unsigned int ndof)
void SetSDPPhiError(const double sdpPhiError)
fSDPThetaError(t.GetSDPThetaError())
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 SetSDPFitChiSquare(const double sdpChi2, const unsigned int ndof)
unsigned int GetTimeOffset() const
Time offset of this Telescope compared to fevt::Header::GetTime [ns].
Fluorescence Detector Eye Event.
PixelIterator PulsedPixelsEnd()
double GetR(const CoordinateSystemPtr &coordinateSystem) const
radius r in spherical coordinates coordinates (distance to origin)
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
EyeIterator EyesEnd(const ComponentSelector::Status status)
#define INFO(message)
Macro for logging informational messages.
void SetT_i(const double t_i, const double error)
void Init()
Initialise the registry.
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.
void AddSDPPixel(fevt::Pixel &pixel)
add a pixel to the list of SDP pixels
PixelIterator PulsedPixelsBegin()
Detector description interface for FDetector-related data.
boost::indirect_iterator< ConstInternalPixelIterator, const Pixel & > ConstPixelIterator
Const iterator over pixels used in reconstruction.
void SetSDP(const utl::AxialVector &vec)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
unsigned int GetId() const
Class representing a document branch.
PixelIterator SDPPixelsBegin()
Fluorescence Detector Pixel event.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
fSDPPhiError(t.GetSDPPhiError())
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
utl::TimeInterval GetT_i() const
double abs(const SVector< n, T > &v)
void SetSDPCorrThetaPhi(double sdpCorrThetaPhi)
unsigned int GetTelescopeId() const
EyeIterator EyesBegin(const ComponentSelector::Status status)
void SetSDPPhiError(const double sdpPhiError)
const Channel & GetChannel(const fevt::Channel &eventChannel) const
Get fdet::Channel from fevt::Channel.
Telescope-specific shower reconstruction data.
void SetSDPThetaError(const double sdpThetaError)
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
unsigned int GetNPulsedPixels() const
Get number of pulsed pixels.
#define WARNING(message)
Macro for logging warning messages.
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)
unsigned int GetTelescopeId() const
boost::indirect_iterator< InternalPixelIterator, fevt::Pixel & > PixelIterator
Iterator over pixels used in reconstruction.
double GetY(const CoordinateSystemPtr &coordinateSystem) const
ResultFlag
Flag returned by module methods to the RunController.
double GetFADCBinSize() const
double GetTotalCharge() const
integrated pulse charge
void SetSDPThetaError(const double sdpThetaError)
void SetSDP(const utl::AxialVector &vec)
PixelIterator SDPPixelsEnd()
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
double GetNanoSecond() const
Get integer number of nanoseconds past seconds boundary.
double GetCentroid() const
unsigned int GetNSDPPixels() const
Get number of SDP pixels.
#define ERROR(message)
Macro for logging error messages.
PixelIterator RemoveSDPPixel(PixelIterator it)
Remove a pixel from the list of SDP pixels.
void SetChi_i(const double chi_i)
PixelRecData & GetRecData()
void SetSDPCorrThetaPhi(double sdpCorrThetaPhi)
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.