BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//____________________________________________________________________
//
//                                                          
// BrRawDataInput provides an interface to raw data         
// 
// The class is derived from the general input/output class BrIOModule 
// and falls natural into the hierachi of module classes.
//
// The connection can be made to a diskfile, or the EventBuilder
// using the DAQ connections (port 7772).
// 
// This module can be used in a module pipeline, see class
// descriptions for BrIOModule, BrModule, BrModuleContainer. However,
// unlike for BrIOModule, we have only two modes of how to handle the
// files opened:
//
//   From disk-resident file (kBrRawDiskFile): 
//     These modules reads data from the disk resident raw file(s) and
//     puts it into a BrEvent object 
//   From the event builders output stream (kBrEventBuilderStream): 
//     These modules reads from port 7772 on opus.brahms.bnl.gov and
//     stores the event in a BrEvent object. 
//
// Of course, there are still the 2 modes for the lifetime of the
// file(s), kBrRunFile and kBrJobFile. However, I think only
// kBrJobFile makes sense for kBrEventBuilderStream modules. 
// 
// To use this module in a pipeline, do something like 
//
//   // Then the input module 
//   BrIOModule* input       = new BrRawDataInput("in", "Input");
//   cont->AddModule(input); 
//   input->SetIOMode(BrRawDataInput::kBrRunFile |
//                    BrRawDataInput::kBrRawDiskFile); 
//
//  By default All raw data record are converted to Root digitized objects
//  If a given analysis is not going to use all data conversions of
//  any subset can be turned off. This is most conviniently done by
//  means of the BrRawDataInput::SetOn methods, preferentially to be used
//  by referencing to the EBrDetectorBits definitions from BrDetectorList
//  e.g.
//  Do not unpack anything from the forward spectrometer except H1 and H2.
//  Notice the slight (?!) inconsistency in naming H1 as TOF1 here (and in
//  gbrahms, while in other connections it is H1.
//
//  input->SetOff(kBrFS);
//  input->SetOn(kBrTOF1);
//  input->SetOn(kBrTOF2);
//  

//____________________________________________________________________
//
// $Id: BrRawDataInput.cxx,v 1.27 2002/07/03 18:26:36 videbaek Exp $
// $Author: videbaek $
// $Date: 2002/07/03 18:26:36 $
// $Copyright: 2001 BRAHMS Collaboration <brahmlib@rhic.bnl.gov>
//

//____________________________________________________________________
#ifndef NODISPATCH
#include <iostream>
#else
#include <iostream.h>
#endif
#include <string.h>
#include <cassert>
#include "BrRawDataInput.h"
#ifndef NODISPATCH
using namespace std;
#endif
#ifndef BRAT_BrDataTable
#include "BrDataTable.h"
#endif
#ifndef BRAT_BrEvent
#include "BrEvent.h"
#endif
#ifndef BRAT_BrTableNames
#include "BrTableNames.h"
#endif
#ifndef ROOT_TSystem
#include "TSystem.h"
#endif
#ifndef ROOT_TString
#include "TString.h"
#endif
#ifndef ROOT_TObjString
#include "TObjString.h"
#endif
#ifndef BrRawIOH
#include "BrRawIO.h"
#endif
#ifndef NODISPATCH
#ifndef DisIOH
#include "DisIO.h"
#endif
#endif
#ifndef BRAT_BrTrigScaler
#include "BrTrigScaler.h"
#endif
#ifndef BRAT_BrZdcDig
#include "BrZdcDig.h"
#endif
#ifndef BRAT_BrBbDig
#include "BrBbDig.h"
#endif
#ifndef  BRAT_BrTrigBB
#include "BrTrigBB.h"
#endif
#ifndef  BRAT_BrTrigClock
#include "BrTrigClock.h"
#endif
#ifndef  BRAT_BrTrigZdc
#include "BrTrigZdc.h"
#endif
#ifndef  BRAT_BrTrigStart
#include "BrTrigStart.h"
#endif
#ifndef BRAT_BrTileDig
#include "BrTileDig.h"
#endif
#ifndef BRAT_BrTpcFibDig
#include "BrTpcFibDig.h"
#endif
#ifndef BRAT_BrSiDig
#include "BrSiDig.h"
#endif
#ifndef BRAT_BrTofDig
#include "BrTofDig.h"
#endif
#ifndef BRAT_BrC1Dig
#include "BrC1Dig.h"
#endif
#ifndef BRAT_BrRichDig
#include "BrRichDig.h"
#endif
#ifndef BRAT_BrDcDig
#include "BrDcDig.h"
#endif
#ifndef BRAT_BrTpcSequence
#include "BrTpcSequence.h"
#endif
#ifndef BRAT_BrDvDig
#include "BrDvDig.h"
#endif

//____________________________________________________________________
ClassImp(BrRawDataInput);


//____________________________________________________________________
const UInt_t BrRawDataInput::kBrRawDiskFile        = BIT(BR_IO_RAW_BIT); //
const UInt_t BrRawDataInput::kBrEventBuilderStream = BIT(BR_IO_EVB_BIT); //

//____________________________________________________________________
 BrRawDataInput::BrRawDataInput()
{
  //
  // Constructor. Set fFilePointer and fEventCounter to NULL
  // In root environment use the named constructor normally.
  // 
  fFileDescriptor  = NULL;
#ifndef NODISPATCH
  fDispatcher      = NULL;
#endif
  fRawEvent        = NULL;
  fReadMode        = kNULLMode;
  fRunNumber=0;
}
//____________________________________________________________________
 BrRawDataInput::BrRawDataInput(Char_t *name, Char_t* title) 
  : BrIOModule(name, (title ? title : name))
{
  //
  // Constructor. Set fFilePointer and fEventCounter to NULL
  // name becomes Name and Title for the Module.
  // No data file is opened this has to be done in
  // the Open() method.
  //
  fFileDescriptor  = NULL;
#ifndef NODISPATCH
  fDispatcher      = NULL;
#endif
  fRawEvent        = NULL;
  fReadMode        = kNULLMode;
  // Init should not be called from CTOR 
  // Init();
  fReqBatch = 50;                //Default value
  fBatchNumber = fReqBatch + 1;  //Needs to be larger for first pass
  ZeroNodesAndTables();
  fRunNumber=0;
}

//_____________________________________________________________________
 BrRawDataInput::~BrRawDataInput(){
  //
  //  Destructor for BrRawDataInput. Close the file if open.
  //
  if(fRawEvent) delete fRawEvent; fRawEvent = 0;
  if(fFileDescriptor) delete fFileDescriptor; fFileDescriptor = 0;
#ifndef NODISPATCH
  if(fDispatcher)     delete fDispatcher;     fDispatcher = 0;
#endif
}

//_____________________________________________________________________
 void BrRawDataInput::SetOn(const Char_t* part, Bool_t val)
{
  if (!strcasecmp(part,"All")) SetAllOn(val);
  if (!strcasecmp(part,"FS")) SetFSOn(val);
  if (!strcasecmp(part,"FFS")) SetFFSOn(val);
  if (!strcasecmp(part,"T1")) SetT1On(val);
  if (!strcasecmp(part,"T2")) SetT2On(val);
  if (!strcasecmp(part,"C1")) SetC1On(val);
  if (!strcasecmp(part,"H1")) SetH1On(val);
  if (!strcasecmp(part,"BFS")) SetBFSOn(val);
  if (!strcasecmp(part,"T3")) SetT3On(val);
  if (!strcasecmp(part,"T4")) SetT4On(val);
  if (!strcasecmp(part,"T5")) SetT5On(val);
  if (!strcasecmp(part,"H2")) SetH2On(val);
  if (!strcasecmp(part,"RICH")) SetRICHOn(val);
  if (!strcasecmp(part,"MRS")) SetMRSOn(val);
  if (!strcasecmp(part,"MTP1")) SetMTP1On(val);
  if (!strcasecmp(part,"MTP2")) SetMTP2On(val);
  if (!strcasecmp(part,"TOFW")) SetTOFWOn(val);
  if (!strcasecmp(part,"Global")) SetGlobalOn(val);
  if (!strcasecmp(part,"Mult")) SetMultOn(val);
  if (!strcasecmp(part,"BB")) SetBBOn(val);
  if (!strcasecmp(part,"ZDC")) SetZDCOn(val);
}


//_____________________________________________________________________
//  void BrRawDataInput::Init() {
//    // Initialize variables
//    //Set the default value of unpack everything
//
//    fReqBatch = 50;                //Default value
//    fBatchNumber = fReqBatch + 1;  //Needs to be larger for first pass
//
//    ZeroNodesAndTables();
//  }

//_____________________________________________________________________
 Bool_t BrRawDataInput::Open(const Char_t *fname, const Option_t *option)
{
  // Open the raw data file with fname or make a connection to the
  // BRAHMS event builder. Returns kFALSE if the file can't be opened
  // or cannot make connection to BRAHMS event builder.
  // Options:
  //      "DISKFILE" => Open diskfile; default
  //      "EVB"      => Open connection to event builder
  //
  fError = fEof = kFALSE;
  TString opt(option);
  opt.ToLower();
  if(opt.Contains("diskfile"))
    return OpenDiskFile(fname);
  else if(opt.Contains("evb")) 
    return OpenEventBuilder(fname);
  return kFALSE;

}

//_____________________________________________________________________
 void BrRawDataInput::OpenNext() 
{
  // PRIVATE METHOD:
  // Open the next file registered with the module, if one such
  // exists. This implements BrIOModule::OpenNext() again, since we
  // need the to non-standard options
  //   kBrRawDiskFile          for disk resident files
  //   kBrEventBuilderStream   for reading the event stream from DAQ
  
  // Test if we really got a file name 
  if (fFileName.IsNull()) {
    Failure("OpenNext", "no file name set");
    return;
  }

  // Check what kind option we need to pass to open. 
  TString openOption("");
  if (TESTBIT(fIOMode, BR_IO_RAW_BIT)) {
    fReadMode  = kDiskFile;
    openOption = "DISKFILE";
  }
  else if (TESTBIT(fIOMode, BR_IO_EVB_BIT)) {
    fReadMode  = kEventBuilder;
    openOption = "EVB";
  }
  else {
    Failure("OpenNext", "unknown file mode");
    return;
  }

  // Since this module is always a reader, we can set kBrReadFile bit
  // in the mode, which is needed by BrIOModule
  SetIOMode(fIOMode|kBrReadFile);

  // Send overloaded message, and check for error 
  if (!Open(fFileName, openOption.Data())) {
    Stop("OpenNext", "couldn't open file "%s" - raw data", 
	 fFileName.Data());
    fEof = kTRUE;
    return;
  }  
  // fEof = kFALSE;
}

//_____________________________________________________________________
 Bool_t BrRawDataInput::OpenDiskFile(const Char_t *fname) {
  // Open the raw data file with name fname.  Return the status of the open
  //
  fIOStatus = 0;
  if(!fname) {
    Failure("OpenDiskFile", "can't open unamed file "%s"", fname);
    return kFALSE;
  }

  // File name expansion adapted from TFile constructor
  const char *name;
  if ((name = gSystem->ExpandPathName(fname))) {
    fFileName = name;
    delete [] (char*)name;
  } 
  else {
    Failure("OpenDiskFile", "can't expand path "%s"", fname);
    return kFALSE;
  }

  //fFileDescriptor = new BrRawIOProxy();  //create the BrRawIO interface class
  //fFileDescriptor->create();             //create BrRawIO inside there
  if (Verbose() > 4)
    cout << "Open File " << fname << endl;

  fFileDescriptor = new BrRawIO();
  Int_t err = fFileDescriptor->readopen(fFileName.Data());
  if(err != BrRawIO::kOk) {
    Stop("OpenDiskFile", fFileDescriptor->getErrorString());
    fError = kTRUE;

    if(fRawEvent) {
      delete fRawEvent;
      fRawEvent = NULL;
    }

    return kFALSE;
  }

  fReadMode        = kDiskFile;
  fIOStatus        = 1;
  fNumBytesRead    = 0;
  fNumBytesWritten = 0;
  // create the event structure and give it what it needs.
  fRawEvent = new BrRawEvent(); 
  return kTRUE;
}

//_____________________________________________________________________
 Bool_t BrRawDataInput::OpenEventBuilder(const Char_t *fname) {
  // Open a connection to the event builder
  // Return the status of the connection.
#ifndef NODISPATCH
  // fDispatcher = new BrDisIOProxy();        //create the interface object
  // fDispatcher->create();                   //create DisIO object in there
  fDispatcher = new DisIO();
  Int_t ret   = fDispatcher->connect(fname);

  if (ret != DisIO::kOk) {
    Abort("OpenEventBuilder", 
	  "cannot connect to Dispatcher, error: %s",
	  fDispatcher->getErrorString());
    return kFALSE;
  }

  fReadMode        = kEventBuilder;
  fIOStatus        = 1;
  fNumBytesRead    = 0;
  fNumBytesWritten = 0;
  // create the event structure and give it what it needs.
  fRawEvent        = new BrRawEvent();     
  return kTRUE;
#else
  return kFALSE;
#endif
}

//_____________________________________________________________________
 Bool_t BrRawDataInput::Close()
{
  // Close the file Opened by the object. Return 
  // kFALSE if no file was open.

  if(fReadMode == kDiskFile) {
    if(fFileDescriptor){
      fFileDescriptor->close();
      delete fFileDescriptor;
      fFileDescriptor = NULL;
      delete fRawEvent; fRawEvent = NULL;
    }
    return kTRUE;
  }
#ifndef NODISPATCH
  else if(fReadMode == kEventBuilder) {
    fDispatcher->disconnect();
    return kTRUE;
  }
#endif
  else {
    Failure("Close", "Unknown read mode; it is %d", fReadMode);
    return kFALSE;
  }
}

//____________________________________________________________________
 void BrRawDataInput::SkipEvent(Int_t numevt)
{
  //Skip numevent events.  This is done by simply doing a read over the
  //number of events specified.
  if(fReadMode == kDiskFile) {

    //Check if End of file found before
    if(fEof) 
      return;

    // 
    for(Int_t iskip = 0; iskip < numevt; iskip++) {
      //    Read an event
      Int_t err = fFileDescriptor->read(*fRawEvent);

      //    Check different status's
      if(err == BrRawIO::kEof) {
	// Close();
	fEof = kTRUE;
	Stop("SkipEvent", 
	     "end of file found during skip; file has been closed");
	return;
      }
      if(err != BrRawIO::kOk) {
	fError = kTRUE;
	Stop("SkipEvent", 
	     "error reading data during skip: %s", 
	     fFileDescriptor->getErrorString());
	//       if(err == BrRawIO::kCrcError) break;
      }
    }
  }
#ifndef NODISPATCH
  else if(fReadMode == kEventBuilder) {
    Warning("SkipEvent", 
	    "skipping events makes no sense in event builder mode; "
	    "simply returning");
  }
#endif
  else 
    Failure("SkipEvent", "unknown read mode; it is %d", fReadMode);
  
}

//______________________________________________________________________
 void BrRawDataInput::Event(BrEvent* event)
{
  // Reads one event from the raw data file or from the BRAHMS event
  // builder. The BrEvent object has the data from the different
  // detectors added to the Event. 
  // 
  // This object is filled with data read from the file. It is the
  // responsibility of the calling program to have created the event.
  // 
  // Releasing the memory for this event is the responsibility of the
  // function/script calling Event(); Status of the reading can be
  // checked via the methods IsError() and IsEof().
  //
  // The Event is build as an event node with the following sub
  // nodes: 
  //
  //  Symbolic name |  Name    | Title 
  //  --------------+----------+-------
  //  FSNode:       | "FS"     | "raw"
  //   FFSNode :    | "FFS"    | "raw" 
  //   BFSNode :    | "BFS"    | "raw"
  //  MRSNode:      | "MRS"    | "raw"
  //  GlobalNode    | "Global" | "raw" 
  //
  // Each of the node has the datatables/objects for the proper
  // detectors included here. See the individual Decode methods for
  // more details. 
  //
  //

  if(fReadMode == kDiskFile) {
    // Check if End of file found before
    if(fEof) {
      if(Verbose())
	cout << "End of File .." << endl;
      Stop("Event", "End Of File");
      return;
    }

    // Set the data state to kTRUE all the time.  Don't have to worry here
    // about not getting an event from the event builder
    SetDataState(kTRUE);
    
    // Read an event
    Int_t err = fFileDescriptor->read(*fRawEvent);

    // Check different status's
    if(err == BrRawIO::kEof) {
      // Close();
      fEof = kTRUE;
      Stop("Event", "End Of File, file has been closed");
      return;
    }
    if(err != BrRawIO::kOk) {
      fError = kTRUE;
      Stop("Event", "error reading data: %s", 
	   fFileDescriptor->getErrorString());
      // if(err == BrRawIO::kCrcError) break;
    }
  }
#ifndef NODISPATCH
  else if (fReadMode == kEventBuilder) {
    // Here for reading from event builder

    // Request an event if we have read more than what we requested
    // before 
    Int_t err;

    if(fBatchNumber >= fReqBatch) {
      // We have read all of the events we requested.
      // So request more as specified by the value of fReqBatch
      Char_t RequestString[32];
      sprintf(RequestString,"REQUEST_RAW:%d",fReqBatch);
      err = fDispatcher->sendCommand(RequestString);
      fBatchNumber = 0;

      if (err != DisIO::kOk) {
	Failure("Event","cannot send command, error %d: %sn",
		err, fDispatcher->getErrorString());
	// Close();
	fEof = kTRUE;
	return;
      }
    }
    // Try to read the event
    Bool_t dontWait = kFALSE;
    // Bool_t dontWait = kTRUE;
    err = fDispatcher->readEvent(*fRawEvent,dontWait);

    if (err == DisIO::kData) {
      //    We got the event
      SetDataState(kTRUE);
      fBatchNumber++;
    }
    else if(err == DisIO::kNoData) {
      // Means there was no error, we just did not get an event this time
      // perhaps EVB paused, or DAQ stopped
      SetDataState(kFALSE);
      gSystem->Sleep(1);
    }
    else {
      Failure("Event","did not get an event, error %d: %sn",
	      err, fDispatcher->getErrorString());
      // Close();
      fEof = kTRUE;
      return;
    }  
  }
#endif
  else 
    Failure("Event", "unknown read mode; it is %d", fReadMode);
  
  // Now event has been read into memory by whatever mode was chosen.
  // Now we unpack it and build the BrEvent
 
  // First, zero nodes so we can decide if we need to build a new node
  // or not 
  if(GetDataState()) {
    // Unpack the events only if there was data.  Safer that way 
    ZeroNodesAndTables();
   
    BuildEvent(event);
  }
  else {
    if(Verbose() > 5)  
      Warning("Event","No Data");
  }
  if (DebugLevel() > 9) 
    event->Print("");
}
//________________________________________________________________________
 void BrRawDataInput::ZeroNodesAndTables() 
{
  //Zero all nodes and table pointers.
  
  //Nodes
  fFSNode               = 0;
  fFFSNode              = 0;
  fBFSNode              = 0;
  fMRSNode              = 0;
  fGlobalNode           = 0;

  //Scalers
  fTriggerScalers       = 0;
  
  //Tables
  fZDCObject            = 0;
  fZDCLoObject          = 0;
  fBBLeftTable          = 0;
  fBBRightTable         = 0;
  fBBLeftTriggerTable   = 0;
  fBBRightTriggerTable  = 0;
  fH1Table              = 0;
  fH1CalTable           = 0;
  fH2Table              = 0;
  fC1Table              = 0;
  fMultTilesTable       = 0;
  fTiles                = 0;
  fSi                   = 0;
  fMultSiTable          = 0;
  fTOFWTable            = 0;
  fTOFWCalTable         = 0;
  fRICHObject           = 0;
  fT3Table              = 0;
  fT4Table              = 0;
  fT5Table              = 0;
  fDvObject             = 0;
}

//________________________________________________________________
 void BrRawDataInput::BuildEvent(BrEvent *event) 
{
  // The table from the previous code is really obsolete
  // The proper place to check for current values is in the
  // ~daq/config/defaultmap.txt which also exists
  // as an HTML file in the daq documentation.
  //

  BrRawEvent::RecordHeader *recordlist = 0;
  Int_t numrecords = 0;
  fRawEvent->getRecordList(&numrecords,&recordlist);
  if(DebugLevel() > 15)
    cout << "BrRawDataInput::BuildEvent: Number of records: " 
	 << numrecords << endl; 
  
  for(Int_t irec=0;irec<numrecords;irec++) {
    Int_t recordId = recordlist[irec].recordId;
    fRecordFormat = fRawEvent->getRecordFormat(recordlist[irec]);
    if (DebugLevel() > 25)
      cout << "BrRawDataInput::BuildEvent: recordId = " << recordId 
	   << " Form = " << fRecordFormat << endl;
    
    if(recordId == kEventHeader) {
      BuildEventHeader(recordId, event);
    }
    else if(recordId == kEventTrigger){
      AddTriggerWord(event);
    }
    else if(recordId == kEventScaler){
      AddScalerRecord(event);
    }
    else {
      
      if(IsOn(kBrAll)) {
        int specId;
        if(recordId==2302){
	  specId = kFS;
        }
        else
	  specId   = recordId/1000;
        if(DebugLevel() > 25) 
	  cout << "SpecId = "<< specId << endl;
        if(specId == kGlobal) {
	  if(IsOn(kBrGlobal)) DecodeGlobal(recordId,event);
	}
        else if(specId == kMRS) {
	  if(IsOn(kBrMRS)) DecodeMRS(recordId, event);
	}
	else if(specId == kFS) {
	  if(IsOn(kBrFS)) DecodeFS(recordId,event);
	}
	else if(specId < 10) {
	  //          Means unmapped data
	}
      }
    }
  }
  if(recordlist) delete recordlist;
}

//___________________________________________________________________________
 void BrRawDataInput::BuildEventHeader(const Int_t recordId,
				      BrEvent *event) 
{
  // Routine to transfer raw event header to BrEventHeader from event
  // Used internally by the BrRawDataInput Class
  //
  BrRawEvent::EventHeader *evh_raw;
  Int_t evh_size;
  BrEventHeader *evh = event->GetEventHeader();
  BrRawEvent::Status err = fRawEvent->getEventHeader(evh_raw, evh_size);
  if(err == BrRawEvent::kOk) {
    fRunNumber = evh_raw->fRunNo;
    evh->SetRunNumber(evh_raw->fRunNo);
    evh->SetEventNumber(evh_raw->fEventNo);
    evh->SetTriggerMask(evh_raw->fTrigger);
    evh->SetTime(evh_raw->fEventEvbTime);
    evh->SetEventType(evh_raw->fEventType);
    Info(15 ,"BuildEventHeader", "run %d event %d", evh->RunNumber(), 
	 evh->EventNumber());
  }
  else {
    Warning("BuildEventHeader","error in event header!!!");
  }
}

//___________________________________________________________________________
 void BrRawDataInput::AddTriggerWord(BrEvent *event) 
{
  // Routine to transfer trigger words to BrEventHeader from event
  // Used internally by the BrRawDataInput Class
  //
  Int_t ret;
  Int_t nhits;
  BrEventHeader *evh = event->GetEventHeader();
  BrRawEvent::mappedAdcBlkHit_t *mapped_adc_blk_hits;

  if(fRecordFormat != BrRawEvent::kFormatAdcBlk) {
    Stop("AddTriggerWord", 
	 "record format for triggerWords not correct; it is %d" ,
	 fRecordFormat); 
    return;
  }
  ret = fRawEvent->getRecordMappedAdcBlk(kEventTrigger,
					 mapped_adc_blk_hits,nhits); 
  if(ret == BrRawEvent::kOk) {
    for(int ihit=0;ihit<nhits;ihit++) {
      BrRawEvent::mappedAdcBlkHit_t *hit = &mapped_adc_blk_hits[ihit];
      evh->SetTriggerWord(ihit+1, *hit);
    }
  }
}

//____________________________________________________________________
 void BrRawDataInput::AddScalerRecord(BrEvent *event) 
{
  // Routine to transfer scaler records to BrTriggerScalers class and
  // add that to the event.
  Int_t ret;
  Int_t nhits;
  BrRawEvent::uint32 *mapped_uint32;

  if(fRecordFormat != BrRawEvent::kFormatUint32) {
    Stop("AddScalerRecord", 
	 "Record format for Scalers not correct; it is %d",
	 fRecordFormat);
    return;
  }

  if(!fTriggerScalers) {
    fTriggerScalers = new BrTrigScaler(BRTABLENAMES kTriggerScalers,"raw");
    event->AddObject(fTriggerScalers);
  }

  ret = fRawEvent->getRecordUint32(kEventScaler, mapped_uint32,nhits);
  if(ret == BrRawEvent::kOk) {
    for(int ihit=0;ihit<nhits;ihit++) {
      BrRawEvent::uint32 *hit = &mapped_uint32[ihit];
      if(ihit < BrTrigScaler::kScalerChan) {
	fTriggerScalers->SetScaler(ihit,*hit);
      }
      else if(ihit < 2*BrTrigScaler::kScalerChan) {
	fTriggerScalers
	  ->SetVetoedScaler(ihit-BrTrigScaler::kScalerChan, *hit);    
      }
    }
  }
}

//____________________________________________________________________
 void BrRawDataInput::DecodeFS(const Int_t recordId, BrEvent *event) 
{
  //
  // Decode the forward Spectrometer Part of the data
  //
  if(!fFSNode) {
    fFSNode = new BrEventNode(BRTABLENAMES kEventNodeFS,"raw");
    event->AddEventNode(fFSNode);
  }
  if(IsOn(kBrFFS)) DecodeFFS(recordId);
  if(IsOn(kBrBFS)) DecodeBFS(recordId);
}

//____________________________________________________________________
 void BrRawDataInput::DecodeFFS(const Int_t recordId) 
{
  Int_t nhits;
  BrRawEvent::mappedATBlkHit_t  *mapped_at_blk_hits;

  Int_t ret;
  Int_t ihit;
  Char_t TableName[64];

  if(!fFFSNode) {
    fFFSNode = new BrEventNode(BRTABLENAMES kEventNodeFFS,"raw");
    fFSNode->AddEventNode(fFFSNode);
  }
  
  switch(recordId) {

  case kH1Cal:
    if(IsOn(kBrTOF1)) {
      UnpackH1Cal(recordId);
    }
    break;
    
  case kTD1:
    UnpackTriggerD1(recordId);
    break;
    
  case kH1:
    if(IsOn(kBrTOF1)) {
      ret = fRawEvent->getRecordMappedATBlk(kH1,mapped_at_blk_hits,nhits);
      if(ret == BrRawEvent::kOk) {
	// Do we have to make this check? Will we com here only once
	// per event?? 
	if(!fH1Table) {
          sprintf(TableName,"%s TOF1",BRTABLENAMES kDigTof);
	  fH1Table = new BrDataTable(TableName,"Raw");
	  fFFSNode->AddDataTable(fH1Table);
	}
	if(nhits != 80)
	  Warning("DecodeFFS", 
		  "nhit for H1 != 80, check it out; it is %d", nhits);
	for(ihit=0;ihit<40;ihit++) {
	  BrTofDig *digtof_p = new BrTofDig();
	  fH1Table->Add(digtof_p);
	  BrRawEvent::mappedATBlkHit_t *hit_up,*hit_down;
	  hit_up   = &mapped_at_blk_hits[ihit];
	  hit_down = &mapped_at_blk_hits[ihit+40];
	  digtof_p->SetSlatno(ihit+1);
	  digtof_p->SetAdcDown(hit_down->adc);
	  digtof_p->SetAdcUp(hit_up->adc);
	  digtof_p->SetTdcDown(hit_down->tdc);
	  digtof_p->SetTdcUp(hit_up->tdc);
	}
      }
      else {
	Warning("DecodeFFS", "Error on H1");
      }
    }
    break;
    
    
  case kC1:
    if(IsOn(kBrC1)) {
      // First check that the record format is what we will read.  If not
      // iform user and get out as what we would do would be bogus anyway
      if(fRecordFormat != BrRawEvent::kFormatATBlk) {
	Stop("DecodeFFS", 
	     "record format for C1 not correct; it is %d",
	     fRecordFormat);
	return;
      }
      ret=fRawEvent->getRecordMappedATBlk(kC1,
					  mapped_at_blk_hits,
					  nhits);
      if(ret == BrRawEvent::kOk) {
	if(nhits != 32) {
	  Stop("DecodeFFS", 
	       "C1: nhits !=32, they are %d returning!!!", nhits);
	  return;
	}
	BrC1Dig *digc1_p = new BrC1Dig(BRTABLENAMES kDigC1,"Raw");
	fFFSNode->AddObject(digc1_p);
	
	for(ihit=0;ihit<nhits;ihit++) {
	  BrRawEvent::mappedATBlkHit_t *hit = &mapped_at_blk_hits[ihit];
	  digc1_p->SetAdc(ihit+1,hit->adc);
	}
      }
      else {
	Warning("DecodeFFS", "Error on C1");
      }
    }
    break;

  case kT2FFib:
  case kT1BFib:
    UnpackTpcFib(recordId);
    break;
    
    
  case 2302:
  case kT1B: 
  case kT1:
  case kT2B:
  case kT2:
    //
    // This code can be called as a method for the 4 TPC- only the 
    // name is different
    //
    {
      Int_t length; 
      BrRawEvent::uint16 *buf16=0;
      if(fRawEvent->getRecordUint16(recordId, buf16, length) !=
	 fRawEvent->kOk) { 
	Warning("DecodeFFS", "cannot get record %d",recordId);
	break;
      }
      if(DebugLevel() > 20) 
	fFFSNode->ListObjects();
      BrDataTable* fTable;
      if(recordId==kT1B){
	sprintf(TableName,"%s T1B",BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName,"Raw mapped");
	fFFSNode->AddDataTable(fTable);
      }
      else if(recordId==kT1){
	sprintf(TableName,"%s T1",BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName, "Raw mapped");
	fFFSNode->AddDataTable(fTable);
      }
      else if(recordId == kT2B){
	sprintf(TableName,"%s T2B",BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName,"Raw mapped");
	fFFSNode->AddDataTable(fTable);
      }
      else if(recordId == kT2){
	sprintf(TableName,"%s T2",BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName, "Raw mapped");
	fFFSNode->AddDataTable(fTable);
      }
      else if(recordId == 2302){
	sprintf(TableName,"%s T1B",BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName,"Raw mapped");
	fFFSNode->AddDataTable(fTable);
      }
      
      Short_t* bufp = (Short_t*) buf16;
      for(int ip = 0; ip+3< length; ){
	Short_t padrow  = bufp[ip+0];
	Short_t time    = bufp[ip+1];
	Short_t numbins = bufp[ip+2];
	Short_t row     = (padrow >> 8) & 0x7F;
	Short_t pad     = padrow & 0xff;
	
	BrTpcSequence* tpcSeq = new BrTpcSequence(numbins);
	fTable->Add(tpcSeq);
	tpcSeq->SetPad(pad); 
	tpcSeq->SetRow(row);
	tpcSeq->SetTime(time);
	Short_t* adc = tpcSeq->GetSequence();
	for(int it=0; it<numbins;it++){
	  *(adc++)  = bufp[ip+it+3];
	}
	ip+=3+numbins;
      }
    }
    break;
    
    
  default:
    break;
  }
  
  //Get WF1
  //Get WF2
}

//______________________________________________________________________
 void BrRawDataInput::DecodeBFS(const Int_t recordId) 
{
  Int_t nhits;
  BrRawEvent::mappedAdcBlkHit_t *mapped_adc_blk_hits;
  BrRawEvent::mappedATBlkHit_t *mapped_at_blk_hits;
  Int_t ret;
  Int_t ihit;
  Char_t TableName[64];

  if(!fBFSNode) {
    fBFSNode = new BrEventNode(BRTABLENAMES kEventNodeBFS,"raw");
    fFSNode->AddEventNode(fBFSNode);
  }
  
  switch(recordId) {
  case kH2:
    //    Get H2
    if(IsOn(kBrTOF2)) {
      ret = fRawEvent->getRecordMappedATBlk(kH2, mapped_at_blk_hits,
					    nhits); 
      if(ret == BrRawEvent::kOk) {
	// Necessary to make this check? Will we come here only once
	// per event 
	if(!fH2Table) {
	  sprintf(TableName,"%s TOF2",BRTABLENAMES kDigTof);
	  fH2Table = new BrDataTable(TableName,"Raw");
	  fBFSNode->AddDataTable(fH2Table);
	}
	if(nhits != 64) {
	  Warning("DecodeBFS", 
		  "nhit for H2 != 64, check it out; it is %d", nhits);
	}
	for(ihit=0;ihit<32;ihit++) {
	  BrTofDig *digtof_p = new BrTofDig();
	  fH2Table->Add(digtof_p);
	  BrRawEvent::mappedATBlkHit_t *hit_up,*hit_down; 
	  hit_up   = &mapped_at_blk_hits[ihit];
	  hit_down = &mapped_at_blk_hits[ihit+32];
	  digtof_p->SetSlatno(ihit+1);
	  digtof_p->SetAdcDown(hit_down->adc);
	  digtof_p->SetAdcUp(hit_up->adc);
	  digtof_p->SetTdcDown(hit_down->tdc);
	  digtof_p->SetTdcUp(hit_up->tdc);
	}
      }
      else 
	Warning("DecodeBFS", "error on H2");
    }
    break;
  case kRICH:
    if(IsOn(kBrRICH)) {
      // First check that the record format is what we will read.  If
      // not inform user and get out as what we would do would be
      // bogus anyway 
      if(fRecordFormat != BrRawEvent::kFormatAdcBlk) {
	Stop("DecodeBFS", 
	     "record format for RICH not correct; it is %d",
	     fRecordFormat);
	return;
      }
      ret=fRawEvent->getRecordMappedAdcBlk(kRICH,mapped_adc_blk_hits,nhits);
      if(ret == BrRawEvent::kOk) {
	BrRichDig *digrich_p;
	// Check if RICH table was already created.  If not, make it,
	// and add to node.  Then create BrRichDig and add to table.
	// If it was already created, give an error message
	if(!fRICHObject) {
	  fRICHObject = new BrRichDig(BRTABLENAMES kDigRICH,"raw");
	  digrich_p = fRICHObject;
	  fBFSNode->AddObject(digrich_p);
	}
	else {
	  Warning("DecodeBFS", 
		  "RICH table already exists; how did that happen; "
		  "check it out");
	}
	
	if(nhits != kNumRICHChan) {
	  Stop("DecodeBFS", 
	       "RICH:nhits != %d, they are %d returning!!!",
	       kNumRICHChan, nhits);  
	  return;
	}
	for(ihit=0;ihit<nhits;ihit++) {
	  BrRawEvent::mappedAdcBlkHit_t *hit = &mapped_adc_blk_hits[ihit];
	  digrich_p->SetAdc(ihit+1,*hit);
	}
      }
      else 
	Warning("DecodeBFS", "error on RICH");
    }
    break;

    //All cases having to do with T3
  case kT31X1:
  case kT31X2:
  case kT31X3:
  case kT31Y1:
  case kT31Y2:
  case kT31Y3:
  case kT31U1:
  case kT31U2:
  case kT31V1:
  case kT31V2:
  case kT32X1:
  case kT32X2:
  case kT32X3:
  case kT32Y1:
  case kT32Y2:
  case kT32Y3:
  case kT32U1:
  case kT32U2:
  case kT32V1:
  case kT32V2:
  case kT33X1:
  case kT33X2:
  case kT33X3:
  case kT33Y1:
  case kT33Y2:
  case kT33Y3:
  case kT33U1:
  case kT33U2:
  case kT33V1:
  case kT33V2:
    if(IsOn(kBrT3)) {
      //Bool_t ret = UnpackT3(recordId);//comment until we really use ret
      UnpackT3(recordId);
    }
    break;

    //All cases having to do with T4
  case kT41X1:
  case kT41X2:
  case kT41Y1:
  case kT41Y2:
  case kT41U1:
  case kT41U2:
  case kT41V1:
  case kT41V2:
  case kT42X1:
  case kT42X2:
  case kT42Y1:
  case kT42Y2:
  case kT42U1:
  case kT42U2:
  case kT42V1:
  case kT42V2:
  case kT43X1:
  case kT43X2:
  case kT43Y1:
  case kT43Y2:
  case kT43U1:
  case kT43U2:
  case kT43V1:
  case kT43V2:
    if(IsOn(kBrT4)) {
      //Bool_t ret = UnpackT4(recordId);//comment until we really use ret
      UnpackT4(recordId);
    }
    break;

    //All cases having to do with T5
  case kT51X1:
  case kT51X2:
  case kT51Y1:
  case kT51Y2:
  case kT51U1:
  case kT51U2:
  case kT51V1:
  case kT51V2:
  case kT52X1:
  case kT52X2:
  case kT52Y1:
  case kT52Y2:
  case kT52U1:
  case kT52U2:
  case kT52V1:
  case kT52V2:
  case kT53X1:
  case kT53X2:
  case kT53Y1:
  case kT53Y2:
  case kT53U1:
  case kT53U2:
  case kT53V1:
  case kT53V2:
    if(IsOn(kBrT5)) {
      //Bool_t ret = UnpackT5(recordId);//comment until we really use ret
      UnpackT5(recordId);
    }
    break;


    
  default:
    break;
  }
  
  //Get T3
  //Get T4
  //Get T5

}
//________________________________________________________________________
 void BrRawDataInput::DecodeMRS(const Int_t recordId,BrEvent *event) 
{
  // private method to look for and fill datatable for detectors in
  // the MidRapidity Spectrometer.

  //Get WM1
  //Get WM2
  Char_t TableName[64];
  BrRawEvent::mappedATBlkHit_t *mapped_at_blk_hits;
  int nhits;
  if(!fMRSNode) {
    fMRSNode = new BrEventNode(BRTABLENAMES kEventNodeMRS,"raw");
    event->AddEventNode(fMRSNode);
  }

  switch(recordId) {

  case kTOFWTop:
  case kTOFWBottom:

    if(IsOn(kBrTOFW)) {
      //Bool_t ret = UnpackTOFW(recordId); //to be uncommented when error imp
      UnpackTOFW(recordId);
    }
    break;
    
  case kTOFWCal:
    if(IsOn(kBrTOFW)) {
      UnpackTOFWCal(recordId);
    }
    break;


  case kTOFW:
    //    Get TOFW
    if(IsOn(kBrTOFW)) {
      if(DebugLevel() > 10)
	cout << "BrRawDataInput::DecodeMRS: " 
	     << "Calling getRecordMapped business" << endl;

      int ret = fRawEvent->getRecordMappedATBlk(recordId,
						mapped_at_blk_hits,
						nhits);
      printf("NSlats read = %dn",nhits/2);

      if(DebugLevel() > 10)
	cout << "BrRawDataInput::DecodeMRS: " 
	     << "Back from business, nhits = " << nhits << endl;

      if(ret == BrRawEvent::kOk) {
	// Necessary to make this check
	// Because there are now two records
	if(!fTOFWTable) {
	  sprintf(TableName,"%s TOFW",BRTABLENAMES kDigTof);
	  fTOFWTable = new BrDataTable(TableName,"Raw");
	  fMRSNode->AddDataTable(fTOFWTable);
	}
	const int nslats     = 83;
	const int first_down =  0;
	const int first_up   = 96;
	if(nhits < (nslats*2)) {
	  Warning("DecodeMRS", 
		  "nhit for TOFW < (nslats*2), check it out; it is %d",
		  nhits);
	}
	for(int ihit=0;ihit<nslats;ihit++) {
	  BrTofDig *digtof_p = new BrTofDig();
	  fTOFWTable->Add(digtof_p);
	  BrRawEvent::mappedATBlkHit_t *hit_up,*hit_down; 
	  hit_down = &mapped_at_blk_hits[ihit+first_down];
	  hit_up   = &mapped_at_blk_hits[ihit+first_up];
	  digtof_p->SetSlatno(ihit+1);
	  digtof_p->SetAdcDown(hit_down->adc);
	  digtof_p->SetAdcUp(hit_up->adc);
	  digtof_p->SetTdcDown(hit_down->tdc);
	  digtof_p->SetTdcUp(hit_up->tdc);
	}
      }
      else {
	Warning("DecodeMRS", "error on TOFW");
      }
    }
    break;
 
  case kTpm2FFib:
  case kTpm2BFib:
  case kT2FFib:
    UnpackTpcFib(recordId);
    break;
    
    
  case kTPM1B: 
  case kTPM1:
  case kTPM2B:
  case kTPM2:
  
    //
    // This code can be called as a method for the 4 TPC- only the
    // name is different 
    //
    {
      Int_t length; 
      BrRawEvent::uint16 *buf16=0;
      Char_t TableName[32];
      if(fRawEvent->getRecordUint16(recordId, buf16, length) !=
	 fRawEvent->kOk) { 
	Warning("DecodeMRS", "cannot get record %d",recordId);
	break;
      }
      if(DebugLevel() > 20)
	fMRSNode->ListObjects();
      BrDataTable* fTable;
      if(recordId== kTPM1B){
	sprintf(TableName,"%s TPM1B", BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName,"Raw mapped");
	fMRSNode->AddDataTable(fTable);
      }
      else if(recordId==kTPM1){
	sprintf(TableName,"%s TPM1", BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName, "Raw mapped");

	fMRSNode->AddDataTable(fTable);
      }
      else if(recordId == kTPM2B){
	sprintf(TableName,"%s TPM2B", BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName,"Raw mapped");
	fMRSNode->AddDataTable(fTable);
      }
      else if(recordId == kTPM2){
	sprintf(TableName,"%s TPM2", BRTABLENAMES kTPCSequence);
	fTable = new BrDataTable(TableName, "Raw mapped");
 	fMRSNode->AddDataTable(fTable);
      }
      
      Short_t* bufp = (Short_t*) buf16;
      for(int ip = 0; ip+3< length; ){
	Short_t padrow = bufp[ip+0];
	Short_t time   = bufp[ip+1];
	Short_t numbins = bufp[ip+2];
	Short_t row = (padrow >> 8) & 0x7F;
	Short_t pad = padrow&0xff;
	
	BrTpcSequence* tpcSeq = new BrTpcSequence(numbins);
	fTable->Add(tpcSeq);
	tpcSeq->SetPad(pad); 
	tpcSeq->SetRow(row);
	tpcSeq->SetTime(time);
	Short_t* adc = tpcSeq->GetSequence();
	for(int it=0; it<numbins;it++){
	  *(adc++)  = bufp[ip+it+3];
	}
	ip+=3+numbins;
      }
    }
    break;

  case kTMRS:
    UnpackTriggerMrs(recordId);
  default:
    break;
  }
  
  
}

//______________________________________________________________________
 void BrRawDataInput::DecodeGlobal(const Int_t recordId,BrEvent *event) 
{
  // Internal method to decode the global Raw Data events
  //
  Char_t TableName[64];
  
  Int_t nhits;
  BrRawEvent::mappedATBlkHit_t *mapped_at_blk_hits;
  BrRawEvent::mappedAdcBlkHit_t *mapped_adc_blk_hits;
  BrRawEvent::mappedTdcHit_t *mapped_tdc_blk_hits;
  Int_t ret;
  Int_t ihit;
  
  //Make the new global node if we need to.
  if(!fGlobalNode) {
    fGlobalNode = new BrEventNode(BRTABLENAMES kEventNodeGlobal,"raw");
    event->AddEventNode(fGlobalNode);
  }
  
  switch(recordId) {
  
  case kZDC:
  case kZDCLo:
    if(IsOn(kBrZDC)) {
      //First check that the record format is what we will read.  If not
      //inform user and get out as what we would do would be bogus anyway
      if(fRecordFormat != BrRawEvent::kFormatATBlk) {
	Stop("DecodeGlobal",
	     "Record format for ZDC not correct; it is %d",
	     fRecordFormat);  
	return;
      }
      ret = fRawEvent->getRecordMappedATBlk(recordId,
					    mapped_at_blk_hits,
					    nhits);
      if(ret == BrRawEvent::kOk) {
	BrZdcDig *digzdc_p;
	if(recordId == kZDC) {
	  if(!fZDCObject)   fZDCObject   = new BrZdcDig(BRTABLENAMES kDigZDC,  "raw");
	  digzdc_p = fZDCObject;          //set pointer to raw data object
	} else {
	  if(!fZDCLoObject) fZDCLoObject = new BrZdcDig(BRTABLENAMES kDigZDCLo,"raw");
	  digzdc_p = fZDCLoObject;        //set pointer to raw data object
	}
	fGlobalNode->AddObject(digzdc_p);
       
	if(nhits != 8) {
	  Warning("DecodeGlobal",
		  "ZDC:nhits !=8, they are %d returning!!!", 
		  nhits);
	  return;
	}
	for(ihit=0; ihit<nhits/2; ihit++) {
	  BrRawEvent::mappedATBlkHit_t *lhit = &mapped_at_blk_hits[ihit];
	  BrRawEvent::mappedATBlkHit_t *rhit = &mapped_at_blk_hits[ihit+4];
	 
	  if(ihit < 3) {
	    digzdc_p->SetRightAdc(ihit,rhit->adc);
	    digzdc_p->SetRightTdc(ihit,rhit->tdc);
	    digzdc_p->SetLeftAdc(ihit,lhit->adc);
	    digzdc_p->SetLeftTdc(ihit,lhit->tdc);
	  }
	  else if(ihit == 3) {
	    digzdc_p->SetRightAdcSum(rhit->adc);
	    digzdc_p->SetRightTdcSum(rhit->tdc);
	    digzdc_p->SetLeftAdcSum(lhit->adc);
	    digzdc_p->SetLeftTdcSum(lhit->tdc);
	  }
	}
      }
      else {
	Warning("DecodeGlobal", "error on ZDC");
      }
    }
    break;
   
  case kBBCRight:
  case kBBCLeft:
    UnpackBeamBeam(recordId);
    break;
  
  case kMultSi:
    //    Get MultSi
    if(IsOn(kBrSi)) {
      if(fRecordFormat != BrRawEvent::kFormatAdcBlk) {
	Stop("DecodeGlobal",
	     "Record format for Silicon not correct; it is %d",
	     fRecordFormat);  
	return;
      }

      ret = fRawEvent->getRecordMappedAdcBlk(kMultSi
					     ,mapped_adc_blk_hits
					     ,nhits);
      if(ret == BrRawEvent::kOk) {
	if(!fSi) {
	  fSi = new BrSiDig(BRTABLENAMES kDigSi,"Raw");
	  fGlobalNode->AddObject(fSi);
	}
	for(ihit=0;ihit<nhits;ihit++) {
	  BrRawEvent::mappedAdcBlkHit_t *hit = &mapped_adc_blk_hits[ihit];

	  fSi->SetAdc(ihit+1, *hit);

	}
      }
      else {
	Warning("DecodeGlobal", "error on Silicon");
      }
    }
    break;
   
  case kMultTiles:
    //    Get MultTiles
    if(IsOn(kBrTile)) {
      if(fRecordFormat != BrRawEvent::kFormatAdcBlk) {
	Stop("DecodeGlobal",
	     "Record format for PTMA not correct; it is %d",
	     fRecordFormat);  
	return;
      }
      ret = fRawEvent->getRecordMappedAdcBlk(kMultTiles
					     ,mapped_adc_blk_hits
					     ,nhits);
      if(ret == BrRawEvent::kOk) {
	if(!fTiles) {
	  fTiles = new BrTileDig(BRTABLENAMES kDigTiles,"Raw");
	  fGlobalNode->AddObject(fTiles);
	}
	for(ihit=0;ihit<nhits;ihit++) {
	  BrRawEvent::mappedAdcBlkHit_t *hit = &mapped_adc_blk_hits[ihit];
	  fTiles->SetAdc(ihit+1, *hit);
	  fTiles->SetId(ihit+1,ihit+1);  //Placekeeper until we zero suppress
	}
      }
      else {
	Warning("DecodeMRS", "error on tiles");
      }
    }
    break;

  case kTriggerBBL:
  case kTriggerBBR:
    UnpackTriggerBB(recordId);
    break;
    
  case kDriftVelTPC:
    UnpackDriftVel(recordId);
    break;
    
  case kTriggerStart:
    UnpackTrigStart(recordId);
    break;

  case kClock:
    UnpackTrigClock(recordId);
    break;

  case kInelRing:
    UnpackInelRing(recordId);
    break;

  case kInelAll:
    UnpackInel(recordId);
    break;

  case kZDCLeft:
    // We should never come here after 10-Dec-1999; kZDCLeft Obsolete
    // after deciding to put all ZDC's in one record.
    if(Verbose() > 5)
      Warning("DecodeGlobal", 
	      "recordId kZDCLeft found, this is obsolete; check it out");
    if(IsOn(kBrZDC)) {
      // First check that the record format is what we will read.  If
      // not inform user and get out as what we would do would be
      // bogus anyway 
      if(fRecordFormat != BrRawEvent::kFormatATBlk) {
	Stop("DecodeGlobal",
	     "Record format for ZDC left not correct; it is %d", 
	     fRecordFormat);  
	return;
      }

      ret = fRawEvent->getRecordMappedATBlk(kZDCLeft,
					    mapped_at_blk_hits,
					    nhits);
      if(ret == BrRawEvent::kOk) {
	BrZdcDig *digzdc_p;
       
	// Check if ZDC table was already created.  If not, make it,
	// and add to node.  Then create BrZdcDig and add to table.
	// If it was already created, get the BrZdcDig out so we can
	// fill the rest of it 
	if(!fZDCObject) {
	  fZDCObject = new BrZdcDig(BRTABLENAMES kDigZDC,"raw");
	  fGlobalNode->AddObject(fZDCObject);
	  digzdc_p = fZDCObject;
	}
	digzdc_p = fZDCObject;
       
	if(nhits != 4) {
	  Warning("DecodeGlobal", 
		  "ZDC Left:nhits !=4, they are %d returning!!!", 
		  nhits);
	  return;
	}
	for(ihit=0;ihit<nhits;ihit++) {
	  BrRawEvent::mappedATBlkHit_t *hit = &mapped_at_blk_hits[ihit];
	 
	  if(ihit < 3) {
	    digzdc_p->SetLeftAdc(ihit,hit->adc);
	    digzdc_p->SetLeftTdc(ihit,hit->tdc);
	  }
	  else if(ihit == 3) {
	    digzdc_p->SetLeftAdcSum(hit->adc);
	    digzdc_p->SetLeftTdcSum(hit->tdc);
	  }	 
	}
      }
      else {
	Warning("DecodeMRS", "error on ZDC Left");
      }
    }
    break;
   
  case kZDCRight:
    // We should never come here after 10-Dec-1999; kZDCLeft Obsolete
    // after deciding to put all ZDC's in one record.
    if(Verbose() > 5)
      Warning("DecodeGlobal", 
	      "recordId kZDCLeft found, this is obsolete; check it out");
    // Get ZDC Right
    if(IsOn(kBrZDC)) {
      // First check that the record format is what we will read.  If
      // not inform user and get out as what we would do would be
      // bogus anyway 
      if(fRecordFormat != BrRawEvent::kFormatATBlk) {
	Stop("DecodeGlobal",
	     "Record format for ZDC right not correct; it is %d", 
	     fRecordFormat);  
	return;
      }
      ret=fRawEvent->getRecordMappedATBlk(kZDCRight,mapped_at_blk_hits,nhits);
      if(ret == BrRawEvent::kOk) {
	BrZdcDig *digzdc_p;
	//Check if ZDC table was already created.  If not, make it, and add
	//to node.  Then create BrZdcDig and add to table.  If it was
	//already created, get the BrZdcDig out so we can fill the rest of it
	if(!fZDCObject) {
	  fZDCObject = new BrZdcDig(BRTABLENAMES kDigZDC,"raw");
	  fGlobalNode->AddObject(fZDCObject);
	}
	digzdc_p = fZDCObject;
       
	if(nhits != 4) {
	  Warning("DecodeGlobal", 
		  "ZDC Right:nhits !=4, they are %d returning!!!", 
		  nhits);
	  return;
	}
	for(ihit = 0; ihit < nhits; ihit++) {
	  BrRawEvent::mappedATBlkHit_t *hit =
	    &mapped_at_blk_hits[ihit]; 
	 
	  if(ihit < 3) {
	    digzdc_p->SetRightAdc(ihit,hit->adc);
	    digzdc_p->SetRightTdc(ihit,hit->tdc);
	  }
	  else if(ihit == 3) {
	    digzdc_p->SetRightAdcSum(hit->adc);
	    digzdc_p->SetRightTdcSum(hit->tdc);
	  }
	}
      }
      else {
	Warning("DecodeGlobal", "error on ZDC Right");
      }
    }
    break;
   
  default:
    Warning("DecodeGlobal", 
	    "Invalid recordId; better check it out, it is %d", 
	    recordId);
    break;

  }

}

//____________________________________________________________________________________________
 Bool_t BrRawDataInput::UnpackBeamBeam(const Int_t recordId){
  //
  // Unpack either the Left or the right beam-Beam counter module
  // Unfortunately a hardware error was found and re-mapping dependent on run-number
  // is beeing introduced.
  // Fix at RUN 6061 (properly present for most of 2001/2002 run 
  // in error at 4671..
  //

  if(!IsOn(kBrBB))
    return kTRUE;

  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("Decode Global", 
	 "record format for BBC Left/right not correct; it is %d",
	 fRecordFormat);
      return kFALSE;
  }
  int nhits;
  BrRawEvent::mappedATBlkHit_t  *mapped_at_blk_hits;
  int ret = fRawEvent->getRecordMappedATBlk(recordId,
					    mapped_at_blk_hits, nhits);
  if(!(ret == BrRawEvent::kOk)) {
    Warning("DecodeGlobal", "error on BBC Left/Right %d", recordId);
    return kFALSE;
  }
  
  Char_t TableName[32];
  if(recordId ==  kBBCLeft)
    sprintf(TableName,"%s Left",BRTABLENAMES kDigBB);
  
  if(recordId ==  kBBCRight)
    sprintf(TableName,"%s Right",BRTABLENAMES kDigBB);
  
  BrDataTable*  table = new BrDataTable(TableName,"Raw");
  fGlobalNode->AddDataTable(table);
  //
  // Setup for mapping
  // Can definitely be made better- hopfully we will not need this for more channels!!
  //

  for(int ihit=0;ihit<nhits;ihit++) {
    BrBbDig *digbb_p = new BrBbDig();
    table->Add(digbb_p);
    BrRawEvent::mappedATBlkHit_t *hit = &mapped_at_blk_hits[ihit];
    digbb_p->SetId(ihit+1);
    digbb_p->SetAdc(hit->adc);
    digbb_p->SetTubeNo(ihit+1);
    digbb_p->SetTdc(hit->tdc);
  }
  
  
  if(fRunNumber < 6061 && fRunNumber > 500){
    if(recordId ==  kBBCRight){
      BrBbDig *digbb_20 = (BrBbDig*) table->At(19);
      BrBbDig *digbb_23 = (BrBbDig*) table->At(22);
      int tmp = digbb_20->GetTdc();
      assert(digbb_20->GetTubeNo()==20);
      assert(digbb_23->GetTubeNo()==23);
      digbb_20->SetTdc(digbb_23->GetTdc());
      digbb_23->SetTdc(tmp);
    }
  }
  
  return kTRUE;
}

//____________________________________________________________________________________
 Bool_t BrRawDataInput::UnpackTriggerBB(const Int_t recordId){
  //
  // trigger pipeline data
  //
  if(fRecordFormat != BrRawEvent::kFormatTdc) {
    Stop("DecodeGlobal",
	 "Record format for Beam-Beam left trigger not "
	 "correct; it is %d", fRecordFormat);  
    return kFALSE;
  }
  Int_t nhits;
  BrRawEvent::mappedTdcHit_t *mapped_tdc_blk_hits;
  
  Int_t  ret = fRawEvent->getRecordMappedTdc(recordId,
					     mapped_tdc_blk_hits, 
					     nhits);
  
  
  if(!(ret == BrRawEvent::kOk))
    return kFALSE;

  if(nhits > 0){
    Char_t TableName[32];
    if(recordId == kTriggerBBL)
      sprintf(TableName,"%s Left", BRTABLENAMES kTrigBB);
    if(recordId == kTriggerBBR)
      sprintf(TableName,"%s Right",BRTABLENAMES kTrigBB);
    
    BrDataTable* table = new BrDataTable(TableName,"Raw");
    fGlobalNode->AddDataTable(table);
    
    for(int ihit=0; ihit < nhits;ihit++){
      BrRawEvent::mappedTdcHit_t *hit = &mapped_tdc_blk_hits[ihit];
      BrTrigBB *trigbb_p = new BrTrigBB();
      table->Add(trigbb_p);
      trigbb_p->SetId(ihit+1);
      trigbb_p->SetTubeNo((hit->channel)+1);
      trigbb_p->SetTdc(hit->tdcLeadingEdge);
      trigbb_p->SetWidth(hit->tdcWidth);
    }
  }    
  return kTRUE;
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackT3(const Int_t recordId) 
{
  // Unpack raw data for T3.  There will be a wide variety of
  // recordId's each of which corresponds to a different plane.  They
  // will be managed /here and assembled into proper DigDC's returns
  // kTRUE if unpacking successful returns kFALSE if not successful,
  // ie if recordId does not correspond to something for T3

  BrRawEvent::mappedTdcHit_t   *mapped_tdc_hits;
  Int_t iplane,submod;
  Int_t ret,ihit,nhits;
  Char_t TableName[64];
  BrDataTable *dcTable;

  // First check that the record format is what we will read.  If not 
  // inform user and get out as what we would do would be bogus anyway
  if(fRecordFormat != BrRawEvent::kFormatTdc) {
    Stop("UnpackT3",
	 "Record format for T3 right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  ret=fRawEvent->getRecordMappedTdc(recordId,mapped_tdc_hits,nhits);
  if(ret == BrRawEvent::kOk) {
    BrDcDig *digdc_p;
    if(!fT3Table) {
      sprintf(TableName,"%s T3",BRTABLENAMES kDigDC);
      fT3Table = new BrDataTable(TableName,"Raw mapped");
      fBFSNode->AddDataTable(fT3Table);
    }
    dcTable = fT3Table;

    //T3 submodule 1
    if(recordId == kT31X1) {
      iplane = BrDcDig::kT3X1;
      submod = 1;
    }
    else if(recordId == kT31X2) {
      iplane = BrDcDig::kT3X2;
      submod = 1;
    }
    else if(recordId == kT31X3) {
      iplane = BrDcDig::kT3X3;
      submod = 1;
    }
    else if(recordId == kT31Y1) {
      iplane = BrDcDig::kT3Y1;
      submod = 1;
    }
    else if(recordId == kT31Y2) {
      iplane = BrDcDig::kT3Y2;
      submod = 1;
    }
    else if(recordId == kT31Y3) {
      iplane = BrDcDig::kT3Y3;
      submod = 1;
    }
    else if(recordId == kT31U1) {
      iplane = BrDcDig::kT3U1;
      submod = 1;
    }
    else if(recordId == kT31U2) {
      iplane = BrDcDig::kT3U2;
      submod = 1;
    }
    else if(recordId == kT31V1) {
      iplane = BrDcDig::kT3V1;
      submod = 1;
    }
    else if(recordId == kT31V2) {
      iplane = BrDcDig::kT3V2;
      submod = 1;
    }

    //T3 submodule 2
    else if(recordId == kT32X1) {
      iplane = BrDcDig::kT3X1;
      submod = 2;
    }
    else if(recordId == kT32X2) {
      iplane = BrDcDig::kT3X2;
      submod = 2;
    }
    else if(recordId == kT32X3) {
      iplane = BrDcDig::kT3X3;
      submod = 2;
    }
    else if(recordId == kT32Y1) {
      iplane = BrDcDig::kT3Y1;
      submod = 2;
    }
    else if(recordId == kT32Y2) {
      iplane = BrDcDig::kT3Y2;
      submod = 2;
    }
    else if(recordId == kT32Y3) {
      iplane = BrDcDig::kT3Y3;
      submod = 2;
    }
    else if(recordId == kT32U1) {
      iplane = BrDcDig::kT3U1;
      submod = 2;
    }
    else if(recordId == kT32U2) {
      iplane = BrDcDig::kT3U2;
      submod = 2;
    }
    else if(recordId == kT32V1) {
      iplane = BrDcDig::kT3V1;
      submod = 2;
    }
    else if(recordId == kT32V2) {
      iplane = BrDcDig::kT3V2;
      submod = 2;
    }

    //T3 submodule 3
    else if(recordId == kT33X1) {
      iplane = BrDcDig::kT3X1;
      submod = 3;
    }
    else if(recordId == kT33X2) {
      iplane = BrDcDig::kT3X2;
      submod = 3;
    }
    else if(recordId == kT33X3) {
      iplane = BrDcDig::kT3X3;
      submod = 3;
    }
    else if(recordId == kT33Y1) {
      iplane = BrDcDig::kT3Y1;
      submod = 3;
    }
    else if(recordId == kT33Y2) {
      iplane = BrDcDig::kT3Y2;
      submod = 3;
    }
    else if(recordId == kT33Y3) {
      iplane = BrDcDig::kT3Y3;
      submod = 3;
    }
    else if(recordId == kT33U1) {
      iplane = BrDcDig::kT3U1;
      submod = 3;
    }
    else if(recordId == kT33U2) {
      iplane = BrDcDig::kT3U2;
      submod = 3;
    }
    else if(recordId == kT33V1) {
      iplane = BrDcDig::kT3V1;
      submod = 3;
    }
    else if(recordId == kT33V2) {
      iplane = BrDcDig::kT3V2;
      submod = 3;
    }
    else {
      Stop("UnpackT3", "invalid recordId; it is %d", recordId);
      return kFALSE;
    }
    
    for(ihit=0;ihit<nhits;ihit++) {
      Int_t ip=iplane;
      digdc_p = new BrDcDig();
      dcTable->Add(digdc_p);

      if(submod==2 && fRunNumber<6763){
	Int_t newplane=0;
	Int_t iwire=mapped_tdc_hits[ihit].channel;
	if(iplane==BrDcDig::kT3Y2 && iwire<15)newplane=BrDcDig::kT3Y3;
	if(iplane==BrDcDig::kT3Y3 && iwire<15)newplane=BrDcDig::kT3Y2;
	
	if(newplane)ip=newplane;
      }      
      
      digdc_p->SetPlane(ip);
      digdc_p->SetSubModule(submod);
      digdc_p->SetWire(mapped_tdc_hits[ihit].channel);
      digdc_p->SetTime(mapped_tdc_hits[ihit].tdcLeadingEdge);
      digdc_p->SetWidth(mapped_tdc_hits[ihit].tdcWidth);
    }


  }
  return kTRUE;
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackT4(const Int_t recordId) 
{
  // Unpack raw data for T4.  There will be a wide variety of
  // recordId's each of which corresponds to a different plane.  They
  // will be managed here and assembled into proper DigDC's returns
  // kTRUE if unpacking successful returns kFALSE if not successful,
  // ie if recordId does not correspond to something for T4

  BrRawEvent::mappedTdcHit_t   *mapped_tdc_hits;
  Int_t                        iplane;
  Int_t                        submod;
  Int_t                        ret;
  Int_t                        ihit;
  Int_t                        nhits;
  Char_t                       TableName[64];
  BrDataTable                  *dcTable;

  //First check that the record format is what we will read.  If not
  //inform user and get out as what we would do would be bogus anyway
  if(fRecordFormat != BrRawEvent::kFormatTdc) {
    Stop("UnpackT4",
	 "Record format for T4 right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  ret=fRawEvent->getRecordMappedTdc(recordId,mapped_tdc_hits,nhits);
  if(ret == BrRawEvent::kOk) {
    BrDcDig *digdc_p;
    if(!fT4Table) {
      sprintf(TableName,"%s T4",BRTABLENAMES kDigDC);
      fT4Table = new BrDataTable(TableName,"Raw mapped");
      fBFSNode->AddDataTable(fT4Table);
    }
    dcTable = fT4Table;


    //T4 submodule 1
    if(recordId == kT41X1) {
      iplane = BrDcDig::kT4X1;
      submod = 1;
    }
    else if(recordId == kT41X2) {
      iplane = BrDcDig::kT4X2;
      submod = 1;
    }
    else if(recordId == kT41Y1) {
      iplane = BrDcDig::kT4Y1;
      submod = 1;
    }
    else if(recordId == kT41Y2) {
      iplane = BrDcDig::kT4Y2;
      submod = 1;
    }
    else if(recordId == kT41U1) {
      iplane = BrDcDig::kT4U1;
      submod = 1;
    }
    else if(recordId == kT41U2) {
      iplane = BrDcDig::kT4U2;
      submod = 1;
    }
    else if(recordId == kT41V1) {
      iplane = BrDcDig::kT4V1;
      submod = 1;
    }
    else if(recordId == kT41V2) {
      iplane = BrDcDig::kT4V2;
      submod = 1;
    }

    //T4 submodule 2
    else if(recordId == kT42X1) {
      iplane = BrDcDig::kT4X1;
      submod = 2;
    }
    else if(recordId == kT42X2) {
      iplane = BrDcDig::kT4X2;
      submod = 2;
    }
    else if(recordId == kT42Y1) {
      iplane = BrDcDig::kT4Y1;
      submod = 2;
    }
    else if(recordId == kT42Y2) {
      iplane = BrDcDig::kT4Y2;
      submod = 2;
    }
    else if(recordId == kT42U1) {
      iplane = BrDcDig::kT4U1;
      submod = 2;
    }
    else if(recordId == kT42U2) {
      iplane = BrDcDig::kT4U2;
      submod = 2;
    }
    else if(recordId == kT42V1) {
      iplane = BrDcDig::kT4V1;
      submod = 2;
    }
    else if(recordId == kT42V2) {
      iplane = BrDcDig::kT4V2;
      submod = 2;
    }

    //T4 submodule 3
    else if(recordId == kT43X1) {
      iplane = BrDcDig::kT4X1;
      submod = 3;
    }
    else if(recordId == kT43X2) {
      iplane = BrDcDig::kT4X2;
      submod = 3;
    }
    else if(recordId == kT43Y1) {
      iplane = BrDcDig::kT4Y1;
      submod = 3;
    }
    else if(recordId == kT43Y2) {
      iplane = BrDcDig::kT4Y2;
      submod = 3;
    }
    else if(recordId == kT43U1) {
      iplane = BrDcDig::kT4U1;
      submod = 3;
    }
    else if(recordId == kT43U2) {
      iplane = BrDcDig::kT4U2;
      submod = 3;
    }
    else if(recordId == kT43V1) {
      iplane = BrDcDig::kT4V1;
      submod = 3;
    }
    else if(recordId == kT43V2) {
      iplane = BrDcDig::kT4V2;
      submod = 3;
    }
    else {
      Stop("UnpackT4", "invalid recordId; it is %d", recordId);
      return kFALSE;
    }


    for(ihit=0;ihit<nhits;ihit++) {
      Int_t wireNumber = mapped_tdc_hits[ihit].channel;
      if(wireNumber > 100) {
	//wireNumber -= 100;
	 //Here we would also do whatever we need to do with tdc info
	 //for the delayed channel.  I do not know what that is kh 26-Mar-2001
         }
      digdc_p = new BrDcDig();
      dcTable->Add(digdc_p);
      digdc_p->SetPlane(iplane);
      digdc_p->SetSubModule(submod);
      digdc_p->SetWire(wireNumber);
      digdc_p->SetTime(mapped_tdc_hits[ihit].tdcLeadingEdge);
      digdc_p->SetWidth(mapped_tdc_hits[ihit].tdcWidth);
    }
  }

  //cout << "Unpack T4 Needs to be implemented all the way, "
  //     << "so far this is only a guess at the unpacking!!!" << endl; 
  return kTRUE;
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackT5(const Int_t recordId) {
  //Unpack raw data for T5.  There will be a wide variety of recordId's
  //each of which corresponds to a different plane.  They will be managed
  //here and assembled into proper DigDC's
  //returns kTRUE if unpacking successful
  //returns kFALSE if not successful, ie if recordId does not correspond
  //to something for T5

  BrRawEvent::mappedTdcHit_t   *mapped_tdc_hits;
  Int_t iplane,submod;
  Int_t ret,ihit,nhits;
  Char_t TableName[64];
  BrDataTable *dcTable;

  //First check that the record format is what we will read.  If not
  //inform user and get out as what we would do would be bogus anyway
  if(fRecordFormat != BrRawEvent::kFormatTdc) {
    Stop("UnpackT5",
	 "Record format for T5 right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  ret=fRawEvent->getRecordMappedTdc(recordId,mapped_tdc_hits,nhits);
  if(ret == BrRawEvent::kOk) {
    BrDcDig *digdc_p;
    if(!fT5Table) {
      sprintf(TableName,"%s T5",BRTABLENAMES kDigDC);
      fT5Table = new BrDataTable(TableName,"Raw mapped");
      fBFSNode->AddDataTable(fT5Table);
    }
    dcTable = fT5Table;

    //T5 submodule 1
    if(recordId == kT51X1) {
      iplane = BrDcDig::kT5X1;
      submod = 1;
    }
    else if(recordId == kT51X2) {
      iplane = BrDcDig::kT5X2;
      submod = 1;
    }
    else if(recordId == kT51Y1) {
      iplane = BrDcDig::kT5Y1;
      submod = 1;
    }
    else if(recordId == kT51Y2) {
      iplane = BrDcDig::kT5Y2;
      submod = 1;
    }
    else if(recordId == kT51U1) {
      iplane = BrDcDig::kT5U1;
      submod = 1;
    }
    else if(recordId == kT51U2) {
      iplane = BrDcDig::kT5U2;
      submod = 1;
    }
    else if(recordId == kT51V1) {
      iplane = BrDcDig::kT5V1;
      submod = 1;
    }
    else if(recordId == kT51V2) {
      iplane = BrDcDig::kT5V2;
      submod = 1;
    }

    //T5 submodule 2
    else if(recordId == kT52X1) {
      iplane = BrDcDig::kT5X1;
      submod = 2;
    }
    else if(recordId == kT52X2) {
      iplane = BrDcDig::kT5X2;
      submod = 2;
    }
    else if(recordId == kT52Y1) {
      iplane = BrDcDig::kT5Y1;
      submod = 2;
    }
    else if(recordId == kT52Y2) {
      iplane = BrDcDig::kT5Y2;
      submod = 2;
    }
    else if(recordId == kT52U1) {
      iplane = BrDcDig::kT5U1;
      submod = 2;
    }
    else if(recordId == kT52U2) {
      iplane = BrDcDig::kT5U2;
      submod = 2;
    }
    else if(recordId == kT52V1) {
      iplane = BrDcDig::kT5V1;
      submod = 2;
    }
    else if(recordId == kT52V2) {
      iplane = BrDcDig::kT5V2;
      submod = 2;
    }

    //T5 submodule 3
    else if(recordId == kT53X1) {
      iplane = BrDcDig::kT5X1;
      submod = 3;
    }
    else if(recordId == kT53X2) {
      iplane = BrDcDig::kT5X2;
      submod = 3;
    }
    else if(recordId == kT53Y1) {
      iplane = BrDcDig::kT5Y1;
      submod = 3;
    }
    else if(recordId == kT53Y2) {
      iplane = BrDcDig::kT5Y2;
      submod = 3;
    }
    else if(recordId == kT53U1) {
      iplane = BrDcDig::kT5U1;
      submod = 3;
    }
    else if(recordId == kT53U2) {
      iplane = BrDcDig::kT5U2;
      submod = 3;
    }
    else if(recordId == kT53V1) {
      iplane = BrDcDig::kT5V1;
      submod = 3;
    }
    else if(recordId == kT53V2) {
      iplane = BrDcDig::kT5V2;
      submod = 3;
    }
    else {
      Stop("UnpackT5", "invalid recordId; it is %d", recordId);
      return kFALSE;
    }

    for(ihit=0;ihit<nhits;ihit++) {
      Int_t wireNumber = mapped_tdc_hits[ihit].channel;
      if(wireNumber > 100) {
	//wireNumber -= 100;
	 //Here we would also do whatever we need to do with tdc info
	 //for the delayed channel.  I do not know what that is kh 26-Mar-2001
         }
      digdc_p = new BrDcDig();
      dcTable->Add(digdc_p);
      digdc_p->SetPlane(iplane);
      digdc_p->SetSubModule(submod);
      digdc_p->SetWire(wireNumber);
      digdc_p->SetTime(mapped_tdc_hits[ihit].tdcLeadingEdge);
      digdc_p->SetWidth(mapped_tdc_hits[ihit].tdcWidth);
    }
  }
  return kTRUE;
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackTOFW(const Int_t recordId) 
{
  // Unpack raw data for TOFW.  There will be two recordId's kTOFWB
  // which corresponds to the bottom of the slats and kTOFWT which 
  // corresponds to the top of the slats.  They will be managed here
  // and assembled into proper DigTof's returns kTRUE if unpacking
  // successful returns kFALSE if not successful, ie if recordId does
  // not correspond to something for TOFW
  // The code expects to look for two recorsId namely kTOFWBottom and
  // kTOFWTop. We do not know which comes first. In any case it will look for 
  // both and manipuate tables at once. This avaoid the unpleasant issue on numbers
  // of 83, 125 (but not least the data run for part of last year was 96 not 83
  // in the mapping. Pick if nhits==96 ->83 otherwise use numbers.
  //


  if(fTOFWTable)
    return kFALSE;

  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("UnpackTOFW",
	 "Record format for TOFW right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }




  BrRawEvent::mappedATBlkHit_t *mapped_top_hits;
  BrRawEvent::mappedATBlkHit_t *mapped_bottom_hits;

  int nhits_top, nhits_bottom;
  Int_t ret_top = fRawEvent->getRecordMappedATBlk(kTOFWTop, mapped_top_hits, nhits_top);
  Int_t ret_bottom = fRawEvent->getRecordMappedATBlk(kTOFWBottom, mapped_bottom_hits, nhits_bottom);

  if(!(ret_top == BrRawEvent::kOk && ret_bottom == BrRawEvent::kOk)) {
    Warning("UnpackTOFW", "Illegal return from getrecord");
    return kFALSE;

  }
  
  if(!(nhits_top == nhits_bottom)){
    Warning("UnpackTOFW", "Top/Bottom different channels %d %d", nhits_top, nhits_bottom);
    return kFALSE;
  }
     
  int nslats;     
  if(nhits_top == 96)
    nslats = 83;
  else
    nslats = nhits_top;
  
  Char_t TableName[64];
  sprintf(TableName,"%s TOFW",BRTABLENAMES kDigTof);
  fTOFWTable = new BrDataTable(TableName,"Raw");
  fMRSNode->AddDataTable(fTOFWTable);
  
  for(int ihit=0;ihit<nslats;ihit++) {
    BrTofDig *digtof_p;
    BrRawEvent::mappedATBlkHit_t *hit_bottom; 
    BrRawEvent::mappedATBlkHit_t *hit_top; 
    
    int slat = ihit + 1;
    hit_top = &mapped_top_hits[ihit];
    hit_bottom = &mapped_bottom_hits[ihit];
    // Possible suppression algorithm    
    // for non-sync events
    // if((hit_bottom->tdc < 4000)&& (hit_bottom->tdc < 4000)){
      digtof_p = new BrTofDig();
      fTOFWTable->Add(digtof_p);
      digtof_p->SetSlatno(slat);
      digtof_p->SetAdcDown(hit_bottom->adc);
      digtof_p->SetTdcDown(hit_bottom->tdc);
      digtof_p->SetAdcUp(hit_top->adc);
      digtof_p->SetTdcUp(hit_top->tdc);
      //}
  }
  
  return kTRUE;
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackTOFWCal(const Int_t recordId) 
{
  // Unpack raw data for TOFWCal. There is a single record
  // There are mapped alternate left/right channels.
  //
 
  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("UnpackTOFWCal",
	 "Record format for TOFWCal right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  Int_t nhits;
  BrRawEvent::mappedATBlkHit_t *mapped_hits;  
  Int_t ret = fRawEvent->getRecordMappedATBlk(kTOFWCal, mapped_hits,nhits);
  if(ret == BrRawEvent::kOk) {
    if(!fTOFWCalTable) {
      Char_t TableName[24];
      sprintf(TableName,"%s TOFWCal",BRTABLENAMES kDigTof);
      fTOFWCalTable = new BrDataTable(TableName,"Raw");
      fMRSNode->AddDataTable(fTOFWCalTable);
    }
    if(nhits != 12)
      Warning("DecodeMRS", 
	      "nhit for TOFWCal != 12, check it out; it is %d", nhits);
    int slatno=1;
    for(int ihit=0;ihit<12;ihit+=2) {
      BrTofDig *digtof_p = new BrTofDig();
      fTOFWCalTable->Add(digtof_p);
      BrRawEvent::mappedATBlkHit_t *hit_up,*hit_down;
      hit_up   = &mapped_hits[ihit];
      hit_down = &mapped_hits[ihit+1];
      digtof_p->SetSlatno(slatno++);
      digtof_p->SetAdcDown(hit_down->adc);
      digtof_p->SetAdcUp(hit_up->adc);
      digtof_p->SetTdcDown(hit_down->tdc);
      digtof_p->SetTdcUp(hit_up->tdc);
    }
  }
  else {
    Warning("DecodeFFS", "Error on TOFWCal");
  }
  
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackH1Cal(const Int_t recordId) 
{
  // Unpack raw data for H1Cal. There is a single record
  // There are mapped alternate left/right channels.
  //
 
  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("UnpackH1Cal",
	 "Record format for H1Cal right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  Int_t nhits;
  BrRawEvent::mappedATBlkHit_t *mapped_hits;  
  Int_t ret = fRawEvent->getRecordMappedATBlk(kH1Cal, mapped_hits,nhits);
  if(ret == BrRawEvent::kOk) {
    if(!fH1CalTable) {
      Char_t TableName[24];
      sprintf(TableName,"%s H1Cal",BRTABLENAMES kDigTof);
      fH1CalTable = new BrDataTable(TableName,"Raw");
      fMRSNode->AddDataTable(fH1CalTable);
    }
    if(nhits != 4)
      Warning("DecodeMRS", 
	      "nhit for H1Cal != 4, check it out; it is %d", nhits);
    int slatno=1;
    for(int ihit=0;ihit<4;ihit+=2) {
      BrTofDig *digH1 = new BrTofDig();
      fH1CalTable->Add(digH1);
      BrRawEvent::mappedATBlkHit_t *hit_up,*hit_down;
      hit_up   = &mapped_hits[ihit];
      hit_down = &mapped_hits[ihit+1];
      digH1->SetSlatno(slatno++);
      digH1->SetAdcDown(hit_down->adc);
      digH1->SetAdcUp(hit_up->adc);
      digH1->SetTdcDown(hit_down->tdc);
      digH1->SetTdcUp(hit_up->tdc);
    }
  }
  else {
    Warning("DecodeFFS", "Error on H1Cal");
  }
  
}


//____________________________________________________________________
 Bool_t BrRawDataInput::UnpackDriftVel(const Int_t recordId) 
{
  // Unpack raw data for DriftVelocity.  
  // These data will eventually only exsist for record type 103
  // but at present are read together with the normal events (102)
  // and with a special trigger.
  // 
  BrRawEvent::mappedTdcHit_t   *mapped_tdc_hits;
  if(fRecordFormat != BrRawEvent::kFormatTdc) {
    Stop("UnpackDriftVel",
	 "Record format for DriftVel right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  Int_t nhits;
  Int_t ret=fRawEvent->getRecordMappedTdc(recordId, mapped_tdc_hits, nhits);
  if(ret == BrRawEvent::kOk) {
    BrDvDig *digDv;
    if(!fDvObject){
      fDvObject = new BrDvDig(BRTABLENAMES kDvDig,"raw");
      fGlobalNode->AddObject(fDvObject);
    }
    for(int ihit=0;ihit<nhits;ihit++) {
      fDvObject->SetTime(mapped_tdc_hits[ihit].channel,
		      mapped_tdc_hits[ihit].tdcLeadingEdge);
      fDvObject->SetWidth(mapped_tdc_hits[ihit].channel,
		       mapped_tdc_hits[ihit].tdcWidth);
    }
  }
}

//____________________________________________________________________
 Bool_t BrRawDataInput::UnpackTpcFib(const Int_t recordId)
{
  // Calibration fibers in MRS. Consist of at most 6 adc channels
  // but always 6 in raw record. Likely 0 if not there.
  //
  // iform user and get out as what we would do would be bogus anyway
  if(fRecordFormat != BrRawEvent::kFormatAdcBlk) {
    Stop("UnpackTpcFib", 
	 "record format for TpcFib not correct; it is %d",
	 fRecordFormat);
    return kFALSE;
  }
  BrRawEvent::mappedAdcBlkHit_t *mapped_adc_blk_hits;
  int nhits;
  int ret=fRawEvent->getRecordMappedAdcBlk(recordId,
					   mapped_adc_blk_hits,
					   nhits);
  if(ret == BrRawEvent::kOk) {
    if(nhits != 6) {
      Stop("UnpackTpcFib", 
	   "TpcFib nhits !=6, they are %d returning!!!", nhits);
      return kFALSE;
    }
    BrTpcFibDig *digp;

    switch (recordId ){
    case kTpm2FFib:
      digp = new BrTpcFibDig(Form("%s %s",BRTABLENAMES kTpcFibDig,"TPM2F"), "Raw");
      break;
    case kTpm2BFib:
      digp = new BrTpcFibDig(Form("%s %s",BRTABLENAMES kTpcFibDig,"TPM2B"), "Raw");
      break;
    case kT2FFib:
      digp = new BrTpcFibDig(Form("%s %s",BRTABLENAMES kTpcFibDig,"T2B"), "Raw");
      break;
    case kT1BFib:
      digp = new BrTpcFibDig(Form("%s %s",BRTABLENAMES kTpcFibDig,"T1F"), "Raw");
      break;
    default:
      Warning("Unpack TpcFib","unknow/wrong id");
      return kFALSE;

    }
    
    fMRSNode->AddObject(digp);
    
    for(int ihit=0;ihit<nhits;ihit++) {
      BrRawEvent::mappedAdcBlkHit_t *hit = &mapped_adc_blk_hits[ihit];
      digp->SetAdc(ihit+1, *hit);
    }
  }
  else {
    Warning("DecodeFibre", "Error on TpcFib");
  }
  return kTRUE;
}


//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackTrigStart(const Int_t recordId) 
{
  // Unpack raw data for Trigger starts.
  //
 
  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("UnpackTrigstart",
	 "Record format for Trig Start right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  Int_t nhits;
  BrRawEvent::mappedATBlkHit_t *mapped_hits;  
  Int_t ret = fRawEvent->getRecordMappedATBlk(kTriggerStart, mapped_hits, nhits);
  if(ret == BrRawEvent::kOk) {
    
    BrTrigStart *dig = new BrTrigStart(BRTABLENAMES kTrigStart,"raw");
    fGlobalNode->AddObject(dig);

    if(nhits != 16)
      Warning("DecodeGlobal", 
	      "nhit for TrigStart != 16, check it out; it is %d", nhits);
    
    for(int ihit=0;ihit<12;ihit++){
      BrRawEvent::mappedATBlkHit_t *hit;
      hit   = &mapped_hits[ihit];
      dig->SetTdc(ihit+1,hit->tdc);
    }
  }
  else {
    Warning("DecodeGlobal", "Error on TrigStart");
  }
  
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackInelRing(const Int_t recordId) 
{
  // Unpack raw data for Trigger starts.
  //
 
  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("UnpackInelRing",
	 "Record format for Inel Ring correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }

  int nhits;
  BrRawEvent::mappedATBlkHit_t *mapped_hits;  

  Int_t ret = fRawEvent->getRecordMappedATBlk(recordId, 
					      mapped_hits, 
					      nhits);
  if(ret == BrRawEvent::kOk) {
 
    BrDataTable * table=0;   
    if(recordId == kInelRing)
      table  = new BrDataTable("BbDig Inel","raw");

    if(recordId == kInelAll)
      table = new BrDataTable("BbDig InelAll","raw");

    fGlobalNode->AddDataTable(table);

    
    if(recordId == kInelRing)
      if(nhits != 8)
	Warning("DecodeGlobal", 
		"nhit for InelRing != 8, check it out; it is %d", nhits);

    if(recordId == kInelAll)
      if(nhits != 32)
	Warning("DecodeGlobal", 
		"nhit for InelAll != 32, check it out; it is %d", nhits);
    
    for(int ihit=0;ihit<nhits;ihit++){
      BrRawEvent::mappedATBlkHit_t *hit;
      hit   = &mapped_hits[ihit];
      BrBbDig* dig = new BrBbDig();
      table->Add(dig);
      dig->SetId(ihit+1);     
      dig->SetAdc(0);
      dig->SetTubeNo(ihit+1);
      dig->SetTdc(hit->tdc);
    }
  }
  else {
    Warning("DecodeGlobal", "Error on InelRing");
  }
  
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackInel(const Int_t recordId) 
{
  // Unpack raw data for Trigger starts.
  //
 
  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("UnpackInelRing",
	 "Record format for Inel Ring correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }

  int nhits;
  BrRawEvent::mappedATBlkHit_t *mapped_hits;  

  Int_t ret = fRawEvent->getRecordMappedATBlk(recordId, 
					      mapped_hits, 
					      nhits);
  if(ret == BrRawEvent::kOk) {
 
    BrDataTable * tableLeft  = new BrDataTable("BbDig INL","raw");
    BrDataTable * tableRight = new BrDataTable("BbDig INR","raw");

    fGlobalNode->AddDataTable(tableLeft);
    fGlobalNode->AddDataTable(tableRight);

    if(recordId == kInelAll)
      if(nhits != 32)
	Warning("DecodeGlobal", 
		"nhit for InelAll != 32, check it out; it is %d", nhits);
    

    nhits = nhits/2;
    for(int ihit=0;ihit<nhits;ihit++){
      BrRawEvent::mappedATBlkHit_t *hit;
      hit   = &mapped_hits[ihit];
      BrBbDig* dig = new BrBbDig();
      tableLeft->Add(dig);
      dig->SetId(ihit+1);     
      dig->SetAdc(0);
      dig->SetTubeNo(ihit+1);
      dig->SetTdc(hit->tdc);

      hit   = &mapped_hits[ihit+16];
      dig = new BrBbDig();
      tableRight->Add(dig);
      dig->SetId(ihit+1);     
      dig->SetAdc(0);
      dig->SetTubeNo(ihit+1);
      dig->SetTdc(hit->tdc);
    }
  }
  else {
    Warning("DecodeGlobal", "Error on INR/INL");
  }
  
}


//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackTriggerD1(const Int_t recordId) 
{
  // Unpack raw data for Trigger counter in front of D1
  // Treat as a TOF counter. So real easy.
  // There are mapped alternate left/right channels.
  //
 
  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("UnpackTriggerD1",
	 "Record format for TD1 right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  Int_t nhits;
  BrRawEvent::mappedATBlkHit_t *mapped_hits;  
  Int_t ret = fRawEvent->getRecordMappedATBlk(kTD1, mapped_hits,nhits);
  if(ret != BrRawEvent::kOk)
    return kFALSE;
    
  Char_t TableName[24];
  sprintf(TableName,"%s TD1",BRTABLENAMES kDigTof);
  BrDataTable*   table = new BrDataTable(TableName,"Raw");
  fFFSNode->AddDataTable(table);
  if(nhits != 6)
    Warning("DecodeTD1", 
	    "nhit for TD1 != 6, check it out; it is %d", nhits);
  int slatno=1;
  for(int ihit=0;ihit<nhits;ihit+=2) {
    BrTofDig *digtof_p = new BrTofDig();
    table->Add(digtof_p);
    BrRawEvent::mappedATBlkHit_t *hit_up,*hit_down;
    hit_up   = &mapped_hits[ihit];
    hit_down = &mapped_hits[ihit+1];
    digtof_p->SetSlatno(slatno++);
    digtof_p->SetAdcDown(hit_down->adc);
    digtof_p->SetAdcUp(hit_up->adc);
    digtof_p->SetTdcDown(hit_down->tdc);
    digtof_p->SetTdcUp(hit_up->tdc);
  }
  
}

//______________________________________________________________________
 Bool_t BrRawDataInput::UnpackTriggerMrs(const Int_t recordId) 
{
  // Unpack raw data for Trigger counter in front of MRS
  // and behind MRS
  // Treat as a TOF counter. So real easy.
  // There are mapped alternate left/right channels.
  // Change this to let slat 1 -> TMrsF and 2-7 ->TMrsB
  // This will make tofsoftware much more happy.
  //
 
  if(fRecordFormat != BrRawEvent::kFormatATBlk) {
    Stop("UnpackTriggerMRS",
	 "Record format for TMRS right not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  Int_t nhits;
  BrRawEvent::mappedATBlkHit_t *mapped_hits;  
  Int_t ret = fRawEvent->getRecordMappedATBlk(kTMRS, mapped_hits,nhits);
  if(ret != BrRawEvent::kOk)
    return kFALSE;
    
  if(nhits != 14)
    Warning("DecodeTMRS", 
	    "nhit for TMRS != 14, check it out; it is %d", nhits);

  Char_t TableName[24];
  sprintf(TableName,"%s TMrsB",BRTABLENAMES kDigTof);
  BrDataTable*   table = new BrDataTable(TableName,"Raw");
  fMRSNode->AddDataTable(table);
  int slatno=1;
  for(int ihit=2;ihit<nhits;ihit+=2) {
    BrTofDig *digtof_p = new BrTofDig();
    table->Add(digtof_p);
    BrRawEvent::mappedATBlkHit_t *hit_up,*hit_down;
    hit_up   = &mapped_hits[ihit];
    hit_down = &mapped_hits[ihit+1];
    digtof_p->SetSlatno(slatno++);
    digtof_p->SetAdcDown(hit_down->adc);
    digtof_p->SetAdcUp(hit_up->adc);
    digtof_p->SetTdcDown(hit_down->tdc);
    digtof_p->SetTdcUp(hit_up->tdc);
  }
  // make a single table for TMrsF 

  sprintf(TableName,"%s TMrsF",BRTABLENAMES kDigTof);
  table = new BrDataTable(TableName,"Raw");
  fMRSNode->AddDataTable(table);
  slatno=1;
  for(int ihit=0;ihit<2;ihit+=2) {
    BrTofDig *digtof_p = new BrTofDig();
    table->Add(digtof_p);
    BrRawEvent::mappedATBlkHit_t *hit_up,*hit_down;
    hit_up   = &mapped_hits[ihit];
    hit_down = &mapped_hits[ihit+1];
    digtof_p->SetSlatno(slatno++);
    digtof_p->SetAdcDown(hit_down->adc);
    digtof_p->SetAdcUp(hit_up->adc);
    digtof_p->SetTdcDown(hit_down->tdc);
    digtof_p->SetTdcUp(hit_up->tdc);
  }
  
}


//____________________________________________________________________
 Bool_t BrRawDataInput::UnpackTrigClock(const Int_t recordId) 
{
  // Unpack raw data for Trigger clock information
  // raw record 10024 implemented 11/23/01
  //
  BrRawEvent::mappedTdcHit_t   *mapped_tdc_hits;
  if(fRecordFormat != BrRawEvent::kFormatTdc) {
    Stop("UnpackTrigClock",
	 "Record format for TrigClock not correct; it is %d", 
	 fRecordFormat);  
    return kFALSE;
  }
  Int_t nhits;
  Int_t ret=fRawEvent->getRecordMappedTdc(recordId, mapped_tdc_hits, nhits);
  if(ret |= BrRawEvent::kOk)
    return kFALSE;
  BrDataTable* clockTable = new BrDataTable("TrigClock","raw");
  BrDataTable* zdcTable = new BrDataTable("TrigZdc","raw");
  fGlobalNode->AddObject(clockTable);
  fGlobalNode->AddObject(zdcTable);
    
  for(int ihit=0;ihit<nhits;ihit++) {
    int id = mapped_tdc_hits[ihit].channel;
    switch (id/2) {
    case 0:
      {
	BrTrigZdc* zdc = new BrTrigZdc();
	zdc->SetTypeId(id%2);
	zdc->SetTdc(mapped_tdc_hits[ihit].tdcLeadingEdge);
	zdc->SetWidth(mapped_tdc_hits[ihit].tdcWidth);
	zdcTable->Add(zdc);
      }
      break;

    case 1:
      {
	BrTrigClock* clock = new BrTrigClock();
	clock->SetTypeId(id%2);
	clock->SetTdc(mapped_tdc_hits[ihit].tdcLeadingEdge);
	clock->SetWidth(mapped_tdc_hits[ihit].tdcWidth);
	clockTable->Add(clock);
      }
      break;
    }
  }
  return kTRUE;
}


//______________________________________________________________________
 Int_t BrRawDataInput::Test() {
  // A method for Kris to test some things.  Not to be used for
  // anything seriously
  Int_t i = 152;
  return i;
}

//______________________________________________________________________
//
//  $Log: BrRawDataInput.cxx,v $
//  Revision 1.27  2002/07/03 18:26:36  videbaek
//  Fix error in converting BbTrigger records
//  Only the left records were converted.
//
//  Revision 1.26  2002/04/02 19:19:58  videbaek
//  The MRS trigger data have been split into two seperate tables
//  namely TMrsF (one slat) and TMrsB (six slats). This make the
//  logic for analysis much better.
//
//  Revision 1.25  2002/03/04 15:05:51  videbaek
//  Changed the decoding of Inel counters from the pp running to appear in
//  2 different tables INR and INL.
//  This make the Inel counters behave much more like the BB counters. This
//  is also utilized in the calibrations routines etc.
//
//  Revision 1.24  2002/02/07 21:53:54  ufstasze
//  Added correction to T3 mapping.
//
//  Revision 1.23  2002/01/03 19:52:01  cholm
//  Prepared to use BrTableNames class (or perhaps BrDetectorList) for table names
//
//  Revision 1.22  2001/12/29 03:54:54  operator
//  Added new records for Inel counters
//
//  Revision 1.21  2001/12/21 14:30:09  operator
//  updated unpacking for TMRS (pp trigger)
//
//  Revision 1.20  2001/12/14 15:38:02  cholm
//  Modified the classes to allow the concept of file set, introduced via
//  BrIOModule. Also use new Info method rather than explicit
//    if (Verbose() > 4)
//       cout << "Opening file ladida" << endl;
//
//  Revision 1.19  2001/12/13 21:51:50  videbaek
//  Re-mapping of Bema Beam right tdc for module 20 and 23 for runs less than 6061
//  (today). Some additional cleanup of unpack modules to make better modularity
//  ie. usage of Unpack<detector> methods rather than in-line.
//
//  Revision 1.18  2001/12/12 20:51:32  operator
//  Added data structure for Mrs Trigger counters. The Name is
//  TMRS and of type BrTofDig (Left/right slat though)
//
//  Revision 1.17  2001/12/06 21:51:10  operator
//  Unpack the inelastic counters so far 4 rings each side.
//  The data are stored as a Bbdig (has timing but no ADC - maybe it will
//  who knows.
//
//  Revision 1.16  2001/11/28 21:44:46  operator
//  Added TD1 trigger record
//
//  Revision 1.15  2001/11/26 18:07:50  videbaek
//  Added creation of Datatables for Sync Clock and ZDC timing.
//  Corrected several typos in warning messages.
//
//  Revision 1.14  2001/11/22 21:37:46  operator
//  Added records 10024
//
//  Revision 1.13  2001/10/10 20:45:28  operator
//  Change name of TPM2 fibre to be TPM2 with capital letters
//
//  Revision 1.12  2001/10/02 22:28:23  videbaek
//  Modified to handle BrTpcFibDig.:wq
//
//  Revision 1.11  2001/09/19 16:23:05  videbaek
//  Remove a lowlevel verbose debug
//
//  Revision 1.10  2001/09/18 13:49:39  operator
//  Unpack BrTrigStart data records added.
//
//  Revision 1.9  2001/08/30 19:45:54  jakobsen
//  // Added H1Cal
//
//  Revision 1.8  2001/08/24 12:00:03  jens
//
//  Corrected typo
//    A BrDataTable with name "TPCSequence TP1MB" was created for pedestals from TPM1. Changed to "TPCSequence TPM1B".
//
//  Revision 1.7  2001/08/09 08:54:58  ekman
//  Changed the C1 tube numbering to start from 1
//
//  Revision 1.6  2001/07/24 01:41:11  videbaek
//  Add verbose statement
//
//  Revision 1.5  2001/07/19 15:21:34  staszel
//  Changes that refer to T4 and T5 unpacking.
//
//  Revision 1.4  2001/07/18 20:44:26  operator
//  Renove unpack debug statement
//
//  Revision 1.3  2001/07/17 17:58:48  videbaek
//  Added BrTpmfib data objects.
//  Unpack these as part of MRS datatable.
//
//  Revision 1.2  2001/06/22 17:40:34  cholm
//  Changes t odo with data classes renaming.
//
//  Revision 1.1.1.1  2001/06/21 14:55:09  hagel
//  Initial revision of brat2
//
//  Revision 1.73  2001/06/15 23:56:51  operator
//  Added the TOFWCal 6 stave detectors with a format as BrTofDig
//  just a different name.
//
//  Revision 1.72  2001/06/04 18:14:29  videbaek
//  Complete implementation of DriftVelocity Monitor dataobjects
//  The data are stored in the BrDvDig dataobjects
//
//  Revision 1.71  2001/06/01 15:50:18  cholm
//  Fixed some output and made it conditional on debug level or verbosity.
//
//  Revision 1.70  2001/05/21 17:49:18  videbaek
//  Modified reading of TOFW data. Take top/bottom at same time, and fills tables
//  accing to # slats present.
//
//  Revision 1.69  2001/05/01 00:33:29  videbaek
//  Changed BrTriggerScalewr -> BrTrigScaler ..
//
//  Revision 1.68  2001/04/30 19:02:36  hagel
//  Added routine to unpack Drift velocity monitors although it does not build the object yet
//
//  Revision 1.67  2001/03/26 22:53:52  hagel
//  Put in unpack for T4 and T5 with correction for delayed wires
//
//  Revision 1.66  2001/03/12 18:46:48  cholm
//  Fixed a few mistakes. Added a hack to histogram module, to make
//  sure it's file is closed as the very last thing in Finish.
//
//  Revision 1.65  2001/03/07 12:22:36  cholm
//  * Changed BrRawDataInput to use signals Stop, Failure, Abort, and
//    added specialised method OpenNext.
//
//  Revision 1.64  2001/01/29 20:37:32  cholm
//  Updated to use the new data objects for the multiplicity array. See the
//  relevant classes (BrTileDig, BrTileRdo, BrSiDig, BrSiRdo) for more details.
//
//  Revision 1.63  2001/01/22 20:00:13  cholm
//  Because renamed BrIOModule::fStatus to BrIOModule::fIOStatus, the classes
//  BrRawDataInput and BrRawDataOutput had to be updated.
//
//  Revision 1.62  2000/09/01 03:39:47  hagel
//  Small changes to T5 unpacking
//
//  Revision 1.61  2000/08/31 21:25:41  hagel
//  Add unpacking for T5 (and unpacking guess for T4)
//
//  Revision 1.60  2000/08/12 23:37:48  hagel
//  Changed unpacking of TOFW for splitting top and bottom data records
//
//  Revision 1.59  2000/08/12 22:12:44  videbaek
//  Modified TOFW readout
//
//  Revision 1.58  2000/08/10 16:10:17  hagel
//  Fix bug in T3 Unpacking
//
//  Revision 1.57  2000/08/03 16:27:28  hagel
//  Take out print statement for DC's
//
//  Revision 1.56  2000/07/29 23:42:27  hagel
//  Implement first version of unpacking T3
//
//  Revision 1.55  2000/07/28 20:46:32  alv
//  Replaced the Bool_t fXXXOn detector flags by a BrDetectorList fDetectors member.
//  Added methods
//    void   SetOn (EBrDetectorBit b)
//    void   SetOn (EBrSectorBit   m)
//    void   SetOn (EBrDetectorBit b, Bool_t v)
//    void   SetOn (EBrSectorBit   m, Bool_t v)
//    void   SetOff(EBrDetectorBit b)
//    void   SetOff(EBrSectorBit   m)
//    Bool_t IsOn  (EBrDetectorBit b) const
//    Bool_t IsOn  (EBrSectorBit   m) const
//  Changed the old SetXXXOn methods to use the new SetOn method.
//  Made GetDataState method const.
//
//  Revision 1.54  2000/07/28 03:23:25  hagel
//  add trigger scaler object to unpacking
//
//  Revision 1.53  2000/07/22 19:45:55  ouerdane
//  Added methods SetOn and SetOff to the set of SetxxxOn and SetxxxOff
//  for a better flexibility, arguments are: name of the detector, boolean
//  value. These methods are internally based on the other existing
//  methods, so that there's no need to modify anything that already
//  exists.
//
//  Revision 1.52  2000/07/20 21:28:00  videbaek
//  moved cvs log info to end
//
//  Revision 1.51 2000/07/15 10:56:51 alv Added decoding and
//  extraction of data record 10021: ZDC attenuated ADC Symbolic
//  record id (in enum ERawMagic): kZDCLo Name of data object (in
//  BrTableNames.h): kDigZDCLo ("DigZDCLo") Name of N-tuple object:
//  "ZDCLo"
//
//  Revision 1.50  2000/06/28 09:21:57  hagel
//  Added const's to Open Args in BrRawDataInput
//
//  Revision 1.49  2000/06/13 17:19:33  alv
//  Open
//    Clear error flag
//  Event and Skip event
//    Set error flag if a read from disk failed
//
//  Revision 1.48  2000/06/09 18:37:14  hagel
//  Set fEof=kFALSE in Open method; necessary for reading multiple files
//
//  Revision 1.47  2000/06/08 06:29:04  videbaek
//  Fixed the error introduced by using kDigC1 name w/o change in Monitor. Took the opprotunity to
//  make BrC1Dig a BrDataObject rather than a TObject that belongs to a table.
//
//  Revision 1.46  2000/06/03 18:18:53  videbaek
//  Removed methods that belongs to base classes.
//
//  Revision 1.45  2000/05/24 15:17:32  videbaek
//  Corrected ZDC code to fill LeftArray too. Also Left and right was interchanged.
//  Checked out.
//
//  Revision 1.44  2000/05/20 18:18:39  hito
//  I (Hiro) added the Silicon strip detector.
//
//  Revision 1.43  2000/05/18 20:24:44  videbaek
//  Moved RICH to BFS eventnode.
//  transform for ihit-->ModuleNo by adding 1.
//
//  Revision 1.42  2000/05/04 03:00:37  hagel
//  Last remnants of memory leak
//
//  Revision 1.41  2000/05/02 16:09:20  hagel
//  Put DebugLevel() requirement to list objects for tpc tables
//
//  Revision 1.40  2000/05/02 01:31:17  alv
//  BuildEvent:
//    Added code to delete recordlist at the end of the routine. (Memory leak fix)
//
//  Revision 1.39  2000/05/02 00:30:38  alv
//  Event:
//    Increment fBatchNumber only when we get a good event.
//    The old code sent too many requests for raw data to the event dispatcher,
//    filled up the Send-Q, and hung the monitor program.
//
//  Revision 1.38  2000/04/27 14:03:05  hagel
//  Changed EventNodes to use names from BrTableNames.h
//
//  Revision 1.37  2000/04/25 15:13:45  alv
//  Updated decoding of TOFW slats in DecodeMRS.
//  There are 83 slats and three groups of ADC channels.
//      1- 96: Bottom tubes
//     97-192: Top tubes
//    193-288: Not used
//
//  Revision 1.36  2000/04/06 22:19:23  hagel
//  Removed the TurnOff of MultTiles
//
//  Revision 1.35  2000/04/04 18:02:10  videbaek
//  Fix for tofw tables in conversion method
//
//  Revision 1.34  2000/03/27 22:29:40  videbaek
//  Adding proper code for reading MTP2
//
//  Revision 1.33  2000/03/24 15:37:45  videbaek
//  The RICHObject was not initialized to NULL. Reason for seg faults when real data arrived.
//
//  Revision 1.32  2000/03/17 01:00:41  hagel
//  Add SetId to BrTileDig
//
//  Revision 1.31  2000/03/09 22:37:41  hagel
//  Implemented constants from BrTableNames.h for data table names
//
//  Revision 1.30  2000/02/22 16:52:59  videbaek
//  Updates for win32 makefile
//
//  Revision 1.29  2000/02/16 22:24:12  brahmlib
//  All code changes to implement the BrTileDig raw data structure.
//
//  Revision 1.28  2000/02/16 20:53:18  hagel
//  1. Changed BrZdcDig to inherit from BrDataObject
//  2. Changed code in BrRawDataInput to reflect that change
//  3. Changed BrMonitorZDC::Event to reflect that change
//  4. Removed Draw methods from BrMonitorZDC, BrMonitorC1, BrMonitorMult because
//     they are obsolete.  BrBaseMonitor now handles that function automatically
//
//  Revision 1.27  2000/02/16 03:21:06  hagel
//  Fix minor bugs having to do with 'dry run'
//
//  Revision 1.26  2000/02/15 20:32:27  videbaek
//
//
//  Revision 1.25  2000/02/11 00:14:07  hagel
//  1. Updated to the latest version of all of Konstantin's online routines
//  2. Changed ZDC to use updated recordId's which return 8 adc values in
//     one recordId.
//  3. Added an alpha-alpha version of unpacking for RICH.  It is mostly
//     placeholder, but will serve as ground work to quickly get unpacking
//     once I understand what needs to be unpacked and what the raw structure is
//
//  Revision 1.24  2000/02/08 22:40:12  videbaek
//  Setup for MTP1,MTP2, added enmu types for TPCs
//  Add DebugLevel condition for some output.
//
//  Revision 1.23  2000/02/04 16:00:23  videbaek
//  Added code for H2 . Still need to be checked.
//
//  Revision 1.22  1999/12/23 15:56:53  videbaek
//  added rawdata recordIds for T1,T2 according to new setup
//
//  Revision 1.20  1999/10/26 16:00:48  videbaek
//  Modified fBytesTransferred to fNumBytesRead and Written to conform to
//  the BrIOModule base class.
//
//  Revision 1.19  1999/08/14 17:01:58  videbaek
//  Updates for
//  a) RawData adding the Trigger TDCs'
//  b) Implied new data objects BrTrigBB
//  c) Clean up of TPC code
//  d) Test MyMonitor and scripts
//
//  Revision 1.18  1999/07/28 14:59:04  hagel
//  Added functionality to BrBaseMonitor
//
//  Revision 1.17  1999/07/27 22:41:08  hagel
//  Added ylog capability to BrMonitorPicture
//
//  Revision 1.16  1999/07/23 22:55:59  hagel
//  Implemented GUI in BrBaseMonitor.
//  Implemented BrMonitorPicture usage in BrBaseMonitor GUI
//  Made use of picture and GUI implementation in inherited classes;
//  ie BrMonitorC1, BrMonitorMult, BrMonitorTof, BrMonitorTof, BrMonitorZDC
//
//  Put in capability for BrRawDataInput not to waitForever for events
//  from EVB.  That is for GUI in case no data acquisition so that
//  it doesn't hang up
//
//  Revision 1.15  1999/07/18 21:25:07  videbaek
//  Added code to deal with trigger words. This applies to raw data, as well as the
//  EventHeader.
//
//  Revision 1.14  1999/07/05 22:07:13  hagel
//  Changed ID's, tubeno's and slatno's to ihit+1 to start counting from 1
//
//  Revision 1.13  1999/07/05 22:00:37  hagel
//  Change BRATHOME to BRATSYS in line where mkconfig.common and mkconfig.$(BRAHMS_ARCH)
//  are included.  This is for the purpose of being able to compile a specific component
//  alone.  These files always reside in BRATSYS directory
//
//  Revision 1.12  1999/07/03 21:08:18  hagel
//  C1 corrections; changed table name of Tof ie DigTof TOF1
//
//  Revision 1.11  1999/07/02 16:50:41  hagel
//  Added C1 unpacking
//
//  Revision 1.10  1999/06/30 15:00:41  hagel
//  Miscelaneous changes
//
//  Revision 1.9  1999/06/22 00:08:59  hagel
//  Impement beginning of C1
//
//  Revision 1.8  1999/06/20 22:42:10  hagel
//  Remove bottleneck from reading Event Builder
//
//  Revision 1.7  1999/06/20 20:56:04  hagel
//  Remove bottleneck with reading from Event Builder
//
//  Revision 1.6  1999/06/19 22:25:15  hagel
//  Add support for MULT
//
//  Revision 1.5  1999/06/18 22:37:13  hagel
//  Various modifications to make read raw data
//
//  Revision 1.4  1999/06/16 15:09:56  hagel
//  Initial revision as copied from Konstantin and ROOTified
//
//  Revision 1.3  1999/06/16 14:00:58  hagel
//  Intermediate step for simple reason to save and have backup.
//  Works with ZDC.
//  Started implementation of reading from event builder
//
//  Revision 1.2  1999/06/11 23:32:38  hagel
//  Closer to real thing
//
//  Revision 1.1  1999/06/02 15:00:24  hagel
//  First version.  This doesn't work; only put in to get into repository for backup.
//  Many things will change; perhaps even the philosophy
//
//
//  History:
//  =======
//  November 1999. Added pre-processor flags NODISPATCH to indicate that EVB access code
//                 is bypassed. This was done for my (fv) standalone laptop system due
//                 to problems in linking with STL templates under VC++ 5.0
//
//  December 1999. Modified code to deal with the TPC raw data as defined by KO
//                 in the Dec 10 document.
//
// May 2000, FV
//                 Moved dealing with RICH detector from FFS section to
//                 BFS part.
//

This page automatically generated by script docBrat by Christian Holm

Copyright ; 2002 BRAHMS Collaboration <brahmlib@rcf.rhic.bnl.gov>
Last Update on by

Validate HTML
Validate CSS