BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
EtsFixing.cxx
Go to the documentation of this file.
1#include "EtsFixing.h"
2#include "TFile.h"
3#include "TTree.h"
4
5static const int NLastBackup = 10;
6static const long OneSecVar = 2000000;
7static const long ShiftThreshold = OneSecVar * 0.5;
8
9// static int _debug = 1;
10// static TFile* _file = NULL;
11// static TTree* _tree = NULL;
12// static int _count = 0;
13// static int _event;
14// static int _time;
15// static int _pileup;
16// static long _t1;
17// static long _rawt1;
18// static long _tdiff = 0;
19// static float _slope;
20
21EtsFixing::EtsFixing( int preRefCount, double factor )
22 : m_nPre( preRefCount )
23 , m_factor( factor )
24 , m_t0Sec( 0 )
25 , m_t0SecLocal( 0 )
26 , m_count( 0 )
27 , m_refSlope( 0.0 )
28 , m_critical( OneSecVar + 999 )
29 , m_pileup( 0 ) {
30 m_preEvt = new int[m_nPre];
31 m_preSec = new int[m_nPre];
32 m_preT1 = new long[m_nPre];
33
34 m_preT1Sec = new int[m_nPre];
35 m_preT1Old = new long[m_nPre];
36 m_prePileup = new long[m_nPre];
37
38 for ( int i = 0; i < m_nPre; ++i )
39 {
40 m_preEvt[i] = -999;
41 m_preSec[i] = -999;
42 m_preT1[i] = -999;
43
44 m_preT1Sec[i] = -999;
45 m_preT1Old[i] = -999;
46 m_prePileup[i] = -999;
47 }
48
49 m_lastEvt = new int[NLastBackup];
50 m_lastT1 = new long[NLastBackup];
51
52 for ( int i = 0; i < NLastBackup; ++i )
53 {
54 m_lastEvt[i] = -999;
55 m_lastT1[i] = -999;
56 }
57
58 // if (_debug) {
59 // _file = new TFile("fff.root", "RECREATE");
60 // _tree = new TTree("ff", "for test");
61 // _tree->Branch("count", &_count);
62 // _tree->Branch("event", &_event);
63 // _tree->Branch("time", &_time);
64 // _tree->Branch("pileup",&_pileup);
65 // _tree->Branch("t1", &_t1, "t1/L");
66 // _tree->Branch("rawt1", &_rawt1, "rawt1/L");
67 // _tree->Branch("tdiff", &_tdiff, "tdiff/L");
68 // _tree->Branch("slope", &_slope, "slope/F");
69 // }
70}
71
73 delete[] m_preEvt;
74 delete[] m_preSec;
75 delete[] m_preT1;
76
77 delete[] m_lastEvt;
78 delete[] m_lastT1;
79
80 delete[] m_preT1Sec;
81 delete[] m_preT1Old;
82 delete[] m_prePileup;
83
84 // if (_debug) {
85 // _file->Write();
86 // _file->Close();
87 // delete _file;
88 // }
89}
90
92 long t1Old = header->etsT1();
93
94 if ( t1Old == 0 ) { return; }
95
96 int evtNo = header->eventNumber();
97 int tnSec = header->time() - m_t0Sec;
98 long t1NanoSec = t1Old % OneSecVar;
99 long t1New = t1NanoSec; // tnSec*OneSecVar + t1NanoSec;
100
101 header->setRawEtsT1( t1Old );
102
103 if ( m_count != 0 )
104 {
105
106 int curIdx = tnSec % m_nPre;
107
108 int preIdx = curIdx;
109 int secShift = 0;
110 if ( tnSec != m_preSec[preIdx] )
111 {
112 preIdx = ( preIdx + m_nPre - 1 ) % m_nPre;
113 secShift = 1;
114 while ( m_preEvt[preIdx] == -999 ||
115 m_preSec[preIdx] < m_preSec[( preIdx + 1 ) % m_nPre] )
116 {
117 preIdx = ( preIdx + m_nPre - 1 ) % m_nPre;
118 ++secShift;
119 }
120 if ( ( m_preSec[preIdx] + secShift ) <= ( tnSec - m_nPre ) )
121 { secShift += m_nPre * ( ( tnSec - secShift - m_preSec[preIdx] ) / m_nPre ); }
122 // if (_debug > 2) std::cout << tnSec << ", " << m_preSec[preIdx] << ", " << secShift <<
123 // std::endl;
124 }
125 t1New += ( m_preT1[preIdx] / OneSecVar + secShift ) * OneSecVar;
126 // if (_debug > 1) std::cout << __LINE__ << ": " << t1New << std::endl;
127
128 /// fix with ideal slope
129 int eDiff = evtNo - m_preEvt[preIdx];
130 long tDiff = t1New - m_preT1[preIdx];
131 long t1Expect = m_preT1[preIdx] + m_refSlope * eDiff;
132 long t1Shift = t1New - t1Expect;
133 if ( t1Shift > ShiftThreshold )
134 {
135 t1New -= OneSecVar;
136 tDiff -= OneSecVar;
137 }
138 else if ( t1Shift < -ShiftThreshold )
139 {
140 t1New += OneSecVar;
141 tDiff += OneSecVar;
142 }
143 // if (_debug) _tdiff = t1New - t1Expect;
144 // if (_debug > 1) std::cout << __LINE__ << ": " << t1New << std::endl;
145
146 /// adjust with event build time
147 if ( tnSec - m_t0SecLocal > 3 )
148 {
149 long tXX = long( tnSec ) * OneSecVar - t1New -
150 long( tnSec - t1Old / OneSecVar ) * OneSecVar * ( m_factor - 1 );
151 // if (_debug > 2) std::cout << "xxx: " << tnSec << ", " << m_critical << ", " << tXX <<
152 // std::endl; expected range: (-m_critical, OneSecVar-m_critical], with a toleration of
153 // 0.04s
154 while ( tXX < -m_critical - OneSecVar * 0.04 )
155 {
156 t1New -= OneSecVar;
157 tDiff -= OneSecVar;
158 tXX += OneSecVar;
159 }
160 while ( tXX > OneSecVar * 1.04 - m_critical )
161 {
162 t1New += OneSecVar;
163 tDiff += OneSecVar;
164 tXX -= OneSecVar;
165 }
166 }
167 else
168 {
169 if ( secShift == 1 )
170 {
171 m_critical = t1New - long( tnSec - 1 ) * OneSecVar;
172 // if (_debug > 2) std::cout << "zzz: " << tnSec << ", " << t1New << ", " << t1Old <<
173 // std::endl;
174 }
175 }
176 // if (_debug > 1) std::cout << __LINE__ << ": " << t1New << std::endl;
177
178 /// fix with neighboring event
179 bool noNeighbor = true;
180 int nearestIdx = NLastBackup - 1;
181 int nearestDE = 10000000;
182 for ( int i = nearestIdx; i >= 0; --i )
183 {
184 int lidx = ( m_count + i ) % NLastBackup;
185 int lediff = evtNo - m_lastEvt[lidx];
186 if ( abs( lediff ) < 20 )
187 {
188 long ltdiff = t1New - m_lastT1[lidx];
189 /// the time difference should not be too large for very near (event id) events
190 while ( ltdiff > ShiftThreshold )
191 {
192 t1New -= OneSecVar;
193 tDiff -= OneSecVar;
194 ltdiff -= OneSecVar;
195 }
196 while ( ltdiff < -ShiftThreshold )
197 {
198 t1New += OneSecVar;
199 tDiff += OneSecVar;
200 ltdiff += OneSecVar;
201 }
202 if ( lediff > 0 )
203 {
204 while ( ltdiff < 0 )
205 {
206 t1New += OneSecVar;
207 tDiff += OneSecVar;
208 ltdiff += OneSecVar;
209 }
210 }
211 else
212 {
213 while ( ltdiff > 0 )
214 {
215 t1New -= OneSecVar;
216 tDiff -= OneSecVar;
217 ltdiff -= OneSecVar;
218 }
219 }
220 noNeighbor = false;
221 break;
222 }
223 else
224 {
225 if ( abs( lediff ) < nearestDE ) { nearestIdx = i; }
226 }
227 }
228 // if (_debug > 1) std::cout << __LINE__ << ": " << t1New << std::endl;
229
230 /// use nearest event if no neighboring event is found
231 if ( noNeighbor )
232 {
233 int lidx = ( m_count + nearestIdx ) % NLastBackup;
234 int lediff = evtNo - m_lastEvt[lidx];
235 long ltdiff = t1New - m_lastT1[lidx];
236 /// in case of negative or abnormal slope
237 if ( lediff > 0 )
238 {
239 while ( ltdiff * 1.0 / lediff < m_refSlope * 0.2 )
240 {
241 t1New += OneSecVar;
242 tDiff += OneSecVar;
243 ltdiff += OneSecVar;
244 if ( ltdiff > OneSecVar && ltdiff * 1.0 / lediff > m_refSlope * 5 )
245 {
246 t1New -= OneSecVar;
247 tDiff -= OneSecVar;
248 ltdiff -= OneSecVar;
249 break;
250 }
251 }
252 }
253 else
254 {
255 while ( ltdiff * 1.0 / lediff > m_refSlope * 5 )
256 {
257 t1New += OneSecVar;
258 tDiff += OneSecVar;
259 ltdiff += OneSecVar;
260 }
261 while ( ltdiff > 0 )
262 {
263 t1New -= OneSecVar;
264 tDiff -= OneSecVar;
265 ltdiff -= OneSecVar;
266 }
267 while ( ltdiff * 1.0 / lediff < m_refSlope * 0.2 )
268 {
269 t1New -= OneSecVar;
270 tDiff -= OneSecVar;
271 ltdiff -= OneSecVar;
272 }
273 }
274 }
275 // if (_debug > 1) std::cout << __LINE__ << ": " << t1New << std::endl;
276
277 /// update slope with reliable events
278 float curSlope = ( 1.0 * tDiff ) / eDiff;
279 if ( curSlope > 0 )
280 {
281 if ( m_count > 30 )
282 {
283 float guard = curSlope / m_refSlope;
284 if ( guard > 0.75 && guard < 1.5 ) { m_refSlope = m_refSlope * 0.9 + curSlope * 0.1; }
285 }
286 else { m_refSlope = ( m_refSlope * ( m_count - 1 ) + curSlope ) / m_count; }
287 }
288
289 /// update parameters for future event
290 /// Note: DO NOT use the finalT1 here. t1New and finalT1 are not consistent
291 if ( secShift == 1 )
292 {
293 // do not update these parameters when an event comes earlier more than 1 second
294 m_preEvt[curIdx] = evtNo;
295 m_preSec[curIdx] = tnSec;
296 m_preT1[curIdx] = t1New;
297 }
298 m_lastEvt[m_count % NLastBackup] = evtNo;
299 m_lastT1[m_count % NLastBackup] = t1New;
300
301 /// Refined fixing of ETS with the factor (1.0000115 by default)
302 if ( t1New != t1Old )
303 {
304 int t1Sec = t1New / OneSecVar;
305 int fIdx = t1Sec % m_nPre;
306 if ( t1Sec == m_preT1Sec[fIdx] ) { m_pileup = m_prePileup[fIdx]; }
307 else
308 {
309 for ( int i = 1; i < m_nPre; ++i )
310 {
311 int pT1Sec = t1Sec - i;
312 int pFIdx = ( pT1Sec + m_nPre ) % m_nPre;
313 if ( pT1Sec == m_preT1Sec[pFIdx] )
314 {
315 int fTotalPileup = t1Sec - t1Old / OneSecVar;
316 int pTotalPileup = m_preT1Sec[pFIdx] - m_preT1Old[pFIdx] / OneSecVar;
317 if ( fTotalPileup != pTotalPileup )
318 {
319 m_pileup = m_prePileup[pFIdx] + long( fTotalPileup - pTotalPileup ) * OneSecVar;
320 }
321 else
322 { // the GPS clock is recovered
323 m_pileup = 0;
324 }
325 break;
326 }
327 }
328 m_preT1Sec[fIdx] = t1Sec;
329 m_preT1Old[fIdx] = t1Old;
330 m_prePileup[fIdx] = m_pileup;
331 }
332 long finalT1 = t1New + ( m_factor - 1.0 ) * m_pileup;
333 if ( finalT1 > 0 ) { header->setEtsT1( finalT1 ); }
334 else { header->setEtsT1( 0 ); }
335 }
336
337 // if (_debug > 1) std::cout << "event " << evtNo << " : "
338 // << header->etsT1() << " - " << header->rawEtsT1()
339 // << " = " << long(header->etsT1()) - long(header->rawEtsT1())
340 // << ", " << m_refSlope
341 // << std::endl;
342 }
343 else
344 { // first event
345 int firstSec = t1Old / OneSecVar;
346 int firstIdx = firstSec % m_nPre;
347 m_t0Sec = header->time() - firstSec;
348 m_t0SecLocal = firstSec;
349 m_preEvt[firstIdx] = evtNo;
350 m_preSec[firstIdx] = firstSec;
351 m_preT1[firstIdx] = t1Old;
352
353 m_lastEvt[0] = evtNo;
354 m_lastT1[0] = t1Old;
355
356 m_pileup = 0;
357 m_preT1Sec[firstIdx] = firstSec;
358 m_preT1Old[firstIdx] = t1Old;
359 m_prePileup[firstIdx] = 0;
360 }
361
362 ++m_count;
363
364 // if (_debug) {
365 // _count = m_count;
366 // _event = header->eventNumber();
367 // _time = header->time();
368 // _pileup = m_pileup/OneSecVar;
369 // _t1 = header->etsT1();
370 // _rawt1 = header->rawEtsT1();
371 // _slope = m_refSlope;
372 // _tree->Fill();
373 // }
374}
virtual ~EtsFixing()
Definition EtsFixing.cxx:72
EtsFixing(int preRefCount=30, double factor=1.0000115)
Definition EtsFixing.cxx:21
void fixT1(Event::EventHeader *header)
Definition EtsFixing.cxx:91
int eventNumber() const
Retrieve event number.
void setEtsT1(unsigned long value)
Update ETS.