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 "AliLoader.h"
40 #include <AliRunLoader.h>
44 #include <AliTPCParamSR.h>
45 #include <AliTPCDigitsArray.h>
46 #include <AliTPCClustersArray.h>
47 #include <AliTPCcluster.h>
48 #include <AliTPCClustersRow.h>
49 #include <AliSimDigits.h>
50 #include "AliCDBManager.h"
51 #include "AliCDBEntry.h"
53 #include "AliHLTTPCLogging.h"
54 #include "AliHLTTPCTransform.h"
55 #include "AliHLTTPCDigitData.h"
56 //#include "AliHLTTPCTrackSegmentData.h"
57 #include "AliHLTTPCSpacePointData.h"
58 //#include "AliHLTTPCTrackArray.h"
59 #include "AliHLTTPCFileHandler.h"
60 #include "AliHLTTPCMapping.h"
61 #include "AliHLTAltroEncoder.h"
69 //_____________________________________________________________
70 // AliHLTTPCFileHandler
72 // The HLT ROOT <-> binary files handling class
74 // This class provides the interface between AliROOT files,
75 // and HLT binary files. It should be used for converting
76 // TPC data stored in AliROOT format (outputfile from a simulation),
77 // into the data format currently used by in the HLT framework.
78 // This enables the possibility to always use the same data format,
79 // whether you are using a binary file as an input, or a AliROOT file.
81 // For example on how to create binary files from a AliROOT simulation,
82 // see example macro exa/Binary.C.
84 // For reading a AliROOT file into HLT format in memory, do the following:
86 // AliHLTTPCFileHandler file;
87 // file.Init(slice,patch);
88 // file.SetAliInput("galice.root");
89 // AliHLTTPCDigitRowData *dataPt = (AliHLTTPCDigitRowData*)file.AliDigits2Memory(nrows,eventnr);
91 // All the data are then stored in memory and accessible via the pointer dataPt.
92 // Accesing the data is then identical to the example 1) showed in AliHLTTPCMemHandler class.
94 // For converting the data back, and writing it to a new AliROOT file do:
96 // AliHLTTPCFileHandler file;
97 // file.Init(slice,patch);
98 // file.SetAliInput("galice.root");
99 // file.Init(slice,patch,NumberOfRowsInPatch);
100 // file.AliDigits2RootFile(dataPt,"new_galice.root");
101 // file.CloseAliInput();
105 ClassImp(AliHLTTPCFileHandler)
107 AliHLTTPCFileHandler::AliHLTTPCFileHandler(Bool_t b)
110 fUseRunLoader(kFALSE),
115 fIndexCreated(kFALSE),
118 //Default constructor
120 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++)
121 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
124 if(fUseStaticIndex&&!fgStaticIndexCreated) CleanStaticIndex();
127 AliHLTTPCFileHandler::~AliHLTTPCFileHandler()
130 if(fMC) CloseMCOutput();
132 if(fInAli) CloseAliInput();
135 // of course on start up the index is not created
136 Bool_t AliHLTTPCFileHandler::fgStaticIndexCreated=kFALSE;
137 Int_t AliHLTTPCFileHandler::fgStaticIndex[36][159];
139 void AliHLTTPCFileHandler::CleanStaticIndex()
141 // use this static call to clean static index after
142 // running over one event
143 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
144 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
145 fgStaticIndex[i][j]=-1;
147 fgStaticIndexCreated=kFALSE;
150 Int_t AliHLTTPCFileHandler::SaveStaticIndex(Char_t *prefix,Int_t event)
152 // use this static call to store static index after
153 if(!fgStaticIndexCreated) return -1;
155 const int fnamelen=1024;
156 Char_t fname[fnamelen];
158 snprintf(fname,fnamelen, "%s-%d.txt",prefix,event);
160 snprintf(fname,fnamelen, "TPC.Digits.staticindex-%d.txt",event);
162 ofstream file(fname,ios::trunc);
163 if(!file.good()) return -1;
165 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
166 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
167 file << fgStaticIndex[i][j] << " ";
174 Int_t AliHLTTPCFileHandler::LoadStaticIndex(Char_t *prefix,Int_t event)
176 // use this static call to store static index after
177 if(fgStaticIndexCreated){
178 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::LoadStaticIndex","Inxed")
179 <<"Static index already created, will overwrite"<<ENDLOG;
183 const int fnamelen=1024;
184 Char_t fname[fnamelen];
186 snprintf(fname,fnamelen,"%s-%d.txt",prefix,event);
188 snprintf(fname,fnamelen,"TPC.Digits.staticindex-%d.txt",event);
190 ifstream file(fname);
191 if(!file.good()) return -1;
193 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
194 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
195 file >> fgStaticIndex[i][j];
199 fgStaticIndexCreated=kTRUE;
203 void AliHLTTPCFileHandler::FreeDigitsTree()
212 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
213 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
216 fIndexCreated=kFALSE;
219 Bool_t AliHLTTPCFileHandler::SetMCOutput(Char_t *name)
222 fMC = fopen(name,"w");
224 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
225 <<"Pointer to File = 0x0 "<<ENDLOG;
231 Bool_t AliHLTTPCFileHandler::SetMCOutput(FILE *file)
236 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
237 <<"Pointer to File = 0x0 "<<ENDLOG;
243 void AliHLTTPCFileHandler::CloseMCOutput()
247 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseMCOutPut","File Close")
248 <<"Nothing to Close"<<ENDLOG;
255 Bool_t AliHLTTPCFileHandler::SetAliInput()
259 // fParam is in all cases an external object
260 const char* cdbEntry="TPC/Calib/Parameters";
261 AliCDBManager* pMan=AliCDBManager::Instance();
263 AliCDBEntry *pEntry = pMan->Get(cdbEntry);
265 pEntry->GetObject()==NULL ||
266 (fParam=dynamic_cast<AliTPCParam*>(pEntry->GetObject()))==NULL) {
267 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
268 <<"can not load AliTPCParam object from OCDB entry " << cdbEntry <<ENDLOG;
272 // the old solution until Nov 2008
274 fParam = (AliTPCParam*)gFile->Get("75x40_100x60_150x60");
276 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
277 <<"No TPC parameters found in \""<<gFile->GetName()
278 <<"\", creating standard parameters "
279 <<"which might not be what you want!"<<ENDLOG;
280 fParam = new AliTPCParamSR;
284 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
285 <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<gFile->GetName()<<ENDLOG;
292 Bool_t AliHLTTPCFileHandler::SetAliInput(Char_t *name)
294 //Open the AliROOT file with name.
295 fInAli= AliRunLoader::Open(name);
297 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
298 <<"Pointer to fInAli = 0x0 "<<ENDLOG;
301 return SetAliInput();
304 Bool_t AliHLTTPCFileHandler::SetAliInput(AliRunLoader *runLoader)
306 //set ali input as runloader
308 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
309 <<"invalid agument: pointer to AliRunLoader NULL "<<ENDLOG;
312 if (fInAli!=NULL && fInAli!=runLoader) {
313 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
314 <<"Pointer to AliRunLoader already set"<<ENDLOG;
318 fUseRunLoader = kTRUE;
319 return SetAliInput();
322 void AliHLTTPCFileHandler::CloseAliInput()
325 if(fUseRunLoader) return;
327 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseAliInput","RunLoader")
328 <<"Nothing to Close"<<ENDLOG;
336 Bool_t AliHLTTPCFileHandler::IsDigit(Int_t event)
338 //Check if there is a TPC digit tree in the current file.
339 //Return kTRUE if tree was found, and kFALSE if not found.
342 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::IsDigit","File")
343 <<"Pointer to fInAli = 0x0 "<<ENDLOG;
344 return kTRUE; //maybe you are using binary input which is Digits!
346 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
348 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandlerNewIO::IsDigit","File")
349 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
352 fInAli->GetEvent(event);
353 tpcLoader->LoadDigits();
354 TTree *t=tpcLoader->TreeD();
356 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
357 <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
361 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
362 <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
367 ///////////////////////////////////////// Digit IO
368 Bool_t AliHLTTPCFileHandler::AliDigits2BinaryFile(Int_t event,Bool_t altro)
370 //save alidigits as binary
373 AliHLTTPCDigitRowData* data = 0;
375 data = AliAltroDigits2Memory(nrow,event);
377 data = AliDigits2Memory(nrow,event);
378 out = Memory2BinaryFile(nrow,data);
383 Bool_t AliHLTTPCFileHandler::AliDigits2CompBinary(Int_t event,Bool_t altro)
385 //Convert AliROOT TPC data, into HLT data format.
386 //event specifies the event you want in the aliroot file.
390 AliHLTTPCDigitRowData *digits=0;
392 digits = AliAltroDigits2Memory(ndigits,event);
394 digits = AliDigits2Memory(ndigits,event);
395 out = Memory2CompBinary(ndigits,digits);
400 Bool_t AliHLTTPCFileHandler::CreateIndex()
402 //create the access index or copy from static index
403 fIndexCreated=kFALSE;
405 if(!fgStaticIndexCreated || !fUseStaticIndex) { //we have to create index
406 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
407 <<"Starting to create index, this can take a while."<<ENDLOG;
410 for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
413 fDigitsTree->GetEvent(n);
414 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
415 if(!AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row)){
416 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::CreateIndex","Slice/Row")
417 <<AliHLTTPCLog::kDec<<"Index could not be created. Wrong values "
418 <<sector<<" "<<row<<ENDLOG;
421 // this is just to make sure the same array dimensions are
422 // used as in the AliHLTTPCTransform class. The check for
423 // correct bounds is done in AliHLTTPCTransform::Sector2Slice
424 assert(lslice>=0 && lslice<fgkNSlice);
425 assert(lrow>=0 && lrow<fgkNRow);
426 if(fIndex[lslice][lrow]==-1) {
427 fIndex[lslice][lrow]=n;
430 assert(AliHLTTPCTransform::GetNSlice()==fgkNSlice);
431 assert(AliHLTTPCTransform::GetNRows()==fgkNRow);
432 if(fUseStaticIndex) { // create static index
433 for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
434 for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
435 fgStaticIndex[islice][irow]=fIndex[islice][irow];
437 fgStaticIndexCreated=kTRUE; //remember that index has been created
440 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
441 <<"Index successfully created."<<ENDLOG;
443 } else if(fUseStaticIndex) { //simply copy static index
444 for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
445 for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
446 fIndex[islice][irow]=fgStaticIndex[islice][irow];
449 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
450 <<"Index successfully taken from static copy."<<ENDLOG;
456 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event, Byte_t* tgtBuffer, UInt_t *pTgtSize)
458 //Read data from AliROOT file into memory, and store it in the HLT data format
459 //in the provided buffer or an allocated buffer.
460 //Returns a pointer to the data.
462 AliHLTTPCDigitRowData *data = 0;
466 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
467 <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
472 if(!GetDigitsTree(event)) return 0;
475 Int_t time,pad,sector,row;
478 Int_t entries = (Int_t)fDigitsTree->GetEntries();
480 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","ndigits")
481 <<"No TPC digits (entries==0)!"<<ENDLOG;
482 nrow = (UInt_t)(fRowMax-fRowMin+1);
483 UInt_t size = nrow*sizeof(AliHLTTPCDigitRowData);
484 if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
485 if (size<=*pTgtSize) {
486 data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
490 data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(size));
492 AliHLTTPCDigitRowData *tempPt = data;
494 if (pTgtSize) *pTgtSize=size;
495 for(Int_t r=fRowMin;r<=fRowMax;r++){
504 Int_t * ndigits = new Int_t[fRowMax+1];
505 memset(ndigits, 0, (fRowMax+1)*sizeof(Int_t));
508 // The digits of the current event have been indexed: all digits are organized in
509 // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
510 // are stored in the digit tree.
511 // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
513 // This loop filters the pad rows according to the slice no set via Init
514 assert(fRowMax<fgkNRow);
515 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
516 Int_t n=fIndex[fSlice][r];
517 if(n!=-1){ // there is data on that row available
519 fDigitsTree->GetEvent(n);
520 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
521 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
522 // LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
523 // << "Sector "<<sector<<" Row " << row << " Slice " << lslice << " lrow " << lrow<<ENDLOG;
526 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
527 <<AliHLTTPCLog::kDec<<"Rows in slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
532 for (bool bHaveData=fDigits->First();
534 bHaveData=fDigits->Next()) {
535 time=fDigits->CurrentRow();
536 pad=fDigits->CurrentColumn();
537 dig = fDigits->GetDigit(time,pad);
538 if(dig <= fParam->GetZeroSup()) continue;
539 if(dig >= AliHLTTPCTransform::GetADCSat())
540 dig = AliHLTTPCTransform::GetADCSat();
542 // if we switch to AliTPCTransform, this maybe needs to be
544 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
545 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
546 // continue; // why 230???
548 ndigits[lrow]++; //for this row only
549 ndigitcount++; //total number of digits to be published
552 //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
554 //see comment below//nrows++;
556 // Matthias 05.11.2007
557 // The question is whether we should always return a AliHLTTPCDigitRowData
558 // for each row, even the empty ones or only for the ones filled with data.
559 // the AliHLTTPCDigitReaderUnpacked as the counnterpart so far assumes
560 // empty RawData structs for empty rows. But some of the code here implies
561 // the latter approach, e.g. the count of nrows in the loop above (now
562 // commented). At least the two loops were not consistent, it's fixed now.
563 nrows=fRowMax-fRowMin+1;
565 UInt_t bufferSize = sizeof(AliHLTTPCDigitData)*ndigitcount
566 + nrows*sizeof(AliHLTTPCDigitRowData);
568 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
569 << "Found "<<ndigitcount<<" Digits in " << nrows << " rows out of [" << fRowMin << "," << fRowMax <<"]"<<ENDLOG;
571 if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
572 if (bufferSize<=*pTgtSize) {
573 data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
576 } else if (bufferSize>0) {
577 data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(bufferSize));
579 if (pTgtSize) *pTgtSize=bufferSize;
584 nrow = (UInt_t)nrows;
585 AliHLTTPCDigitRowData *tempPt = data;
586 memset(data, 0, bufferSize);
588 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
589 Int_t n=fIndex[fSlice][r];
591 AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
595 if(n!=-1){//data on that row
597 fDigitsTree->GetEvent(n);
598 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
599 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
601 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
602 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
606 // set the correct row no and digit count
608 tempPt->fNDigit = ndigits[lrow];
611 for (bool bHaveData=fDigits->First();
613 bHaveData=fDigits->Next()) {
614 time=fDigits->CurrentRow();
615 pad=fDigits->CurrentColumn();
616 dig = fDigits->GetDigit(time,pad);
617 if (dig <= fParam->GetZeroSup()) continue;
618 if(dig >= AliHLTTPCTransform::GetADCSat())
619 dig = AliHLTTPCTransform::GetADCSat();
621 //Exclude data outside cone:
622 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
623 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
624 // continue; // why 230???
626 if(localcount >= ndigits[lrow])
627 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliDigits2Binary","Memory")
628 <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
629 <<ndigits[lrow]<<ENDLOG;
631 tempPt->fDigitData[localcount].fCharge=dig;
632 tempPt->fDigitData[localcount].fPad=pad;
633 tempPt->fDigitData[localcount].fTime=time;
634 tempPt->fDigitData[localcount].fTrackID[0] = fDigits->GetTrackID(time,pad,0);
635 tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
636 tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
641 Byte_t *tmp = (Byte_t*)tempPt;
642 Int_t blockSize = sizeof(AliHLTTPCDigitRowData)
643 + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
645 tempPt = (AliHLTTPCDigitRowData*)tmp;
647 assert((Byte_t*)tempPt==((Byte_t*)data)+bufferSize);
652 int AliHLTTPCFileHandler::AliDigits2Altro(Int_t event, Byte_t* tgtBuffer, UInt_t tgtSize)
654 //Read data from AliROOT file into memory, and store it in the ALTRO data format
655 //in the provided buffer
656 //Returns: size of the encoded data in bytes
660 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Altro","File")
661 <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
670 if(!GetDigitsTree(event)) return 0;
677 AliHLTTPCMapping mapper(fPatch);
678 AliHLTAltroEncoder encoder;
679 encoder.SetBuffer(tgtBuffer, tgtSize);
681 // The digits of the current event have been indexed: all digits are organized in
682 // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
683 // are stored in the digit tree.
684 // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
686 // This loop filters the pad rows according to the slice no set via Init
688 assert(fRowMax<fgkNRow);
689 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow && iResult>=0;r++){
690 Int_t n=fIndex[fSlice][r];
694 AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
695 AliHLTTPCTransform::Slice2Sector(fSlice,AliHLTTPCTransform::GetFirstRow(fPatch),sector,rowOffset);
697 if(n!=-1){//data on that row
699 fDigitsTree->GetEvent(n);
700 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
701 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
703 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Altro","Row")
704 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
708 Int_t channelAddress=-1;
711 time=fDigits->CurrentRow();
712 pad=fDigits->CurrentColumn();
713 dig = fDigits->GetDigit(time,pad);
714 if (dig <= fParam->GetZeroSup()) continue;
715 if(dig >= AliHLTTPCTransform::GetADCSat())
716 dig = AliHLTTPCTransform::GetADCSat();
718 channelAddress=mapper.GetHwAddress(row-rowOffset, pad);
719 iResult=encoder.AddChannelSignal(dig, time, channelAddress);
720 } while (fDigits->Next() && iResult>=0);
721 if (iResult>=0 && channelAddress>=0) {
722 iResult=encoder.SetChannel(channelAddress);
728 iResult=(encoder.GetTotal40bitWords()*5)/4;
734 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
736 //Read data from AliROOT file into memory, and store it in the HLT data format.
737 //Returns a pointer to the data.
738 //This functions filter out single timebins, which is noise. The timebins which
739 //are removed are timebins which have the 4 zero neighbours;
740 //(pad-1,time),(pad+1,time),(pad,time-1),(pad,time+1).
742 AliHLTTPCDigitRowData *data = 0;
746 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
747 <<"No Input avalible: Pointer to TFile == NULL"<<ENDLOG;
750 if(eventmerge == kTRUE && event >= 1024)
752 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","TrackIDs")
753 <<"Too many events if you want to merge!"<<ENDLOG;
758 /* Dont understand why we have to do
759 reload the tree, but otherwise the code crashes */
761 if(!GetDigitsTree(event)) return 0;
764 Int_t time,pad,sector,row;
767 Int_t entries = (Int_t)fDigitsTree->GetEntries();
769 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","ndigits")
770 <<"No TPC digits (entries==0)!"<<ENDLOG;
771 nrow = (UInt_t)(fRowMax-fRowMin+1);
772 Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
773 data=(AliHLTTPCDigitRowData*) Allocate(size);
774 AliHLTTPCDigitRowData *tempPt = data;
775 for(Int_t r=fRowMin;r<=fRowMax;r++){
782 Int_t * ndigits = new Int_t[fRowMax+1];
784 Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
787 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
788 Int_t n=fIndex[fSlice][r];
792 if(n!=-1){//data on that row
793 fDigitsTree->GetEvent(n);
794 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
795 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
796 //cout << lslice << " " << fSlice << " " << lrow << " " << r << " " << sector << " " << row << endl;
797 if((lslice!=fSlice)||(lrow!=r)){
798 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
799 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
803 fDigits->ExpandBuffer();
804 fDigits->ExpandTrackBuffer();
805 for(Int_t i=0; i<fDigits->GetNCols(); i++){
806 for(Int_t j=0; j<fDigits->GetNRows(); j++){
809 dig = fDigits->GetDigitFast(time,pad);
810 if(dig <= zerosupval) continue;
811 if(dig >= AliHLTTPCTransform::GetADCSat())
812 dig = AliHLTTPCTransform::GetADCSat();
814 //Check for single timebins, and remove them because they are noise for sure.
815 if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
816 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
817 fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
818 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
819 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
825 if(j < fDigits->GetNRows()-1 && j > 0)
827 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
828 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
829 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
834 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
835 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
841 if(i < fDigits->GetNCols()-1 && i > 0)
843 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
844 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
845 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
850 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
851 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
856 if(i==fDigits->GetNCols()-1)
858 if(j>0 && j<fDigits->GetNRows()-1)
860 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
861 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
862 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
865 else if(j==0 && j<fDigits->GetNRows()-1)
867 if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
868 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
873 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
874 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
879 if(j==fDigits->GetNRows()-1)
881 if(i>0 && i<fDigits->GetNCols()-1)
883 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
884 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
885 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
888 else if(i==0 && fDigits->GetNCols()-1)
890 if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
891 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
896 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
897 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
902 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
903 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
906 ndigits[lrow]++; //for this row only
907 ndigitcount++; //total number of digits to be published
914 Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
915 + nrows*sizeof(AliHLTTPCDigitRowData);
917 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Digits")
918 <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
920 data=(AliHLTTPCDigitRowData*) Allocate(size);
921 nrow = (UInt_t)nrows;
922 AliHLTTPCDigitRowData *tempPt = data;
924 for(Int_t r=fRowMin;r<=fRowMax;r++){
925 Int_t n=fIndex[fSlice][r];
928 if(n!=-1){ //no data on that row
929 fDigitsTree->GetEvent(n);
930 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
931 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
934 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
935 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
939 tempPt->fNDigit = ndigits[lrow];
942 fDigits->ExpandBuffer();
943 fDigits->ExpandTrackBuffer();
944 for(Int_t i=0; i<fDigits->GetNCols(); i++){
945 for(Int_t j=0; j<fDigits->GetNRows(); j++){
948 dig = fDigits->GetDigitFast(time,pad);
949 if(dig <= zerosupval) continue;
950 if(dig >= AliHLTTPCTransform::GetADCSat())
951 dig = AliHLTTPCTransform::GetADCSat();
953 //Check for single timebins, and remove them because they are noise for sure.
954 if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
955 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
956 fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
957 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
958 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
964 if(j < fDigits->GetNRows()-1 && j > 0)
966 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
967 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
968 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
973 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
974 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
980 if(i < fDigits->GetNCols()-1 && i > 0)
982 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
983 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
984 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
989 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
990 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
995 if(i == fDigits->GetNCols()-1)
997 if(j>0 && j<fDigits->GetNRows()-1)
999 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
1000 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1001 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1004 else if(j==0 && j<fDigits->GetNRows()-1)
1006 if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1007 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1012 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
1013 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1017 if(j==fDigits->GetNRows()-1)
1019 if(i>0 && i<fDigits->GetNCols()-1)
1021 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1022 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1023 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1026 else if(i==0 && fDigits->GetNCols()-1)
1028 if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1029 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1034 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1035 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1040 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
1041 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
1044 if(localcount >= ndigits[lrow])
1045 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliAltroDigits2Binary","Memory")
1046 <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
1047 <<ndigits[lrow]<<ENDLOG;
1049 tempPt->fDigitData[localcount].fCharge=dig;
1050 tempPt->fDigitData[localcount].fPad=pad;
1051 tempPt->fDigitData[localcount].fTime=time;
1052 tempPt->fDigitData[localcount].fTrackID[0] = (fDigits->GetTrackIDFast(time,pad,0)-2);
1053 tempPt->fDigitData[localcount].fTrackID[1] = (fDigits->GetTrackIDFast(time,pad,1)-2);
1054 tempPt->fDigitData[localcount].fTrackID[2] = (fDigits->GetTrackIDFast(time,pad,2)-2);
1055 if(eventmerge == kTRUE) //careful track mc info will be touched
1056 {//Event are going to be merged, so event number is stored in the upper 10 bits.
1057 tempPt->fDigitData[localcount].fTrackID[0] += 128; //leave some room
1058 tempPt->fDigitData[localcount].fTrackID[1] += 128; //for neg. numbers
1059 tempPt->fDigitData[localcount].fTrackID[2] += 128;
1060 tempPt->fDigitData[localcount].fTrackID[0] += ((event&0x3ff)<<22);
1061 tempPt->fDigitData[localcount].fTrackID[1] += ((event&0x3ff)<<22);
1062 tempPt->fDigitData[localcount].fTrackID[2] += ((event&0x3ff)<<22);
1068 Byte_t *tmp = (Byte_t*)tempPt;
1069 tmp += sizeof(AliHLTTPCDigitRowData)
1070 + ndigits[r]*sizeof(AliHLTTPCDigitData);
1071 tempPt = (AliHLTTPCDigitRowData*)tmp;
1077 Bool_t AliHLTTPCFileHandler::GetDigitsTree(Int_t event)
1079 //Connects to the TPC digit tree in the AliROOT file.
1080 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1082 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::GetDigitsTree","File")
1083 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1086 fInAli->GetEvent(event);
1087 tpcLoader->LoadDigits();
1088 fDigitsTree = tpcLoader->TreeD();
1091 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::GetDigitsTree","Digits Tree")
1092 <<AliHLTTPCLog::kHex<<"Error getting digitstree "<<(void*)fDigitsTree<<ENDLOG;
1095 fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
1097 if(!fIndexCreated) return CreateIndex();
1101 ///////////////////////////////////////// Point IO
1102 Bool_t AliHLTTPCFileHandler::AliPoints2Binary(Int_t eventn)
1107 AliHLTTPCSpacePointData *data = AliPoints2Memory(npoint,eventn);
1108 out = Memory2Binary(npoint,data);
1113 AliHLTTPCSpacePointData * AliHLTTPCFileHandler::AliPoints2Memory(UInt_t & npoint,Int_t eventn)
1116 AliHLTTPCSpacePointData *data = 0;
1119 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1120 <<"No Input avalible: no object fInAli"<<ENDLOG;
1124 TDirectory *savedir = gDirectory;
1125 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1127 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1128 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1131 fInAli->GetEvent(eventn);
1132 tpcLoader->LoadRecPoints();
1134 AliTPCClustersArray carray;
1135 carray.Setup(fParam);
1136 carray.SetClusterType("AliTPCcluster");
1137 Bool_t clusterok = carray.ConnectTree(tpcLoader->TreeR());
1139 if(!clusterok) return 0;
1141 AliTPCClustersRow ** clusterrow =
1142 new AliTPCClustersRow*[ (int)carray.GetTree()->GetEntries()];
1143 Int_t *rows = new int[ (int)carray.GetTree()->GetEntries()];
1144 Int_t *sects = new int[ (int)carray.GetTree()->GetEntries()];
1148 for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1149 AliSegmentID *s = carray.LoadEntry(i);
1151 fParam->AdjustSectorRow(s->GetID(),sector,row);
1155 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1156 if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
1157 clusterrow[i] = carray.GetRow(sector,row);
1159 sum+=clusterrow[i]->GetArray()->GetEntriesFast();
1161 UInt_t size = sum*sizeof(AliHLTTPCSpacePointData);
1163 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1164 <<AliHLTTPCLog::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
1166 data = (AliHLTTPCSpacePointData *) Allocate(size);
1172 for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1173 if(!clusterrow[i]) continue;
1174 Int_t row = rows[i];
1175 Int_t sector = sects[i];
1176 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1177 Int_t entriesInRow = clusterrow[i]->GetArray()->GetEntriesFast();
1178 for(Int_t j = 0;j<entriesInRow;j++){
1179 AliTPCcluster *c = (AliTPCcluster*)(*clusterrow[i])[j];
1180 data[n].fZ = c->GetZ();
1181 data[n].fY = c->GetY();
1182 data[n].fX = fParam->GetPadRowRadii(sector,row);
1183 data[n].fCharge = (UInt_t)c->GetQ();
1184 data[n].SetID( fSlice, pat, n );
1185 data[n].fPadRow = lrow;
1186 data[n].fSigmaY2 = c->GetSigmaY2();
1187 data[n].fSigmaZ2 = c->GetSigmaZ2();
1189 data[n].fTrackID[0] = c->GetLabel(0);
1190 data[n].fTrackID[1] = c->GetLabel(1);
1191 data[n].fTrackID[2] = c->GetLabel(2);
1193 if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
1197 for(Int_t i=0;i<carray.GetTree()->GetEntries();i++){
1198 Int_t row = rows[i];
1199 Int_t sector = sects[i];
1200 if(carray.GetRow(sector,row))
1201 carray.ClearRow(sector,row);
1204 delete [] clusterrow;