    // @(#)root/star:$Name:  $Id: TResponseTable.cxx,v 1.2 2003/02/11 12:17:19 rdm Exp $
    // Author: Valery Fine(fine@bnl.gov)   03/04/2002
    // Copyright(c) 2002 [BNL] Brookhaven National Laboratory, Valeri Fine (fine@bnl.gov)
    // All right reserved

    #include "TResponseTable.h"

    ClassImp(TResponseTable)
    TableClassStreamerImp(TResponseTable)

    //______________________________________________________________________________
     TResponseTable::TResponseTable():TGenericTable(), fResponseLocation(-1){}

    //______________________________________________________________________________
     TResponseTable::TResponseTable(const char *name,const char *volumePath, const char *responseDefinition, Int_t /*allocSize*/)
     :  TGenericTable(), fResponseLocation(-1)
    {
       // Set an empty descriptor
       SetDescriptorPointer(new TTableDescriptor(name));

       // The first element is always "int TRACK;"
       AddElement("TRACK",kInt);
       AddVolumePath(volumePath);
       AddResponse(responseDefinition);
       fSize = GetDescriptorPointer()->Sizeof();
       fResponseLocation = FindResponseLocation(*GetDescriptorPointer());
       SetType("DetectorResponse");
    }
    //______________________________________________________________________________
     void TResponseTable::AddVolumePath(const char *path)
    {
       Int_t counter = 0;
       const Int_t maxResponseCounter = 15;
       const char *next = &path[0];
       while( ( *next && *next != ' ') &&  counter < maxResponseCounter )
       {
         TString elName;
          for (int j=0; j<4 && (next[j] != ' ');j++)  elName += next[j];
          AddElement(elName,kInt);
          next += 4;
          counter++;
       }
    }
    //______________________________________________________________________________
     void TResponseTable::AddResponse(const char *chit)
    {
       Int_t counter = 0;
       const Int_t maxResponseCounter = 15;
       const char *next = &chit[0];
       while( ( *next != ' ' ) &&  counter < maxResponseCounter )
       {
         TString elName;
          for (int j=0; j<4 && (next[j] != ' ');j++)  elName += next[j];
          AddElement(elName,kFloat);
          next += 4;
          counter++;
       }
    }
    //______________________________________________________________________________
     void TResponseTable::AddElement(const char *path,EColumnType type)
    {
      assert( (type == kInt || type == kFloat ) );

      TTableDescriptor  &dsc = *GetTableDescriptors();
      Int_t nRow = dsc.GetNRows();
      tableDescriptor_st row;

       memset(&row,0,sizeof(row));
       strncpy(row.fColumnName,path,sizeof(row.fColumnName));
       if (nRow) row.fOffset = dsc[nRow-1].fOffset + dsc[nRow-1].fSize;

       row.fType = type;
       if (type == kInt)
          row.fTypeSize = sizeof(Int_t);
       else
          row.fTypeSize = sizeof(Float_t);

       row.fSize = row.fTypeSize;
       dsc.AddAt(&row);
    }

    //______________________________________________________________________________
     void TResponseTable::SetResponse(int track, int *nvl, float *response)
    {
      // Add one extra his/digit to the table
      // Reallocate the table if needed
      char    *charBuffer     = new char[GetRowSize()];
      Int_t   *nvlBuffer      = (Int_t *)charBuffer;
      Float_t *responseBuffer = (Float_t *)charBuffer;
      Int_t jResponse  = 0;
      Int_t jNvl       = 0;

      // Loop for the response information
      TTableDescriptor  &dsc = *GetTableDescriptors();
      Int_t nRow = dsc.GetNRows();
      tableDescriptor_st *row = dsc.GetTable();
      nvlBuffer[0] =  track; row++;
      for (int i=1;i<nRow;i++,row++) {
        if (row->fType == kFloat) {
          responseBuffer[i] = response[jResponse++];
        } else {
          nvlBuffer[i] = nvl[jNvl++];
        }
      }
      AddAt(charBuffer);
      delete [] charBuffer;
    }

    //______________________________________________________________________________
     Int_t TResponseTable::FindResponseLocation(TTableDescriptor  &dsc)
    {
     // Look up the table descriptor to find the
     // first respnse value location
     // TResponsetable layout:
     //  offset
     //   +0    int TRACK
     //   +1
     //   ...   int <volume path description>
     //  +nVl.
     //  +nVl+1  <----  fResponseLocation
     //   ...   response values
     //  RowSize

     // responseLocation is an offset of the first float data-member
      Int_t responseLocation = -1;
      Int_t nRow = dsc.GetNRows();
      tableDescriptor_st *row = dsc.GetTable();
      for (int i=0;i<nRow;i++,row++) {
        if (row->fType == kFloat) {
         // found
         responseLocation = i;
         break;
        }
      }
      return responseLocation;
    }