HdAxisFinder.cc
Go to the documentation of this file.
1 
10 #include "HdAxisFinder.h"
11 
12 #include <det/Detector.h>
13 #include <fdet/FDetector.h>
14 #include <sdet/SDetector.h>
15 
16 #include <evt/Event.h>
17 #include <evt/ShowerRecData.h>
18 #include <evt/ShowerFRecData.h>
19 
20 #include <fdet/Channel.h>
21 #include <fdet/Eye.h>
22 #include <fdet/Pixel.h>
23 
24 #include <fevt/Eye.h>
25 #include <fevt/EyeHeader.h>
26 #include <fevt/EyeRecData.h>
27 #include <fevt/FEvent.h>
28 #include <fevt/Pixel.h>
29 #include <fevt/PixelRecData.h>
30 #include <fevt/Telescope.h>
31 
32 #include <fwk/CoordinateSystemRegistry.h>
33 #include <fwk/CentralConfig.h>
34 
35 #include <sevt/SEvent.h> // define type `struct sevt::SEvent'
36 #include <sevt/StationRecData.h> // to get the station RecData
37 #include <sevt/Station.h>
38 
39 #include <utl/ErrorLogger.h>
40 #include <utl/MathConstants.h>
41 #include <utl/PhysicalConstants.h>
42 #include <utl/Reader.h>
43 #include <utl/Transformation.h>
44 
45 #include <TMinuit.h>
46 
47 #include <iostream>
48 
49 using namespace det;
50 using namespace std;
51 using namespace fwk;
52 using namespace utl;
53 using namespace fevt;
54 using namespace sevt;
55 using namespace evt;
56 using namespace HdAxisFinderUU;
57 
58 fevt::Eye * HdAxisFinder::fCurEye = 0;
59 sevt::SEvent * HdAxisFinder::fCurSEvent = 0 ;
60 double HdAxisFinder::fChi2 = 0;
61 double HdAxisFinder::fMyChiSquare = 0;
62 unsigned int HdAxisFinder::fNDof = 0;
63 
65 
67 // Note: I need to check all eyes were recon.
68 // ie. may be an stereo event reconstructs only one of the eyes...
69 // Anyway, use the same cuts as the axis guesser:
70  CentralConfig* cc = CentralConfig::GetInstance();
71 
72  Branch topB =
73  cc->GetTopBranch("HdAxisFinder");
74 
75  if (!topB) {
76  ERROR("Could not find branch HdAxisFinder");
77  return eFailure;
78  }
79 
80 
81  Branch minPixB = topB.GetChild("MinPixels");
82  if (!minPixB) {
83  ERROR("Could not find branch MinPixels");
84  return eFailure;
85  }
86  minPixB.GetData(fMinPixels);
87 
88 
89  return eSuccess;
90 }
91 
92 VModule::ResultFlag HdAxisFinder::Run(evt::Event& event){
93 // INFO("HdAxisFinder::Run()");
94 
95  fMinuitFailed = false;
96 
97  fevt::FEvent& fevent = event.GetFEvent();
98  sevt::SEvent& sevent= event.GetSEvent();
99 
100  fCurSEvent = &sevent; // acrobacy for TMinuit
101 
103 
104 /* I'm NOT filling the "event" core, so forget about this:
105  // Before anything, check if it's an stereo event
106  int MaxNPixels = 0, numEyes = 0;
107  int fHotEyeId = 0;
108  for (eyeiter= fevent.EyesBegin();
109  eyeiter != fevent.EyesEnd();
110  ++eyeiter){
111 
112  fevt::Eye& eye = *eyeiter;
113  fevt::EyeRecData& eyerecdata = eye.GetRecData();
114  int numPix = eyerecdata.GetNTimeFitPixels() ;
115 
116 // cout << "Eye #" << eye.GetId() << " has " << numPix << " pixels." << endl ;
117 
118  if (numPix > MaxNPixels) {
119  MaxNPixels = numPix ;
120  fHotEyeId = eye.GetId();
121  }
122  ++numEyes;
123  }
124 
125  bool Stereo = false;
126  if (numEyes > 1) Stereo = true ;
127  // End of checking on stereo event
128  */
129 
130  for (eyeiter= fevent.EyesBegin();
131  eyeiter != fevent.EyesEnd();
132  ++eyeiter){
133 
134  fevt::Eye& eye = *eyeiter;
135 
136  fevt::EyeRecData& eyerecdata = eye.GetRecData();
137 
138  if(eyerecdata.GetNTimeFitPixels() < fMinPixels) continue ;
139 
140  fSDP = eyerecdata.GetSDP();
141 
142  fCurEye = &eye; // acrobacy for TMinuit
143 
144  this->FillPoints(eye);
145 
146  fChi0First = eyerecdata.GetChiZero() ;
147  fRpFirst = eyerecdata.GetRp() ;
148  fT0First = eyerecdata.GetTZero() ;
149 
150  this->FindAxis(eye);
151 
152 // change this. If Minuit failed, skip all the following
153 /*
154  if (fMinuitFailed && (!Stereo || (Stereo && (eye.GetId()==fHotEyeId))))
155  return eContinueLoop;
156 // if (fMinuitFailed) return eContinueLoop;
157  */
158  if (fMinuitFailed) continue;
159 // if it's an stereo event and both eyes failed
160 // the event will be cut next in the Final Cut (or it should...)
161 // right, but what if this happens in the iteration AFTER the final cut...
162 
163  eyerecdata.SetChiZero(fChi0,fChi0Error);
164  eyerecdata.SetTZero(fT0,fT0Error);
165  eyerecdata.SetRp(fRp,fRpError);
166 // Do this later!
167 // eyerecdata.SetTimeFitChiSquare(fChi2,fNDof);
168 
169  // calculate axis parameters.
170  CoordinateSystemPtr eyeCS =
171  det::Detector::GetInstance().GetFDetector().GetEye(eye).GetEyeCoordinateSystem();
172 
173  Vector vertical(0,0,1,eyeCS);
174  Vector horizontalInSDP = cross(fSDP,vertical); // horizontal
175  horizontalInSDP.Normalize();
176 
177  // check the horizontal points outward
178  if ( horizontalInSDP.GetPhi(eyeCS) < 0 ||
179  horizontalInSDP.GetPhi(eyeCS) > kPi) {
180  fSDP *= -1;
181  horizontalInSDP *= -1;
182  }
183 
184  Transformation rot (Transformation::Rotation(-fChi0,fSDP, eyeCS));
185 
186  Vector axis (rot* horizontalInSDP); // apply rotation
187  if (axis.GetTheta(eyeCS) > (kPi/2)) axis *= -1; // reflect if necessary
188  axis.Normalize();
189 
190  CoordinateSystemPtr siteCS =
191  det::Detector::GetInstance().GetSiteCoordinateSystem();
192 
193  /* Minimize print outs...
194  cout << "(Hybrid) Axis(Theta,Phi)(siteCS) : " << axis.GetTheta( siteCS) / degree
195  << "," << axis.GetPhi( siteCS) /degree << " [deg]" <<endl; ;
196  cout << "(Hybrid) Axis(Theta,Phi)(eyeCS) : " << axis.GetTheta( eyeCS) / degree
197  << "," << axis.GetPhi( eyeCS) /degree << " [deg]" <<endl; ;
198  */
199 
200  Vector core_eye_vec = fRp / sin( kPi - fChi0) * horizontalInSDP;
201 
202  Point eyeposition =
203  det::Detector::GetInstance().GetFDetector().GetEye(eye).GetPosition();
204 
205  // Calc. the core at the stations height! and NOT at the Fd height.
206  // Note: still each eye keeps its right Rp, Chi0 and T0
207  //
208  // loop on stations
209  const sdet::SDetector& theSDetector = det::Detector::GetInstance().GetSDetector();
210 
212  double station_level = 0.0 ;
213  int ntanks = 0 ;
215  iter != sevent.CandidateStationsEnd(); ++iter) {
216 
217  ++ntanks ; // Actual candidate tanks!
218  const sevt::Station& station = *iter;
219  const sdet::Station& currentSt = theSDetector.GetStation(station);
220  const Point& SdPos = currentSt.GetPosition();
221  // cout << " Station " << iter->GetId() << " has elevation: " << SdPos.GetZ(eyeCS) << " m" << endl;
222 
223  station_level += SdPos.GetZ(eyeCS) ;
224  }
225 
226  if (ntanks > 0)
227  station_level /= ntanks;
228  else
229  station_level = core_eye_vec.GetZ(eyeCS) ;
230 // This is wrong: (Remember I might leave tanks there... but they're just not "candidates")
231 // station_level /= sevent.GetNumberOfStations() ;
232 // cout << "Core level = " << station_level << " m." << endl ;
233 
234  if (station_level==0) station_level = core_eye_vec.GetZ(eyeCS) ;
235  double coord_along_axis = (station_level - core_eye_vec.GetZ(eyeCS))/axis.GetZ(eyeCS) ;
236 
237  Point core = eyeposition + core_eye_vec + coord_along_axis * axis;
238 
239  /*
240  cout << "(Hybrid) Core (x,y)(eyeCS) " << core.GetX(eyeCS)<<","
241  << core.GetY(eyeCS)<< " [m]" << endl;
242 
243  cout << "(Hybrid) Core (x,y)(siteCS) " << core.GetX(siteCS)<<","
244  << core.GetY(siteCS)<< " [m]" << endl;
245  */
246 
247 // Set all the EYE rec data:
248  if (!eyerecdata.HasFRecShower()) eyerecdata.MakeFRecShower();
249  ShowerFRecData& eyerecshower = eyerecdata.GetFRecShower();
250  eyerecshower.SetAxis(axis);
251  eyerecshower.SetCorePosition(core);
252  eyerecshower.SetCoreTime(fCurEye->GetHeader().GetTimeStamp() -
253  TimeInterval(1000*100*ns), fRp, fChi0, fT0);
254 
255 /* I moved these lines to the Final Cut because they are being executed in the first pass to the Axis Finder
256 So, all tanks are there... I guess...
257 // Add these lines for the RecDataProducer:
258  for(iter=sevent.StationsBegin(); iter != sevent.StationsEnd(); ++iter)
259  {
260  if (iter->IsCandidate()){
261  eyerecshower.AddStationId( iter->GetId() );
262  }
263  }
264  */
265 
266 
267 // Fill out the "real" chi square!
268 /*
269  cout << "Compare Chi square: " << fChi2 << " (old) vs. " << fMyChiSquare << " (new) and ndof = "
270  << fNDof << " (old) vs. " << ntanks+eyerecdata.GetNTimeFitPixels()-3 << " (new) " << endl ;
271  */
272  eyerecdata.SetTimeFitChiSquare(fMyChiSquare,ntanks+eyerecdata.GetNTimeFitPixels()-3);
273 
274 /* This crap doesn't really make too much sense.
275  * Don't fill this no more!
276 
277  // Note: For the EVENT core it uses ONLY the "Hot" eye, ie the one with more pixels...
278  // when it's an stereo event.
279  if (!Stereo || (fHotEyeId == eye.GetId()) )
280  {
281  if (!event.HasRecShower()) event.MakeRecShower();
282  ShowerRecData& recshower = event.GetRecShower();
283  recshower.SetAxis(axis);
284  recshower.SetCorePosition(core);
285  }
286  */
287 
288  }// for eyeiter
289 
290  return eSuccess;
291 }
292 
293 
294 void
295 HdAxisFinder::FindAxis(fevt::Eye& /*eye*/)
296 {
297  const int npar = 3; // number of parameters
298 
299  TMinuit theMinuit(npar); // 3 parameter fit
300  // this line was leaking memory! :O(
301 // TMinuit * theMinuit = new TMinuit (npar); // 3 parameter fit
302 
303  theMinuit.SetPrintLevel(-1); // minuit verbosity
304  theMinuit.SetFCN(HdAxisFinder::MinuitFitFunc);
305 
306  double arglist[npar]; // arguments to pass to the Minuit interpreter
307  int ierflag =0;
308 
309  arglist[0]=1; // [up]
310  arglist[1]=1; // unused
311  theMinuit.mnexcm("SET ERR", arglist,1,ierflag);
312 
313  if (ierflag) ERROR ("Minuit SET ERR failed");
314 
315  static double vstart[npar]; // inital point
316  static double step[npar]; // step size
317 
318  vstart[0] = fChi0First;
319  vstart[1] = fT0First;
320  vstart[2] = fRpFirst;
321 
322  step[0]=0.001;
323  step[1]=0.001;
324  step[2]=0.001;
325 
326  theMinuit.mnparm(0,"Chi0",vstart[0], step[0],0,0,ierflag);
327  theMinuit.mnparm(1,"T0", vstart[1], step[1],0,0,ierflag);
328  theMinuit.mnparm(2,"Rp", vstart[2], step[2],0,0,ierflag);
329 
330  arglist[0]=5000; // [maxcalls]
331  arglist[1]=1; // [tolerance]
332  theMinuit.mnexcm("MIGRAD", arglist ,2,ierflag);
333 
334 // theMinuit.mncomd("SHOW COV", ierflag);
335 // theMinuit.mncomd("SHOW COR", ierflag);
336 
337 
338  if (ierflag) {
339  ERROR ("Minuit MIGRAD failed");
340  fMinuitFailed=true;
341  }
342  theMinuit.GetParameter(0,fChi0,fChi0Error);
343  theMinuit.GetParameter(1,fT0,fT0Error);
344  theMinuit.GetParameter(2,fRp,fRpError);
345 
346  /*
347  cout << "(Hybrid) TO " << fT0 << " +/- " << fT0Error << endl;
348  cout << "(Hybrid) ChiO " << fChi0/degree << " +/- " << fChi0Error/degree << endl;
349  cout << "(Hybrid) Rp " << fRp << " +/- " << fRpError << endl;
350  */
351 
352 }
353 
354 void HdAxisFinder::FillPoints(fevt::Eye& eye){
355 
356  fevt::EyeRecData& recdata = eye.GetRecData();
357 
358  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
359  const fdet::Eye& deteye = detFD.GetEye(eye);
360 
361  // do all calculation in the eye reference system
363 
364  // old stuff:
365 // const double timebinsize = fdet::Channel::GetFADCBinSize();
366 // // now this stuf is moved into the pixel loop
367 
368 //there's no need to do this for EVERY pixel!
369  fSDP.TransformTo(CS);
370  fSDP.Normalize();
371 
372  Vector vertical(0,0,1,CS,Vector::kCartesian);
373  Vector horizontalWithinSDP = cross(fSDP, vertical);
374 
375  // check that it is the one looking outward
376  if ( (horizontalWithinSDP.GetPhi(CS) < 0) || (horizontalWithinSDP.GetPhi(CS) > kPi) ) //is looking outward!
377  {
378  horizontalWithinSDP*=-1;
379  fSDP *= -1;
380  }
381  horizontalWithinSDP.Normalize();
382 
383  // iterate over pixels used for time fit, fill chi_0 and t_0
385 
386  for (pixeliter = recdata.TimeFitPixelsBegin();
387  pixeliter != recdata.TimeFitPixelsEnd();
388  ++pixeliter){
389 
390  fevt::Pixel& evtpixel = *pixeliter;
391  const fdet::Pixel& detpixel = detFD.GetPixel(evtpixel);
392  const fdet::Channel& detChannel = detFD.GetChannel(evtpixel);
393  //const double timebinsize = fdet::Channel::GetFADCBinSize();
394  const double timebinsize = detChannel.GetFADCBinSize();
395 
396  PixelRecData& pixrec = evtpixel.GetRecData();
397 
398  // time correction for different eyes
399  int telid = evtpixel.GetTelescopeId();
400  unsigned int timeoffset = eye.GetTelescope(telid).GetTimeOffset();
401 
402  double t_i = pixrec.GetCentroid() ;
403 
404  t_i *= timebinsize; // convert to nanosecond
405  t_i += timeoffset; // add offset
406 
407 /* New stuff. Replace centroid error (too small) with "my" function
408  * that parametrizes the funny steps of GAP 2003-072
409  double t_i_Err = evtpixel.GetRecData().GetCentroidError() ;
410  t_i_Err *= timebinsize;
411  */
412  double charge = pixrec.GetTotalCharge() ;
413  double noise = pixrec.GetRMS() ;
414  double duration = (pixrec.GetPulseStop() - pixrec.GetPulseStart())* timebinsize ;
415  double ratio = (charge/noise)/(duration/timebinsize) ;
416 // double t_i_Err = (200*exp(-log(4.)*duration/500)+50) * (4*exp(-log(8.)*ratio/7)+0.5) ;
417 // Implement latest parameterization
418  double t_i_Err = (180*exp(-duration/280)+50) * (3.6*exp(-ratio/3)+0.4) ;
419 // end of new parametrization of errors
420 
421  Vector pixeldir = detpixel.GetDirection();
422  pixeldir.TransformTo(CS);
423 
424  // subtract component parallel to sdp
425  Vector chi_i_vector = pixeldir - (fSDP * pixeldir) * fSDP;
426  chi_i_vector.TransformTo(CS);
427  chi_i_vector.Normalize();
428 
429  double chi_i = Angle(chi_i_vector,horizontalWithinSDP);
430 //cout << "fit values: chi_i = " << chi_i/deg << " ti = " << t_i << endl ;
431 //cout << "Pixel #" << evtpixel.GetId() << " fit values: chi_i = " << chi_i/deg << " ti = " << t_i
432 // << "; t_i error = " << t_i_Err << " [ns]" << endl ;
433  pixrec.SetChi_i(chi_i);
434  pixrec.SetT_i(t_i,t_i_Err);
435 
436  } // for pixel
437 
438 }
439 
440 
441 void
442 HdAxisFinder::MinuitFitFunc(int& /*npar*/, double* /*gin*/, double& f,
443  double* par, int /*iflag*/)
444 {
445  fevt::EyeRecData& recdata = fCurEye->GetRecData();
446 
447  fMyChiSquare = 0.0;
448 
449  double chisq =0;
450  double sdchisq = 0;
451  unsigned int ndof =0;
452 
453  double& chi_0 = par[0];
454  double& t_0 = par[1] ;
455  double& r_p = par[2] ;
456 
458  double totalcharge = 0. ;
459  double max_error = 0.0 ;
460 
461  for (iter= recdata.TimeFitPixelsBegin();
462  iter!=recdata.TimeFitPixelsEnd(); ++iter){
463 
464  const Pixel& pixel = *iter;
465  const PixelRecData& pixrec = pixel.GetRecData();
466 
467  double t_i = pixrec.GetT_i().GetNanoSecond();
468  double t_i_Err = pixrec.GetT_iError().GetInterval();
469 // cout << "(In Fit) Pixel #" << pixel.GetId() << " t_i = " << t_i << " error = " << t_i_Err << " [ns]" << endl ;
470  if (t_i_Err > max_error) max_error = t_i_Err ; // keep it to weight the tank-core distance error
471 
472  double chi_i = pixrec.GetChi_i();
473 // double chi_i_Err = 0;
474 
475  double t_expected =
476  t_0 + r_p/kSpeedOfLight * std::tan((chi_0 - chi_i) /2. );
477 
478  double tmp = t_i - t_expected ;
479 
480  double charge = pixrec.GetTotalCharge() ;
481  totalcharge += charge ;
482 /*
483  */
484 // Try just the time uncertainty for now...
485 // chisq += tmp*tmp/t_i_Err /t_i_Err ;
486  chisq += tmp*tmp/ t_i_Err / t_i_Err * charge;
487  fMyChiSquare += tmp*tmp/t_i_Err/t_i_Err ;
488  ++ndof;
489 
490  }// for iter
491 
492  int npixels = recdata.GetNTimeFitPixels() ;
493  chisq *= npixels ;
494 // chisq /= recdata.GetNTimeFitPixels() ;
495  chisq /= totalcharge ;
496 
497 //cout << "fd chi sq. = " << chisq << endl ;
498  // Get all the Eye info: Rp vector, axis, etc.
499  CoordinateSystemPtr CS =
500  Detector::GetInstance().GetFDetector().GetEye(*fCurEye).GetLocalCoordinateSystem();
501 
502  fSDP.TransformTo(CS) ;
503  Vector vertical(0,0,1,CS,Vector::kCartesian) ;
504  AxialVector horizontal = cross(fSDP, vertical) ;
505 
506  CoordinateSystemPtr EyeCS =
507  Detector::GetInstance().GetFDetector().GetEye(*fCurEye).GetEyeCoordinateSystem();
508 
509  if ( (horizontal.GetPhi(EyeCS) < 0) || (horizontal.GetPhi(EyeCS) > kPi) ) //is looking outward!
510  {
511  fSDP *= -1 ; // I need this to get the rotation right => the axis
512  horizontal *= -1 ;
513  }
514  horizontal.Normalize() ;
515 
516  Transformation rot (Transformation::Rotation(-chi_0, fSDP, CS));
517 
518  Vector axis (rot*horizontal); // apply rotation
519  if (axis.GetTheta(CS) > (kPi/2)) axis *= -1; // reflect if necessary
520  axis.Normalize();
521 
522  double theta = Angle(axis,vertical);
523 
524  Vector FdCore = r_p / sin(kPi - chi_0) * horizontal;
525  FdCore.TransformTo(CS) ;
526 
527 /*
528  cout << "(Hybrid) Axis(Theta,Phi)(eyeCS) : " << axis.GetTheta(CS) / degree
529  << "," << axis.GetPhi(CS) /degree << " [deg]" <<endl; ;
530 
531  cout << "(FD) Core (x,y)(eyeCS) " << FdCore.GetX(CS)<<","
532  << FdCore.GetY(CS)<< "," << FdCore.GetZ(CS) << " [m]" << endl;
533  */
534 
535  double EyeTriggerTime = fCurEye->GetHeader().GetTimeStamp().GetGPSNanoSecond() - 1e5 ;
536 
537  const sdet::SDetector& theSDetector = det::Detector::GetInstance().GetSDetector();
538 
539  // loop on stations now
540  totalcharge = 0. ;
541  //double max_signal = 0.0 ;
542  //double min_distance = 0.0 ;
543 
544  double baryWeight, baryWeightSum = 0.0, baryX = 0.0, baryY = 0.0, baryZ = 0.0 ;
545 
546  for (SEvent::ConstCandidateStationIterator Stiter = fCurSEvent->CandidateStationsBegin();
547  Stiter != fCurSEvent->CandidateStationsEnd(); ++Stiter) {
548 
549  const sevt::Station& station = *Stiter;
550  const sdet::Station& currentSt = theSDetector.GetStation(station);
551  const Point& SdPos = currentSt.GetPosition();
552  //cout << "Tank position: " << SdPos.GetX(CS)<<"," << SdPos.GetY(CS)<< "," << SdPos.GetZ(CS) << " [m]" << endl;
553  const Vector TankToEye(SdPos.GetX(CS), SdPos.GetY(CS), SdPos.GetZ(CS), CS);
554  const Vector FdCoreToTank = TankToEye - FdCore;
555  /*
556  cout << "(fit) Vector fd core to tank X = " << FdCoreToTank.GetX(CS)
557  << ", Y = " << FdCoreToTank.GetY(CS) <<", Z = " << FdCoreToTank.GetZ(CS) << " [m]" <<endl;
558 
559  cout << "Distance core-to-tank: " << FdCoreToTank.GetMag() << " [m]" << endl;
560  */
561 
562  const double station_level = SdPos.GetZ(CS); // for the distance to the core I need the "real" core.
563  //cout << "Core level = " << station_level << " m." << endl ;
564 
565  const double coord_along_axis = (station_level - FdCore.GetZ(CS))/axis.GetZ(CS);
566  // this "coordinate" is the delta(altitude)/cos(theta). (In the unit axis the Z coord. is equal to cos(theta)
567 
568  const Vector RealCore = FdCore + coord_along_axis * axis; //The plus sign depends only on the "direction" of the (altitude) subtraction.
569  /*
570  cout << "(real) Core (x,y)(eyeCS) " << RealCore.GetX(CS)<<","
571  << RealCore.GetY(CS)<< "," << RealCore.GetZ(CS) << " [m]" << endl;
572  */
573  const Vector CoreToTank = TankToEye - RealCore;
574 
575  const double distance = CoreToTank.GetMag(); // distance between the tank and the real core
576  //cout << "Distance to core " << distance << " [m]" << endl;
577 
578  // project tank into axis
579  const double TankProj = FdCoreToTank * axis;
580  //cout << "Distance (in axis) to core = " << TankProj << " [m] angle = " << acos(TankProj/FdCoreToTank.GetMag())/deg << endl;
581  const Vector TankToAxis = FdCoreToTank - (TankProj * axis);
582  const double d = TankToAxis.GetMag(); // distance from the tank to the shower axis
583 
584  // To get the time uncertainties copy
585  // from GAP 2003-012:
586  double sigma_t2 = (2800. + 0.0064*distance*distance)/3.5;
587 
588  const StationRecData& recdata = station.GetRecData();
589  const double t_i = recdata.GetSignalStartTime().GetGPSNanoSecond();
590 
591  // time expected at the tank:
592  double t_expected = t_0 - r_p/(kSpeedOfLight * tan(chi_0)); // time at the (Fd) core.
593  t_expected += EyeTriggerTime;
594  t_expected -= TankProj/kSpeedOfLight;
595  //cout << " First time comp. = " << TankProj/kSpeedOfLight << " [ns]" << endl ;
596 
597  // Finally, the so expected curvature correction! MAM 01/10/05
598  const double Rinit = 6500./cos(theta) ;// fixed for now
599  // add asymmetry effect GAP 2003-108 => variable (adjustable) curvature radius
600  // except for the sign of 2*R*r*cos(alpha) that I think they got wrong.
601  const double alpha = Angle(axis,CoreToTank) ;
602  const double Rcurv = sqrt(Rinit*Rinit + distance*distance - 2*Rinit*distance*cos(alpha));
603  // -------------------------------------------------------^ this sign is + in their gap note...
604  // Next step: fit the damn thing!
605  const double gamma = 1/(2*Rcurv) ;
606  t_expected += (d*d*gamma/kSpeedOfLight);
607  //cout << " Second time comp. = " << d*d*gamma/kSpeedOfLight << " [ns]" << endl;
608 
609  // also add effect to variance
610  const double crit_dist = 700./sqrt(cos(theta));
611  sigma_t2 *= 1 + pow(d/crit_dist, 4);
612 
613  const double tmp = t_i - t_expected;
614  /*
615  cout << "\tTime at tank: " << int(t_i) << " - " << int(t_expected) << " (expected) = " << (tmp) << " [ns] +/- "
616  << int(sqrt(sigma_t2)) << " trigger time: " << int(EyeTriggerTime) << endl;
617  */
618 
619  const double StTotSig = recdata.GetTotalSignal();
620  /* not doing this anymore, now I use the barycenter for minimization
621  if (StTotSig > max_signal) {
622  min_distance = distance ;
623  max_signal = StTotSig ;
624  }
625  */
626 
627  // Calc. barycenter (to cut on the hybrid core -> barycenter distance
628  baryWeight = sqrt(StTotSig);
629  baryWeightSum += baryWeight;
630  baryX += baryWeight * SdPos.GetX(CS);
631  baryY += baryWeight * SdPos.GetY(CS);
632  baryZ += baryWeight * station_level;
633 
634  totalcharge += StTotSig;
635 
636  // also here. Try only time uncertainty for the chi^2
637  //sdchisq += tmp*tmp/sigma_t2;
638  sdchisq += tmp*tmp/sigma_t2 * StTotSig;
639  fMyChiSquare += tmp*tmp/sigma_t2;
640 
641  ++ndof;
642 
643  } // end of tanks loop
644 
645  const int ntanks = ndof - npixels;
646  sdchisq *= ntanks;
647  sdchisq /= totalcharge;
648  //int ntanks = fCurSEvent->GetNumberOfStations();
649  //sdchisq /= fCurSEvent->GetNumberOfStations();
650  //sdchisq /= totalcharge;
651  //cout << "sd chi sq. = " << sdchisq << endl;
652 
653  // Add one term for minimizing the core-tank distance for the one with the largest signal.
654  // 10*m is too low, and they drive the fit always.
655  // 100*m fixed is still not optimum (but much better than 10.)
656  // Do this only on wimpy events! (MAM 03/25/05)
657  //if (ntanks < 4)
658  // Now instead always minimize the distance between the barycenter and the hybrid core:
659  //double dist_err = 100*m + max_error*kSpeedOfLight;
660  baryX /= baryWeightSum;
661  baryY /= baryWeightSum;
662  baryZ /= baryWeightSum;
663  const Vector BaryCenter(baryX, baryY, baryZ, CS);
664 
665  const double coord_along_axis = (baryZ - FdCore.GetZ(CS))/axis.GetZ(CS);
666  const Vector RealCore = FdCore + coord_along_axis * axis; //The plus sign depends on the altitude subtraction.
667  const Vector CoreToBary = BaryCenter - RealCore;
668  const double min_distance = CoreToBary.GetMag(); // distance between the tank and the real core
669 
670  const double dist_err = 500*m; // from Billoir's cut
671  const double dist_chi = min_distance*min_distance / (dist_err*dist_err);
672  ++ndof;
673 
674  sdchisq += dist_chi;
675  //chisq *= (npixels + ntanks);
676  // move on:
677 
678  chisq += sdchisq;
679 
680  //cout << "\t\t\tTotal chi^2 = " << chisq << " contribution from barycenter distance = " << dist_chi << endl;
681 
682  f = chisq;
683  fChi2 = chisq;
684  fNDof = ndof - 3;
685 }
686 
687 
689 HdAxisFinder::Finish()
690 {
691  return eSuccess;
692 }
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
Class to access station level reconstructed data.
const utl::Vector & GetDirection() const
pointing direction of this pixel
double GetChi_i() const
Definition: PixelRecData.h:117
void SetChiZero(const double chiZero, const double error)
Definition: EyeRecData.h:237
void Normalize()
Definition: Vector.h:64
int GetPulseStop() const
pulse stop (to be defined)
Definition: PixelRecData.h:72
Point object.
Definition: Point.h:32
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.
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
Detector description interface for Station-related data.
double GetRMS() const
Get the baseline RMS of the trace.
Definition: PixelRecData.h:76
unsigned int GetTimeOffset() const
Time offset of this Telescope compared to fevt::Header::GetTime [ns].
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
Definition: FDetector.cc:198
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
double GetChiZero() const
Definition: EyeRecData.h:85
int GetPulseStart() const
pulse start (to be defined)
Definition: PixelRecData.h:70
fRp(t.GetRp())
void SetCorePosition(const utl::Point &core)
EyeIterator EyesEnd(const ComponentSelector::Status status)
Definition: FEvent.h:66
sevt::StationRecData & GetRecData()
Get station level reconstructed data.
void SetT_i(const double t_i, const double error)
Definition: PixelRecData.h:119
void SetRp(const double rp, const double error)
Definition: EyeRecData.h:239
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
double pow(const double x, const unsigned int i)
double GetMag() const
Definition: Vector.h:58
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
utl::Point GetPosition() const
Tank position.
CandidateStationIterator CandidateStationsBegin()
Definition: SEvent.h:72
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
class to hold data at Station level
void MakeFRecShower()
Allocate reconstructed shower info.
Definition: EyeRecData.cc:58
utl::TimeStamp GetSignalStartTime() const
Start time of the signal.
Fluorescence Detector Pixel event.
Definition: FEvent/Pixel.h:28
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
const double ns
void SetCoreTime(const utl::TimeStamp &coreTime, const utl::TimeInterval &coreTimeErr)
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
utl::TimeInterval GetT_i() const
Definition: PixelRecData.h:124
constexpr double kPi
Definition: MathConstants.h:24
void SetAxis(const utl::Vector &axis)
double GetTotalSignal() const
Total integrated signal in VEM unit, averaged over pmts.
Active transformations of geometrical objects.
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
Definition: EyeRecData.h:330
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
const Channel & GetChannel(const fevt::Channel &eventChannel) const
Get fdet::Channel from fevt::Channel.
Definition: FDetector.cc:161
void SetTimeFitChiSquare(const double tfitChi2, const unsigned int ndof)
Definition: EyeRecData.h:232
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
fRpError(t.GetRpError())
Top of Fluorescence Detector event hierarchy.
Definition: FEvent.h:33
Eye-specific shower reconstruction data.
Definition: EyeRecData.h:65
double GetInterval() const
Get the time interval as a double (in Auger base units)
Definition: TimeInterval.h:69
const utl::AxialVector & GetSDP() const
Definition: EyeRecData.h:75
unsigned int GetTelescopeId() const
Definition: FEvent/Pixel.h:32
unsigned int GetNTimeFitPixels() const
Get number of Time Fit pixels.
Definition: EyeRecData.h:184
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
constexpr double kSpeedOfLight
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
fSDP(t.GetSDP())
double GetFADCBinSize() const
double GetGPSNanoSecond() const
GPS nanosecond.
Definition: TimeStamp.h:127
double GetRp() const
Definition: EyeRecData.h:87
double GetTotalCharge() const
integrated pulse charge
Definition: PixelRecData.h:68
Description of a pixel.
PixelIterator TimeFitPixelsEnd()
Definition: EyeRecData.h:171
Vector object.
Definition: Vector.h:30
Interface class to access to Fluorescence reconstruction of a Shower.
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
utl::TimeInterval GetT_iError() const
Definition: PixelRecData.h:125
Main configuration utility.
Definition: CentralConfig.h:51
boost::indirect_iterator< InternalStationIterator, Station & > StationIterator
Iterator over all stations.
Definition: SEvent.h:52
AxialVector object.
Definition: AxialVector.h:30
CandidateStationIterator CandidateStationsEnd()
Definition: SEvent.h:74
double GetTZero() const
Definition: EyeRecData.h:83
void SetTZero(const double tzero, const double error)
Definition: EyeRecData.h:235
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
double GetNanoSecond() const
Get integer number of nanoseconds past seconds boundary.
Definition: TimeInterval.cc:25
double GetCentroid() const
Definition: PixelRecData.h:78
PixelIterator TimeFitPixelsBegin()
Definition: EyeRecData.h:167
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
Fluorescence Detector Pixel Reconstructed Data.
Definition: PixelRecData.h:27
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
void SetChi_i(const double chi_i)
Definition: PixelRecData.h:114
PixelRecData & GetRecData()
Definition: FEvent/Pixel.h:40
boost::filter_iterator< CandidateStationFilter, ConstStationIterator > ConstCandidateStationIterator
Definition: SEvent.h:70
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130

, generated on Tue Sep 26 2023.