3 // Author: Uli Frankenfeld <mailto:franken@fi.uib.no>, Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright © Uli
6 #include "AliL3StandardIncludes.h"
7 #include <TClonesArray.h>
9 #include <AliTPCDigitsArray.h>
10 #include <AliTPCClustersArray.h>
11 #include <AliTPCcluster.h>
12 #include <AliTPCClustersRow.h>
13 #include <AliSimDigits.h>
15 #include "AliL3Logging.h"
16 #include "AliL3Transform.h"
17 #include "AliL3MemHandler.h"
18 #include "AliL3FileHandler.h"
19 #include "AliL3DigitData.h"
20 #include "AliL3TrackSegmentData.h"
21 #include "AliL3SpacePointData.h"
22 #include "AliL3TrackArray.h"
25 //_____________________________________________________________
28 // The HLT ROOT <-> binary files handling class
30 // This class provides the interface between AliROOT files,
31 // and HLT binary files. It should be used for converting
32 // TPC data stored in AliROOT format (outputfile from a simulation),
33 // into the data format currently used by in the HLT framework.
34 // This enables the possibility to always use the same data format,
35 // whether you are using a binary file as an input, or a AliROOT file.
37 // For example on how to create binary files from a AliROOT simulation,
38 // see example macro exa/Binary.C.
40 // For reading a AliROOT file into HLT format in memory, do the following:
42 // AliL3FileHandler file;
43 // file.SetAliInput("galice.root");
44 // AliL3DigitRowData *dataPt = (AliL3DigitRowData*)file.AliDigits2Memory(nrows,eventnr);
46 // All the data are then stored in memory and accessible via the pointer dataPt.
47 // Accesing the data is then identical to the example 1) showed in AliL3MemHandler class.
49 // For converting the data back, and writing it to a new AliROOT file do:
51 // AliL3FileHandler file;
52 // file.SetAliInput("galice.root");
53 // file.Init(slice,patch,NumberOfRowsInPatch);
54 // file.AliDigits2RootFile(dataPt,"new_galice.root");
55 // file.CloseAliInput();
57 ClassImp(AliL3FileHandler)
59 AliL3FileHandler::AliL3FileHandler()
70 AliL3FileHandler::~AliL3FileHandler()
73 if(fMC) CloseMCOutput();
75 if(fInAli) CloseAliInput();
79 void AliL3FileHandler::FreeDigitsTree()
83 LOG(AliL3Log::kWarning,"AliL3FileHandler::FreeDigitsTree()","Pointer")
84 <<"Cannot free digitstree, it is not present"<<ENDLOG;
88 fDigitsTree->Delete();
92 Bool_t AliL3FileHandler::SetMCOutput(char *name)
94 fMC = fopen(name,"w");
96 LOG(AliL3Log::kWarning,"AliL3FileHandler::SetMCOutput","File Open")
97 <<"Pointer to File = 0x0 "<<ENDLOG;
103 Bool_t AliL3FileHandler::SetMCOutput(FILE *file)
107 LOG(AliL3Log::kWarning,"AliL3FileHandler::SetMCOutput","File Open")
108 <<"Pointer to File = 0x0 "<<ENDLOG;
114 void AliL3FileHandler::CloseMCOutput()
117 LOG(AliL3Log::kWarning,"AliL3FileHandler::CloseMCOutPut","File Close")
118 <<"Nothing to Close"<<ENDLOG;
125 Bool_t AliL3FileHandler::SetAliInput()
127 if(!fInAli->IsOpen()){
128 LOG(AliL3Log::kError,"AliL3FileHandler::SetAliInput","File Open")
129 <<"Ali File "<<fInAli->GetName()<<" does not exist"<<ENDLOG;
132 fParam = (AliTPCParam*)fInAli->Get(AliL3Transform::GetParamName());
134 LOG(AliL3Log::kError,"AliL3FileHandler::SetAliInput","File Open")
135 <<"No AliTPCParam "<<AliL3Transform::GetParamName()<<" in File "<<fInAli->GetName()<<ENDLOG;
141 Bool_t AliL3FileHandler::SetAliInput(char *name)
143 //Open the AliROOT file with name.
145 fInAli= new TFile(name,"READ");
147 LOG(AliL3Log::kWarning,"AliL3FileHandler::SetAliInput","File Open")
148 <<"Pointer to TFile = 0x0 "<<ENDLOG;
151 return SetAliInput();
154 Bool_t AliL3FileHandler::SetAliInput(TFile *file)
156 //Specify already opened AliROOT file to use as an input.
160 LOG(AliL3Log::kWarning,"AliL3FileHandler::SetAliInput","File Open")
161 <<"Pointer to TFile = 0x0 "<<ENDLOG;
164 return SetAliInput();
167 void AliL3FileHandler::CloseAliInput()
170 LOG(AliL3Log::kWarning,"AliL3FileHandler::CloseAliInput","File Close")
171 <<"Nothing to Close"<<ENDLOG;
174 if(fInAli->IsOpen()) fInAli->Close();
180 Bool_t AliL3FileHandler::IsDigit(Int_t event)
182 //Check if there is a TPC digit tree in the current file.
183 //Return kTRUE if tree was found, and kFALSE if not found.
186 LOG(AliL3Log::kWarning,"AliL3FileHandler::IsDigit","File")
187 <<"Pointer to TFile = 0x0 "<<ENDLOG;
188 return kTRUE; //maybe you are using binary input which is Digits!!
191 sprintf(name,"TreeD_%s_%d",AliL3Transform::GetParamName(),event);
192 TTree *t=(TTree*)fInAli->Get(name);
194 LOG(AliL3Log::kInformational,"AliL3FileHandler::IsDigit","File Type")
195 <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
199 LOG(AliL3Log::kInformational,"AliL3FileHandler::IsDigit","File Type")
200 <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
205 ///////////////////////////////////////// Digit IO
206 Bool_t AliL3FileHandler::AliDigits2Binary(Int_t event)
210 AliL3DigitRowData* data = AliDigits2Memory(nrow,event);
211 out = Memory2Binary(nrow,data);
216 Bool_t AliL3FileHandler::AliDigits2CompBinary(Int_t event)
218 //Convert AliROOT TPC data, into HLT data format.
219 //event specifies the event you want in the aliroot file.
223 AliL3DigitRowData* digits = AliDigits2Memory(ndigits,event);
224 out = Memory2CompBinary(ndigits,digits);
229 AliL3DigitRowData * AliL3FileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event)
231 //Read data from AliROOT file into memory, and store it in the HLT data format.
232 //Returns a pointer to the data.
234 AliL3DigitRowData *data = 0;
238 LOG(AliL3Log::kWarning,"AliL3FileHandler::AliDigits2Memory","File")
239 <<"No Input avalible: no object TFile"<<ENDLOG;
242 if(!fInAli->IsOpen()){
243 LOG(AliL3Log::kWarning,"AliL3FileHandler::AliDigits2Memory","File")
244 <<"No Input avalible: TFile not opened"<<ENDLOG;
249 GetDigitsTree(event);
252 Int_t time,pad,sector,row;
255 Int_t entries = (Int_t)fDigitsTree->GetEntries();
256 Int_t ndigits[entries];
260 for(Int_t n=fLastIndex; n<fDigitsTree->GetEntries(); n++)
262 fDigitsTree->GetEvent(n);
263 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
264 AliL3Transform::Sector2Slice(lslice,lrow,sector,row);
265 //if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
266 if(lslice < fSlice) continue;
267 if(lslice != fSlice) break;
268 if(lrow < fRowMin) continue;
269 if(lrow > fRowMax) break;
274 time=fDigits->CurrentRow();
275 pad=fDigits->CurrentColumn();
276 dig = fDigits->GetDigit(time,pad);
277 if(dig<=fParam->GetZeroSup()) continue;
279 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
280 if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
283 ndigits[lrow]++; //for this row only
284 ndigitcount++; //total number of digits to be published
286 } while (fDigits->Next());
287 //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
291 Int_t size = sizeof(AliL3DigitData)*ndigitcount
292 + nrows*sizeof(AliL3DigitRowData);
294 LOG(AliL3Log::kDebug,"AliL3FileHandler::AliDigits2Memory","Digits")
295 <<AliL3Log::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
297 data=(AliL3DigitRowData*) Allocate(size);
298 nrow = (UInt_t)nrows;
299 AliL3DigitRowData *tempPt = data;
300 for(Int_t n=fLastIndex; n<fDigitsTree->GetEntries(); n++)
302 fDigitsTree->GetEvent(n);
303 fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
304 AliL3Transform::Sector2Slice(lslice,lrow,sector,row);
305 //if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
306 if(lslice < fSlice) continue;
307 if(lslice != fSlice) break;
308 if(lrow < fRowMin) continue;
309 if(lrow > fRowMax) break;
312 tempPt->fNDigit = ndigits[lrow];
317 time=fDigits->CurrentRow();
318 pad=fDigits->CurrentColumn();
319 dig = fDigits->GetDigit(time,pad);
320 if (dig <= fParam->GetZeroSup()) continue;
322 //Exclude data outside cone:
323 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
324 if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
327 if(localcount >= ndigits[lrow])
328 LOG(AliL3Log::kFatal,"AliL3FileHandler::AliDigits2Binary","Memory")
329 <<AliL3Log::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
330 <<ndigits[lrow]<<ENDLOG;
332 tempPt->fDigitData[localcount].fCharge=dig;
333 tempPt->fDigitData[localcount].fPad=pad;
334 tempPt->fDigitData[localcount].fTime=time;
336 tempPt->fDigitData[localcount].fTrackID[0] = fDigits->GetTrackID(time,pad,0);
337 tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
338 tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
341 } while (fDigits->Next());
343 Byte_t *tmp = (Byte_t*)tempPt;
344 Int_t size = sizeof(AliL3DigitRowData)
345 + ndigits[lrow]*sizeof(AliL3DigitData);
347 tempPt = (AliL3DigitRowData*)tmp;
358 Bool_t AliL3FileHandler::GetDigitsTree(Int_t event)
360 //Connects to the TPC digit tree in the AliROOT file.
364 sprintf(dname,"TreeD_%s_%d",AliL3Transform::GetParamName(),event);
365 fDigitsTree = (TTree*)fInAli->Get(dname);
368 LOG(AliL3Log::kError,"AliL3FileHandler::GetDigitsTree","Digits Tree")
369 <<AliL3Log::kHex<<"Error getting digitstree "<<(Int_t)fDigitsTree<<ENDLOG;
372 fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
376 void AliL3FileHandler::AliDigits2RootFile(AliL3DigitRowData *rowPt,Char_t *new_digitsfile)
378 //Write the data stored in rowPt, into a new AliROOT file.
379 //The data is stored in the AliROOT format
380 //This is specially a nice thing if you have modified data, and wants to run it
381 //through the offline reconstruction chain.
382 //The arguments is a pointer to the data, and the name of the new AliROOT file.
383 //Remember to pass the original AliROOT file (the one that contains the original
384 //simulated data) to this object, in order to retrieve the MC id's of the digits.
388 printf("AliL3FileHandler::AliDigits2RootFile : No rootfile\n");
393 printf("AliL3FileHandler::AliDigits2RootFile : No parameter object. Run on rootfile\n");
397 //Get the original digitstree:
399 AliTPCDigitsArray *old_array = new AliTPCDigitsArray();
400 old_array->Setup(fParam);
401 old_array->SetClass("AliSimDigits");
404 sprintf(dname,"TreeD_%s_0",AliL3Transform::GetParamName());
406 Bool_t ok = old_array->ConnectTree(dname);
409 printf("AliL3FileHandler::AliDigits2RootFile : No digits tree object\n");
413 Bool_t create=kFALSE;
416 digFile = TFile::Open(new_digitsfile,"NEW");
417 if(digFile->IsOpen())
420 fParam->Write(fParam->GetTitle());
424 LOG(AliL3Log::kDebug,"AliL3FileHandler::AliDigits2RootFile","Rootfile")
425 <<"Rootfile did already exist, so I will just open it for updates"<<ENDLOG;
426 digFile = TFile::Open(new_digitsfile,"UPDATE");
429 if(!digFile->IsOpen())
431 LOG(AliL3Log::kError,"AliL3FileHandler::AliDigits2RootFile","Rootfile")
432 <<"Error opening rootfile "<<new_digitsfile<<ENDLOG;
438 //setup a new one, or connect it to the existing one:
439 AliTPCDigitsArray *arr = new AliTPCDigitsArray;
440 arr->SetClass("AliSimDigits");
446 Bool_t ok = arr->ConnectTree(dname);
449 printf("AliL3FileHandler::AliDigits2RootFile : No digits tree object in existing file\n");
455 for(Int_t i=fRowMin; i<=fRowMax; i++)
458 if((Int_t)rowPt->fRow != i) printf("AliL3FileHandler::AliDigits2RootFile : Mismatching row numbering!!!\n");
461 AliL3Transform::Slice2Sector(fSlice,i,sector,row);
462 AliSimDigits * dig = (AliSimDigits*)arr->CreateRow(sector,row);
463 AliSimDigits *old_dig = (AliSimDigits*)old_array->LoadRow(sector,row);
465 printf("AliL3FileHandler::AliDigits2RootFile : No padrow %d %d\n",sector,row);
467 AliL3DigitData *digPt = rowPt->fDigitData;
469 for(UInt_t j=0; j<rowPt->fNDigit; j++)
471 Int_t charge = (Int_t)digPt[j].fCharge;
472 Int_t pad = (Int_t)digPt[j].fPad;
473 Int_t time = (Int_t)digPt[j].fTime;
475 if(charge == 0) //Only write the digits that has not been removed
478 dig->SetDigitFast(charge,time,pad);
480 Int_t trackID[3] = {old_dig->GetTrackID(time,pad,0),old_dig->GetTrackID(time,pad,1),old_dig->GetTrackID(time,pad,2)};
482 Int_t s_time = time - 1;
483 while(trackID[0] < 0)
485 if(s_time >= 0 && s_time < AliL3Transform::GetNTimeBins() && s_pad >= 0 && s_pad < AliL3Transform::GetNPads(i))
487 if(old_dig->GetTrackID(s_time,s_pad,0) > 0)
489 trackID[0]=old_dig->GetTrackID(s_time,s_pad,0);
490 trackID[1]=old_dig->GetTrackID(s_time,s_pad,1);
491 trackID[2]=old_dig->GetTrackID(s_time,s_pad,2);
494 if(s_pad == pad && s_time == time - 1)
496 else if(s_pad == pad && s_time == time + 1)
497 {s_pad = pad - 1; s_time = time;}
498 else if(s_pad == pad - 1 && s_time == time)
500 else if(s_pad == pad - 1 && s_time == time - 1)
502 else if(s_pad == pad - 1 && s_time == time + 1)
503 {s_pad = pad + 1; s_time = time;}
504 else if(s_pad == pad + 1 && s_time == time)
506 else if(s_pad == pad + 1 && s_time == time - 1)
512 dig->SetTrackIDFast(trackID[0],time,pad,0);
513 dig->SetTrackIDFast(trackID[1],time,pad,1);
514 dig->SetTrackIDFast(trackID[2],time,pad,2);
517 //cout<<"Wrote "<<digcounter<<" on row "<<i<<endl;
518 UpdateRowPointer(rowPt);
519 arr->StoreRow(sector,row);
520 arr->ClearRow(sector,row);
521 old_array->ClearRow(sector,row);
525 sprintf(treeName,"TreeD_%s_0",fParam->GetTitle());
526 printf("Writing tree to file.....");
527 arr->GetTree()->Write(treeName,TObject::kOverwrite);
530 //arr->GetTree()->Delete();
534 ///////////////////////////////////////// Point IO
535 Bool_t AliL3FileHandler::AliPoints2Binary(){
538 AliL3SpacePointData *data = AliPoints2Memory(npoint);
539 out = Memory2Binary(npoint,data);
544 AliL3SpacePointData * AliL3FileHandler::AliPoints2Memory(UInt_t & npoint){
545 AliL3SpacePointData *data = 0;
548 LOG(AliL3Log::kWarning,"AliL3FileHandler::AliPoints2Memory","File")
549 <<"No Input avalible: no object TFile"<<ENDLOG;
552 if(!fInAli->IsOpen()){
553 LOG(AliL3Log::kWarning,"AliL3FileHandler::AliPoints2Memory","File")
554 <<"No Input avalible: TFile not opend"<<ENDLOG;
558 TDirectory *savedir = gDirectory;
563 sprintf(cname,"TreeC_TPC_%d",eventn);
564 AliTPCClustersArray carray;
565 carray.Setup(fParam);
566 carray.SetClusterType("AliTPCcluster");
567 Bool_t clusterok = carray.ConnectTree(cname);
568 if(!clusterok) return 0;
570 AliTPCClustersRow ** clusterrow =
571 new AliTPCClustersRow*[ (int)carray.GetTree()->GetEntries()];
572 Int_t *rows = new int[ (int)carray.GetTree()->GetEntries()];
573 Int_t *sects = new int[ (int)carray.GetTree()->GetEntries()];
577 for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
578 AliSegmentID *s = carray.LoadEntry(i);
580 fParam->AdjustSectorRow(s->GetID(),sector,row);
584 AliL3Transform::Sector2Slice(lslice,lrow,sector,row);
585 if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
586 clusterrow[i] = carray.GetRow(sector,row);
588 sum+=clusterrow[i]->GetArray()->GetEntriesFast();
590 UInt_t size = sum*sizeof(AliL3SpacePointData);
592 LOG(AliL3Log::kDebug,"AliL3FileHandler::AliPoints2Memory","File")
593 <<AliL3Log::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
595 data = (AliL3SpacePointData *) Allocate(size);
598 for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
599 if(!clusterrow[i]) continue;
601 Int_t sector = sects[i];
602 AliL3Transform::Sector2Slice(lslice,lrow,sector,row);
603 Int_t entries_in_row = clusterrow[i]->GetArray()->GetEntriesFast();
604 for(Int_t j = 0;j<entries_in_row;j++){
605 AliTPCcluster *c = (AliTPCcluster*)(*clusterrow[i])[j];
606 data[n].fZ = c->GetZ();
607 data[n].fY = c->GetY();
608 data[n].fX = fParam->GetPadRowRadii(sector,row);
609 data[n].fID = n+((fSlice&0x7f)<<25)+((fPatch&0x7)<<22);//uli
610 data[n].fPadRow = lrow;
611 data[n].fXYErr = c->GetSigmaY2();
612 data[n].fZErr = c->GetSigmaZ2();
613 if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
617 for(Int_t i=0;i<carray.GetTree()->GetEntries();i++){
619 Int_t sector = sects[i];
620 if(carray.GetRow(sector,row))
621 carray.ClearRow(sector,row);
624 delete [] clusterrow;