ROOT logo
//*-- Author:   Ole Hansen, October 2013

//////////////////////////////////////////////////////////////////////////
//
// THaDecData
//
// Hall A miscellaneous decoder data, which typically do not belong to a
// detector class. Provides a place to rapidly add new channels and to
// make their data available as analyzer global variables.
//
// To use this class, add something like the following to your analysis
// script:
//
// gHaApps->Add( new THaDecData("D","Decoder raw data") );
// 
// This will give your class the name "D", which will be the prefix for
// all its database keys and global variables.
//
// To define channels, corresponding database entries have to be
// set up. Either use the old-style flat file database format
// (see examples/decdata.map) or the new key/value format.
// For each channel, first decide how to identify the data:
//
// 1. "crate" variables define single 32-bit data words by crate/slot/channel
// 2. "multi" is the same as "crate", except it allows multihit channels
//    with an arbitrary number of hits.
// 3. "word" variables define single data words found in a given crate's
//    event buffer by a 32-bit header word and an offset. Offset = 1
//    means the data word following the header, etc.
// 4. "roclen" variables contain the event length of a given crate.
// 5. Hall A-specific: "bitNN" variables, where NN is a number 0-31,
//    report the value of a trigger bit read via a multihit TDC.
//    Ask the DAQ expert for details.
//
// In the key/value database format, define one database key for ALL
// the variables of a given type. The key's value is then a long string
// of n-tuples of configuration parameters, variable name first. For
// example:
//
/*
// D.crate = syncadc1, 1, 25, 16,  \
//           syncadc2, 2, 24, 48
*/
//
// will set up two "crate" variables, for crate/slot/chan = (1/25/16) and
// (2/24/48), respectively, that will appear as global variables
// "D.syncadc1" and "D.syncadc2". Note the continuation mark "\".
//
// "word" variables are defined similarly, but take header (in hex) and
// offset as the 3rd and 4th parameters.
//
// Alternatively, use the "decdata.map" example file to define channels
// line by line. (This file format will be phased out in the future.)
// To add a new variable, if it is on a single-hit channel, you may
// imitate 'synchadc1' if you know the (crate,slot,chan), and 
// imitate 'timeroc2' if you know the (crate,header,offset).
//
// If your variable is more complicated and relies on several 
// channels, you may easily write you own plug-in class derived
// from BdataLoc (see BdataLoc.[Ch]). Decoding is done in Load().
// You'll have to define a new, unique type name (like "crate") and
// initialize the class with a static initialization call to DoRegister
// (see top of BdataLoc.C). Also, you'll probably need to override
// Configure() to get additional or different parameters from the
// database.
//
// Originally written by R. Michaels, March 2002
// Modified by R.J. Feuerbach, April 2004
// Rewritten by O. Hansen, October 2013
//
//////////////////////////////////////////////////////////////////////////

#include "THaDecData.h"
#include "THaVarList.h"
#include "THaGlobals.h"
#include "TDatime.h"
#include "TClass.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "BdataLoc.h"
#include "THaEvData.h"

#include <iostream>
#include <cctype>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <memory>

#define DECDATA_LEGACY_DB

using namespace std;

static Int_t kInitHashCapacity = 100;
static Int_t kRehashLevel = 3;

//_____________________________________________________________________________
THaDecData::THaDecData( const char* name, const char* descript )
  : THaApparatus( name, descript ), evtype(0), evtypebits(0),
    fBdataLoc( kInitHashCapacity, kRehashLevel )
{
  fProperties &= ~kNeedsRunDB;
  fBdataLoc.SetOwner(kTRUE);
}

//_____________________________________________________________________________
THaDecData::~THaDecData()
{
  // Destructor. Delete data location objects and global variables.

  fBdataLoc.Clear();
  RemoveVariables();
}

//_____________________________________________________________________________
void THaDecData::Clear( Option_t* )
{
  // Reset event-by-event data

  TIter next( &fBdataLoc );
  while( TObject* obj = next() ) {
    obj->Clear();
  }
  evtype     = 0;
  evtypebits = 0;

}

//_____________________________________________________________________________
Int_t THaDecData::DefineVariables( EMode mode )
{
  // Register global variables, open decdata map file, and parse it.
  // If mode == kDelete, remove global variables.

  // Each defined decoder data location defines its own global variable(s)
  // The BdataLoc have their own equivalent of fIsSetup, so we can
  // unconditionally call their DefineVariables() here (similar to detetcor
  // initialization in THaAppratus::Init).
  Int_t retval = kOK;
  TIter next( &fBdataLoc );
  while( BdataLoc* dataloc = static_cast<BdataLoc*>( next() ) ) {
    if( dataloc->DefineVariables( mode ) != kOK )
      retval = kInitError;
  }
  if( retval != kOK )
    return retval;

  if( mode == kDefine && fIsSetup ) return kOK;
  fIsSetup = ( mode == kDefine );

  RVarDef vars[] = {
    { "evtype",     "CODA event type",             "evtype" },  
    { "evtypebits", "event type bit pattern",      "evtypebits" },  
    { 0 }
  };
  return DefineVarsFromList( vars, mode );
}

//_____________________________________________________________________________
Int_t THaDecData::DefineLocType( const BdataLoc::BdataLocType& loctype,
				 const TString& configstr, bool re_init )
{
  // Define variables for given loctype using parameters in configstr

  const char* const here = "DefineLocType";

  Int_t err = 0;

  // Split the string from the database into values separated by commas,
  // spaces, and/or tabs
  auto_ptr<TObjArray> config( configstr.Tokenize(", \t") );
  if( !config->IsEmpty() ) {
    Int_t nparams = config->GetLast()+1;
    assert( nparams > 0 );   // else bug in IsEmpty() or GetLast()
      
    if( nparams % loctype.fNparams != 0 ) {
      Error( Here(here), "Incorrect number of parameters in database key "
	     "%s%s. Have %d, but must be a multiple of %d. Fix database.",
	     GetPrefix(), loctype.fDBkey, nparams, loctype.fNparams );
      return -1;
    }

    TObjArray* params = config.get();
    for( Int_t ip = 0; ip < nparams; ip += loctype.fNparams ) {
      // Prepend prefix to name in parameter array
      TString& bname = GetObjArrayString( params, ip );
      bname.Prepend(GetPrefix());
      BdataLoc* item = static_cast<BdataLoc*>(fBdataLoc.FindObject(bname) );
      Bool_t already_defined = ( item != 0 );
      if( already_defined ) {
	// Name already exists
	if( re_init ) {
	  // Changing the variable type during a run makes no sense
	  if( loctype.fTClass != item->IsA() ) {
	    Error( Here(here), "Attempt to redefine existing variable %s "
		   "with different type.\nOld = %s, new = %s. Fix database.",
		   item->GetName(), item->IsA()->GetName(),
		   loctype.fTClass->GetName() );
	    return -1;
	  }
	  if( fDebug>2 ) 
	    Info( Here(here), "Updating variable %s", bname.Data() );
	} else {
	  // Duplicate variable name (i.e. duplicate names in database)
	  Error( Here(here), "Duplicate variable name %s. Fix database.",
		 item->GetName() );
	  return -1;
	}
      } else {
	// Make a new BdataLoc
	if( fDebug>2 )
	  Info( Here(here), "Defining new variable %s",  bname.Data() );
	item = static_cast<BdataLoc*>( loctype.fTClass->New() );
	if( !item ) {
	  Error( Here(here), "Failed to create variable of type %s. Should "
		 "never happen. Call expert.", loctype.fTClass->GetName() );
	  return -1;
	}
      }
      // Configure the new or existing BdataLoc with current database parameters. 
      // The first parameter is always the name. Note that this object's prefix
      // was already prepended above.
      err = item->Configure( params, ip );
      if( !err && loctype.fOptptr != 0 ) {
	// Optional pointer to some type-specific data
	err = item->OptionPtr( loctype.fOptptr );
      }
      if( err ) {
	Int_t in = ip - (ip % loctype.fNparams); // index of name
	Error( Here(here), "Illegal parameter for variable %s, "
	       "index = %d, value = %s. Fix database.",
	       GetObjArrayString(params,in).Data(), ip,
	       GetObjArrayString(params,ip).Data() );
	if( !already_defined )
	  delete item;
	break;
      } else if( !already_defined ) {
	// Add this BdataLoc to the list to be processed
	fBdataLoc.Add(item);
      }
    }
  } else {
    Warning( Here(here), "Empty database key %s%s.",
	     GetPrefix(), loctype.fDBkey );
  }

  return err;
}

//_____________________________________________________________________________
FILE* THaDecData::OpenFile( const TDatime& date )
{ 
  // Open DecData database file. First look for standard file name,
  // e.g. "db_D.dat", then for legacy file name "decdata.map"

  FILE* fi = THaApparatus::OpenFile( date );
  if( fi )
    return fi;
  return THaAnalysisObject::OpenFile("decdata.dat", date,
				     Here("OpenFile()"), "r", fDebug);
}

//_____________________________________________________________________________
#ifdef DECDATA_LEGACY_DB
#include <map>

static Int_t CheckDBVersion( FILE* file )
{
  // Check database version. Similar to emacs mode specs, versions are
  // determined by an identifier comment "# Version: 2" on the first line
  // (within first 80 chars). If no such tag is found, version 1 is assumed.

  const TString identifier("Version:");

  const size_t bufsiz = 82;
  char* buf = new char[bufsiz];
  rewind(file);
  const char* s = fgets(buf,bufsiz,file);
  if( !s ) { // No first line? Not our problem...
    delete [] buf;
    return 1;
  }
  TString line(buf);
  delete [] buf;
  Ssiz_t pos = line.Index(identifier,0,TString::kIgnoreCase);
  if( pos == kNPOS )
    return 1;
  pos += identifier.Length();
  while( pos < line.Length() && isspace(line(pos)) ) pos++;
  if( pos >= line.Length() )
    return 1;
  TString line2 = line(pos,line.Length() );
  Int_t vers = line2.Atoi();
  if( vers == 0 )
    vers = 1;
  return vers;
}

//_____________________________________________________________________________
inline
static TString& GetString( const TObjArray* params, Int_t pos )
{
  return THaAnalysisObject::GetObjArrayString(params,pos);
}

//_____________________________________________________________________________
static Int_t ReadOldFormatDB( FILE* file, map<TString,TString>& configstr_map )
{
  // Read old-style THaDecData database file and put results into a map from
  // database key to value (simulating the new-style key/value database info).
  // Old-style "crate" objects are all assumed to be multihit channels, even
  // though they usually are not.

  const size_t bufsiz = 256;
  char* buf = new char[bufsiz];
  string dbline;
  const int nkeys = 3;
  TString confkey[nkeys] = { "multi", "word", "bit" };
  TString confval[nkeys];
  // Read all non-comment lines
  rewind(file);
  while( THaAnalysisObject::ReadDBline(file, buf, bufsiz, dbline) != EOF ) {
    if( dbline.empty() ) continue;
    // Tokenize each line read
    TString line( dbline.c_str() );
    auto_ptr<TObjArray> tokens( line.Tokenize(" \t") );
    TObjArray* params = tokens.get();
    if( params->IsEmpty() || params->GetLast() < 4 ) continue;
    // Determine data type
    bool is_slot = ( GetString(params,1) == "crate" );
    int idx = is_slot ? 0 : 1;
    TString name = GetString(params,0);
    // TrigBits are crate types with special names
    if( is_slot && name.BeginsWith("bit") ) {
      if( name.Length() > 3 ) {
	TString name2 = name(3,name.Length());
	if( name2.IsDigit() && name2.Atoi() < 32 )
	  idx = 2;
      }
    }
    confval[idx] += name;
    confval[idx] += " ";
    for( int i = 2; i < 5; ++ i ) {
      confval[idx] += GetString(params,i).Data();
      confval[idx] += " ";
    }
  }
  delete [] buf;
  // Put the retrieved strings into the key/value map
  for( int i = 0; i < nkeys; ++ i ) {
    if( !confval[i].IsNull() )
      configstr_map[confkey[i]] = confval[i];
  }
  return 0;
}
#endif

//_____________________________________________________________________________
Int_t THaDecData::ReadDatabase( const TDatime& date )
{
  // Read THaDecData database

  static const char* const here = "ReadDatabase";

  FILE* file = OpenFile( date );
  if( !file ) return kFileError;

  Bool_t re_init = fIsInit;
  fIsInit = kFALSE;
  if( !re_init ) {
    fBdataLoc.Clear();
  }

#ifdef DECDATA_LEGACY_DB
  bool old_format = (CheckDBVersion(file) == 1);
  map<TString,TString> configstr_map;
  if( old_format )
    ReadOldFormatDB( file, configstr_map );
#endif

  Int_t err = 0;
  for( BdataLoc::TypeIter_t it = BdataLoc::fgBdataLocTypes().begin();
       !err && it != BdataLoc::fgBdataLocTypes().end(); ++it ) {
    const BdataLoc::BdataLocType& loctype = *it;

    // Get the ROOT class for this type
    assert( loctype.fClassName && *loctype.fClassName );
    if( !loctype.fTClass ) {
      loctype.fTClass = TClass::GetClass( loctype.fClassName );
      if( !loctype.fTClass ) {
	// Probably typo in the call to BdataLoc::DoRegister
	Error( Here(here), "No class defined for data type \"%s\". Programming "
	       "error. Call expert.", loctype.fClassName );
	err = -1;
	break;
      }
    }
    if( !loctype.fTClass->InheritsFrom( BdataLoc::Class() )) {
      Error( Here(here), "Class %s is not a BdataLoc. Programming error. "
	     "Call expert.", loctype.fTClass->GetName() );
      err = -1;
      break;
    }

    TString configstr;
#ifdef DECDATA_LEGACY_DB
    // Retrieve old-format database parameters read above for this type
    if( old_format ) {
      map<TString,TString>::const_iterator found =
	configstr_map.find(loctype.fDBkey);
      if( found == configstr_map.end() )
	continue;
      configstr = found->second;
    } else
#endif
    {
      // Read key/value database format
      TString dbkey = loctype.fDBkey;
      dbkey.Prepend( GetPrefix() );
      if( LoadDBvalue( file, date, dbkey, configstr ) != 0 )
	continue;  // No definitions in database for this BdataLoc type
    }
    err = DefineLocType( loctype, configstr, re_init );
  }

  fclose(file);
  if( err )
    return kInitError;

// ======= FIXME: Hall A lib ================================================
  // Configure the trigger bits with a pointer to our evtypebits
  TIter next( &fBdataLoc );
  while( BdataLoc* dataloc = static_cast<BdataLoc*>( next() ) ) {
    if( dataloc->Class() == TrigBitLoc::Class() )
      dataloc->OptionPtr( &evtypebits );
  }
// ======= END FIXME: Hall A lib ============================================

  fIsInit = kTRUE;
  return kOK;
}


//_____________________________________________________________________________
THaAnalysisObject::EStatus THaDecData::Init( const TDatime& run_time ) 
{
  // Custom Init() method. Since this apparatus has no traditional "detectors",
  // we skip the detector initialization.

  // Standard analysis object init, calls MakePrefix(), ReadDatabase()
  // and DefineVariables(), and Clear("I")
  return THaAnalysisObject::Init( run_time );
}

//_____________________________________________________________________________
Int_t THaDecData::Decode(const THaEvData& evdata)
{
  // Extract the requested variables from the event data

  if( !IsOK() )
    return -1;

  Clear();

  evtype = evdata.GetEvType();   // CODA event type 

  // For each raw data source registered in fBdataLoc, get the data 

  //TODO: accelerate search for multiple header words in same crate
  //- group WordLoc objects by crate
  //- for each crate with >1 WordLoc defs, make a MultiWordLoc
  //- MultiWordLoc uses faster search algo to scan crate buffer

  TIter next( &fBdataLoc );
  while( BdataLoc *dataloc = static_cast<BdataLoc*>( next() ) ) {
    dataloc->Load( evdata );
  }
  
  if( fDebug>1 )
    Print();

  return 0;
}

//_____________________________________________________________________________
void THaDecData::Print( Option_t* opt ) const
{
  // Print current status of all THaDecData variables

  THaAnalysisObject::Print(opt);

  cout << " event types,  CODA = " << evtype
       << "   bit pattern = 0x"      << hex << evtypebits << dec
       << endl;

  if( evtypebits != 0 ) {
    cout << " trigger bits set = ";
    bool cont = false;
    for( UInt_t i = 0; i < sizeof(evtypebits)*kBitsPerByte-1; ++i ) {
      if( TESTBIT(evtypebits,i) ) {
	if( cont ) cout << ", ";
	else       cont = true;
	cout << i;
      }
    }
    cout << endl;
  }

  // Print variables in the order they were defined
  cout << " number of user variables: " << fBdataLoc.GetSize() << endl;
  TIter next( &fBdataLoc );
  while( TObject* obj = next() ) {
    obj->Print(opt);
  }
}

//_____________________________________________________________________________
ClassImp(THaDecData)

 THaDecData.C:1
 THaDecData.C:2
 THaDecData.C:3
 THaDecData.C:4
 THaDecData.C:5
 THaDecData.C:6
 THaDecData.C:7
 THaDecData.C:8
 THaDecData.C:9
 THaDecData.C:10
 THaDecData.C:11
 THaDecData.C:12
 THaDecData.C:13
 THaDecData.C:14
 THaDecData.C:15
 THaDecData.C:16
 THaDecData.C:17
 THaDecData.C:18
 THaDecData.C:19
 THaDecData.C:20
 THaDecData.C:21
 THaDecData.C:22
 THaDecData.C:23
 THaDecData.C:24
 THaDecData.C:25
 THaDecData.C:26
 THaDecData.C:27
 THaDecData.C:28
 THaDecData.C:29
 THaDecData.C:30
 THaDecData.C:31
 THaDecData.C:32
 THaDecData.C:33
 THaDecData.C:34
 THaDecData.C:35
 THaDecData.C:36
 THaDecData.C:37
 THaDecData.C:38
 THaDecData.C:39
 THaDecData.C:40
 THaDecData.C:41
 THaDecData.C:42
 THaDecData.C:43
 THaDecData.C:44
 THaDecData.C:45
 THaDecData.C:46
 THaDecData.C:47
 THaDecData.C:48
 THaDecData.C:49
 THaDecData.C:50
 THaDecData.C:51
 THaDecData.C:52
 THaDecData.C:53
 THaDecData.C:54
 THaDecData.C:55
 THaDecData.C:56
 THaDecData.C:57
 THaDecData.C:58
 THaDecData.C:59
 THaDecData.C:60
 THaDecData.C:61
 THaDecData.C:62
 THaDecData.C:63
 THaDecData.C:64
 THaDecData.C:65
 THaDecData.C:66
 THaDecData.C:67
 THaDecData.C:68
 THaDecData.C:69
 THaDecData.C:70
 THaDecData.C:71
 THaDecData.C:72
 THaDecData.C:73
 THaDecData.C:74
 THaDecData.C:75
 THaDecData.C:76
 THaDecData.C:77
 THaDecData.C:78
 THaDecData.C:79
 THaDecData.C:80
 THaDecData.C:81
 THaDecData.C:82
 THaDecData.C:83
 THaDecData.C:84
 THaDecData.C:85
 THaDecData.C:86
 THaDecData.C:87
 THaDecData.C:88
 THaDecData.C:89
 THaDecData.C:90
 THaDecData.C:91
 THaDecData.C:92
 THaDecData.C:93
 THaDecData.C:94
 THaDecData.C:95
 THaDecData.C:96
 THaDecData.C:97
 THaDecData.C:98
 THaDecData.C:99
 THaDecData.C:100
 THaDecData.C:101
 THaDecData.C:102
 THaDecData.C:103
 THaDecData.C:104
 THaDecData.C:105
 THaDecData.C:106
 THaDecData.C:107
 THaDecData.C:108
 THaDecData.C:109
 THaDecData.C:110
 THaDecData.C:111
 THaDecData.C:112
 THaDecData.C:113
 THaDecData.C:114
 THaDecData.C:115
 THaDecData.C:116
 THaDecData.C:117
 THaDecData.C:118
 THaDecData.C:119
 THaDecData.C:120
 THaDecData.C:121
 THaDecData.C:122
 THaDecData.C:123
 THaDecData.C:124
 THaDecData.C:125
 THaDecData.C:126
 THaDecData.C:127
 THaDecData.C:128
 THaDecData.C:129
 THaDecData.C:130
 THaDecData.C:131
 THaDecData.C:132
 THaDecData.C:133
 THaDecData.C:134
 THaDecData.C:135
 THaDecData.C:136
 THaDecData.C:137
 THaDecData.C:138
 THaDecData.C:139
 THaDecData.C:140
 THaDecData.C:141
 THaDecData.C:142
 THaDecData.C:143
 THaDecData.C:144
 THaDecData.C:145
 THaDecData.C:146
 THaDecData.C:147
 THaDecData.C:148
 THaDecData.C:149
 THaDecData.C:150
 THaDecData.C:151
 THaDecData.C:152
 THaDecData.C:153
 THaDecData.C:154
 THaDecData.C:155
 THaDecData.C:156
 THaDecData.C:157
 THaDecData.C:158
 THaDecData.C:159
 THaDecData.C:160
 THaDecData.C:161
 THaDecData.C:162
 THaDecData.C:163
 THaDecData.C:164
 THaDecData.C:165
 THaDecData.C:166
 THaDecData.C:167
 THaDecData.C:168
 THaDecData.C:169
 THaDecData.C:170
 THaDecData.C:171
 THaDecData.C:172
 THaDecData.C:173
 THaDecData.C:174
 THaDecData.C:175
 THaDecData.C:176
 THaDecData.C:177
 THaDecData.C:178
 THaDecData.C:179
 THaDecData.C:180
 THaDecData.C:181
 THaDecData.C:182
 THaDecData.C:183
 THaDecData.C:184
 THaDecData.C:185
 THaDecData.C:186
 THaDecData.C:187
 THaDecData.C:188
 THaDecData.C:189
 THaDecData.C:190
 THaDecData.C:191
 THaDecData.C:192
 THaDecData.C:193
 THaDecData.C:194
 THaDecData.C:195
 THaDecData.C:196
 THaDecData.C:197
 THaDecData.C:198
 THaDecData.C:199
 THaDecData.C:200
 THaDecData.C:201
 THaDecData.C:202
 THaDecData.C:203
 THaDecData.C:204
 THaDecData.C:205
 THaDecData.C:206
 THaDecData.C:207
 THaDecData.C:208
 THaDecData.C:209
 THaDecData.C:210
 THaDecData.C:211
 THaDecData.C:212
 THaDecData.C:213
 THaDecData.C:214
 THaDecData.C:215
 THaDecData.C:216
 THaDecData.C:217
 THaDecData.C:218
 THaDecData.C:219
 THaDecData.C:220
 THaDecData.C:221
 THaDecData.C:222
 THaDecData.C:223
 THaDecData.C:224
 THaDecData.C:225
 THaDecData.C:226
 THaDecData.C:227
 THaDecData.C:228
 THaDecData.C:229
 THaDecData.C:230
 THaDecData.C:231
 THaDecData.C:232
 THaDecData.C:233
 THaDecData.C:234
 THaDecData.C:235
 THaDecData.C:236
 THaDecData.C:237
 THaDecData.C:238
 THaDecData.C:239
 THaDecData.C:240
 THaDecData.C:241
 THaDecData.C:242
 THaDecData.C:243
 THaDecData.C:244
 THaDecData.C:245
 THaDecData.C:246
 THaDecData.C:247
 THaDecData.C:248
 THaDecData.C:249
 THaDecData.C:250
 THaDecData.C:251
 THaDecData.C:252
 THaDecData.C:253
 THaDecData.C:254
 THaDecData.C:255
 THaDecData.C:256
 THaDecData.C:257
 THaDecData.C:258
 THaDecData.C:259
 THaDecData.C:260
 THaDecData.C:261
 THaDecData.C:262
 THaDecData.C:263
 THaDecData.C:264
 THaDecData.C:265
 THaDecData.C:266
 THaDecData.C:267
 THaDecData.C:268
 THaDecData.C:269
 THaDecData.C:270
 THaDecData.C:271
 THaDecData.C:272
 THaDecData.C:273
 THaDecData.C:274
 THaDecData.C:275
 THaDecData.C:276
 THaDecData.C:277
 THaDecData.C:278
 THaDecData.C:279
 THaDecData.C:280
 THaDecData.C:281
 THaDecData.C:282
 THaDecData.C:283
 THaDecData.C:284
 THaDecData.C:285
 THaDecData.C:286
 THaDecData.C:287
 THaDecData.C:288
 THaDecData.C:289
 THaDecData.C:290
 THaDecData.C:291
 THaDecData.C:292
 THaDecData.C:293
 THaDecData.C:294
 THaDecData.C:295
 THaDecData.C:296
 THaDecData.C:297
 THaDecData.C:298
 THaDecData.C:299
 THaDecData.C:300
 THaDecData.C:301
 THaDecData.C:302
 THaDecData.C:303
 THaDecData.C:304
 THaDecData.C:305
 THaDecData.C:306
 THaDecData.C:307
 THaDecData.C:308
 THaDecData.C:309
 THaDecData.C:310
 THaDecData.C:311
 THaDecData.C:312
 THaDecData.C:313
 THaDecData.C:314
 THaDecData.C:315
 THaDecData.C:316
 THaDecData.C:317
 THaDecData.C:318
 THaDecData.C:319
 THaDecData.C:320
 THaDecData.C:321
 THaDecData.C:322
 THaDecData.C:323
 THaDecData.C:324
 THaDecData.C:325
 THaDecData.C:326
 THaDecData.C:327
 THaDecData.C:328
 THaDecData.C:329
 THaDecData.C:330
 THaDecData.C:331
 THaDecData.C:332
 THaDecData.C:333
 THaDecData.C:334
 THaDecData.C:335
 THaDecData.C:336
 THaDecData.C:337
 THaDecData.C:338
 THaDecData.C:339
 THaDecData.C:340
 THaDecData.C:341
 THaDecData.C:342
 THaDecData.C:343
 THaDecData.C:344
 THaDecData.C:345
 THaDecData.C:346
 THaDecData.C:347
 THaDecData.C:348
 THaDecData.C:349
 THaDecData.C:350
 THaDecData.C:351
 THaDecData.C:352
 THaDecData.C:353
 THaDecData.C:354
 THaDecData.C:355
 THaDecData.C:356
 THaDecData.C:357
 THaDecData.C:358
 THaDecData.C:359
 THaDecData.C:360
 THaDecData.C:361
 THaDecData.C:362
 THaDecData.C:363
 THaDecData.C:364
 THaDecData.C:365
 THaDecData.C:366
 THaDecData.C:367
 THaDecData.C:368
 THaDecData.C:369
 THaDecData.C:370
 THaDecData.C:371
 THaDecData.C:372
 THaDecData.C:373
 THaDecData.C:374
 THaDecData.C:375
 THaDecData.C:376
 THaDecData.C:377
 THaDecData.C:378
 THaDecData.C:379
 THaDecData.C:380
 THaDecData.C:381
 THaDecData.C:382
 THaDecData.C:383
 THaDecData.C:384
 THaDecData.C:385
 THaDecData.C:386
 THaDecData.C:387
 THaDecData.C:388
 THaDecData.C:389
 THaDecData.C:390
 THaDecData.C:391
 THaDecData.C:392
 THaDecData.C:393
 THaDecData.C:394
 THaDecData.C:395
 THaDecData.C:396
 THaDecData.C:397
 THaDecData.C:398
 THaDecData.C:399
 THaDecData.C:400
 THaDecData.C:401
 THaDecData.C:402
 THaDecData.C:403
 THaDecData.C:404
 THaDecData.C:405
 THaDecData.C:406
 THaDecData.C:407
 THaDecData.C:408
 THaDecData.C:409
 THaDecData.C:410
 THaDecData.C:411
 THaDecData.C:412
 THaDecData.C:413
 THaDecData.C:414
 THaDecData.C:415
 THaDecData.C:416
 THaDecData.C:417
 THaDecData.C:418
 THaDecData.C:419
 THaDecData.C:420
 THaDecData.C:421
 THaDecData.C:422
 THaDecData.C:423
 THaDecData.C:424
 THaDecData.C:425
 THaDecData.C:426
 THaDecData.C:427
 THaDecData.C:428
 THaDecData.C:429
 THaDecData.C:430
 THaDecData.C:431
 THaDecData.C:432
 THaDecData.C:433
 THaDecData.C:434
 THaDecData.C:435
 THaDecData.C:436
 THaDecData.C:437
 THaDecData.C:438
 THaDecData.C:439
 THaDecData.C:440
 THaDecData.C:441
 THaDecData.C:442
 THaDecData.C:443
 THaDecData.C:444
 THaDecData.C:445
 THaDecData.C:446
 THaDecData.C:447
 THaDecData.C:448
 THaDecData.C:449
 THaDecData.C:450
 THaDecData.C:451
 THaDecData.C:452
 THaDecData.C:453
 THaDecData.C:454
 THaDecData.C:455
 THaDecData.C:456
 THaDecData.C:457
 THaDecData.C:458
 THaDecData.C:459
 THaDecData.C:460
 THaDecData.C:461
 THaDecData.C:462
 THaDecData.C:463
 THaDecData.C:464
 THaDecData.C:465
 THaDecData.C:466
 THaDecData.C:467
 THaDecData.C:468
 THaDecData.C:469
 THaDecData.C:470
 THaDecData.C:471
 THaDecData.C:472
 THaDecData.C:473
 THaDecData.C:474
 THaDecData.C:475
 THaDecData.C:476
 THaDecData.C:477
 THaDecData.C:478
 THaDecData.C:479
 THaDecData.C:480
 THaDecData.C:481
 THaDecData.C:482
 THaDecData.C:483
 THaDecData.C:484
 THaDecData.C:485
 THaDecData.C:486
 THaDecData.C:487
 THaDecData.C:488
 THaDecData.C:489
 THaDecData.C:490
 THaDecData.C:491
 THaDecData.C:492
 THaDecData.C:493
 THaDecData.C:494
 THaDecData.C:495
 THaDecData.C:496
 THaDecData.C:497
 THaDecData.C:498
 THaDecData.C:499
 THaDecData.C:500
 THaDecData.C:501
 THaDecData.C:502
 THaDecData.C:503
 THaDecData.C:504
 THaDecData.C:505
 THaDecData.C:506
 THaDecData.C:507
 THaDecData.C:508
 THaDecData.C:509
 THaDecData.C:510
 THaDecData.C:511
 THaDecData.C:512
 THaDecData.C:513
 THaDecData.C:514
 THaDecData.C:515
 THaDecData.C:516
 THaDecData.C:517
 THaDecData.C:518
 THaDecData.C:519