Hall C ROOT/C++ Analyzer (hcana)
THcTimeSyncEvtHandler.cxx
Go to the documentation of this file.
1 
30 /* This version will deal with bad run coin_all_03302.dat.
31 
32 That has an event with most of a noisy set of 1190 data in ROC 3.
33 The next event has the remainder of the noisy data. It's good 1190 data
34 is in the next event.
35 So the 1190 data for the first event with noisy data should be discarded.
36 (Empty bank). The next event should be cached, and then written out when
37 the next event comes.
38 */
39 
40 #include "THcTimeSyncEvtHandler.h"
41 #include "THaEvData.h"
42 #include "THaGlobals.h"
43 #include "THcGlobals.h"
44 #include "THcParmList.h"
45 #include "THaCodaFile.h"
46 #include "THaRunBase.h"
47 #include <cstring>
48 #include <cstdio>
49 #include <cstdlib>
50 #include <iostream>
51 #include <iomanip>
52 //#include "evio.h"
53 
54 using namespace std;
55 using namespace Decoder;
56 
57 THcTimeSyncEvtHandler::THcTimeSyncEvtHandler(const char *name, const char* description)
58  : THaEvtTypeHandler(name,description)
59 {
60  ExpectedOffsetMap.clear();
61  fBadROC = -1;
62  fResync = kTRUE;
63  fBadSyncSizeTrigger = 450;
64  fCodaOut = 0;
66 }
67 
69 {
70 }
71 
72 //Float_t THcTimeSyncEvtHandler::GetData(const std::string& tag)
73 //{
74 // // A public method which other classes may use
75 // if (theDataMap.find(tag) == theDataMap.end())
76 // return 0;
77 // return theDataMap[tag];
78 //}
79 
80 
82 {
83 
84  // cout << evdata->GetEvType() << " " << evdata->GetEvLength() << endl;
85 
86  // If filtering data file, pass through all events we are not dealing with
87  if ( !IsMyEvent(evdata->GetEvType()) ) {
88  if(fCodaOut) {
90  }
91  return -1;
92  }
93 
94 
95  if (fDebug) cout << "------------------\n Time Syncronization Checker"<<endl;
96 
97  Int_t evlen = evdata->GetEvLength();
98 
99  UInt_t *rdata = (UInt_t*) evdata->GetRawDataBuffer();
100 
101  UInt_t *pslippedbank=0;
102 
103  UInt_t *p = (UInt_t*) rdata;
104  UInt_t *plast = p+*p; // Index to last word in the bank
105  Int_t roc = -1;
106  Bool_t issyncevent=kFALSE;
107 
108  CrateTimeMap.clear();
109 
110  while(p<plast) {
111  Int_t banklen = *p;
112  p++;
113  if (fDebugFile) {
114  *fDebugFile << "Bank: " << hex << *p << dec << " len: " << banklen << endl;
115  }
116  if((*p & 0xff00) == 0x1000) { // Bank Containing banks
117  if(evlen-*(p-1) > 1) { // Don't use overall event header
118  roc = (*p>>16) & 0xf;
119  if(fDebug) cout << "ROC: " << roc << " " << evlen << " " << *(p-1) << hex << " " << *p << dec << endl;
120  CrateTimeMap[roc] = new RocTimes_t;
121  }
122  p++; // Now pointing to a bank in the bank
123  } else if (((*p & 0xff00) == 0x100) && (*p != 0xC0000100)) {
124  // Bank containing integers.
125  // This is either ROC bank containing integers or
126  // a bank within a ROC containing data from modules of a single type
127  // Look for TI and FADC banks.
128  UInt_t tag = (*p>>16) & 0xffff;
129  UInt_t num = *p & 0xff;
130  UInt_t *pnext = p+banklen; // Next bank
131  p++; // First data word
132  if(tag==4) { // This is a TI blob banks
133  // Actually second word is usually a filler
134  // This could be done in a safer way, but it works for now
135  Int_t ifill = ((((*p)>>27)&0x1F) == 0x1F) ? 1 : 0;
136  if(ifill) {
137  p++; banklen--; // Skip filler word
138  }
139  CrateTimeMap[roc]->ti_evcount = p[3];
140  if(banklen>=5) { // Need bank header, at least 2 TI headers, the trailer and 2 data words
141  UInt_t titime = p[4];
142  if(fDebug) cout << roc << ": TItime " << titime << endl;
143  CrateTimeMap[roc]->has_ti_ttime = kTRUE;
144  CrateTimeMap[roc]->ti_ttime = titime;
145  }
146  } else if (tag==3801) {
147  if(fResync && num==1) {
148  issyncevent = kTRUE;
149  }
150  } else if (tag==250) { // This is an FADC bank
151  if(fDebug) cout << roc << ": FADC" << endl;
152  // Walk through this bank looking for FADC headers.
153  Int_t slot=-1;
154  while(p<pnext) {
155  UInt_t code = (*p >> 27) & 0x1F;
156  switch(code) {
157  case 0x10: // block header
158  slot = (*p >> 22) & 0x1F;
159  p++;
160  break;
161  case 0x13: // trigger time word
162  {
163  UInt_t fadctime = ((*p)&0xFFFFFF) + (((*(p+1))&0xFF)<<24);
164  if(fDebug) cout << " " << slot << ": " << fadctime << endl;
165  CrateTimeMap[roc]->fadcTimesMap[slot] = fadctime;
166  p += 2;
167  break;
168  }
169  default: // event headers, trailers, fillers, data nwords
170  p++;
171  break;
172  }
173  }
174  } else if (tag==1190) { // Bank with CAEN 1190 TDCs
175  if(roc==fBadROC) { // Point to slipped bank
176  if(fSlippage) {
177  pslippedbank = p-2;
178  // cout << banklen << " " << pslippedbank[0] << endl;
179  if(AllTdcsPresent(pslippedbank) && (banklen > fBadSyncSizeTrigger)) {
180  cout << "Slippage detected at event " << evdata->GetEvNum() << " with size " << banklen << " but not corrected" << endl;
181  }
182  } else {
183  if(AllTdcsPresent(p-2) && (banklen > fBadSyncSizeTrigger)) {
184  cout << "Slippage enabled at event " << evdata->GetEvNum() << " with size " << banklen << endl;
185  fSlippage = 1;
186  }
187  }
188  }
189  if(fDebug) cout << roc << ": 1190" << endl;
190  // Walk through this bank looking for TDC headers
191  while(p<pnext) {
192  if((*p & 0xf8000000) == 0x40000000) {
193  Int_t slot= *p & 0x1f;
194  Int_t evcount = (*p >> 5) & 0x3fffff;
195  CrateTimeMap[roc]->ftdcEvCountMap[slot] = evcount;
196  }
197  p++;
198  }
199  }
200  p=pnext; // Skip to next bank
201  } else {
202  p = p+*(p-1);
203  }
204  }
205 
206  if(fFirstTime) {
207  InitStats();
208  fLastEvent[0] = 0;
209  fFirstTime = kFALSE;
210  fDumpNew=2;
211  }
212  if(issyncevent) cout << "SYNC event" << endl;
214  fLastEventWasSync = issyncevent;
215 
216  if(!fCodaOut) return(1);
217 
218  if(fSlippage > 0) {
219  if(fLastEvent[0]>0) { // Now slipping. Output corrected event
221  // cout << "Will write corrected event" << endl;
222  } else {
223  cout << "Skipping event " << evdata->GetEvNum() << endl;
224  }
225  } else { // Not slipping yet, just copy event
226  if(fCodaOut) {
227  fCodaOut->codaWrite(evdata->GetRawDataBuffer());
228  }
229  }
230 
231  if(fWriteDelayed) {
232 
233  // Dump event before fixing
234  // if(fDumpNew > 0) {
235  // cout << "Unmodified event" << endl;
236  // for(UInt_t i=0;i<=fLastEvent[0];i++) {
237  // if(i%5 == 0) cout<<endl<<dec<<i<<": ";
238  // cout << hex << setw(10) << fLastEvent[i];
239  // }
240  // }
241  // cout << dec << endl;
242 
243  // Use fLastEvent with current pslipped bank to write out fixed event
244  // Find the 1190 bank. Shift everything beyond that bank forward or
245  // or back to make room for the 1190 bank from the current event.
246  // Copy the current 1190 bank into fLastEvent. Write the event.
247  p = fLastEvent;
248  plast = p+*p;
249  roc = -1;
250  UInt_t *poverwrite=0;
251  Int_t replacementlen;
252  Int_t banklen;
253  UInt_t *rocbanklenp=0;
254  UInt_t *roc3banklenp=0;
255 
256  // cout << "Old Size: " << fLastEvent[0] << " " << pslippedbank[0] << " ";
257  while(p<plast) {
258  banklen = *p;
259  p++;
260  if((*p & 0xff00) == 0x1000) { // Bank Containing banks
261  if((fLastEvent[0]+1)-*(p-1) > 1) { // Don't use overall event header
262  roc = (*p>>16) & 0xf;
263  rocbanklenp = p-1; // Pointer to rocbank length
264  }
265  p++; // Now pointing to a bank in the bank
266  } else if (((*p & 0xff00) == 0x100) && (*p != 0xC0000100)) {
267  // Bank containing integers.
268  // This is either ROC bank containing integers or
269  // a bank within a ROC containing data from modules of a single type
270  // Look for TI and FADC banks.
271  UInt_t tag = (*p>>16) & 0xffff;
272  UInt_t *pnext = p+banklen; // Next bank
273  p++; // First data word
274  if(tag==1190 && roc==fBadROC) { // The TDC bank we want to replace
275  replacementlen=pslippedbank[0];
276  roc3banklenp=rocbanklenp; // Save pointer to ROC bank header
277  poverwrite=p-2; // Where to write the slipped bank
278  break;
279  }
280  p=pnext;
281  } else {
282  p=p+*(p-1);
283  }
284  }
285  Int_t icopied=0;
286  if(poverwrite) {
287  // cout << banklen << endl;
288  if(replacementlen < banklen) { // Shift data after bank down
289  p = poverwrite+banklen+1; // Data to be shifted
290  // cout << "Shifting " << (p-fLastEvent) << " to " << (p+replacementlen-banklen-fLastEvent) << endl;
291  while(p<=plast) {
292  // cout << (p+replacementlen-banklen-fLastEvent) << ": " << hex << *p << dec << endl;
293  *(p + replacementlen - banklen) = *p;
294  p++;
295  icopied++;
296  }
297  } else if (replacementlen > banklen) { // Shift data up
298  p = plast;
299  // UInt_t *pfirst = poverwrite + replacementlen + 1;
300  UInt_t *pfirst = poverwrite + banklen + 1;
301  // cout << "Shifting " << (plast-pfirst+1) << " words " << (pfirst-fLastEvent) << " to " << (pfirst+replacementlen-banklen-fLastEvent) << endl;
302  while(p>=pfirst) {
303  // cout << (p+replacementlen-banklen-fLastEvent) << ": " << hex << *p << dec << endl;
304  *(p+replacementlen-banklen) = *p;
305  p--;
306  icopied++;
307  }
308  }
309  fLastEvent[0] += replacementlen-banklen; // Correct overall event length
310  *roc3banklenp += replacementlen-banklen; // Also ROC3 bank length
311  // cout << "Copying " << replacementlen+1 << " words of new bank to " << poverwrite-fLastEvent << endl;
312  for(Int_t i=0;i<=replacementlen;i++) { // Copy slipped bank into last event
313  poverwrite[i] = pslippedbank[i];
314  }
315  }
316  // cout << "New Size: " << fLastEvent[0] << " copied " << icopied << endl;
317  if(fCodaOut) {
318  // if(fDumpNew > 0) {
319  // for(UInt_t i=0;i<=fLastEvent[0];i++) {
320  // if(i%5 == 0) cout<<endl<<dec<<i<<": ";
321  // cout << hex << setw(10) << fLastEvent[i];
322  // }
323  // fDumpNew--;
324  // }
325  // cout << dec << endl;
327  if(issyncevent) { // If this was a sync event, write it out and stop rewriting
328  cout << "Run back in sync at event " << evdata->GetEvNum() << endl;
329  fCodaOut->codaWrite(evdata->GetRawDataBuffer());
330  fSlippage = 0;
331  fLastEvent[0] = 0;
333  }
334  }
335  }
336  if(fSlippage>0) { // Just handle slippage of 1 now
337  for(UInt_t i=0;i<=rdata[0];i++) {
338  fLastEvent[i]=rdata[i];
339  }
340  // cout << "Cached event " << evdata->GetEvNum() << " " << fLastEvent[0] << endl;
341  }
342 
343  return 1;
344 }
345 
351  // Assume the smallest ROC # is the TI master
352  if(fMasterRoc < 0) {
353  fMasterRoc = CrateTimeMap.begin()->first;
354  }
355  if(fDebug) cout << "fMasterRoc " << fMasterRoc << endl;
356  UInt_t master_ttime = CrateTimeMap[fMasterRoc]->ti_ttime;
357  if(fDebug) cout << "master_ttime " << master_ttime << endl;
358 
359  CrateStatsMap.clear();
360 
361  std::map<Int_t, struct RocTimes *>::iterator it = CrateTimeMap.begin();
362  while(it != CrateTimeMap.end()) {
363  Int_t roc = it->first;
364  struct RocTimes *roctimes = it->second;
365  it++;
366  CrateStatsMap[roc] = new RocStats_t;
367  CrateStatsMap[roc]->ti_ttime_offset = roctimes->ti_ttime - master_ttime;
368  if(roctimes->fadcTimesMap.size()>0) {
369  if(fDebug) cout << endl << " FADC";
370  std::map<Int_t, UInt_t>::iterator itt = roctimes->fadcTimesMap.begin();
371  Bool_t use_expected_offset = kFALSE;
372  Int_t expected_offset = 0;
373  if(ExpectedOffsetMap.find(roc) != ExpectedOffsetMap.end()) {
374  expected_offset = ExpectedOffsetMap[roc];
375  use_expected_offset = kTRUE;
376  }
377  while(itt != roctimes->fadcTimesMap.end()) {
378  Int_t slot = itt->first;
379  UInt_t fadctime = itt->second;
380  itt++;
381  if(use_expected_offset) {
382  CrateStatsMap[roc]->fadcOffsetMap[slot] = expected_offset;
383  } else {
384  CrateStatsMap[roc]->fadcOffsetMap[slot] = fadctime - master_ttime;
385  }
386  CrateStatsMap[roc]->fadcEarlySlipCountMap[slot] = 0;
387  CrateStatsMap[roc]->fadcLateSlipCountMap[slot] = 0;
388  }
389  }
390  if(roctimes->ftdcEvCountMap.size()>0) {
391  if(fDebug) cout << endl << " 1190";
392  std::map<Int_t, UInt_t>::iterator itt = roctimes->ftdcEvCountMap.begin();
393  while(itt != roctimes->ftdcEvCountMap.end()) {
394  Int_t slot = itt->first;
395  itt++;
396  CrateStatsMap[roc]->ftdcEvCountWrongMap[slot] = 0;
397  }
398  }
399  }
400 }
401 
403  fNEvents++;
404  // Get trigger time from master CrateInfo
405  UInt_t master_ttime = CrateTimeMap[fMasterRoc]->ti_ttime;
406  std::map<Int_t, RocStats_t *>::iterator it = CrateStatsMap.begin();
407  while(it != CrateStatsMap.end()) {
408  Int_t roc = it->first;
409  RocStats* rocstats = it->second;
410  it++;
411  if(CrateTimeMap[roc]->ti_ttime < master_ttime + rocstats->ti_ttime_offset) {
412  rocstats->ti_earlyslipcount++;
413  } else if(CrateTimeMap[roc]->ti_ttime > master_ttime + rocstats->ti_ttime_offset) {
414  rocstats->ti_lateslipcount++;
415  }
416  if(rocstats->fadcOffsetMap.size()>0) {
417  std::map<Int_t, Int_t>::iterator itt = rocstats->fadcOffsetMap.begin();
418  while(itt != rocstats->fadcOffsetMap.end()) {
419  Int_t slot = itt->first;
420  Int_t fadcoffset = itt->second;
421  itt++;
422  if(CrateTimeMap[roc]->fadcTimesMap[slot] < master_ttime+fadcoffset) {
423  rocstats->fadcEarlySlipCountMap[slot]++;
424  } else if(CrateTimeMap[roc]->fadcTimesMap[slot] > master_ttime+fadcoffset) {
425  rocstats->fadcLateSlipCountMap[slot]++;
426  }
427  }
428  }
429  if(rocstats->ftdcEvCountWrongMap.size()>0) {
430  std::map<Int_t, Int_t>::iterator itt = rocstats->ftdcEvCountWrongMap.begin();
431  while(itt != rocstats->ftdcEvCountWrongMap.end()) {
432  Int_t slot = itt->first;
433  itt++;
434  if(rocstats->ftdcEvCountOffsetMap.find(slot)==rocstats->ftdcEvCountOffsetMap.end()) {
435  rocstats->ftdcEvCountOffsetMap[slot] = 1;
436  }
437  Int_t cdiff = (CrateTimeMap[roc]->ti_evcount & 0x3fffff) -
438  ((CrateTimeMap[roc]->ftdcEvCountMap[slot]+rocstats->ftdcEvCountOffsetMap[slot])&0x3fffff);
439  if(sync) { // Need to do this check on the event after the sync event too
440  if(cdiff>2) {
441  cout << "ROC/Slot " << roc << "/" << slot << " count diff correction " << cdiff << endl;
442  rocstats->ftdcEvCountOffsetMap[slot] += cdiff;
443  cdiff = 0;
444  }
445  }
446  if(cdiff != 0) {
447  rocstats->ftdcEvCountWrongMap[slot]++;
448  }
449  }
450  }
451  }
452 }
454 /* Print time syncrhonization statistics.
455  Need to add an optional filename argument
456 */
457 {
458  cout << "-------------------------------------------------------------------" << endl;
459  cout << "------ TI and FADC250 trigger time synchronization statitics ------" << endl;
460  cout << "-------------------------------------------------------------------" << endl;
461  cout << " " << fNEvents << " events analyzed" << endl;
462  // Dump the map to see if we did it right.
463  std::map<Int_t, RocStats_t *>::iterator it = CrateStatsMap.begin();
464  while(it != CrateStatsMap.end()) {
465  Int_t roc = it->first;
466  struct RocStats *rocstats = it->second;
467  it++;
468  cout << "ROC " << roc << " TI Offset " << rocstats->ti_ttime_offset << " Slips " << rocstats->ti_earlyslipcount << " " << rocstats->ti_lateslipcount << endl;
469  std::map<Int_t, Int_t>::iterator itt = rocstats->fadcEarlySlipCountMap.begin();
470  while(itt != rocstats->fadcEarlySlipCountMap.end()) {
471  Int_t slot = itt->first;
472  Int_t earlyslips = itt->second;
473  Int_t lateslips = rocstats->fadcLateSlipCountMap[slot];
474  itt++;
475  if(earlyslips+lateslips > 0) { // Only print slots with slippage
476  cout << " " << slot << " " << rocstats->fadcOffsetMap[slot] << " " << earlyslips << " " << lateslips << endl;
477  }
478  }
479  std::map<Int_t, Int_t>::iterator itw = rocstats->ftdcEvCountWrongMap.begin();
480  while(itw != rocstats->ftdcEvCountWrongMap.end()) {
481  Int_t slot = itw->first;
482  Int_t wrongcount = itw->second;
483  itw++;
484  if(wrongcount > 0) {
485  cout << " " << slot << " " << wrongcount << endl;
486  }
487  }
488 
489  }
490  cout << "-------------------------------------------------------------------" << endl;
491 }
493  ExpectedOffsetMap.clear();
494  AddExpectedOffset(roc, offset);
495 }
497  ExpectedOffsetMap[roc] = offset;
498 }
499 
500 THaAnalysisObject::EStatus THcTimeSyncEvtHandler::Init(const TDatime& date)
501 {
502 
503  cout << "Howdy ! We are initializing THcTimeSyncEvtHandler !! name = "<<fName<<endl;
504 
505  if(eventtypes.size()==0) {
506  eventtypes.push_back(1); // If no event types specified,
507  eventtypes.push_back(2); // check timestamp synchronization on these event types
508  eventtypes.push_back(3);
509  eventtypes.push_back(4);
510  eventtypes.push_back(5);
511  eventtypes.push_back(6);
512  eventtypes.push_back(7);
513  }
514 
515  fFirstTime = kTRUE;
517  fMasterRoc = -1;
518  fNEvents = 0;
519  CrateTimeMap.clear();
520  fSlippage=0;
522  fLastEvent[0]=0;
523  //CrateStatsMap.clear();
524  if(fCodaOut && fBadROC < 0) {
525  Warning(Here("Init"), "Sync filtering requested, but bad ROC not specified");
526  }
527 
528  fStatus = kOK;
529  return kOK;
530 }
531 
533  if(!fCodaOut) {
534  return 0;
535  }
536  return fCodaOut->codaClose();
537 }
538 
540  if(filename==0 || strlen(filename)==0) {
541  fCodaOut = 0;
542  cout << "THcTimeSyncEvtHandler sync filtering disabled" << endl;
543  } else {
544  TString ts=filename;
545  fCodaOut = new THaCodaFile;
546  if (!fCodaOut) {
547  Error(Here("SetRewriteFile"),"Cannot create CODA output file object. "
548  "Something is very wrong." );
549  return -2;
550  }
551  if ( fCodaOut->codaOpen(ts, "w", 1) ) {
552  Error(Here("SetRewriteFile"),"Cannot open CODA file %s for writing.",ts.Data());
553  return -3;
554  }
555  cout << "THcTimeSYncEvtHandler writing sync filtered coda file to " << ts <<endl;
556  }
557  return(0);
558 }
569  UInt_t headermask=0;
570  UInt_t trailermask=0;
571 
572  UInt_t *p=bank;
573  Int_t banklen = *p;
574  p++; // Header word
575  while(p++ < bank+banklen) {
576  if((*p & 0xf8000000) == 0x40000000) {
577  headermask |= (1<<(*p&0x1f));
578  } else if ((*p & 0xf8000000) == 0x80000000) {
579  trailermask |= (1<<(*p&0x1f));
580  }
581  }
582 
583  if(fFirstTdcCheck) {
585  fTdcMask = headermask | trailermask;
586  return(0); // All TDC present by definition
587  } else {
588  if((fTdcMask == headermask) && (fTdcMask == trailermask)) {
589  return(0);
590  } else {
591  cout << hex << "Header mask " << headermask << " Trailer mask " << trailermask << dec << endl;
592  cout << "TDC1190 Bank" << endl;
593  for(Int_t i=0;i<=banklen;i++) {
594  if(i%5 == 0) cout<<endl<<dec<<i<<": ";
595  cout << hex << setw(10) << bank[i];
596  }
597  cout << dec << endl;
598  return(1); // Just return this for now
599  }
600  }
601 }
602 
Int_t codaWrite(const UInt_t *evbuffer)
std::map< Int_t, RocStats_t * > CrateStatsMap
std::map< Int_t, Int_t > ftdcEvCountOffsetMap
virtual void SetExpectedOffset(Int_t roc, Int_t offset)
virtual void AddExpectedOffset(Int_t roc, Int_t offset)
Event handler to check TI and FADC synchronization.
std::map< Int_t, Int_t > ExpectedOffsetMap
THcTimeSyncEvtHandler(const char *name, const char *description)
UInt_t GetEvNum() const
int Int_t
bool Bool_t
virtual Int_t End(THaRunBase *r=0)
virtual Int_t codaClose()
STL namespace.
Decoder::THaCodaFile * fCodaOut
virtual Int_t SetRewriteFile(const char *filename)
std::map< Int_t, UInt_t > ftdcEvCountMap
const char * Data() const
std::map< Int_t, Int_t > fadcOffsetMap
virtual void AccumulateStats(Bool_t sync)
UInt_t GetEvLength() const
std::map< Int_t, Int_t > fadcEarlySlipCountMap
void Error(const char *location, const char *msgfmt,...)
const UInt_t * GetRawDataBuffer() const
struct THcTimeSyncEvtHandler::RocStats RocStats_t
unsigned int UInt_t
void Warning(const char *location, const char *msgfmt,...)
const Bool_t kFALSE
virtual Int_t codaOpen(const char *filename, Int_t mode=1)
virtual Int_t Analyze(THaEvData *evdata)
Int_t fDebug
Definition: THcParmList.cxx:62
UInt_t GetEvType() const
ClassImp(THcDCLookupTTDConv) THcDCLookupTTDConv
std::map< Int_t, UInt_t > fadcTimesMap
std::map< Int_t, Int_t > fadcLateSlipCountMap
std::map< Int_t, RocTimes_t * > CrateTimeMap
virtual Int_t AllTdcsPresent(UInt_t *bank)
struct THcTimeSyncEvtHandler::RocTimes RocTimes_t
std::map< Int_t, Int_t > ftdcEvCountWrongMap
const Bool_t kTRUE
virtual EStatus Init(const TDatime &run_time)