FdSDPFinder.cc
Go to the documentation of this file.
1 
10 #include <iostream>
11 
12 #include <evt/Event.h>
13 
14 #include <fevt/FEvent.h>
15 #include <fevt/Eye.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>
21 
22 #include <fwk/CentralConfig.h>
23 
24 #include <utl/AxialVector.h>
25 #include <utl/ErrorLogger.h>
26 #include <utl/MathConstants.h>
27 #include <utl/Reader.h>
28 
29 #include <det/Detector.h>
30 
31 #include <fdet/FDetector.h>
32 #include <fdet/Eye.h>
33 #include <fdet/Pixel.h>
34 #include <fdet/Channel.h>
35 
36 #include <TMinuit.h>
37 
38 #include "FdSDPFinder.h"
39 
40 using namespace std;
41 using namespace FdSDPFinderOG;
42 using namespace evt;
43 using namespace fevt;
44 using namespace fwk;
45 using namespace utl;
46 using namespace det;
47 using namespace fdet;
48 
49 
50 fevt::Eye * FdSDPFinder::fCurEye =0;
51 double FdSDPFinder::fChi2=0;
52 unsigned int FdSDPFinder::fNDof=0;
53 
55 
56  Branch topB =
57  CentralConfig::GetInstance()->GetTopBranch("FdSDPFinder");
58 
59  if (!topB) {
60  ERROR("Could not find branch FdSDPFinder");
61  return eFailure;
62  }
63 
64  topB.GetChild("minPixels").GetData(fMinPixels);
65  topB.GetChild("maxDistance").GetData(fMaxDistance);
66  topB.GetChild("firstGuessFromCharge").GetData(fFirstGuessFromCharge);
67 
68  // info output
69  ostringstream info;
70  info << "\n"
71  " Version: " << GetVersionInfo(VModule::eRevisionNumber) << "\n"
72  " Parameters:\n"
73  " min no. pixels: " << fMinPixels << "\n"
74  " max distance: " << fMaxDistance << "\n"
75  " first guess from track bed "
76  << (fFirstGuessFromCharge?"charge":"pixels") << '\n';
77 
78  INFO(info);
79 
80  return eSuccess;
81 }
82 
83 
86 VModule::ResultFlag FdSDPFinder::Run(evt::Event& event){
87 
88  if (!event.HasFEvent()) return eSuccess;
89 
90  FEvent& fevent = event.GetFEvent();
91 
92  FEvent::EyeIterator eyeiter;
93 
94  unsigned int neyes =0; // number of eyes with enough pixels
95 
96  for (eyeiter = fevent.EyesBegin(ComponentSelector::eHasData);
97  eyeiter != fevent.EyesEnd(ComponentSelector::eHasData);
98  ++eyeiter) {
99 
100  fevt::Eye& eye = *eyeiter;
101 
102  // skip virtual eyes
103  if (det::Detector::GetInstance().GetFDetector().GetEye(eye).IsVirtual())
104  continue;
105 
106  if (!eye.HasRecData())
107  eye.MakeRecData();
108  EyeRecData& eyerecdata = eye.GetRecData();
109 
110  ostringstream info;
111  info << eyerecdata.GetNPulsedPixels() << " pixels had signal in Eye " << eye.GetId();
112  INFO(info);
113 
114  if (eyerecdata.GetNPulsedPixels() < fMinPixels) {
115  ostringstream warn;
116  warn << " **** too few pixels with signal (minNPixels=" << fMinPixels << "). Skipping eye. **** ";
117  INFO(warn);
118  continue;
119  }
120 
121 
122 
123  fIsolationLimit = 0;
124 
125  fGoodEvent = true;
126  fSDPFirstGuess = FindSDPFirstGuess(eye);
127 
128  if (!fGoodEvent ) continue;
129 
130  // Finds a trial SDP.
131  // Only pixels that
132  // are not isolated in time or space
133  // are considered.
134 
135  ReadmitPixel(eye);
136  info.str("");
137  info << eyerecdata.GetNSDPPixels()
138  << " pixels remaining after removing noise";
139  INFO(info);
140  // Estimating Chi_i for each Pixel using the SDP first guess
141 
142  if (eyerecdata.GetNSDPPixels() < 3 ) continue;
143 
144  neyes++;
145 
146  EstimateChi_i(eye);
147 
148  RemoveOutliers(eye); // Reject pixels according a linear
149  // time fit.
150  info.str("");
151  info << eyerecdata.GetNSDPPixels()
152  << " pixels remaining after removing outliers";
153  INFO(info);
154 
155  FindSDP(eye); // Fits a SDP
156 
157 
158 
159  if ( eyerecdata.GetNSDPPixels() < eyerecdata.GetNPulsedPixels() ) {
160 
161  unsigned int PixelsReadmited = true;
162  while ( PixelsReadmited ) {
163  PixelsReadmited = false;
164  unsigned int nopixels = eyerecdata.GetNSDPPixels();
165  // Now we use the fitted SDP
166  // to check whether we need to readmit
167  // (or remove) any pixel that was rejected (or admitted) when
168  // using the TRIAL SDP
169  fSDPFirstGuess = fSDP;
170  ReadmitPixel(eye);
171  int nReadmitted = eyerecdata.GetNSDPPixels() - nopixels;
172 
173  info.str("");
174  info << nReadmitted << " pixels readmitted.";
175  INFO(info);
176 
177  unsigned int nopixels2 = eyerecdata.GetNSDPPixels();
178  RemoveNoise(eye); // Reject pixels far from SDP
179  int nRemoved = nopixels2 - eyerecdata.GetNSDPPixels();
180 
181  info.str("");
182  info << nRemoved << " pixels removed.";
183  INFO(info);
184 
185  if ( nReadmitted != 0 || nRemoved != 0) {
186  FindSDP(eye); // Fits a new SDP
187  PixelsReadmited = true;
188  }
189  }
190  }
191  eyerecdata.SetSDP(fSDP);
192  eyerecdata.SetSDPThetaError(fSDPThetaError);
193  eyerecdata.SetSDPPhiError(fSDPPhiError);
194  eyerecdata.SetSDPCorrThetaPhi (fSDPCorrThetaPhi);
195  eyerecdata.SetSDPFitChiSquare(fChi2,fNDof);
196 
197  //--------------------------------------------
198  // Also fill the TelescopeRecData with the same values
199  // since this module isn't able to deal with compound eyes
200  // that consist of telescopes at multiple different positions
201  for (fevt::Eye::TelescopeIterator telIt = eye.TelescopesBegin(ComponentSelector::eHasData);
202  telIt != eye.TelescopesEnd(ComponentSelector::eHasData); ++telIt)
203  {
204  if (!telIt->HasRecData())
205  telIt->MakeRecData();
206  fevt::TelescopeRecData& telRecData = telIt->GetRecData();
207  telRecData.SetSDP(fSDP);
208  telRecData.SetSDPThetaError(fSDPThetaError);
209  telRecData.SetSDPPhiError(fSDPPhiError);
210  telRecData.SetSDPCorrThetaPhi(fSDPCorrThetaPhi);
211  telRecData.SetSDPFitChiSquare(fChi2, fNDof);
212  }
213  }// for eyeiter
214 
215  if (!neyes) return eContinueLoop; //no eyes worth reconstructing, next event
216  return eSuccess;
217 }
218 
219 VModule::ResultFlag FdSDPFinder::Finish(){
220  return eSuccess;
221 }
222 
223 /*
224  * \brief Find an inital guess of the SDP.
225  *
226  * Find the cross products of the pixels with a pulse
227  * Pick the one that accomodates most trackbed pixels
228  *
229  */
230 
231 utl::AxialVector FdSDPFinder::FindSDPFirstGuess(fevt::Eye& eye){
232 
233  const double trackbed = 2.0 * degree;
234  const double trackbedCut = cos(trackbed)*cos(trackbed);
235 
236  const fdet::Eye& deteye =
237  det::Detector::GetInstance().GetFDetector().GetEye(eye);
238 
240 
241  // get the candidate normal vectors (cross products of all pixels in pairs(
242  // and put them in a vector
243  // order the cross product earlier cross later
244 
245  const EyeRecData& recdata = eye.GetRecData();
246 
247  const FDetector& fdetector = Detector::GetInstance().GetFDetector();
248 
249  // transform all directions to eyeCS to avoid useless coordinate transformations
250  CoordinateSystemPtr eyeCS = fdetector.GetEye(eye).GetEyeCoordinateSystem();
251 
252  std::vector<double> candidatePixelTimes;
253  std::vector<Vector > candidatePixelDirections;
254  std::vector<std::vector<double> > candidatePixDirComponents;
255  std::vector<double> candidatePixelCharge;
256 
257  // fill vectors of pixels, which are not isolated
259  for (pixeliter = recdata.PulsedPixelsBegin();
260  pixeliter != recdata.PulsedPixelsEnd();
261  ++pixeliter) {
262 
263  if ( ! IsIsolated(*pixeliter,eye) ) {
264 
265  const fdet::Pixel& detpixel = fdetector.GetPixel(*pixeliter);
266  const fdet::Channel& detChannel = fdetector.GetChannel(*pixeliter);
267  const int telid = pixeliter->GetTelescopeId();
268  const unsigned int timeoffset = eye.GetTelescope(telid).GetTimeOffset();
269 
270  const double pixelTime = pixeliter->GetRecData().GetCentroid() +
271  double(timeoffset/detChannel.GetFADCBinSize());
272  const double charge = pixeliter->GetRecData().GetTotalCharge();
273 
274  const Vector& pixelDirection=detpixel.GetDirection();
275  pixelDirection.TransformTo(eyeCS);
276 
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));
281 
282  candidatePixDirComponents.push_back(components);
283  candidatePixelDirections.push_back(pixelDirection);
284  candidatePixelCharge.push_back(charge);
285  candidatePixelTimes.push_back(pixelTime);
286 
287  }
288 
289  }
290 
291 
292  if( candidatePixelTimes.size() < 3) {
293  fGoodEvent = false;
294  ostringstream warn;
295  warn << " ************* This event has less than 3 good pixels. Skip! ****************";
296  WARNING(warn);
297  return utl::AxialVector(0.,0.,1.,eyeCS);
298  }
299 
300  // loop on pixels to fill candidate SDPs
301 
302  std::vector <utl::AxialVector> crossProducts;
303 
304  for (unsigned int i=0;i<candidatePixelTimes.size(); i++ ) {
305 
306  const double t_1 = candidatePixelTimes[i];
307  const Vector& dir1 = candidatePixelDirections[i];
308 
309  for (unsigned int j = i; j < candidatePixelTimes.size(); ++j) {
310 
311  if (j != i) {
312 
313  const double t_2 = candidatePixelTimes[j];
314  const Vector& dir2 = candidatePixelDirections[j];
315 
316  // order the cross product : earlier cross later
317  utl::AxialVector crossprod = (t_1 < t_2) ?
318  cross(dir1,dir2) :
319  cross(dir2,dir1);
320  crossprod.Normalize();
321 
322  if ( crossprod.GetMag() != 0. )
323  crossProducts.push_back(crossprod);
324 
325  }
326  }
327  }
328 
329  // look for best trial between candidate vectors:
330  // it will be the one that accomodates most trackbed pixels
331 
332 
333  ostringstream info;
334  info << " track bed maximization (N=" << crossProducts.size() << "*"
335  << candidatePixelTimes.size() << ")="
336  << crossProducts.size()*candidatePixelTimes.size();
337  INFO(info);
338 
339  double maxTrackBed=-1.;
340  utl::AxialVector trialSDP;
341 
342  for(unsigned int k=0;k<crossProducts.size(); k++) {
343 
344  double thisTrackBed=0.;
345 
346  const utl::Vector& tmpSDP = crossProducts[k];
347 
348  const double x1 = tmpSDP.GetX(eyeCS);
349  const double y1 = tmpSDP.GetY(eyeCS);
350  const double z1 = tmpSDP.GetZ(eyeCS);
351 
352  for (unsigned int i=0;i<candidatePixelTimes.size(); i++ ) {
353 
354  const double * pixDir = &(candidatePixDirComponents[i].front());
355  const double cosTheta = x1*(*(pixDir))
356  +y1*(*(pixDir+1))
357  +z1*(*(pixDir+2));
358  const double sin2Theta = 1. - cosTheta*cosTheta;
359 
360  // --> original cut:
361  // const double d = abs (kPi/2 - acos(cosTheta));
362  // if ( d <trackbed)
363 
364  // --> same thing without acos():
365  if ( sin2Theta > trackbedCut ) {
366  if ( fFirstGuessFromCharge )
367  thisTrackBed+=candidatePixelCharge[i];
368  else
369  thisTrackBed+=1.;
370  }
371 
372  }
373 
374  if (thisTrackBed > maxTrackBed) {
375  maxTrackBed = thisTrackBed;
376  trialSDP = tmpSDP;
377  }
378 
379  }
380 
381  if( maxTrackBed <=0. ) {
382  fGoodEvent = false;
383  ostringstream warn;
384  warn << " ************* no signal/pixels in track bed!!! Skip! ****************";
385  WARNING(warn);
386  return utl::AxialVector(0.,0.,1.,eyeCS);
387  }
388 
389  return trialSDP;
390 
391 }
392 
393 /* \brief call Minuit using MinuitFunction as function to be minimized
394  */
395 
396 void FdSDPFinder::FindSDP(fevt::Eye& eye){
397 
398  fCurEye = &eye;
399 
400  const fdet::Eye& deteye =
401  Detector::GetInstance().GetFDetector().GetEye(eye);
402 
403  // use the eye coordinate system to do calculations
405 
407 
408  const int npar = 2; // number of parameters
409 
410  TMinuit theMinuit(npar); // 2 parameter fit
411 
412  theMinuit.SetPrintLevel(-1); // minuit verbosity
413  theMinuit.SetFCN(FdSDPFinder::MinuitFitFunc);
414 
415  double arglist[2]; // arguments to pass to the Minuit interpreter
416  int ierflag =0;
417 
418  arglist[0]=1; // [up]
419  theMinuit.mnexcm("SET ERR", arglist,1,ierflag);
420 
421  if (ierflag) ERROR ("Minuit SET ERR failed");
422 
423  double vstart[npar]; // inital point
424  double step[npar]; // step size
425 
426 
427  vstart[0] = fSDPFirstGuess.GetTheta(CS);
428  vstart[1] = fSDPFirstGuess.GetPhi(CS);
429 
430  ostringstream info;
431  info << "SDPn Initial guess (theta, phi): ("
432  << vstart[0]/degree << ", " << vstart[1]/degree <<")";
433  INFO(info);
434 
435  step[0]=0.01;
436  step[1]=0.01;
437 
438  theMinuit.mnparm(0,"Theta",vstart[0], step[0],0,0,ierflag);
439  theMinuit.mnparm(1,"Phi", vstart[1], step[1],0,0,ierflag);
440 
441  arglist[0]=500; // [maxcalls]
442  arglist[1]=1; // [tolerance]
443  theMinuit.mnexcm("MIGRAD", arglist ,2,ierflag);
444 
445  if (ierflag) ERROR ("Minuit MIGRAD failed");
446 
447  theMinuit.mnexcm("HESSE", arglist, 2, ierflag);
448 
449  // Check the status of the covariance matrix
450  // if bad use MINOS
451  double fmin, fedm, errdef; // unused dummies
452  int npari, nparx; //unused dummies
453  int istat = 0;
454  theMinuit.mnstat(fmin, fedm, errdef, npari, nparx, istat);
455  if (istat < 3) { // no accurate covariance matrix
456  theMinuit.mnexcm("MINOS", arglist, 2, ierflag);
457  theMinuit.mnstat(fmin, fedm, errdef, npari, nparx, istat);
458  if (istat < 3)
459  WARNING("Neither HESSE nor MINOS found accurate covariance matrix");
460  }
461 
462  double sdpTheta, sdpThetaErr;
463  double sdpPhi,sdpPhiErr;
464 
465  theMinuit.GetParameter(0,sdpTheta,sdpThetaErr);
466  theMinuit.GetParameter(1,sdpPhi,sdpPhiErr);
467 
468  info.str("");
469  info << "Fitted SDPn (theta,phi): (" << sdpTheta/degree
470  << "," << sdpPhi/degree << ")";
471  INFO(info);
472 
473  fSDP = Vector(1,sdpTheta,sdpPhi,CS, Vector::kSpherical);
474  fSDPThetaError = sdpThetaErr;
475  fSDPPhiError = sdpPhiErr;
476 
477  //Retrieve the covariance matrix
478  double covMatrix[npar][npar];
479  theMinuit.mnemat( &covMatrix[0][0], npar );
480  fSDPCorrThetaPhi = covMatrix[0][1]/sdpThetaErr/sdpPhiErr;
481 
482  fChi2 = theMinuit.fAmin;
483 
484 }
485 
486 
492 void
493 FdSDPFinder::RemoveNoise(fevt::Eye& eye)
494 {
495  EyeRecData& recdata = eye.GetRecData();
496 
497  // iterate over pixels with a pulse
498  for (EyeRecData::PixelIterator pixeliter = recdata.SDPPixelsBegin();
499  pixeliter != recdata.SDPPixelsEnd();) {
500 
501  fevt::Pixel& evtpixel = *pixeliter;
502  const fdet::Pixel& detpixel =
503  Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
504  const Vector& dir = detpixel.GetDirection();
505 
506  const double d = abs(kPi/2 - Angle(dir, fSDPFirstGuess));
507  if (d > fMaxDistance )
508  pixeliter = recdata.RemoveSDPPixel(pixeliter);
509  else ++pixeliter;
510  }
511 }
512 
513 
519 void
520 FdSDPFinder::ReadmitPixel(fevt::Eye& eye)
521 {
522  EyeRecData& recdata = eye.GetRecData();
523 
524 
525  // iterate over pixels with a pulse
526  for (EyeRecData::PixelIterator pixeliter = recdata.PulsedPixelsBegin();
527  pixeliter != recdata.PulsedPixelsEnd(); ++pixeliter) {
528 
529  fevt::Pixel& evtpixel = *pixeliter;
530  const fdet::Pixel& detpixel =
531  Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
532  const unsigned int pixel_id = evtpixel.GetId();
533  //-----------------------------
534  // Checking whether this pixel was already
535  // selected for SDP fitting.
536  bool SDPfit_pixel = false;
537  for (EyeRecData::ConstPixelIterator iter = recdata.SDPPixelsBegin();
538  iter != recdata.SDPPixelsEnd(); ++iter)
539  if (pixel_id == iter->GetId()) {
540  SDPfit_pixel = true;
541  break;
542  }
543  //-------------------------------------
544  if (SDPfit_pixel)
545  continue;
546  Vector dir = detpixel.GetDirection();
547  const double d = abs(kPi/2 - Angle(dir, fSDPFirstGuess));
548  if (d < fMaxDistance && !IsIsolated(evtpixel, eye))
549  recdata.AddSDPPixel(evtpixel);
550 
551  } // for pixel
552 }
553 
554 
555 bool
556 FdSDPFinder::IsIsolated(const fevt::Pixel& pixel, const fevt::Eye& eye)
557 {
558  const EyeRecData& recdata = eye.GetRecData();
559  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
560 
562  //----------------------------------------------------------
563  //checking for wheter the pixel is isolated in time
564  //or in space.
565 
566  //- For each triggered pixel the time distance to each of the rest
567  // of the triggered pixels is computed.
568  //- If the time distance to all triggered pixels is greater
569  // than fIsolationLimit, the pixel is considered isolated
570  // in time and excluded.
571  //- fIsolationLimit is estimated for every event. Depending
572  // on the event geometry fIsolationLimit can be as small as 1000ns.
573  // Far away showers need a bigger fIsolationLimit.
574  //- If none of the neighbour pixels triggered, then the corresponding
575  // pixel is considered isolated in space. This pixel will not be used
576  // to estimate the SDP first guess. However, it could be admitted
577  // for the final SDP fitting.
578 
579  //---------------------------------------------------
580  // Searching for the best fIsolationLimi for this
581  // particular event.
582  //
583  // The time differences among all pixels are distributed in the
584  // array timediff_bin_population[400]. The array size is 400 bins
585  // and the bin size is 500 ns.
586 
587  const int nbins = 400;
588  int timediff_bin_population[nbins]={0};
589  const double timediff_bin_size = 500.0;
590 
591  if ( fIsolationLimit == 0 ) {
592 
593  std::vector<double> candidatePixelTimes;
594  for (pixeliter = recdata.PulsedPixelsBegin();
595  pixeliter != recdata.PulsedPixelsEnd();
596  ++pixeliter){
597 
598  const fdet::Channel& detChannel = detFD.GetChannel(*pixeliter);
599  const int telid = pixeliter->GetTelescopeId();
600  const unsigned int timeoffset = eye.GetTelescope(telid).GetTimeOffset();
601 
602  const double pixelTime = pixeliter->GetRecData().GetCentroid()*detChannel.GetFADCBinSize()
603  + timeoffset;
604 
605  candidatePixelTimes.push_back(pixelTime);
606  }
607 
608 
609  for (unsigned int i=0;i<candidatePixelTimes.size(); i++ ) {
610 
611  const double t1 = candidatePixelTimes[i];
612 
613  for (unsigned int j=0;j<candidatePixelTimes.size(); j++ ) {
614 
615  if ( i==j )
616  continue;
617 
618  const double t2 = candidatePixelTimes[j];
619 
620  double timediff = std::abs(t1-t2);
621 
622  int timediff_bin = int(timediff / timediff_bin_size );
623  if (timediff_bin >= nbins )
624  continue;
625  timediff_bin_population[timediff_bin]++ ;
626  }
627  }
628 
629  // Selecting the best fIsolationLimit
630 
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];
637  }
638  }
639  fIsolationLimit = (bin_with_maximum+6) * timediff_bin_size ;
640 
641  }
642 
643 
644  const fdet::Pixel& detpixel1 = detFD.GetPixel(pixel);
645  const fdet::Channel& detChannel1 = detFD.GetChannel(pixel);
646  const int telid1 = pixel.GetTelescopeId();
647  const unsigned int timeoffset1 = eye.GetTelescope(telid1).GetTimeOffset();
648 
649  const double pixelTime1 = pixel.GetRecData().GetCentroid()*detChannel1.GetFADCBinSize()
650  + timeoffset1;
651 
652  const Vector& PixelDir1 = detpixel1.GetDirection();
653 
654  for (pixeliter = recdata.PulsedPixelsBegin();
655  pixeliter != recdata.PulsedPixelsEnd();
656  ++pixeliter){
657 
658  if (*pixeliter==pixel)
659  continue;
660 
661  const fdet::Pixel& detpixel2 = detFD.GetPixel(*pixeliter);
662  const fdet::Channel& detChannel2 = detFD.GetChannel(*pixeliter);
663  const int telid2 = pixeliter->GetTelescopeId();
664  const unsigned int timeoffset2 = eye.GetTelescope(telid2).GetTimeOffset();
665 
666  const double pixelTime2 = pixeliter->GetRecData().GetCentroid()*detChannel2.GetFADCBinSize()
667  + timeoffset2;
668 
669  const double timediff =
670  std::abs(pixelTime1 - pixelTime2);
671 
672  const Vector& PixelDir2 = detpixel2.GetDirection();
673  const double angdiff = Angle (PixelDir1, PixelDir2);
674 
675  // Checking whether the trial pixel is
676  // isolated in time or in space
677  if (timediff < fIsolationLimit && angdiff < 5* degree)
678  return false;
679 
680  } // for
681 
682  return true;
683 }
684 
685 
686 
688 void FdSDPFinder::RemoveOutliers(fevt::Eye& eye) {
689 
690 
691  if (!eye.HasRecData()) return;
692  EyeRecData& recdata = eye.GetRecData();
693 
694 
695  double TrackBed= 1.5 *degree;
696  //use all pairs to generate candidate lines
699 
700  vector<double> slope;
701  vector<double> intcpt;
702 
703  for (iter=recdata.SDPPixelsBegin();
704  iter!=recdata.SDPPixelsEnd(); ++iter){
705 
706  for (iter2= iter + 1;
707  iter2!=recdata.SDPPixelsEnd();
708  ++iter2){
709 
710  const fevt::Pixel& pix1 = *iter;
711  const fevt::Pixel& pix2 = *iter2;
712 
713  double t1 = pix1.GetRecData().GetT_i().GetNanoSecond();
714  double t2 = pix2.GetRecData().GetT_i().GetNanoSecond();
715  double chi1 = pix1.GetRecData().GetChi_i();
716  double chi2 = pix2.GetRecData().GetChi_i();
717 
718  double tmpSlope = (t1-t2) / (chi1-chi2);
719  double tmpIntcpt = t1 - tmpSlope*chi1;
720  slope.push_back(tmpSlope);
721  intcpt.push_back(tmpIntcpt);
722  }
723 
724  }// for
725 
726  if (! slope.size()) return;
727 
728  // pick the line that accomodates more trackbed pixels
729 
730  unsigned int maxNPixels=0;
731  unsigned int bestIndex=0;
732 
733  for (unsigned int i=0; i<slope.size(); i++){
734 
735  unsigned int tmpNPixels=0;
736  for (iter= recdata.SDPPixelsBegin();
737  iter!=recdata.SDPPixelsEnd();
738  ++iter){
739 
740  const fevt::Pixel& pix = *iter;
741 
742  const double chi_i = pix.GetRecData().GetChi_i();
743  const double t_i = pix.GetRecData().GetT_i().GetNanoSecond();
744 
745 
746 
747  double dchi = chi_i - (t_i - intcpt[i])/slope[i];
748 
749  if (std::abs(dchi) < TrackBed * 2) tmpNPixels++;
750 
751  } // for pixel
752 
753 
754  if (tmpNPixels> maxNPixels) {bestIndex=i; maxNPixels= tmpNPixels;}
755 
756 
757  }// for slope
758 
759  const double theSlope = slope[bestIndex];
760  const double theIntcpt = intcpt[bestIndex];
761 
762  if ( theSlope > 0 ) fSDPFirstGuess *= -1;
763 
764  // Remove outliers
765  // bool pixel_removed = false; // unused
766  for (iter=recdata.SDPPixelsBegin();
767  iter!=recdata.SDPPixelsEnd(); ){
768 
769  const fevt::Pixel& pix = *iter;
770  const double chi_i = pix.GetRecData().GetChi_i();
771  const double t_i = pix.GetRecData().GetT_i().GetNanoSecond();
772 
773  double dchi = chi_i - (t_i - theIntcpt)/theSlope;
774 
775  if (std::abs(dchi) > TrackBed * 2 && recdata.GetNSDPPixels() > 3) {
776  iter = recdata.RemoveSDPPixel(iter);
777  // pixel_removed = true; // unused
778 
779  } else ++iter;
780 
781 
782 
783  }// for pixels
784 }
785 
786 
787 
800 void
801 FdSDPFinder::MinuitFitFunc(int& /*npar*/, double* /*gin*/, double& f,
802  double* par, int /*iflag*/)
803 {
804  // fCurEye is an escamotage : we need something static for TMinuit,
805  // which needs a static function ! Ahhh ! (sa,23122003)
806  const EyeRecData& recdata = fCurEye->GetRecData();
807 
809 
810  double chisq =0;
811 
812  const fdet::Eye& deteye =
813  Detector::GetInstance().GetFDetector().GetEye(*fCurEye);
814 
815  // use the eye coordinate system (must be the same we used before)
817 
818  double& sdpTheta = par[0];
819  double& sdpPhi = par[1];
820 
821  // the trial SDP
822  Vector sdp (1,sdpTheta ,sdpPhi ,CS, Vector::kSpherical);
823 
824  // iterate over pixels with a pulse
825  unsigned int ndof =0;
826  double total_charge=0;
827 
828  for (pixeliter = recdata.SDPPixelsBegin();
829  pixeliter != recdata.SDPPixelsEnd();
830  ++pixeliter){
831 
832  const fevt::Pixel& evtpixel = *pixeliter;
833  const fdet::Pixel& detpixel =
834  Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
835 
836  Vector dir = detpixel.GetDirection();
837  dir.TransformTo(CS);
838 
839  // distance from trial plane
840  double tmp = kPi/2. - Angle( dir , sdp) ;
841 
842  // weight to assign
843  double charge = evtpixel.GetRecData().GetTotalCharge();
844 
845  // 0.35 degree from Jose's studies on laser shots
846  chisq += tmp*tmp * charge /(0.35 * degree * 0.35 * degree);
847  ndof++;
848  total_charge += charge;
849  }// for pixeliter
850 
851  // normalize chisq
852  chisq /= total_charge;
853  chisq *= ndof;
854  //
855  f= chisq;
856 
857  fNDof = ndof -2 ;
858 }
859 
860 void
861 FdSDPFinder::EstimateChi_i(fevt::Eye& eye)
862 {
863  fevt::EyeRecData& recdata = eye.GetRecData();
864  const fdet::Eye& deteye =
865  det::Detector::GetInstance().GetFDetector().GetEye(eye);
866 
867  // do all calculation in the eye reference system
869 
870  // iterate over pulsed pixels
871  for (fevt::EyeRecData::PixelIterator pixeliter = recdata.PulsedPixelsBegin();
872  pixeliter != recdata.PulsedPixelsEnd(); ++pixeliter) {
873 
874  fevt::Pixel& evtpixel = *pixeliter;
875  const fdet::Pixel& detpixel =
876  det::Detector::GetInstance().GetFDetector().GetPixel(evtpixel);
877  const fdet::Channel& detChannel =
878  det::Detector::GetInstance().GetFDetector().GetChannel(evtpixel);
879  const double timebinsize = detChannel.GetFADCBinSize();
880 
881 
882  // time correction for different eyes
883  const int telid = evtpixel.GetTelescopeId();
884  const unsigned int timeoffset = eye.GetTelescope(telid).GetTimeOffset();
885  const double t_i =
886  timebinsize * evtpixel.GetRecData().GetCentroid() + timeoffset;
887 
888  //----------------------------------------------
889  //estimating Chi_i
890 
891  Vector pixeldir = detpixel.GetDirection();
892  pixeldir.TransformTo(cs);
893 
894  Vector vertical(0,0,1, cs, Vector::kCartesian);
895  Vector horizontalWithinSDP = cross(fSDPFirstGuess, vertical);
896  horizontalWithinSDP /= horizontalWithinSDP.GetR(cs);
897 
898 
899  // subtract component parallel to sdp
900  Vector chi_i_vector = pixeldir - (fSDPFirstGuess * pixeldir) * fSDPFirstGuess;
901  chi_i_vector.TransformTo(cs);
902  // chi_i_vector.Normalize();
903  chi_i_vector /= chi_i_vector.GetR(cs);
904  const double chi_i = Angle(chi_i_vector, horizontalWithinSDP);
905 
906  evtpixel.GetRecData().SetChi_i(chi_i);
907  evtpixel.GetRecData().SetT_i(t_i, 100);
908 
909  }
910 }
911 
912 
913 // Configure (x)emacs for this file ...
914 // Local Variables:
915 // mode:c++
916 // compile-command: "make -C .. FdSDPFinderOG/FdSDPFinder.o -k"
917 // End:
AxialVector cross(const Vector &l, const Vector &r)
vector cross product
Definition: OperationsAV.h:32
Telescope & GetTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Telescope by Id, throw exception if not existent.
Definition: FEvent/Eye.cc:57
Branch GetTopBranch() const
Definition: Branch.cc:63
unsigned int GetId() const
Definition: FEvent/Eye.h:54
const utl::Vector & GetDirection() const
pointing direction of this pixel
double GetChi_i() const
Definition: PixelRecData.h:117
void SetSDPFitChiSquare(const double sdpChi2, const unsigned int ndof)
void SetSDPPhiError(const double sdpPhiError)
Definition: EyeRecData.h:223
fSDPThetaError(t.GetSDPThetaError())
const double degree
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)
Definition: EyeRecData.h:229
unsigned int GetTimeOffset() const
Time offset of this Telescope compared to fevt::Header::GetTime [ns].
bool HasRecData() const
Definition: FEvent/Eye.h:116
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
PixelIterator PulsedPixelsEnd()
Definition: EyeRecData.h:121
bool HasFEvent() const
double GetR(const CoordinateSystemPtr &coordinateSystem) const
radius r in spherical coordinates coordinates (distance to origin)
Definition: BasicVector.h:257
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
Definition: FDetector.cc:198
void MakeRecData()
Definition: FEvent/Eye.cc:145
EyeIterator EyesEnd(const ComponentSelector::Status status)
Definition: FEvent.h:66
double GetMag() const
Definition: AxialVector.h:56
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void SetT_i(const double t_i, const double error)
Definition: PixelRecData.h:119
const unsigned int npar
Definition: UnivRec.h:75
void Init()
Initialise the registry.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Definition: FDetector.cc:68
Detector description interface for Eye-related data.
Definition: FDetector/Eye.h:45
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Definition: FEvent.h:55
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
void AddSDPPixel(fevt::Pixel &pixel)
add a pixel to the list of SDP pixels
Definition: EyeRecData.h:149
PixelIterator PulsedPixelsBegin()
Definition: EyeRecData.h:119
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
boost::indirect_iterator< ConstInternalPixelIterator, const Pixel & > ConstPixelIterator
Const iterator over pixels used in reconstruction.
Definition: EyeRecData.h:117
void SetSDP(const utl::AxialVector &vec)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
unsigned int GetId() const
Definition: FEvent/Pixel.h:31
Class representing a document branch.
Definition: Branch.h:107
PixelIterator SDPPixelsBegin()
Definition: EyeRecData.h:139
Fluorescence Detector Pixel event.
Definition: FEvent/Pixel.h:28
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
fSDPPhiError(t.GetSDPPhiError())
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
utl::TimeInterval GetT_i() const
Definition: PixelRecData.h:124
constexpr double kPi
Definition: MathConstants.h:24
double abs(const SVector< n, T > &v)
void SetSDPCorrThetaPhi(double sdpCorrThetaPhi)
Definition: EyeRecData.h:226
unsigned int GetTelescopeId() const
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
void SetSDPPhiError(const double sdpPhiError)
const Channel & GetChannel(const fevt::Channel &eventChannel) const
Get fdet::Channel from fevt::Channel.
Definition: FDetector.cc:161
Telescope-specific shower reconstruction data.
void SetSDPThetaError(const double sdpThetaError)
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
Definition: FEvent/Eye.h:72
unsigned int GetNPulsedPixels() const
Get number of pulsed pixels.
Definition: EyeRecData.h:137
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
Top of Fluorescence Detector event hierarchy.
Definition: FEvent.h:33
a second level trigger
Definition: XbT2.h:8
Eye-specific shower reconstruction data.
Definition: EyeRecData.h:65
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
unsigned int GetTelescopeId() const
Definition: FEvent/Pixel.h:32
boost::indirect_iterator< InternalPixelIterator, fevt::Pixel & > PixelIterator
Iterator over pixels used in reconstruction.
Definition: EyeRecData.h:113
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
fSDP(t.GetSDP())
double GetFADCBinSize() const
double GetTotalCharge() const
integrated pulse charge
Definition: PixelRecData.h:68
Description of a pixel.
Vector object.
Definition: Vector.h:30
void SetSDPThetaError(const double sdpThetaError)
Definition: EyeRecData.h:220
void SetSDP(const utl::AxialVector &vec)
Definition: EyeRecData.h:218
AxialVector object.
Definition: AxialVector.h:30
PixelIterator SDPPixelsEnd()
Definition: EyeRecData.h:143
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
double GetNanoSecond() const
Get integer number of nanoseconds past seconds boundary.
Definition: TimeInterval.cc:25
double GetCentroid() const
Definition: PixelRecData.h:78
unsigned int GetNSDPPixels() const
Get number of SDP pixels.
Definition: EyeRecData.h:165
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
PixelIterator RemoveSDPPixel(PixelIterator it)
Remove a pixel from the list of SDP pixels.
Definition: EyeRecData.h:161
void SetChi_i(const double chi_i)
Definition: PixelRecData.h:114
PixelRecData & GetRecData()
Definition: FEvent/Pixel.h:40
void SetSDPCorrThetaPhi(double sdpCorrThetaPhi)
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130

, generated on Tue Sep 26 2023.