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 <AliTPCclusterMI.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;
154 const int fnamelen=1024;
155 Char_t fname[fnamelen];
157 snprintf(fname,fnamelen, "%s-%d.txt",prefix,event);
159 snprintf(fname,fnamelen, "TPC.Digits.staticindex-%d.txt",event);
161 ofstream file(fname,ios::trunc);
162 if(!file.good()) return -1;
164 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
165 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
166 file << fgStaticIndex[i][j] << " ";
173 Int_t AliHLTTPCFileHandler::LoadStaticIndex(Char_t *prefix,Int_t event)
175 // use this static call to store static index after
176 if(fgStaticIndexCreated){
177 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::LoadStaticIndex","Inxed")
178 <<"Static index already created, will overwrite"<<ENDLOG;
182 const int fnamelen=1024;
183 Char_t fname[fnamelen];
185 snprintf(fname,fnamelen,"%s-%d.txt",prefix,event);
187 snprintf(fname,fnamelen,"TPC.Digits.staticindex-%d.txt",event);
189 ifstream file(fname);
190 if(!file.good()) return -1;
192 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
193 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
194 file >> fgStaticIndex[i][j];
198 fgStaticIndexCreated=kTRUE;
202 void AliHLTTPCFileHandler::FreeDigitsTree()
211 for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
212 for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
215 fIndexCreated=kFALSE;
218 Bool_t AliHLTTPCFileHandler::SetMCOutput(Char_t *name)
221 fMC = fopen(name,"w");
223 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
224 <<"Pointer to File = 0x0 "<<ENDLOG;
230 Bool_t AliHLTTPCFileHandler::SetMCOutput(FILE *file)
235 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
236 <<"Pointer to File = 0x0 "<<ENDLOG;
242 void AliHLTTPCFileHandler::CloseMCOutput()
246 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseMCOutPut","File Close")
247 <<"Nothing to Close"<<ENDLOG;
254 Bool_t AliHLTTPCFileHandler::SetAliInput()
258 // fParam is in all cases an external object
259 const char* cdbEntry="TPC/Calib/Parameters";
260 AliCDBManager* pMan=AliCDBManager::Instance();
262 AliCDBEntry *pEntry = pMan->Get(cdbEntry);
264 pEntry->GetObject()==NULL ||
265 (fParam=dynamic_cast<AliTPCParam*>(pEntry->GetObject()))==NULL) {
266 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
267 <<"can not load AliTPCParam object from OCDB entry " << cdbEntry <<ENDLOG;
271 // the old solution until Nov 2008
273 fParam = (AliTPCParam*)gFile->Get("75x40_100x60_150x60");
275 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
276 <<"No TPC parameters found in \""<<gFile->GetName()
277 <<"\", creating standard parameters "
278 <<"which might not be what you want!"<<ENDLOG;
279 fParam = new AliTPCParamSR;
283 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
284 <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<gFile->GetName()<<ENDLOG;
291 Bool_t AliHLTTPCFileHandler::SetAliInput(Char_t *name)
293 //Open the AliROOT file with name.
294 fInAli= AliRunLoader::Open(name);
296 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
297 <<"Pointer to fInAli = 0x0 "<<ENDLOG;
300 return SetAliInput();
303 Bool_t AliHLTTPCFileHandler::SetAliInput(AliRunLoader *runLoader)
305 //set ali input as runloader
307 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
308 <<"invalid agument: pointer to AliRunLoader NULL "<<ENDLOG;
311 if (fInAli!=NULL && fInAli!=runLoader) {
312 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
313 <<"Pointer to AliRunLoader already set"<<ENDLOG;
317 fUseRunLoader = kTRUE;
318 return SetAliInput();
321 void AliHLTTPCFileHandler::CloseAliInput()
324 if(fUseRunLoader) return;
326 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseAliInput","RunLoader")
327 <<"Nothing to Close"<<ENDLOG;
335 Bool_t AliHLTTPCFileHandler::IsDigit(Int_t event)
337 //Check if there is a TPC digit tree in the current file.
338 //Return kTRUE if tree was found, and kFALSE if not found.
341 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::IsDigit","File")
342 <<"Pointer to fInAli = 0x0 "<<ENDLOG;
343 return kTRUE; //maybe you are using binary input which is Digits!
345 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
347 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandlerNewIO::IsDigit","File")
348 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
351 fInAli->GetEvent(event);
352 tpcLoader->LoadDigits();
353 TTree *t=tpcLoader->TreeD();
355 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
356 <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
360 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
361 <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
366 ///////////////////////////////////////// Digit IO
367 Bool_t AliHLTTPCFileHandler::AliDigits2BinaryFile(Int_t event,Bool_t altro)
369 //save alidigits as binary
372 AliHLTTPCDigitRowData* data = 0;
374 data = AliAltroDigits2Memory(nrow,event);
376 data = AliDigits2Memory(nrow,event);
377 out = Memory2BinaryFile(nrow,data);
382 Bool_t AliHLTTPCFileHandler::AliDigits2CompBinary(Int_t event,Bool_t altro)
384 //Convert AliROOT TPC data, into HLT data format.
385 //event specifies the event you want in the aliroot file.
389 AliHLTTPCDigitRowData *digits=0;
391 digits = AliAltroDigits2Memory(ndigits,event);
393 digits = AliDigits2Memory(ndigits,event);
394 out = Memory2CompBinary(ndigits,digits);
399 Bool_t AliHLTTPCFileHandler::CreateIndex()
401 //create the access index or copy from static index
402 fIndexCreated=kFALSE;
404 if(!fgStaticIndexCreated || !fUseStaticIndex) { //we have to create index
405 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
406 <<"Starting to create index, this can take a while."<<ENDLOG;
409 for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
412 fDigitsTree->GetEvent(n);
413 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
414 if(!AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row)){
415 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::CreateIndex","Slice/Row")
416 <<AliHLTTPCLog::kDec<<"Index could not be created. Wrong values "
417 <<sector<<" "<<row<<ENDLOG;
420 // this is just to make sure the same array dimensions are
421 // used as in the AliHLTTPCTransform class. The check for
422 // correct bounds is done in AliHLTTPCTransform::Sector2Slice
423 assert(lslice>=0 && lslice<fgkNSlice);
424 assert(lrow>=0 && lrow<fgkNRow);
425 if(fIndex[lslice][lrow]==-1) {
426 fIndex[lslice][lrow]=n;
429 assert(AliHLTTPCTransform::GetNSlice()==fgkNSlice);
430 assert(AliHLTTPCTransform::GetNRows()==fgkNRow);
431 if(fUseStaticIndex) { // create static index
432 for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
433 for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
434 fgStaticIndex[islice][irow]=fIndex[islice][irow];
436 fgStaticIndexCreated=kTRUE; //remember that index has been created
439 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
440 <<"Index successfully created."<<ENDLOG;
442 } else if(fUseStaticIndex) { //simply copy static index
443 for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
444 for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
445 fIndex[islice][irow]=fgStaticIndex[islice][irow];
448 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
449 <<"Index successfully taken from static copy."<<ENDLOG;
455 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event, Byte_t* tgtBuffer, UInt_t *pTgtSize)
457 //Read data from AliROOT file into memory, and store it in the HLT data format
458 //in the provided buffer or an allocated buffer.
459 //Returns a pointer to the data.
461 AliHLTTPCDigitRowData *data = 0;
465 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
466 <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
471 if(!GetDigitsTree(event)) return 0;
474 Int_t time,pad,sector,row;
477 Int_t entries = (Int_t)fDigitsTree->GetEntries();
479 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","ndigits")
480 <<"No TPC digits (entries==0)!"<<ENDLOG;
481 nrow = (UInt_t)(fRowMax-fRowMin+1);
482 UInt_t size = nrow*sizeof(AliHLTTPCDigitRowData);
483 if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
484 if (size<=*pTgtSize) {
485 data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
489 data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(size));
491 AliHLTTPCDigitRowData *tempPt = data;
493 if (pTgtSize) *pTgtSize=size;
494 for(Int_t r=fRowMin;r<=fRowMax;r++){
503 Int_t * ndigits = new Int_t[fRowMax+1];
504 memset(ndigits, 0, (fRowMax+1)*sizeof(Int_t));
507 // The digits of the current event have been indexed: all digits are organized in
508 // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
509 // are stored in the digit tree.
510 // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
512 // This loop filters the pad rows according to the slice no set via Init
513 assert(fRowMax<fgkNRow);
514 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
515 Int_t n=fIndex[fSlice][r];
516 if(n!=-1){ // there is data on that row available
518 fDigitsTree->GetEvent(n);
519 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
520 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
521 // LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
522 // << "Sector "<<sector<<" Row " << row << " Slice " << lslice << " lrow " << lrow<<ENDLOG;
525 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
526 <<AliHLTTPCLog::kDec<<"Rows in slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
531 for (bool bHaveData=fDigits->First();
533 bHaveData=fDigits->Next()) {
534 time=fDigits->CurrentRow();
535 pad=fDigits->CurrentColumn();
536 dig = fDigits->GetDigit(time,pad);
537 if(dig <= fParam->GetZeroSup()) continue;
538 if(dig >= AliHLTTPCTransform::GetADCSat())
539 dig = AliHLTTPCTransform::GetADCSat();
541 // if we switch to AliTPCTransform, this maybe needs to be
543 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
544 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
545 // continue; // why 230???
547 ndigits[lrow]++; //for this row only
548 ndigitcount++; //total number of digits to be published
551 //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
553 //see comment below//nrows++;
555 // Matthias 05.11.2007
556 // The question is whether we should always return a AliHLTTPCDigitRowData
557 // for each row, even the empty ones or only for the ones filled with data.
558 // the AliHLTTPCDigitReaderUnpacked as the counnterpart so far assumes
559 // empty RawData structs for empty rows. But some of the code here implies
560 // the latter approach, e.g. the count of nrows in the loop above (now
561 // commented). At least the two loops were not consistent, it's fixed now.
562 nrows=fRowMax-fRowMin+1;
564 UInt_t bufferSize = sizeof(AliHLTTPCDigitData)*ndigitcount
565 + nrows*sizeof(AliHLTTPCDigitRowData);
567 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
568 << "Found "<<ndigitcount<<" Digits in " << nrows << " rows out of [" << fRowMin << "," << fRowMax <<"]"<<ENDLOG;
570 if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
571 if (bufferSize<=*pTgtSize) {
572 data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
575 } else if (bufferSize>0) {
576 data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(bufferSize));
578 if (pTgtSize) *pTgtSize=bufferSize;
583 nrow = (UInt_t)nrows;
584 AliHLTTPCDigitRowData *tempPt = data;
585 memset(data, 0, bufferSize);
587 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
588 Int_t n=fIndex[fSlice][r];
590 AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
594 if(n!=-1){//data on that row
596 fDigitsTree->GetEvent(n);
597 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
598 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
600 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
601 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
605 // set the correct row no and digit count
607 tempPt->fNDigit = ndigits[lrow];
610 for (bool bHaveData=fDigits->First();
612 bHaveData=fDigits->Next()) {
613 time=fDigits->CurrentRow();
614 pad=fDigits->CurrentColumn();
615 dig = fDigits->GetDigit(time,pad);
616 if (dig <= fParam->GetZeroSup()) continue;
617 if(dig >= AliHLTTPCTransform::GetADCSat())
618 dig = AliHLTTPCTransform::GetADCSat();
620 //Exclude data outside cone:
621 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
622 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
623 // continue; // why 230???
625 if(localcount >= ndigits[lrow])
626 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliDigits2Binary","Memory")
627 <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
628 <<ndigits[lrow]<<ENDLOG;
630 tempPt->fDigitData[localcount].fCharge=dig;
631 tempPt->fDigitData[localcount].fPad=pad;
632 tempPt->fDigitData[localcount].fTime=time;
633 tempPt->fDigitData[localcount].fTrackID[0] = fDigits->GetTrackID(time,pad,0);
634 tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
635 tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
640 Byte_t *tmp = (Byte_t*)tempPt;
641 Int_t blockSize = sizeof(AliHLTTPCDigitRowData)
642 + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
644 tempPt = (AliHLTTPCDigitRowData*)tmp;
646 assert((Byte_t*)tempPt==((Byte_t*)data)+bufferSize);
651 int AliHLTTPCFileHandler::AliDigits2Altro(Int_t event, Byte_t* tgtBuffer, UInt_t tgtSize)
653 //Read data from AliROOT file into memory, and store it in the ALTRO data format
654 //in the provided buffer
655 //Returns: size of the encoded data in bytes
659 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Altro","File")
660 <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
669 if(!GetDigitsTree(event)) return 0;
676 AliHLTTPCMapping mapper(fPatch);
677 AliHLTAltroEncoder encoder;
678 encoder.SetBuffer(tgtBuffer, tgtSize);
680 // The digits of the current event have been indexed: all digits are organized in
681 // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
682 // are stored in the digit tree.
683 // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
685 // This loop filters the pad rows according to the slice no set via Init
687 assert(fRowMax<fgkNRow);
688 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow && iResult>=0;r++){
689 Int_t n=fIndex[fSlice][r];
693 AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
694 AliHLTTPCTransform::Slice2Sector(fSlice,AliHLTTPCTransform::GetFirstRow(fPatch),sector,rowOffset);
696 if(n!=-1){//data on that row
698 fDigitsTree->GetEvent(n);
699 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
700 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
702 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Altro","Row")
703 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
707 Int_t channelAddress=-1;
710 time=fDigits->CurrentRow();
711 pad=fDigits->CurrentColumn();
712 dig = fDigits->GetDigit(time,pad);
713 if (dig <= fParam->GetZeroSup()) continue;
714 if(dig >= AliHLTTPCTransform::GetADCSat())
715 dig = AliHLTTPCTransform::GetADCSat();
717 channelAddress=mapper.GetHwAddress(row-rowOffset, pad);
718 iResult=encoder.AddChannelSignal(dig, time, channelAddress);
719 } while (fDigits->Next() && iResult>=0);
720 if (iResult>=0 && channelAddress>=0) {
721 iResult=encoder.SetChannel(channelAddress);
727 iResult=(encoder.GetTotal40bitWords()*5)/4;
733 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
735 //Read data from AliROOT file into memory, and store it in the HLT data format.
736 //Returns a pointer to the data.
737 //This functions filter out single timebins, which is noise. The timebins which
738 //are removed are timebins which have the 4 zero neighbours;
739 //(pad-1,time),(pad+1,time),(pad,time-1),(pad,time+1).
741 AliHLTTPCDigitRowData *data = 0;
745 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
746 <<"No Input avalible: Pointer to TFile == NULL"<<ENDLOG;
749 if(eventmerge == kTRUE && event >= 1024)
751 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","TrackIDs")
752 <<"Too many events if you want to merge!"<<ENDLOG;
757 /* Dont understand why we have to do
758 reload the tree, but otherwise the code crashes */
760 if(!GetDigitsTree(event)) return 0;
763 Int_t time,pad,sector,row;
766 Int_t entries = (Int_t)fDigitsTree->GetEntries();
768 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","ndigits")
769 <<"No TPC digits (entries==0)!"<<ENDLOG;
770 nrow = (UInt_t)(fRowMax-fRowMin+1);
771 Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
772 data=(AliHLTTPCDigitRowData*) Allocate(size);
773 AliHLTTPCDigitRowData *tempPt = data;
774 for(Int_t r=fRowMin;r<=fRowMax;r++){
781 Int_t * ndigits = new Int_t[fRowMax+1];
783 Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
786 for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
787 Int_t n=fIndex[fSlice][r];
791 if(n!=-1){//data on that row
792 fDigitsTree->GetEvent(n);
793 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
794 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
795 //cout << lslice << " " << fSlice << " " << lrow << " " << r << " " << sector << " " << row << endl;
796 if((lslice!=fSlice)||(lrow!=r)){
797 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
798 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
802 fDigits->ExpandBuffer();
803 fDigits->ExpandTrackBuffer();
804 for(Int_t i=0; i<fDigits->GetNCols(); i++){
805 for(Int_t j=0; j<fDigits->GetNRows(); j++){
808 dig = fDigits->GetDigitFast(time,pad);
809 if(dig <= zerosupval) continue;
810 if(dig >= AliHLTTPCTransform::GetADCSat())
811 dig = AliHLTTPCTransform::GetADCSat();
813 //Check for single timebins, and remove them because they are noise for sure.
814 if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
815 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
816 fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
817 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
818 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
824 if(j < fDigits->GetNRows()-1 && j > 0)
826 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
827 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
828 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
833 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
834 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
840 if(i < fDigits->GetNCols()-1 && i > 0)
842 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
843 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
844 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
849 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
850 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
855 if(i==fDigits->GetNCols()-1)
857 if(j>0 && j<fDigits->GetNRows()-1)
859 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
860 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
861 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
864 else if(j==0 && j<fDigits->GetNRows()-1)
866 if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
867 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
872 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
873 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
878 if(j==fDigits->GetNRows()-1)
880 if(i>0 && i<fDigits->GetNCols()-1)
882 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
883 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
884 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
887 else if(i==0 && fDigits->GetNCols()-1)
889 if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
890 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
895 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
896 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
901 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
902 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
905 ndigits[lrow]++; //for this row only
906 ndigitcount++; //total number of digits to be published
913 Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
914 + nrows*sizeof(AliHLTTPCDigitRowData);
916 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Digits")
917 <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
919 data=(AliHLTTPCDigitRowData*) Allocate(size);
920 nrow = (UInt_t)nrows;
921 AliHLTTPCDigitRowData *tempPt = data;
923 for(Int_t r=fRowMin;r<=fRowMax;r++){
924 Int_t n=fIndex[fSlice][r];
927 if(n!=-1){ //no data on that row
928 fDigitsTree->GetEvent(n);
929 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
930 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
933 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
934 <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
938 tempPt->fNDigit = ndigits[lrow];
941 fDigits->ExpandBuffer();
942 fDigits->ExpandTrackBuffer();
943 for(Int_t i=0; i<fDigits->GetNCols(); i++){
944 for(Int_t j=0; j<fDigits->GetNRows(); j++){
947 dig = fDigits->GetDigitFast(time,pad);
948 if(dig <= zerosupval) continue;
949 if(dig >= AliHLTTPCTransform::GetADCSat())
950 dig = AliHLTTPCTransform::GetADCSat();
952 //Check for single timebins, and remove them because they are noise for sure.
953 if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
954 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
955 fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
956 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
957 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
963 if(j < fDigits->GetNRows()-1 && j > 0)
965 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
966 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
967 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
972 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
973 fDigits->GetDigitFast(time,pad+1)<=zerosupval)
979 if(i < fDigits->GetNCols()-1 && i > 0)
981 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
982 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
983 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
988 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
989 fDigits->GetDigitFast(time+1,pad)<=zerosupval)
994 if(i == fDigits->GetNCols()-1)
996 if(j>0 && j<fDigits->GetNRows()-1)
998 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
999 fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1000 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1003 else if(j==0 && j<fDigits->GetNRows()-1)
1005 if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1006 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1011 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
1012 fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1016 if(j==fDigits->GetNRows()-1)
1018 if(i>0 && i<fDigits->GetNCols()-1)
1020 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1021 fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1022 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1025 else if(i==0 && fDigits->GetNCols()-1)
1027 if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1028 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1033 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1034 fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1039 AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
1040 // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
1043 if(localcount >= ndigits[lrow])
1044 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliAltroDigits2Binary","Memory")
1045 <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
1046 <<ndigits[lrow]<<ENDLOG;
1048 tempPt->fDigitData[localcount].fCharge=dig;
1049 tempPt->fDigitData[localcount].fPad=pad;
1050 tempPt->fDigitData[localcount].fTime=time;
1051 tempPt->fDigitData[localcount].fTrackID[0] = (fDigits->GetTrackIDFast(time,pad,0)-2);
1052 tempPt->fDigitData[localcount].fTrackID[1] = (fDigits->GetTrackIDFast(time,pad,1)-2);
1053 tempPt->fDigitData[localcount].fTrackID[2] = (fDigits->GetTrackIDFast(time,pad,2)-2);
1054 if(eventmerge == kTRUE) //careful track mc info will be touched
1055 {//Event are going to be merged, so event number is stored in the upper 10 bits.
1056 tempPt->fDigitData[localcount].fTrackID[0] += 128; //leave some room
1057 tempPt->fDigitData[localcount].fTrackID[1] += 128; //for neg. numbers
1058 tempPt->fDigitData[localcount].fTrackID[2] += 128;
1059 tempPt->fDigitData[localcount].fTrackID[0] += ((event&0x3ff)<<22);
1060 tempPt->fDigitData[localcount].fTrackID[1] += ((event&0x3ff)<<22);
1061 tempPt->fDigitData[localcount].fTrackID[2] += ((event&0x3ff)<<22);
1067 Byte_t *tmp = (Byte_t*)tempPt;
1068 tmp += sizeof(AliHLTTPCDigitRowData)
1069 + ndigits[r]*sizeof(AliHLTTPCDigitData);
1070 tempPt = (AliHLTTPCDigitRowData*)tmp;
1076 Bool_t AliHLTTPCFileHandler::GetDigitsTree(Int_t event)
1078 //Connects to the TPC digit tree in the AliROOT file.
1079 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1081 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::GetDigitsTree","File")
1082 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1085 fInAli->GetEvent(event);
1086 tpcLoader->LoadDigits();
1087 fDigitsTree = tpcLoader->TreeD();
1090 LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::GetDigitsTree","Digits Tree")
1091 <<AliHLTTPCLog::kHex<<"Error getting digitstree "<<(void*)fDigitsTree<<ENDLOG;
1094 fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
1096 if(!fIndexCreated) return CreateIndex();
1100 ///////////////////////////////////////// Point IO
1101 Bool_t AliHLTTPCFileHandler::AliPoints2Binary(Int_t eventn)
1106 AliHLTTPCSpacePointData *data = AliPoints2Memory(npoint,eventn);
1107 out = Memory2Binary(npoint,data);
1113 // Is this really still used : JMT 2013-03-03
1114 AliHLTTPCSpacePointData * AliHLTTPCFileHandler::AliPoints2Memory(UInt_t & npoint,Int_t eventn)
1117 AliHLTTPCSpacePointData *data = 0;
1120 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1121 <<"No Input avalible: no object fInAli"<<ENDLOG;
1125 TDirectory *savedir = gDirectory;
1126 AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1128 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1129 <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1132 fInAli->GetEvent(eventn);
1133 tpcLoader->LoadRecPoints();
1135 AliTPCClustersArray carray;
1136 carray.Setup(fParam);
1137 carray.SetClusterType("AliTPCclusterMI");
1138 Bool_t clusterok = carray.ConnectTree(tpcLoader->TreeR());
1140 if(!clusterok) return 0;
1142 AliTPCClustersRow ** clusterrow =
1143 new AliTPCClustersRow*[ (int)carray.GetTree()->GetEntries()];
1144 Int_t *rows = new int[ (int)carray.GetTree()->GetEntries()];
1145 Int_t *sects = new int[ (int)carray.GetTree()->GetEntries()];
1149 for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1150 AliSegmentID *s = carray.LoadEntry(i);
1152 fParam->AdjustSectorRow(s->GetID(),sector,row);
1156 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1157 if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
1158 clusterrow[i] = carray.GetRow(sector,row);
1160 sum+=clusterrow[i]->GetArray()->GetEntriesFast();
1162 UInt_t size = sum*sizeof(AliHLTTPCSpacePointData);
1164 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1165 <<AliHLTTPCLog::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
1167 data = (AliHLTTPCSpacePointData *) Allocate(size);
1173 for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1174 if(!clusterrow[i]) continue;
1175 Int_t row = rows[i];
1176 Int_t sector = sects[i];
1177 AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1178 Int_t entriesInRow = clusterrow[i]->GetArray()->GetEntriesFast();
1179 for(Int_t j = 0;j<entriesInRow;j++){
1180 AliTPCclusterMI *c = (AliTPCclusterMI*)(*clusterrow[i])[j];
1181 data[n].fZ = c->GetZ();
1182 data[n].fY = c->GetY();
1183 data[n].fX = fParam->GetPadRowRadii(sector,row);
1184 data[n].fCharge = (UInt_t)c->GetQ();
1185 data[n].SetID( fSlice, pat, n );
1186 data[n].fPadRow = lrow;
1187 data[n].fSigmaY2 = c->GetSigmaY2();
1188 data[n].fSigmaZ2 = c->GetSigmaZ2();
1190 data[n].fTrackID[0] = c->GetLabel(0);
1191 data[n].fTrackID[1] = c->GetLabel(1);
1192 data[n].fTrackID[2] = c->GetLabel(2);
1194 if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
1198 for(Int_t i=0;i<carray.GetTree()->GetEntries();i++){
1199 Int_t row = rows[i];
1200 Int_t sector = sects[i];
1201 if(carray.GetRow(sector,row))
1202 carray.ClearRow(sector,row);
1205 delete [] clusterrow;