2 // Original: AliHLTFileHandler.cxx,v 1.49 2005/06/23 17:46:55 hristov
4 /**************************************************************************
5 * This file is property of and copyright by the ALICE HLT Project *
6 * ALICE Experiment at CERN, All rights reserved. *
8 * Primary Authors: U. Frankenfeld, A. Vestbo, C. Loizides *
9 * Matthias Richter <Matthias.Richter@ift.uib.no> *
10 * for The ALICE HLT Project. *
12 * Permission to use, copy, modify and distribute this software and its *
13 * documentation strictly for non-commercial purposes is hereby granted *
14 * without fee, provided that the above copyright notice appears in all *
15 * copies and that both the copyright notice and this permission notice *
16 * appear in the supporting documentation. The authors make no claims *
17 * about the suitability of this software for any purpose. It is *
18 * provided "as is" without express or implied warranty. *
19 **************************************************************************/
21 /** @file AliHLTTPCFileHandler.cxx
22 @author U. Frankenfeld, A. Vestbo, C. Loizides, maintained by
25 @brief file input for the TPC tracking code before migration to the
26 HLT component framework
28 // see below for class documentation
30 // refer to README to build package
32 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
35 #include <TClonesArray.h>
39 #include <AliRunLoader.h>
43 #include <AliTPCParamSR.h>
44 #include <AliTPCDigitsArray.h>
45 #include <AliTPCClustersArray.h>
46 #include <AliTPCcluster.h>
47 #include <AliTPCClustersRow.h>
48 #include <AliSimDigits.h>
49 #include "AliCDBManager.h"
50 #include "AliCDBEntry.h"
52 #include "AliHLTTPCLogging.h"
53 #include "AliHLTTPCTransform.h"
54 #include "AliHLTTPCDigitData.h"
55 //#include "AliHLTTPCTrackSegmentData.h"
56 #include "AliHLTTPCSpacePointData.h"
57 //#include "AliHLTTPCTrackArray.h"
58 #include "AliHLTTPCFileHandler.h"
59 #include "AliHLTTPCMapping.h"
60 #include "AliHLTAltroEncoder.h"
68 //_____________________________________________________________
69 // AliHLTTPCFileHandler
71 // The HLT ROOT <-> binary files handling class
73 // This class provides the interface between AliROOT files,
74 // and HLT binary files. It should be used for converting
75 // TPC data stored in AliROOT format (outputfile from a simulation),
76 // into the data format currently used by in the HLT framework.
77 // This enables the possibility to always use the same data format,
78 // whether you are using a binary file as an input, or a AliROOT file.
80 // For example on how to create binary files from a AliROOT simulation,
81 // see example macro exa/Binary.C.
83 // For reading a AliROOT file into HLT format in memory, do the following:
85 // AliHLTTPCFileHandler file;
86 // file.Init(slice,patch);
87 // file.SetAliInput("galice.root");
88 // AliHLTTPCDigitRowData *dataPt = (AliHLTTPCDigitRowData*)file.AliDigits2Memory(nrows,eventnr);
90 // All the data are then stored in memory and accessible via the pointer dataPt.
91 // Accesing the data is then identical to the example 1) showed in AliHLTTPCMemHandler class.
93 // For converting the data back, and writing it to a new AliROOT file do:
95 // AliHLTTPCFileHandler file;
96 // file.Init(slice,patch);
97 // file.SetAliInput("galice.root");
98 // file.Init(slice,patch,NumberOfRowsInPatch);
99 // file.AliDigits2RootFile(dataPt,"new_galice.root");
100 // file.CloseAliInput();
104 ClassImp(AliHLTTPCFileHandler)
106 AliHLTTPCFileHandler::AliHLTTPCFileHandler(Bool_t b)
109 fUseRunLoader(kFALSE),
114 fIndexCreated(kFALSE),
117 //Default constructor
119 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++)
120 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
123 if(fUseStaticIndex&&!fgStaticIndexCreated) CleanStaticIndex();
126 AliHLTTPCFileHandler::~AliHLTTPCFileHandler()
129 if(fMC) CloseMCOutput();
131 if(fInAli) CloseAliInput();
134 // of course on start up the index is not created
135 Bool_t AliHLTTPCFileHandler::fgStaticIndexCreated=kFALSE;
136 Int_t AliHLTTPCFileHandler::fgStaticIndex[36][159];
138 void AliHLTTPCFileHandler::CleanStaticIndex()
140 // use this static call to clean static index after
141 // running over one event
142 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
143 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
144 fgStaticIndex[i][j]=-1;
146 fgStaticIndexCreated=kFALSE;
149 Int_t AliHLTTPCFileHandler::SaveStaticIndex(Char_t *prefix,Int_t event)
151 // use this static call to store static index after
152 if(!fgStaticIndexCreated) return -1;
156 sprintf(fname,"%s-%d.txt",prefix,event);
158 sprintf(fname,"TPC.Digits.staticindex-%d.txt",event);
160 ofstream file(fname,ios::trunc);
161 if(!file.good()) return -1;
163 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
164 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
165 file << fgStaticIndex[i][j] << " ";
172 Int_t AliHLTTPCFileHandler::LoadStaticIndex(Char_t *prefix,Int_t event)
174 // use this static call to store static index after
175 if(fgStaticIndexCreated){
176 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::LoadStaticIndex","Inxed")
177 <<"Static index already created, will overwrite"<<ENDLOG;
183 sprintf(fname,"%s-%d.txt",prefix,event);
185 sprintf(fname,"TPC.Digits.staticindex-%d.txt",event);
187 ifstream file(fname);
188 if(!file.good()) return -1;
190 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
191 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
192 file >> fgStaticIndex[i][j];
196 fgStaticIndexCreated=kTRUE;
200 void AliHLTTPCFileHandler::FreeDigitsTree()
209 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
210 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
213 fIndexCreated=kFALSE;
216 Bool_t AliHLTTPCFileHandler::SetMCOutput(Char_t *name)
219 fMC = fopen(name,"w");
221 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
222 <<"Pointer to File = 0x0 "<<ENDLOG;
228 Bool_t AliHLTTPCFileHandler::SetMCOutput(FILE *file)
233 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
234 <<"Pointer to File = 0x0 "<<ENDLOG;
240 void AliHLTTPCFileHandler::CloseMCOutput()
244 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseMCOutPut","File Close")
245 <<"Nothing to Close"<<ENDLOG;
252 Bool_t AliHLTTPCFileHandler::SetAliInput()
256 // fParam is in all cases an external object
257 const char* cdbEntry="TPC/Calib/Parameters";
258 AliCDBManager* pMan=AliCDBManager::Instance();
260 AliCDBEntry *pEntry = pMan->Get(cdbEntry);
262 pEntry->GetObject()==NULL ||
263 (fParam=dynamic_cast<AliTPCParam*>(pEntry->GetObject()))==NULL) {
264 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
265 <<"can not load AliTPCParam object from OCDB entry " << cdbEntry <<ENDLOG;
269 // the old solution until Nov 2008
271 fParam = (AliTPCParam*)gFile->Get("75x40_100x60_150x60");
273 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
274 <<"No TPC parameters found in \""<<gFile->GetName()
275 <<"\", creating standard parameters "
276 <<"which might not be what you want!"<<ENDLOG;
277 fParam = new AliTPCParamSR;
281 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
282 <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<gFile->GetName()<<ENDLOG;
289 Bool_t AliHLTTPCFileHandler::SetAliInput(Char_t *name)
291 //Open the AliROOT file with name.
292 fInAli= AliRunLoader::Open(name);
294 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
295 <<"Pointer to fInAli = 0x0 "<<ENDLOG;
298 return SetAliInput();
301 Bool_t AliHLTTPCFileHandler::SetAliInput(AliRunLoader *runLoader)
303 //set ali input as runloader
305 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
306 <<"invalid agument: pointer to AliRunLoader NULL "<<ENDLOG;
309 if (fInAli!=NULL && fInAli!=runLoader) {
310 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
311 <<"Pointer to AliRunLoader already set"<<ENDLOG;
315 fUseRunLoader = kTRUE;
316 return SetAliInput();
319 void AliHLTTPCFileHandler::CloseAliInput()
322 if(fUseRunLoader) return;
324 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseAliInput","RunLoader")
325 <<"Nothing to Close"<<ENDLOG;
333 Bool_t AliHLTTPCFileHandler::IsDigit(Int_t event)
335 //Check if there is a TPC digit tree in the current file.
336 //Return kTRUE if tree was found, and kFALSE if not found.
339 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::IsDigit","File")
340 <<"Pointer to fInAli = 0x0 "<<ENDLOG;
341 return kTRUE; //maybe you are using binary input which is Digits!
343 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
345 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandlerNewIO::IsDigit","File")
346 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
349 fInAli->GetEvent(event);
350 tpcLoader->LoadDigits();
351 TTree *t=tpcLoader->TreeD();
353 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
354 <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
358 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
359 <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
364 ///////////////////////////////////////// Digit IO
365 Bool_t AliHLTTPCFileHandler::AliDigits2BinaryFile(Int_t event,Bool_t altro)
367 //save alidigits as binary
370 AliHLTTPCDigitRowData* data = 0;
372 data = AliAltroDigits2Memory(nrow,event);
374 data = AliDigits2Memory(nrow,event);
375 out = Memory2BinaryFile(nrow,data);
380 Bool_t AliHLTTPCFileHandler::AliDigits2CompBinary(Int_t event,Bool_t altro)
382 //Convert AliROOT TPC data, into HLT data format.
383 //event specifies the event you want in the aliroot file.
387 AliHLTTPCDigitRowData *digits=0;
389 digits = AliAltroDigits2Memory(ndigits,event);
391 digits = AliDigits2Memory(ndigits,event);
392 out = Memory2CompBinary(ndigits,digits);
397 Bool_t AliHLTTPCFileHandler::CreateIndex()
399 //create the access index or copy from static index
400 fIndexCreated=kFALSE;
402 if(!fgStaticIndexCreated || !fUseStaticIndex) { //we have to create index
403 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
404 <<"Starting to create index, this can take a while."<<ENDLOG;
407 for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
410 fDigitsTree->GetEvent(n);
411 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
412 if(!AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row)){
413 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::CreateIndex","Slice/Row")
414 <<AliHLTTPCLog::kDec<<"Index could not be created. Wrong values "
415 <<sector<<" "<<row<<ENDLOG;
418 // this is just to make sure the same array dimensions are
419 // used as in the AliHLTTPCTransform class. The check for
420 // correct bounds is done in AliHLTTPCTransform::Sector2Slice
421 assert(lslice>=0 && lslice<fgkNSlice);
422 assert(lrow>=0 && lrow<fgkNRow);
423 if(fIndex[lslice][lrow]==-1) {
424 fIndex[lslice][lrow]=n;
427 assert(AliHLTTPCTransform::GetNSlice()==fgkNSlice);
428 assert(AliHLTTPCTransform::GetNRows()==fgkNRow);
429 if(fUseStaticIndex) { // create static index
430 for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
431 for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
432 fgStaticIndex[islice][irow]=fIndex[islice][irow];
434 fgStaticIndexCreated=kTRUE; //remember that index has been created
437 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
438 <<"Index successfully created."<<ENDLOG;
440 } else if(fUseStaticIndex) { //simply copy static index
441 for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
442 for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
443 fIndex[islice][irow]=fgStaticIndex[islice][irow];
446 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
447 <<"Index successfully taken from static copy."<<ENDLOG;
453 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event, Byte_t* tgtBuffer, UInt_t *pTgtSize)
455 //Read data from AliROOT file into memory, and store it in the HLT data format
456 //in the provided buffer or an allocated buffer.
457 //Returns a pointer to the data.
459 AliHLTTPCDigitRowData *data = 0;
463 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
464 <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
469 if(!GetDigitsTree(event)) return 0;
472 Int_t time,pad,sector,row;
475 Int_t entries = (Int_t)fDigitsTree->GetEntries();
477 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","ndigits")
478 <<"No TPC digits (entries==0)!"<<ENDLOG;
479 nrow = (UInt_t)(fRowMax-fRowMin+1);
480 UInt_t size = nrow*sizeof(AliHLTTPCDigitRowData);
481 if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
482 if (size<=*pTgtSize) {
483 data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
487 data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(size));
489 AliHLTTPCDigitRowData *tempPt = data;
491 if (pTgtSize) *pTgtSize=size;
492 for(Int_t r=fRowMin;r<=fRowMax;r++){
501 Int_t * ndigits = new Int_t[fRowMax+1];
504 // The digits of the current event have been indexed: all digits are organized in
505 // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
506 // are stored in the digit tree.
507 // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
509 // This loop filters the pad rows according to the slice no set via Init
510 assert(fRowMax<fgkNRow);
511 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
512 Int_t n=fIndex[fSlice][r];
513 if(n!=-1){ // there is data on that row available
515 fDigitsTree->GetEvent(n);
516 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
517 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
518 // LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
519 // << "Sector "<<sector<<" Row " << row << " Slice " << lslice << " lrow " << lrow<<ENDLOG;
522 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
523 <<AliHLTTPCLog::kDec<<"Rows in slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
528 for (bool bHaveData=fDigits->First();
530 bHaveData=fDigits->Next()) {
531 time=fDigits->CurrentRow();
532 pad=fDigits->CurrentColumn();
533 dig = fDigits->GetDigit(time,pad);
534 if(dig <= fParam->GetZeroSup()) continue;
535 if(dig >= AliHLTTPCTransform::GetADCSat())
536 dig = AliHLTTPCTransform::GetADCSat();
538 // if we switch to AliTPCTransform, this maybe needs to be
540 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
541 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
542 // continue; // why 230???
544 ndigits[lrow]++; //for this row only
545 ndigitcount++; //total number of digits to be published
548 //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
550 //see comment below//nrows++;
552 // Matthias 05.11.2007
553 // The question is whether we should always return a AliHLTTPCDigitRowData
554 // for each row, even the empty ones or only for the ones filled with data.
555 // the AliHLTTPCDigitReaderUnpacked as the counnterpart so far assumes
556 // empty RawData structs for empty rows. But some of the code here implies
557 // the latter approach, e.g. the count of nrows in the loop above (now
558 // commented). At least the two loops were not consistent, it's fixed now.
559 nrows=fRowMax-fRowMin+1;
561 UInt_t bufferSize = sizeof(AliHLTTPCDigitData)*ndigitcount
562 + nrows*sizeof(AliHLTTPCDigitRowData);
564 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
565 << "Found "<<ndigitcount<<" Digits in " << nrows << " rows out of [" << fRowMin << "," << fRowMax <<"]"<<ENDLOG;
567 if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
568 if (bufferSize<=*pTgtSize) {
569 data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
572 } else if (bufferSize>0) {
573 data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(bufferSize));
575 if (pTgtSize) *pTgtSize=bufferSize;
580 nrow = (UInt_t)nrows;
581 AliHLTTPCDigitRowData *tempPt = data;
582 memset(data, 0, bufferSize);
584 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
585 Int_t n=fIndex[fSlice][r];
587 AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
591 if(n!=-1){//data on that row
593 fDigitsTree->GetEvent(n);
594 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
595 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
597 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
598 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
602 // set the correct row no and digit count
604 tempPt->fNDigit = ndigits[lrow];
607 for (bool bHaveData=fDigits->First();
609 bHaveData=fDigits->Next()) {
610 time=fDigits->CurrentRow();
611 pad=fDigits->CurrentColumn();
612 dig = fDigits->GetDigit(time,pad);
613 if (dig <= fParam->GetZeroSup()) continue;
614 if(dig >= AliHLTTPCTransform::GetADCSat())
615 dig = AliHLTTPCTransform::GetADCSat();
617 //Exclude data outside cone:
618 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
619 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
620 // continue; // why 230???
622 if(localcount >= ndigits[lrow])
623 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliDigits2Binary","Memory")
624 <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
625 <<ndigits[lrow]<<ENDLOG;
627 tempPt->fDigitData[localcount].fCharge=dig;
628 tempPt->fDigitData[localcount].fPad=pad;
629 tempPt->fDigitData[localcount].fTime=time;
630 tempPt->fDigitData[localcount].fTrackID[0] = fDigits->GetTrackID(time,pad,0);
631 tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
632 tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
637 Byte_t *tmp = (Byte_t*)tempPt;
638 Int_t blockSize = sizeof(AliHLTTPCDigitRowData)
639 + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
641 tempPt = (AliHLTTPCDigitRowData*)tmp;
643 assert((Byte_t*)tempPt==((Byte_t*)data)+bufferSize);
648 int AliHLTTPCFileHandler::AliDigits2Altro(Int_t event, Byte_t* tgtBuffer, UInt_t tgtSize)
650 //Read data from AliROOT file into memory, and store it in the ALTRO data format
651 //in the provided buffer
652 //Returns: size of the encoded data in bytes
656 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Altro","File")
657 <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
666 if(!GetDigitsTree(event)) return 0;
673 AliHLTTPCMapping mapper(fPatch);
674 AliHLTAltroEncoder encoder;
675 encoder.SetBuffer(tgtBuffer, tgtSize);
677 // The digits of the current event have been indexed: all digits are organized in
678 // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
679 // are stored in the digit tree.
680 // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
682 // This loop filters the pad rows according to the slice no set via Init
684 assert(fRowMax<fgkNRow);
685 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow && iResult>=0;r++){
686 Int_t n=fIndex[fSlice][r];
690 AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
691 AliHLTTPCTransform::Slice2Sector(fSlice,AliHLTTPCTransform::GetFirstRow(fPatch),sector,rowOffset);
693 if(n!=-1){//data on that row
695 fDigitsTree->GetEvent(n);
696 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
697 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
699 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Altro","Row")
700 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
704 Int_t channelAddress=-1;
707 time=fDigits->CurrentRow();
708 pad=fDigits->CurrentColumn();
709 dig = fDigits->GetDigit(time,pad);
710 if (dig <= fParam->GetZeroSup()) continue;
711 if(dig >= AliHLTTPCTransform::GetADCSat())
712 dig = AliHLTTPCTransform::GetADCSat();
714 channelAddress=mapper.GetHwAddress(row-rowOffset, pad);
715 iResult=encoder.AddChannelSignal(dig, time, channelAddress);
716 } while (fDigits->Next() && iResult>=0);
717 if (iResult>=0 && channelAddress>=0) {
718 iResult=encoder.SetChannel(channelAddress);
724 iResult=(encoder.GetTotal40bitWords()*5)/4;
730 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
732 //Read data from AliROOT file into memory, and store it in the HLT data format.
733 //Returns a pointer to the data.
734 //This functions filter out single timebins, which is noise. The timebins which
735 //are removed are timebins which have the 4 zero neighbours;
736 //(pad-1,time),(pad+1,time),(pad,time-1),(pad,time+1).
738 AliHLTTPCDigitRowData *data = 0;
742 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
743 <<"No Input avalible: Pointer to TFile == NULL"<<ENDLOG;
746 if(eventmerge == kTRUE && event >= 1024)
748 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","TrackIDs")
749 <<"Too many events if you want to merge!"<<ENDLOG;
754 /* Dont understand why we have to do
755 reload the tree, but otherwise the code crashes */
757 if(!GetDigitsTree(event)) return 0;
760 Int_t time,pad,sector,row;
763 Int_t entries = (Int_t)fDigitsTree->GetEntries();
765 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","ndigits")
766 <<"No TPC digits (entries==0)!"<<ENDLOG;
767 nrow = (UInt_t)(fRowMax-fRowMin+1);
768 Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
769 data=(AliHLTTPCDigitRowData*) Allocate(size);
770 AliHLTTPCDigitRowData *tempPt = data;
771 for(Int_t r=fRowMin;r<=fRowMax;r++){
778 Int_t * ndigits = new Int_t[fRowMax+1];
780 Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
783 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
784 Int_t n=fIndex[fSlice][r];
788 if(n!=-1){//data on that row
789 fDigitsTree->GetEvent(n);
790 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
791 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
792 //cout << lslice << " " << fSlice << " " << lrow << " " << r << " " << sector << " " << row << endl;
793 if((lslice!=fSlice)||(lrow!=r)){
794 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
795 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
799 fDigits->ExpandBuffer();
800 fDigits->ExpandTrackBuffer();
801 for(Int_t i=0; i<fDigits->GetNCols(); i++){
802 for(Int_t j=0; j<fDigits->GetNRows(); j++){
805 dig = fDigits->GetDigitFast(time,pad);
806 if(dig <= zerosupval) continue;
807 if(dig >= AliHLTTPCTransform::GetADCSat())
808 dig = AliHLTTPCTransform::GetADCSat();
810 //Check for single timebins, and remove them because they are noise for sure.
811 if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
812 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
813 fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
814 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
815 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
821 if(j < fDigits->GetNRows()-1 && j > 0)
823 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
824 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
825 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
830 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
831 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
837 if(i < fDigits->GetNCols()-1 && i > 0)
839 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
840 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
841 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
846 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
847 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
852 if(i==fDigits->GetNCols()-1)
854 if(j>0 && j<fDigits->GetNRows()-1)
856 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
857 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
858 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
861 else if(j==0 && j<fDigits->GetNRows()-1)
863 if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
864 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
869 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
870 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
875 if(j==fDigits->GetNRows()-1)
877 if(i>0 && i<fDigits->GetNCols()-1)
879 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
880 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
881 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
884 else if(i==0 && fDigits->GetNCols()-1)
886 if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
887 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
892 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
893 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
898 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
899 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
902 ndigits[lrow]++; //for this row only
903 ndigitcount++; //total number of digits to be published
910 Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
911 + nrows*sizeof(AliHLTTPCDigitRowData);
913 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Digits")
914 <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
916 data=(AliHLTTPCDigitRowData*) Allocate(size);
917 nrow = (UInt_t)nrows;
918 AliHLTTPCDigitRowData *tempPt = data;
920 for(Int_t r=fRowMin;r<=fRowMax;r++){
921 Int_t n=fIndex[fSlice][r];
924 if(n!=-1){ //no data on that row
925 fDigitsTree->GetEvent(n);
926 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
927 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
930 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
931 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
935 tempPt->fNDigit = ndigits[lrow];
938 fDigits->ExpandBuffer();
939 fDigits->ExpandTrackBuffer();
940 for(Int_t i=0; i<fDigits->GetNCols(); i++){
941 for(Int_t j=0; j<fDigits->GetNRows(); j++){
944 dig = fDigits->GetDigitFast(time,pad);
945 if(dig <= zerosupval) continue;
946 if(dig >= AliHLTTPCTransform::GetADCSat())
947 dig = AliHLTTPCTransform::GetADCSat();
949 //Check for single timebins, and remove them because they are noise for sure.
950 if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
951 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
952 fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
953 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
954 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
960 if(j < fDigits->GetNRows()-1 && j > 0)
962 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
963 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
964 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
969 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
970 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
976 if(i < fDigits->GetNCols()-1 && i > 0)
978 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
979 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
980 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
985 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
986 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
991 if(i == fDigits->GetNCols()-1)
993 if(j>0 && j<fDigits->GetNRows()-1)
995 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
996 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
997 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1000 else if(j==0 && j<fDigits->GetNRows()-1)
1002 if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1003 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1008 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
1009 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1013 if(j==fDigits->GetNRows()-1)
1015 if(i>0 && i<fDigits->GetNCols()-1)
1017 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1018 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1019 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1022 else if(i==0 && fDigits->GetNCols()-1)
1024 if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1025 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1030 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1031 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1036 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
1037 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
1040 if(localcount >= ndigits[lrow])
1041 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliAltroDigits2Binary","Memory")
1042 <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
1043 <<ndigits[lrow]<<ENDLOG;
1045 tempPt->fDigitData[localcount].fCharge=dig;
1046 tempPt->fDigitData[localcount].fPad=pad;
1047 tempPt->fDigitData[localcount].fTime=time;
1048 tempPt->fDigitData[localcount].fTrackID[0] = (fDigits->GetTrackIDFast(time,pad,0)-2);
1049 tempPt->fDigitData[localcount].fTrackID[1] = (fDigits->GetTrackIDFast(time,pad,1)-2);
1050 tempPt->fDigitData[localcount].fTrackID[2] = (fDigits->GetTrackIDFast(time,pad,2)-2);
1051 if(eventmerge == kTRUE) //careful track mc info will be touched
1052 {//Event are going to be merged, so event number is stored in the upper 10 bits.
1053 tempPt->fDigitData[localcount].fTrackID[0] += 128; //leave some room
1054 tempPt->fDigitData[localcount].fTrackID[1] += 128; //for neg. numbers
1055 tempPt->fDigitData[localcount].fTrackID[2] += 128;
1056 tempPt->fDigitData[localcount].fTrackID[0] += ((event&0x3ff)<<22);
1057 tempPt->fDigitData[localcount].fTrackID[1] += ((event&0x3ff)<<22);
1058 tempPt->fDigitData[localcount].fTrackID[2] += ((event&0x3ff)<<22);
1064 Byte_t *tmp = (Byte_t*)tempPt;
1065 tmp += sizeof(AliHLTTPCDigitRowData)
1066 + ndigits[r]*sizeof(AliHLTTPCDigitData);
1067 tempPt = (AliHLTTPCDigitRowData*)tmp;
1073 Bool_t AliHLTTPCFileHandler::GetDigitsTree(Int_t event)
1075 //Connects to the TPC digit tree in the AliROOT file.
1076 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1078 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::GetDigitsTree","File")
1079 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1082 fInAli->GetEvent(event);
1083 tpcLoader->LoadDigits();
1084 fDigitsTree = tpcLoader->TreeD();
1087 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::GetDigitsTree","Digits Tree")
1088 <<AliHLTTPCLog::kHex<<"Error getting digitstree "<<(void*)fDigitsTree<<ENDLOG;
1091 fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
1093 if(!fIndexCreated) return CreateIndex();
1097 void AliHLTTPCFileHandler::AliDigits2RootFile(AliHLTTPCDigitRowData *rowPt,Char_t *newDigitsfile)
1099 //Write the data stored in rowPt, into a new AliROOT file.
1100 //The data is stored in the AliROOT format
1101 //This is specially a nice thing if you have modified data, and wants to run it
1102 //through the offline reconstruction chain.
1103 //The arguments is a pointer to the data, and the name of the new AliROOT file.
1104 //Remember to pass the original AliROOT file (the one that contains the original
1105 //simulated data) to this object, in order to retrieve the MC id's of the digits.
1109 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1110 <<"No rootfile "<<ENDLOG;
1115 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1116 <<"No parameter object. Run on rootfile "<<ENDLOG;
1120 //Get the original digitstree:
1121 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1123 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1124 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1127 tpcLoader->LoadDigits();
1128 TTree *treeD=tpcLoader->TreeD();
1130 AliTPCDigitsArray *oldArray = new AliTPCDigitsArray();
1131 oldArray->Setup(fParam);
1132 oldArray->SetClass("AliSimDigits");
1134 Bool_t ok = oldArray->ConnectTree(treeD);
1137 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1138 << "No digits tree object" << ENDLOG;
1142 tpcLoader->SetDigitsFileName(newDigitsfile);
1143 tpcLoader->MakeDigitsContainer();
1145 //setup a new one, or connect it to the existing one:
1146 AliTPCDigitsArray *arr = new AliTPCDigitsArray();
1147 arr->SetClass("AliSimDigits");
1149 arr->MakeTree(tpcLoader->TreeD());
1151 Int_t digcounter=0,trackID[3];
1153 for(Int_t i=fRowMin; i<=fRowMax; i++)
1156 if((Int_t)rowPt->fRow != i)
1157 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
1158 <<"Mismatching row numbering "<<(Int_t)rowPt->fRow<<" "<<i<<ENDLOG;
1161 AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
1163 AliSimDigits *oldDig = (AliSimDigits*)oldArray->LoadRow(sector,row);
1164 AliSimDigits * dig = (AliSimDigits*)arr->CreateRow(sector,row);
1165 oldDig->ExpandBuffer();
1166 oldDig->ExpandTrackBuffer();
1167 dig->ExpandBuffer();
1168 dig->ExpandTrackBuffer();
1171 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
1172 <<"No padrow " << sector << " " << row <<ENDLOG;
1174 AliHLTTPCDigitData *digPt = rowPt->fDigitData;
1176 for(UInt_t j=0; j<rowPt->fNDigit; j++)
1178 Short_t charge = (Short_t)digPt[j].fCharge;
1179 Int_t pad = (Int_t)digPt[j].fPad;
1180 Int_t time = (Int_t)digPt[j].fTime;
1182 if(charge == 0) //Only write the digits that has not been removed
1184 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
1185 <<"Zero charge" <<ENDLOG;
1191 //Tricks to get and set the correct track id's.
1192 for(Int_t track=0; track<3; track++)
1194 Int_t label = oldDig->GetTrackIDFast(time,pad,track);
1196 trackID[track] = label - 2;
1198 trackID[track] = -2;
1200 trackID[track] = -1;
1203 dig->SetDigitFast(charge,time,pad);
1205 for(Int_t track=0; track<3; track++)
1206 ((AliSimDigits*)dig)->SetTrackIDFast(trackID[track],time,pad,track);
1209 //cout<<"Wrote "<<digcounter<<" on row "<<i<<endl;
1210 UpdateRowPointer(rowPt);
1211 arr->StoreRow(sector,row);
1212 arr->ClearRow(sector,row);
1213 oldArray->ClearRow(sector,row);
1217 sprintf(treeName,"TreeD_%s_0",fParam->GetTitle());
1219 arr->GetTree()->SetName(treeName);
1220 arr->GetTree()->AutoSave();
1221 tpcLoader->WriteDigits("OVERWRITE");
1226 ///////////////////////////////////////// Point IO
1227 Bool_t AliHLTTPCFileHandler::AliPoints2Binary(Int_t eventn)
1232 AliHLTTPCSpacePointData *data = AliPoints2Memory(npoint,eventn);
1233 out = Memory2Binary(npoint,data);
1238 AliHLTTPCSpacePointData * AliHLTTPCFileHandler::AliPoints2Memory(UInt_t & npoint,Int_t eventn)
1241 AliHLTTPCSpacePointData *data = 0;
1244 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1245 <<"No Input avalible: no object fInAli"<<ENDLOG;
1249 TDirectory *savedir = gDirectory;
1250 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1252 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1253 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1256 fInAli->GetEvent(eventn);
1257 tpcLoader->LoadRecPoints();
1259 AliTPCClustersArray carray;
1260 carray.Setup(fParam);
1261 carray.SetClusterType("AliTPCcluster");
1262 Bool_t clusterok = carray.ConnectTree(tpcLoader->TreeR());
1264 if(!clusterok) return 0;
1266 AliTPCClustersRow ** clusterrow =
1267 new AliTPCClustersRow*[ (int)carray.GetTree()->GetEntries()];
1268 Int_t *rows = new int[ (int)carray.GetTree()->GetEntries()];
1269 Int_t *sects = new int[ (int)carray.GetTree()->GetEntries()];
1273 for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1274 AliSegmentID *s = carray.LoadEntry(i);
1276 fParam->AdjustSectorRow(s->GetID(),sector,row);
1280 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1281 if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
1282 clusterrow[i] = carray.GetRow(sector,row);
1284 sum+=clusterrow[i]->GetArray()->GetEntriesFast();
1286 UInt_t size = sum*sizeof(AliHLTTPCSpacePointData);
1288 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1289 <<AliHLTTPCLog::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
1291 data = (AliHLTTPCSpacePointData *) Allocate(size);
1297 for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1298 if(!clusterrow[i]) continue;
1299 Int_t row = rows[i];
1300 Int_t sector = sects[i];
1301 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1302 Int_t entriesInRow = clusterrow[i]->GetArray()->GetEntriesFast();
1303 for(Int_t j = 0;j<entriesInRow;j++){
1304 AliTPCcluster *c = (AliTPCcluster*)(*clusterrow[i])[j];
1305 data[n].fZ = c->GetZ();
1306 data[n].fY = c->GetY();
1307 data[n].fX = fParam->GetPadRowRadii(sector,row);
1308 data[n].fCharge = (UInt_t)c->GetQ();
1309 data[n].fID = n+((fSlice&0x7f)<<25)+((pat&0x7)<<22);//uli
1310 data[n].fPadRow = lrow;
1311 data[n].fSigmaY2 = c->GetSigmaY2();
1312 data[n].fSigmaZ2 = c->GetSigmaZ2();
1314 data[n].fTrackID[0] = c->GetLabel(0);
1315 data[n].fTrackID[1] = c->GetLabel(1);
1316 data[n].fTrackID[2] = c->GetLabel(2);
1318 if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
1322 for(Int_t i=0;i<carray.GetTree()->GetEntries();i++){
1323 Int_t row = rows[i];
1324 Int_t sector = sects[i];
1325 if(carray.GetRow(sector,row))
1326 carray.ClearRow(sector,row);
1329 delete [] clusterrow;