// or
// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
*/
-
+#include <cassert>
#include <TClonesArray.h>
#include <TSystem.h>
#include <TMath.h>
#include <AliTPCcluster.h>
#include <AliTPCClustersRow.h>
#include <AliSimDigits.h>
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
#include "AliHLTTPCLogging.h"
#include "AliHLTTPCTransform.h"
#include "AliHLTTPCSpacePointData.h"
//#include "AliHLTTPCTrackArray.h"
#include "AliHLTTPCFileHandler.h"
+#include "AliHLTTPCMapping.h"
+#include "AliHLTAltroEncoder.h"
#if __GNUC__ >= 3
using namespace std;
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){
<<"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;
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;
<<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
}
<<"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")
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();
// 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")
}
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???
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);
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);
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.
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;
}
}
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;
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")
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;