]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/TPCLib/AliHLTTPCFileHandler.cxx
bugfix: correct handling of empty rows in TPC digit data, bug #50771
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCFileHandler.cxx
index 4a155895d1a77da6efebf5c3251074a1eb2a7d67..ce952c37105d056865ffe5864b392ca36bdd88a7 100644 (file)
@@ -31,7 +31,7 @@
 // or
 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
                                                                           */
-
+#include <cassert>
 #include <TClonesArray.h>
 #include <TSystem.h>
 #include <TMath.h>
@@ -46,6 +46,8 @@
 #include <AliTPCcluster.h>
 #include <AliTPCClustersRow.h>
 #include <AliSimDigits.h>
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
 
 #include "AliHLTTPCLogging.h"
 #include "AliHLTTPCTransform.h"
@@ -54,6 +56,8 @@
 #include "AliHLTTPCSpacePointData.h"
 //#include "AliHLTTPCTrackArray.h"
 #include "AliHLTTPCFileHandler.h"
+#include "AliHLTTPCMapping.h"
+#include "AliHLTAltroEncoder.h"
 
 #if __GNUC__ >= 3
 using namespace std;
@@ -248,6 +252,21 @@ void AliHLTTPCFileHandler::CloseMCOutput()
 Bool_t AliHLTTPCFileHandler::SetAliInput()
 { 
   //set ali input
+
+  // fParam is in all cases an external object
+  const char* cdbEntry="TPC/Calib/Parameters";
+  AliCDBManager* pMan=AliCDBManager::Instance();
+  if (pMan) {
+    AliCDBEntry *pEntry = pMan->Get(cdbEntry);
+    if (pEntry==NULL || 
+       pEntry->GetObject()==NULL ||
+       (fParam=dynamic_cast<AliTPCParam*>(pEntry->GetObject()))==NULL) {
+      LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
+       <<"can not load AliTPCParam object from OCDB entry " << cdbEntry <<ENDLOG;
+    }
+  }
+  if (!fParam) {
+  // the old solution until Nov 2008
   fInAli->CdGAFile();
   fParam = (AliTPCParam*)gFile->Get("75x40_100x60_150x60");
   if(!fParam){
@@ -257,6 +276,7 @@ Bool_t AliHLTTPCFileHandler::SetAliInput()
       <<"which might not be what you want!"<<ENDLOG;
     fParam = new AliTPCParamSR;
   }
+  }
   if(!fParam){ 
     LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
       <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<gFile->GetName()<<ENDLOG;
@@ -383,6 +403,7 @@ Bool_t AliHLTTPCFileHandler::CreateIndex()
     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
       <<"Starting to create index, this can take a while."<<ENDLOG;
 
+    //Int_t lslice,lrow;
     for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
       Int_t sector, row;
       Int_t lslice,lrow;
@@ -394,14 +415,21 @@ Bool_t AliHLTTPCFileHandler::CreateIndex()
          <<sector<<" "<<row<<ENDLOG;
        return kFALSE;
       }
+      // this is just to make sure the same array dimensions are
+      // used as in the AliHLTTPCTransform class. The check for
+      // correct bounds is done in AliHLTTPCTransform::Sector2Slice
+      assert(lslice>=0 && lslice<fgkNSlice);
+      assert(lrow>=0 && lrow<fgkNRow);
       if(fIndex[lslice][lrow]==-1) {
        fIndex[lslice][lrow]=n;
       }
     }
+    assert(AliHLTTPCTransform::GetNSlice()==fgkNSlice);
+    assert(AliHLTTPCTransform::GetNRows()==fgkNRow);
     if(fUseStaticIndex) { // create static index
-      for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
-       for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
-         fgStaticIndex[i][j]=fIndex[i][j];
+      for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
+       for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
+         fgStaticIndex[islice][irow]=fIndex[islice][irow];
       }
       fgStaticIndexCreated=kTRUE; //remember that index has been created
     }
@@ -410,9 +438,9 @@ Bool_t AliHLTTPCFileHandler::CreateIndex()
     <<"Index successfully created."<<ENDLOG;
 
   } else if(fUseStaticIndex) { //simply copy static index
-    for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
-      for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
-       fIndex[i][j]=fgStaticIndex[i][j];
+    for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
+      for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
+       fIndex[islice][irow]=fgStaticIndex[islice][irow];
     }
 
   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
@@ -442,7 +470,6 @@ AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int
 
   UShort_t dig;
   Int_t time,pad,sector,row;
-  Int_t lslice,lrow;
   Int_t nrows=0;
   Int_t ndigitcount=0;
   Int_t entries = (Int_t)fDigitsTree->GetEntries();
@@ -480,12 +507,16 @@ AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int
   // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
   // in the TPC
   // This loop filters the pad rows according to the slice no set via Init
-  for(Int_t r=fRowMin;r<=fRowMax;r++){
+  assert(fRowMax<fgkNRow);
+  for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
     Int_t n=fIndex[fSlice][r];
     if(n!=-1){ // there is data on that row available
+      Int_t lslice,lrow;
       fDigitsTree->GetEvent(n);
       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+//       LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
+//     << "Sector "<<sector<<" Row " << row << " Slice " << lslice << " lrow " << lrow<<ENDLOG;
 
       if(lrow!=r){
        LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
@@ -494,15 +525,18 @@ AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int
       }
 
       ndigits[lrow] = 0;
-      fDigits->First();
-      do {
+      for (bool bHaveData=fDigits->First();
+          bHaveData;
+          bHaveData=fDigits->Next()) {
        time=fDigits->CurrentRow();
        pad=fDigits->CurrentColumn();
        dig = fDigits->GetDigit(time,pad);
        if(dig <= fParam->GetZeroSup()) continue;
        if(dig >= AliHLTTPCTransform::GetADCSat())
          dig = AliHLTTPCTransform::GetADCSat();
-      
+
+       // if we switch to AliTPCTransform, this maybe needs to be 
+       // adjusted as well
        AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
        //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
        //        continue; // why 230???
@@ -510,37 +544,52 @@ AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int
        ndigits[lrow]++; //for this row only
        ndigitcount++;   //total number of digits to be published
 
-      } while (fDigits->Next());
+      }
       //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
     }
-    nrows++;
+    //see comment below//nrows++;
   }
-
-  UInt_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
+  // Matthias 05.11.2007
+  // The question is whether we should always return a AliHLTTPCDigitRowData
+  // for each row, even the empty ones or only for the ones filled with data.
+  // the AliHLTTPCDigitReaderUnpacked as the counnterpart so far assumes 
+  // empty RawData structs for empty rows. But some of the code here implies
+  // the latter approach, e.g. the count of nrows in the loop above (now
+  // commented). At least the two loops were not consistent, it's fixed now.
+  nrows=fRowMax-fRowMin+1;
+
+  UInt_t bufferSize = sizeof(AliHLTTPCDigitData)*ndigitcount
     + nrows*sizeof(AliHLTTPCDigitRowData);
 
   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
-    <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
-  
+    << "Found "<<ndigitcount<<" Digits in " << nrows << " rows out of [" << fRowMin << "," << fRowMax <<"]"<<ENDLOG;
+
   if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
-    if (size<=*pTgtSize) {
+    if (bufferSize<=*pTgtSize) {
       data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
     } else {
     }
-  } else {
-    data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(size));
+  } else if (bufferSize>0) {
+    data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(bufferSize));
+  }
+  if (pTgtSize) *pTgtSize=bufferSize;
+  if (data==NULL) {
+    delete [] ndigits;
+    return NULL;
   }
-  if (pTgtSize) *pTgtSize=size;
-  if (data==NULL) return NULL;
   nrow = (UInt_t)nrows;
   AliHLTTPCDigitRowData *tempPt = data;
+  memset(data, 0, bufferSize);
 
-  for(Int_t r=fRowMin;r<=fRowMax;r++){
+  for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
     Int_t n=fIndex[fSlice][r];
-    tempPt->fRow = r;
+
+    AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
+    tempPt->fRow = row;
     tempPt->fNDigit = 0;
 
     if(n!=-1){//data on that row
+      Int_t lslice,lrow;
       fDigitsTree->GetEvent(n);
       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
@@ -550,11 +599,14 @@ AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int
        continue;
       }
 
+      // set the correct row no and digit count
+      tempPt->fRow = row;
       tempPt->fNDigit = ndigits[lrow];
 
       Int_t localcount=0;
-      fDigits->First();
-      do {
+      for (bool bHaveData=fDigits->First();
+          bHaveData;
+          bHaveData=fDigits->Next()) {
        time=fDigits->CurrentRow();
        pad=fDigits->CurrentColumn();
        dig = fDigits->GetDigit(time,pad);
@@ -579,18 +631,102 @@ AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int
        tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
        tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
        localcount++;
-      } while (fDigits->Next());
-      Byte_t *tmp = (Byte_t*)tempPt;
-      Int_t size = sizeof(AliHLTTPCDigitRowData)
-       + ndigits[lrow]*sizeof(AliHLTTPCDigitData);
-      tmp += size;
-      tempPt = (AliHLTTPCDigitRowData*)tmp;
+      }
     }
+
+    Byte_t *tmp = (Byte_t*)tempPt;
+    Int_t blockSize = sizeof(AliHLTTPCDigitRowData)
+      + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
+    tmp += blockSize;
+    tempPt = (AliHLTTPCDigitRowData*)tmp;
   }
+  assert((Byte_t*)tempPt==((Byte_t*)data)+bufferSize);
   delete [] ndigits;
   return data;
 }
 
+int AliHLTTPCFileHandler::AliDigits2Altro(Int_t event, Byte_t* tgtBuffer, UInt_t tgtSize)
+{
+  //Read data from AliROOT file into memory, and store it in the ALTRO data format
+  //in the provided buffer 
+  //Returns: size of the encoded data in bytes
+  int iResult=0;
+
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Altro","File")
+    <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
+    return 0; 
+  }
+
+  if (!tgtBuffer) {
+    return -EINVAL;
+  }
+
+  if(!fDigitsTree)
+    if(!GetDigitsTree(event)) return 0;
+
+  UShort_t dig;
+  Int_t time=0;
+  Int_t pad=0;
+  Int_t sector=0;
+
+  AliHLTTPCMapping mapper(fPatch);
+  AliHLTAltroEncoder encoder;
+  encoder.SetBuffer(tgtBuffer, tgtSize);
+
+  // The digits of the current event have been indexed: all digits are organized in
+  // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
+  // are stored in the digit tree.
+  // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
+  // in the TPC
+  // This loop filters the pad rows according to the slice no set via Init
+
+  assert(fRowMax<fgkNRow);
+  for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow && iResult>=0;r++){
+    Int_t n=fIndex[fSlice][r];
+
+    Int_t row=0;
+    Int_t rowOffset=0;
+    AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
+    AliHLTTPCTransform::Slice2Sector(fSlice,AliHLTTPCTransform::GetFirstRow(fPatch),sector,rowOffset);
+
+    if(n!=-1){//data on that row
+      Int_t lslice,lrow;
+      fDigitsTree->GetEvent(n);
+      fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+      AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+      if(lrow!=r){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Altro","Row")
+         <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+       continue;
+      }
+
+      Int_t channelAddress=-1;
+      fDigits->First();
+      do {
+       time=fDigits->CurrentRow();
+       pad=fDigits->CurrentColumn();
+       dig = fDigits->GetDigit(time,pad);
+       if (dig <= fParam->GetZeroSup()) continue;
+       if(dig >= AliHLTTPCTransform::GetADCSat())
+         dig = AliHLTTPCTransform::GetADCSat();
+       
+       channelAddress=mapper.GetHwAddress(row-rowOffset, pad);
+       iResult=encoder.AddChannelSignal(dig, time, channelAddress);
+      } while (fDigits->Next() && iResult>=0);
+      if (iResult>=0 && channelAddress>=0) {
+       iResult=encoder.SetChannel(channelAddress);
+      }
+    }
+  }
+
+  if (iResult>=0) {
+    iResult=(encoder.GetTotal40bitWords()*5)/4;
+  }
+
+  return iResult;
+}
+
 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
 {
   //Read data from AliROOT file into memory, and store it in the HLT data format.
@@ -644,7 +780,7 @@ AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nro
   Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
   Float_t xyz[3];
 
-  for(Int_t r=fRowMin;r<=fRowMax;r++){
+  for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
     Int_t n=fIndex[fSlice][r];
 
     ndigits[r] = 0;
@@ -926,9 +1062,8 @@ AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nro
       }
     }
     Byte_t *tmp = (Byte_t*)tempPt;
-    Int_t size = sizeof(AliHLTTPCDigitRowData)
+    tmp += sizeof(AliHLTTPCDigitRowData)
       + ndigits[r]*sizeof(AliHLTTPCDigitData);
-    tmp += size;
     tempPt = (AliHLTTPCDigitRowData*)tmp;
   }
   delete [] ndigits;
@@ -990,13 +1125,13 @@ void AliHLTTPCFileHandler::AliDigits2RootFile(AliHLTTPCDigitRowData *rowPt,Char_
     return;
   }
   tpcLoader->LoadDigits();
-  TTree *t=tpcLoader->TreeD();
+  TTree *treeD=tpcLoader->TreeD();
 
   AliTPCDigitsArray *oldArray = new AliTPCDigitsArray();
   oldArray->Setup(fParam);
   oldArray->SetClass("AliSimDigits");
 
-  Bool_t ok = oldArray->ConnectTree(t);
+  Bool_t ok = oldArray->ConnectTree(treeD);
   if(!ok)
     {
       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
@@ -1054,21 +1189,21 @@ void AliHLTTPCFileHandler::AliDigits2RootFile(AliHLTTPCDigitRowData *rowPt,Char_
          digcounter++;
          
          //Tricks to get and set the correct track id's. 
-         for(Int_t t=0; t<3; t++)
+         for(Int_t track=0; track<3; track++)
            {
-             Int_t label = oldDig->GetTrackIDFast(time,pad,t);
+             Int_t label = oldDig->GetTrackIDFast(time,pad,track);
              if(label > 1)
-               trackID[t] = label - 2;
+               trackID[track] = label - 2;
              else if(label==0)
-               trackID[t] = -2;
+               trackID[track] = -2;
              else
-               trackID[t] = -1;
+               trackID[track] = -1;
            }
          
          dig->SetDigitFast(charge,time,pad);
          
-         for(Int_t t=0; t<3; t++)
-           ((AliSimDigits*)dig)->SetTrackIDFast(trackID[t],time,pad,t);
+         for(Int_t track=0; track<3; track++)
+           ((AliSimDigits*)dig)->SetTrackIDFast(trackID[track],time,pad,track);
          
        }
       //cout<<"Wrote "<<digcounter<<" on row "<<i<<endl;