FindTimeOffset.cc
Go to the documentation of this file.
1 
11 #include <evt/Event.h>
12 #include <evt/ShowerFRecData.h>
13 
14 #include <fdet/FDetector.h>
15 #include <fdet/Eye.h>
16 #include <fevt/FEvent.h>
17 #include <fevt/Eye.h>
18 #include <fevt/EyeHeader.h>
19 #include <fevt/EyeRecData.h>
20 
21 #include <utl/ErrorLogger.h>
22 #include <utl/PhysicalConstants.h>
23 #include <utl/TimeStamp.h>
24 #include <utl/Transformation.h>
25 #include <utl/GeometryUtilities.h>
26 #include <utl/FileName.h>
27 
28 #include <fwk/LocalCoordinateSystem.h>
29 #include <fwk/CoordinateSystemRegistry.h>
30 
31 #include <sdet/SDetector.h>
32 #include <sdet/Station.h>
33 #include <sevt/SEvent.h>
34 #include <sevt/Station.h>
35 
36 #include <sstream>
37 #include <fstream>
38 
39 #include "FindTimeOffset.h"
40 
41 
42 namespace FindTimeOffset {
43 
45  FindTimeOffset::Run(evt::Event& event)
46  {
47  if (!event.HasFEvent())
49 
50  if (!event.HasSEvent()) {
51  INFO("No SEvent");
53  }
54  auto& sEvent = event.GetSEvent();
55 
56  bool isCeleste = false;
57  bool isRamiro = false;
58 
59  for (const auto& station : sEvent.StationsRange()) {
60  if (!station.HasRecData() || !station.IsCandidate())
61  continue;
62  if (station.GetId() == 203)
63  isCeleste = true;
64  else if (station.GetId() == 805)
65  isRamiro = true;
66  }
67 
68  if (isCeleste)
69  INFO("This is a CLF event.");
70  if (isRamiro)
71  INFO("This is an XLF event.");
72  if (isCeleste && isRamiro) {
73  INFO("Cannot have both Celeste and Ramiro; skipping.");
75  }
76  if (!isCeleste && !isRamiro) {
77  INFO("No Celeste or Ramiro found: NOT a hybrid laser event; skipping.");
79  }
80 
81  ExamineFEvent(event, isCeleste);
82 
84  }
85 
86 
87  void
88  FindTimeOffset::ExamineFEvent(const evt::Event& event, const bool isCeleste)
89  {
90  const auto& sEvent = event.GetSEvent();
91  const auto& fEvent = event.GetFEvent();
92  for (auto eye = fEvent.EyesBegin(fevt::ComponentSelector::eHasData);
93  eye != fEvent.EyesEnd(fevt::ComponentSelector::eHasData); ++eye)
94  FindOffset(sEvent, *eye, isCeleste);
95  }
96 
97 
98  template<class V>
99  std::string
100  ToString(const V& v, const utl::CoordinateSystemPtr& cs, const double unit)
101  {
102  std::ostringstream os;
103  os << '('
104  << v.GetX(cs)/unit << ", "
105  << v.GetY(cs)/unit << ", "
106  << v.GetZ(cs)/unit << ')';
107  return os.str();
108  }
109 
110 
111  void
112  FindTimeOffset::FindOffset(const sevt::SEvent& sEvent, const fevt::Eye& eye,
113  const bool isCeleste)
114  {
115  const utl::CoordinateSystemPtr& laserCs = (isCeleste) ?
118  const utl::Point laserPos(0,0,0, laserCs);
119 
120  const auto& det = det::Detector::GetInstance();
121  const auto& dEye = det.GetFDetector().GetEye(eye);
122  const auto& eyePos = dEye.GetPosition();
123  const auto& eyeCs = dEye.GetLocalCoordinateSystem();
124  const utl::Vector verticalAtEye(0,0,1, eyeCs);
125  const auto eye2Laser = laserPos - eyePos;
126 
127  const auto& eyeRec = eye.GetRecData();
128 
129  const double chi0 = eyeRec.GetChiZero();
130  const double rp = eyeRec.GetRp();
131  const double t0 = eyeRec.GetTZero();
132  const auto& sdp = eyeRec.GetSDP();
133 
134  const auto& fdEventTime = eye.GetHeader().GetTimeStamp();
135  // DV: we should look this up from fdet
136  const utl::TimeInterval fdTraceLength = 1000 * 100*utl::ns;
137  // DV: absolute reference for all relative times (ie when given as double,
138  // eg t0 or centroids etc) is the EyeHeader::TimeStamp minus the trace length
139  const auto fdEyeTriggerTime = fdEventTime - fdTraceLength;
140 
141  // DV: moved the *= -1 in original code to swap the cross product
142  const utl::Vector sdpHorizontalAtEye = Normalized(Cross(verticalAtEye, sdp));
143 
144  // obtain laser pointing by rotating horizontal Vector around the sdp normal by -chi0
145  const auto laserPointing =
146  utl::Transformation::Rotation(-chi0, sdp, eyeCs) * sdpHorizontalAtEye;
147 
148  std::ostringstream info;
149  info << "GPS = " << fdEventTime.GetGPSSecond() << " s "
150  << int(fdEventTime.GetGPSNanoSecond()) << " ns, "
151  "eye = " << eye.GetId() << ", "
152  "chi0 = " << chi0/utl::deg << " deg, "
153  "Rp = " << rp/utl::meter << " m, "
154  "t0 = " << t0/utl::ns << " ns";
155  INFO(info);
156 
157  info.str("");
158  info << "laser pointing (eye CS): "
159  "theta = " << laserPointing.GetTheta(eyeCs)/utl::deg << " deg, "
160  "phi = " << laserPointing.GetPhi(eyeCs)/utl::deg << " deg";
161  INFO(info);
162 
163  info.str("");
164  info << "laser pointing (laser CS): "
165  "theta = " << laserPointing.GetTheta(laserCs)/utl::deg << ", "
166  "phi = " << laserPointing.GetPhi(laserCs)/utl::deg << " deg";
167  INFO(info);
168 
169  const double beta = utl::Angle(-eye2Laser, laserPointing);
170 
171  // DV: delays have to be subtracted from time
172  // geometrical delay is negative since it's early
173  const utl::TimeInterval geometricDelay = -eye2Laser.GetMag() * std::cos(beta) / utl::kSpeedOfLight;
174  const utl::TimeInterval fiberDelay = 180*utl::ns;
175 
176  info.str("");
177  info << "beta = " << beta/utl::deg << " deg, "
178  "dt = " << geometricDelay/utl::ns << " ns";
179  INFO(info);
180 
181  const auto& shFRec = eyeRec.GetFRecShower();
182  const auto& fdCore = shFRec.GetCorePosition();
183  const auto& fdCoreTime = shFRec.GetCoreTime();
184  const auto& fdAxis = shFRec.GetAxis();
185 
186  for (const auto& station : sEvent.StationsRange()) {
187 
188  if (!station.HasRecData() ||
189  !station.IsCandidate() ||
190  !(station.GetId() == 203 || station.GetId() == 805))
191  continue;
192 
193  // the offset is obtained as the difference of sd and fd times in the t0 point
194  const auto& stationStart = station.GetRecData().GetSignalStartTime();
195  const auto laserStart = stationStart - fiberDelay;
196  // time at the t0 point from sd
197  const auto sdT0 = laserStart - geometricDelay;
198 
199  info.str("");
200  info << "sdT0 = " << sdT0;
201  INFO(info);
202 
203  // time at the t0 point from fd
204  const auto fdT0 = fdEyeTriggerTime + t0;
205 
206  info.str("");
207  info << "fdT0 = " << fdT0;
208  INFO(info);
209 
210  const auto offset = sdT0 - fdT0;
211 
212  info.str("");
213  info << "SD/FD time offset = " << offset/utl::ns << " ns";
214  INFO(info);
215 
216  // the alternative offset2 is the difference of the sd time and the time
217  // of the fd-reconstructed shower front arriving at the xlf/clf
218 
219  // correct the core time by a (small) axis-parallel shift delay for when the front passes through the station
220  const double coreLaserParallelDistance = fdAxis * (fdCore - laserPos);
221  const double coreLaserParallelDt = coreLaserParallelDistance / utl::kSpeedOfLight;
222  const auto fdTimeAtLaser = fdCoreTime + coreLaserParallelDt;
223 
224  const auto offset2 = laserStart - fdTimeAtLaser;
225 
226  const auto& stationPos = det.GetSDetector().GetStation(station).GetPosition();
227  const auto projectedFdCore =
228  utl::Intersection(utl::Line(fdCore, fdAxis), utl::Plane(laserPos, utl::Vector(0,0,1, laserCs)));
229  info.str("");
230  info << "(in CS of the laser)\n"
231  " fdCore = " << ToString(fdCore, laserCs, utl::m) << " m\n"
232  " fdCore_proj = " << ToString(projectedFdCore, laserCs, utl::m) << " m\n"
233  " stationPos = " << ToString(stationPos, laserCs, utl::m) << " m\n"
234  " laserPos = " << ToString(laserPos, laserCs, utl::m) << " m\n"
235  " distance(core, laser) = " << (fdCore - laserPos).GetMag()/utl::meter << " m\n"
236  " distance(core, station) = " << (fdCore - stationPos).GetMag()/utl::meter << " m\n"
237  " laserStart - fdCoreTime = " << (laserStart - fdCoreTime)/utl::ns << " ns\n"
238  " projection delay = " << coreLaserParallelDt/utl::ns << " ns";
239  INFO(info);
240 
241  info.str("");
242  info << "SD/FD time offset from core = " << offset2/utl::ns << " ns";
243  INFO(info);
244 
245  const double laserPointingElevation = utl::kHalfPi - laserPointing.GetTheta(laserCs);
246 
247  const auto outputFile = "offset.dat";
248  if (!utl::File::Exists(outputFile)) {
249  std::ofstream fout(outputFile);
250  fout << "# fd_id offset gps_sec gps_ns laser_elevation laser_azimuth signal celeste offset2 fd_core_x y z\n";
251  }
252  std::ofstream fout(outputFile, std::ios::app);
253  fout << eye.GetId() << ' '
254  << offset/utl::ns << ' '
255  << fdEventTime.GetGPSSecond() << ' '
256  << int(fdEventTime.GetGPSNanoSecond()) << ' '
257  << laserPointingElevation/utl::deg << ' '
258  << laserPointing.GetPhi(laserCs)/utl::deg << ' '
259  << station.GetRecData().GetTotalSignal() << ' '
260  << isCeleste << ' '
261  << offset2/utl::ns << ' '
262  << projectedFdCore.GetX(laserCs)/utl::m << ' '
263  << projectedFdCore.GetY(laserCs)/utl::m << ' '
264  << projectedFdCore.GetZ(laserCs)/utl::m
265  << '\n';
266 
267  }
268  }
269 
270 }
AxialVector Cross(const Vector &l, const Vector &r)
Definition: OperationsAV.h:25
unsigned int GetId() const
Definition: FEvent/Eye.h:54
Point object.
Definition: Point.h:32
Report success to RunController.
Definition: VModule.h:62
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
Definition: FEvent/Eye.cc:180
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
bool Exists(const string &filename)
Definition: FileName.cc:88
static Policy::type Rotation(const double angle, const Vector &theAxis, const CoordinateSystemPtr &theCS)
Construct from general rotation about axis.
bool HasFEvent() const
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
double GetChiZero() const
Definition: EyeRecData.h:85
Skip remaining modules in the current loop and continue with next iteration of the loop...
Definition: VModule.h:68
std::string ToString(const V &v, const utl::CoordinateSystemPtr &cs, const double unit)
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
Line Intersection(const Plane &p1, const Plane &p2)
#define V
constexpr double deg
Definition: AugerUnits.h:140
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class describing a Plane object.
Definition: Plane.h:17
constexpr double meter
Definition: AugerUnits.h:81
AxialVector Normalized(const AxialVector &v)
Definition: AxialVector.h:81
const double unit[npar]
Definition: UnivRec.h:76
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
utl::TimeStamp GetTimeStamp() const
Time of the Eye Event as tagged by FD-DAS (== eye trigger time plus pixel trace length) ...
Definition: EyeHeader.h:118
void ExamineFEvent(const evt::Event &event, const bool isCeleste)
double Angle(const Vector &left, const Vector &right)
Definition: OperationsVV.h:82
Vector object.
Definition: Vector.h:30
void FindOffset(const sevt::SEvent &sEvent, const fevt::Eye &eye, const bool isCeleste)
constexpr double ns
Definition: AugerUnits.h:162
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
constexpr double m
Definition: AugerUnits.h:121
bool HasSEvent() const
constexpr double kHalfPi
Definition: MathConstants.h:26
Definition: Line.h:17
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130

, generated on Tue Sep 26 2023.