ROOT logo
/////////////////////////////////////////////////////////////////////
//
//   THaEvData
//   Hall A Event Data from One "Event"
//
//   This is a pure virtual base class.  You should not
//   instantiate this directly (and actually CAN not), but
//   rather use THaCodaDecoder or (less likely) a sim class like
//   THaVDCSimDecoder.
//
//   This class is intended to provide a crate/slot structure
//   for derived classes to use.  All derived class must define and
//   implement LoadEvent(const int*).  See the header.
//
//   original author  Robert Michaels (rom@jlab.org)
//
//   modified for abstraction by Ken Rossato (rossato@jlab.org)
//
//
/////////////////////////////////////////////////////////////////////

#include "THaEvData.h"
#include "Module.h"
#include "THaSlotData.h"
#include "THaFastBusWord.h"
#include "THaCrateMap.h"
#include "THaUsrstrutils.h"
#include "THaBenchmark.h"
#include "TError.h"
#include <cstring>
#include <cstdio>
#include <cctype>
#include <iostream>
#include <iomanip>
#include <ctime>

#ifndef STANDALONE
#include "THaVarList.h"
#include "THaGlobals.h"
#endif

using namespace std;
using namespace Decoder;

// Instances of this object
TBits THaEvData::fgInstances;

const Double_t THaEvData::kBig = 1e38;

// If false, signal attempted use of unimplemented features
#ifndef NDEBUG
Bool_t THaEvData::fgAllowUnimpl = false;
#else
Bool_t THaEvData::fgAllowUnimpl = true;
#endif

TString THaEvData::fgDefaultCrateMapName = "cratemap";

//_____________________________________________________________________________

THaEvData::THaEvData() :
  fMap(0), first_decode(true), fTrigSupPS(true),
  buffer(0), fDebugFile(0), run_num(0), run_type(0), fRunTime(0),
  evt_time(0), recent_event(0), fNSlotUsed(0), fNSlotClear(0),
  fDoBench(kFALSE), fBench(0), fNeedInit(true), fDebug(0)
{
  fInstance = fgInstances.FirstNullBit();
  fgInstances.SetBitNumber(fInstance);
  fInstance++;
  // FIXME: dynamic allocation
  crateslot = new THaSlotData*[MAXROC*MAXSLOT];
  fSlotUsed  = new UShort_t[MAXROC*MAXSLOT];
  fSlotClear = new UShort_t[MAXROC*MAXSLOT];
  //memset(psfact,0,MAX_PSFACT*sizeof(int));
  memset(crateslot,0,MAXROC*MAXSLOT*sizeof(THaSlotData*));
  fRunTime = time(0); // default fRunTime is NOW
#ifndef STANDALONE
// Register global variables.
  if( gHaVars ) {
    VarDef vars[] = {
      { "runnum",    "Run number",     kInt,    0, &run_num },
      { "runtype",   "CODA run type",  kInt,    0, &run_type },
      { "runtime",   "CODA run time",  kULong,  0, &fRunTime },
      { "evnum",     "Event number",   kInt,    0, &event_num },
      { "evtyp",     "Event type",     kInt,    0, &event_type },
      { "evlen",     "Event Length",   kInt,    0, &event_length },
      { "evtime",    "Event time",     kULong,  0, &evt_time },
      { 0 }
    };
    TString prefix("g");
    // Prevent global variable clash if there are several instances of us
    if( fInstance > 1 )
      prefix.Append(Form("%d",fInstance));
    prefix.Append(".");
    gHaVars->DefineVariables( vars, prefix, "THaEvData::THaEvData" );
  } else
    Warning("THaEvData::THaEvData","No global variable list found. "
	    "Variables not registered.");
#endif
}


THaEvData::~THaEvData() {
  if( fDoBench ) {
    Float_t a,b;
    fBench->Summary(a,b);
  }
  delete fBench;
#ifndef STANDALONE
  if( gHaVars ) {
    TString prefix("g");
    if( fInstance > 1 )
      prefix.Append(Form("%d",fInstance));
    prefix.Append(".*");
    gHaVars->RemoveRegexp( prefix );
  }
#endif
  // We must delete every array element since not all may be in fSlotUsed.
  for( int i=0; i<MAXROC*MAXSLOT; i++ )
    delete crateslot[i];
  delete [] crateslot;
  delete [] fSlotUsed;
  delete [] fSlotClear;
  fInstance--;
  fgInstances.ResetBitNumber(fInstance);
}

const char* THaEvData::DevType(int crate, int slot) const {
// Device type in crate, slot
  return ( GoodIndex(crate,slot) ) ?
    crateslot[idx(crate,slot)]->devType() : " ";
}

void THaEvData::SetRunTime( ULong64_t tloc )
{
  // Set run time and re-initialize crate map (and possibly other
  // database parameters for the new time.
  if( fRunTime == tloc )
    return;
  fRunTime = tloc;

  init_cmap();
}

void THaEvData::EnableBenchmarks( Bool_t enable )
{
  // Enable/disable run time reporting
  fDoBench = enable;
  if( fDoBench ) {
    if( !fBench )
      fBench = new THaBenchmark;
  } else {
    delete fBench;
    fBench = 0;
  }
}

void THaEvData::EnableHelicity( Bool_t enable )
{
  // Enable/disable helicity decoding
  SetBit(kHelicityEnabled, enable);
}

void THaEvData::EnableScalers( Bool_t enable )
{
  // Enable/disable scaler decoding
  SetBit(kScalersEnabled, enable);
}

void THaEvData::SetVerbose( UInt_t level )
{
  // Set verbosity level. Identical to SetDebug(). Kept for compatibility.

  SetDebug(level);
}

void THaEvData::SetDebug( UInt_t level )
{
  // Set debug level

  fDebug = level;
}

void THaEvData::SetOrigPS(Int_t evtyp)
{
  fTrigSupPS = true;  // default after Nov 2003
  if (evtyp == PRESCALE_EVTYPE) {
    fTrigSupPS = false;
    return;
  } else if (evtyp != TS_PRESCALE_EVTYPE) {
    cout << "SetOrigPS::Warn: PS factors";
    cout << " originate only from evtype ";
    cout << PRESCALE_EVTYPE << "  or ";
    cout << TS_PRESCALE_EVTYPE << endl;
  }
}

TString THaEvData::GetOrigPS() const
{
  TString answer = "PS from ";
  if (fTrigSupPS) {
    answer += " Trig Sup evtype ";
    answer.Append(Form("%d",TS_PRESCALE_EVTYPE));
  } else {
    answer += " PS evtype ";
    answer.Append(Form("%d",PRESCALE_EVTYPE));
  }
  return answer;
}

void THaEvData::hexdump(const char* cbuff, size_t nlen)
{
  // Hexdump buffer 'cbuff' of length 'nlen'
  const int NW = 16; const char* p = cbuff;
  while( p<cbuff+nlen ) {
    cout << dec << setw(4) << setfill('0') << (size_t)(p-cbuff) << " ";
    int nelem = TMath::Min((Long_t)NW,(Long_t)(cbuff+nlen-p));
    for(int i=0; i<NW; i++) {
      UInt_t c = (i<nelem) ? *(const unsigned char*)(p+i) : 0;
      cout << " " << hex << setfill('0') << setw(2) << c << dec;
    } cout << setfill(' ') << "  ";
    for(int i=0; i<NW; i++) {
      char c = (i<nelem) ? *(p+i) : 0;
      if(isgraph(c)||c==' ') cout << c; else cout << ".";
    } cout << endl;
    p += NW;
  }
}

void THaEvData::SetDefaultCrateMapName( const char* name )
{
  // Static function to set fgDefaultCrateMapName. Call this function to set a
  // global default name for all decoder instances before initialization. This
  // is usually what you want to do for a given replay.

  if( name && *name ) {
    fgDefaultCrateMapName = name;
  }
  else {
    ::Error( "THaEvData::SetDefaultCrateMapName", "Default crate map name "
	     "must not be empty" );
  }
}

void THaEvData::SetCrateMapName( const char* name )
{
  // Set fCrateMapName for this decoder instance only

  if( name && *name ) {
    if( fCrateMapName != name ) {
      fCrateMapName = name;
      fNeedInit = true;
    }
  } else if( fCrateMapName != fgDefaultCrateMapName ) {
    fCrateMapName = fgDefaultCrateMapName;
    fNeedInit = true;
  }
}

// Set up and initialize the crate map
int THaEvData::init_cmap()  {
  if( fCrateMapName.IsNull() )
    fCrateMapName = fgDefaultCrateMapName;
  if( !fMap || fNeedInit || fCrateMapName != fMap->GetName() ) {
    delete fMap;
    fMap = new THaCrateMap( fCrateMapName );
  }
  if( fDebug>0 ) cout << "Init crate map " << endl;
  if( fMap->init(GetRunTime()) == THaCrateMap::CM_ERR )
    return HED_FATAL; // Can't continue w/o cratemap
  fNeedInit = false;
  return HED_OK;
}

void THaEvData::makeidx(int crate, int slot)
{
  // Activate crate/slot
  int idx = slot+MAXSLOT*crate;
  delete crateslot[idx];  // just in case
  crateslot[idx] = new THaSlotData(crate,slot);
  if (fDebugFile) crateslot[idx]->SetDebugFile(fDebugFile);
  if( !fMap ) return;
  if( fMap->crateUsed(crate) && fMap->slotUsed(crate,slot)) {
    crateslot[idx]
      ->define( crate, slot, fMap->getNchan(crate,slot),
		fMap->getNdata(crate,slot) );
    fSlotUsed[fNSlotUsed++] = idx;
    if( fMap->slotClear(crate,slot))
      fSlotClear[fNSlotClear++] = idx;
  }
}

void THaEvData::PrintOut() const {
  //TODO
  cout << "THaEvData::PrintOut() called" << endl;
}

void THaEvData::PrintSlotData(int crate, int slot) const {
  // Print the contents of (crate, slot).
  if( GoodIndex(crate,slot)) {
    crateslot[idx(crate,slot)]->print();
  } else {
      cout << "THaEvData: Warning: Crate, slot combination";
      cout << "\nexceeds limits.  Cannot print"<<endl;
  }
  return;
}

// To initialize the THaSlotData member on first call to decoder
int THaEvData::init_slotdata(const THaCrateMap* map)
{
  // Update lists of used/clearable slots in case crate map changed
  if(!map) return HED_ERR;
  for( int i=0; i<fNSlotUsed; i++ ) {
    THaSlotData* module = crateslot[fSlotUsed[i]];
    int crate = module->getCrate();
    int slot  = module->getSlot();
    if( !map->crateUsed(crate) || !map->slotUsed(crate,slot) ||
	!map->slotClear(crate,slot)) {
      for( int k=0; k<fNSlotClear; k++ ) {
	if( module == crateslot[fSlotClear[k]] ) {
	  for( int j=k+1; j<fNSlotClear; j++ )
	    fSlotClear[j-1] = fSlotClear[j];
	  fNSlotClear--;
	  break;
	}
      }
    }
    if( !map->crateUsed(crate) || !map->slotUsed(crate,slot)) {
      for( int j=i+1; j<fNSlotUsed; j++ )
	fSlotUsed[j-1] = fSlotUsed[j];
      fNSlotUsed--;
    }
  }
  return HED_OK;
}

//_____________________________________________________________________________
Module* THaEvData::GetModule(Int_t roc, Int_t slot) const
{
  THaSlotData *sldat = crateslot[idx(roc,slot)];
  if (sldat) return sldat->GetModule();
  return NULL;
}

ClassImp(THaEvData)
ClassImp(THaBenchmark)
 THaEvData.C:1
 THaEvData.C:2
 THaEvData.C:3
 THaEvData.C:4
 THaEvData.C:5
 THaEvData.C:6
 THaEvData.C:7
 THaEvData.C:8
 THaEvData.C:9
 THaEvData.C:10
 THaEvData.C:11
 THaEvData.C:12
 THaEvData.C:13
 THaEvData.C:14
 THaEvData.C:15
 THaEvData.C:16
 THaEvData.C:17
 THaEvData.C:18
 THaEvData.C:19
 THaEvData.C:20
 THaEvData.C:21
 THaEvData.C:22
 THaEvData.C:23
 THaEvData.C:24
 THaEvData.C:25
 THaEvData.C:26
 THaEvData.C:27
 THaEvData.C:28
 THaEvData.C:29
 THaEvData.C:30
 THaEvData.C:31
 THaEvData.C:32
 THaEvData.C:33
 THaEvData.C:34
 THaEvData.C:35
 THaEvData.C:36
 THaEvData.C:37
 THaEvData.C:38
 THaEvData.C:39
 THaEvData.C:40
 THaEvData.C:41
 THaEvData.C:42
 THaEvData.C:43
 THaEvData.C:44
 THaEvData.C:45
 THaEvData.C:46
 THaEvData.C:47
 THaEvData.C:48
 THaEvData.C:49
 THaEvData.C:50
 THaEvData.C:51
 THaEvData.C:52
 THaEvData.C:53
 THaEvData.C:54
 THaEvData.C:55
 THaEvData.C:56
 THaEvData.C:57
 THaEvData.C:58
 THaEvData.C:59
 THaEvData.C:60
 THaEvData.C:61
 THaEvData.C:62
 THaEvData.C:63
 THaEvData.C:64
 THaEvData.C:65
 THaEvData.C:66
 THaEvData.C:67
 THaEvData.C:68
 THaEvData.C:69
 THaEvData.C:70
 THaEvData.C:71
 THaEvData.C:72
 THaEvData.C:73
 THaEvData.C:74
 THaEvData.C:75
 THaEvData.C:76
 THaEvData.C:77
 THaEvData.C:78
 THaEvData.C:79
 THaEvData.C:80
 THaEvData.C:81
 THaEvData.C:82
 THaEvData.C:83
 THaEvData.C:84
 THaEvData.C:85
 THaEvData.C:86
 THaEvData.C:87
 THaEvData.C:88
 THaEvData.C:89
 THaEvData.C:90
 THaEvData.C:91
 THaEvData.C:92
 THaEvData.C:93
 THaEvData.C:94
 THaEvData.C:95
 THaEvData.C:96
 THaEvData.C:97
 THaEvData.C:98
 THaEvData.C:99
 THaEvData.C:100
 THaEvData.C:101
 THaEvData.C:102
 THaEvData.C:103
 THaEvData.C:104
 THaEvData.C:105
 THaEvData.C:106
 THaEvData.C:107
 THaEvData.C:108
 THaEvData.C:109
 THaEvData.C:110
 THaEvData.C:111
 THaEvData.C:112
 THaEvData.C:113
 THaEvData.C:114
 THaEvData.C:115
 THaEvData.C:116
 THaEvData.C:117
 THaEvData.C:118
 THaEvData.C:119
 THaEvData.C:120
 THaEvData.C:121
 THaEvData.C:122
 THaEvData.C:123
 THaEvData.C:124
 THaEvData.C:125
 THaEvData.C:126
 THaEvData.C:127
 THaEvData.C:128
 THaEvData.C:129
 THaEvData.C:130
 THaEvData.C:131
 THaEvData.C:132
 THaEvData.C:133
 THaEvData.C:134
 THaEvData.C:135
 THaEvData.C:136
 THaEvData.C:137
 THaEvData.C:138
 THaEvData.C:139
 THaEvData.C:140
 THaEvData.C:141
 THaEvData.C:142
 THaEvData.C:143
 THaEvData.C:144
 THaEvData.C:145
 THaEvData.C:146
 THaEvData.C:147
 THaEvData.C:148
 THaEvData.C:149
 THaEvData.C:150
 THaEvData.C:151
 THaEvData.C:152
 THaEvData.C:153
 THaEvData.C:154
 THaEvData.C:155
 THaEvData.C:156
 THaEvData.C:157
 THaEvData.C:158
 THaEvData.C:159
 THaEvData.C:160
 THaEvData.C:161
 THaEvData.C:162
 THaEvData.C:163
 THaEvData.C:164
 THaEvData.C:165
 THaEvData.C:166
 THaEvData.C:167
 THaEvData.C:168
 THaEvData.C:169
 THaEvData.C:170
 THaEvData.C:171
 THaEvData.C:172
 THaEvData.C:173
 THaEvData.C:174
 THaEvData.C:175
 THaEvData.C:176
 THaEvData.C:177
 THaEvData.C:178
 THaEvData.C:179
 THaEvData.C:180
 THaEvData.C:181
 THaEvData.C:182
 THaEvData.C:183
 THaEvData.C:184
 THaEvData.C:185
 THaEvData.C:186
 THaEvData.C:187
 THaEvData.C:188
 THaEvData.C:189
 THaEvData.C:190
 THaEvData.C:191
 THaEvData.C:192
 THaEvData.C:193
 THaEvData.C:194
 THaEvData.C:195
 THaEvData.C:196
 THaEvData.C:197
 THaEvData.C:198
 THaEvData.C:199
 THaEvData.C:200
 THaEvData.C:201
 THaEvData.C:202
 THaEvData.C:203
 THaEvData.C:204
 THaEvData.C:205
 THaEvData.C:206
 THaEvData.C:207
 THaEvData.C:208
 THaEvData.C:209
 THaEvData.C:210
 THaEvData.C:211
 THaEvData.C:212
 THaEvData.C:213
 THaEvData.C:214
 THaEvData.C:215
 THaEvData.C:216
 THaEvData.C:217
 THaEvData.C:218
 THaEvData.C:219
 THaEvData.C:220
 THaEvData.C:221
 THaEvData.C:222
 THaEvData.C:223
 THaEvData.C:224
 THaEvData.C:225
 THaEvData.C:226
 THaEvData.C:227
 THaEvData.C:228
 THaEvData.C:229
 THaEvData.C:230
 THaEvData.C:231
 THaEvData.C:232
 THaEvData.C:233
 THaEvData.C:234
 THaEvData.C:235
 THaEvData.C:236
 THaEvData.C:237
 THaEvData.C:238
 THaEvData.C:239
 THaEvData.C:240
 THaEvData.C:241
 THaEvData.C:242
 THaEvData.C:243
 THaEvData.C:244
 THaEvData.C:245
 THaEvData.C:246
 THaEvData.C:247
 THaEvData.C:248
 THaEvData.C:249
 THaEvData.C:250
 THaEvData.C:251
 THaEvData.C:252
 THaEvData.C:253
 THaEvData.C:254
 THaEvData.C:255
 THaEvData.C:256
 THaEvData.C:257
 THaEvData.C:258
 THaEvData.C:259
 THaEvData.C:260
 THaEvData.C:261
 THaEvData.C:262
 THaEvData.C:263
 THaEvData.C:264
 THaEvData.C:265
 THaEvData.C:266
 THaEvData.C:267
 THaEvData.C:268
 THaEvData.C:269
 THaEvData.C:270
 THaEvData.C:271
 THaEvData.C:272
 THaEvData.C:273
 THaEvData.C:274
 THaEvData.C:275
 THaEvData.C:276
 THaEvData.C:277
 THaEvData.C:278
 THaEvData.C:279
 THaEvData.C:280
 THaEvData.C:281
 THaEvData.C:282
 THaEvData.C:283
 THaEvData.C:284
 THaEvData.C:285
 THaEvData.C:286
 THaEvData.C:287
 THaEvData.C:288
 THaEvData.C:289
 THaEvData.C:290
 THaEvData.C:291
 THaEvData.C:292
 THaEvData.C:293
 THaEvData.C:294
 THaEvData.C:295
 THaEvData.C:296
 THaEvData.C:297
 THaEvData.C:298
 THaEvData.C:299
 THaEvData.C:300
 THaEvData.C:301
 THaEvData.C:302
 THaEvData.C:303
 THaEvData.C:304
 THaEvData.C:305
 THaEvData.C:306
 THaEvData.C:307
 THaEvData.C:308
 THaEvData.C:309
 THaEvData.C:310
 THaEvData.C:311
 THaEvData.C:312
 THaEvData.C:313
 THaEvData.C:314
 THaEvData.C:315
 THaEvData.C:316
 THaEvData.C:317
 THaEvData.C:318
 THaEvData.C:319
 THaEvData.C:320
 THaEvData.C:321
 THaEvData.C:322
 THaEvData.C:323
 THaEvData.C:324
 THaEvData.C:325
 THaEvData.C:326
 THaEvData.C:327
 THaEvData.C:328
 THaEvData.C:329
 THaEvData.C:330
 THaEvData.C:331
 THaEvData.C:332
 THaEvData.C:333
 THaEvData.C:334
 THaEvData.C:335
 THaEvData.C:336
 THaEvData.C:337
 THaEvData.C:338
 THaEvData.C:339
 THaEvData.C:340
 THaEvData.C:341
 THaEvData.C:342
 THaEvData.C:343
 THaEvData.C:344
 THaEvData.C:345
 THaEvData.C:346
 THaEvData.C:347