3ae48ae6b2318871472c1aa5bf1a24814f9ea23e
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCFileHandler.cxx
1 // @(#) $Id$
2 // Original: AliL3FileHandler.cxx,v 1.49 2005/06/23 17:46:55 hristov 
3
4 // Author: Uli Frankenfeld <mailto:franken@fi.uib.no>, Anders Vestbo <mailto:vestbo$fi.uib.no>, C. Loizides <mailto:loizides@ikf.uni-frankfurt.de>
5 //*-- Copyright &copy ALICE HLT Group 
6
7 #include <TClonesArray.h>
8 #include <TSystem.h>
9 #include <TMath.h>
10
11 #ifdef use_newio
12 #include <AliRunLoader.h>
13 #endif
14 #include <AliTPCParamSR.h>
15 #include <AliTPCDigitsArray.h>
16 #include <AliTPCClustersArray.h>
17 #include <AliTPCcluster.h>
18 #include <AliTPCClustersRow.h>
19 #include <AliSimDigits.h>
20
21 #include "AliHLTTPCLogging.h"
22 #include "AliHLTTPCTransform.h"
23 #include "AliHLTTPCMemHandler.h"
24 #include "AliHLTTPCDigitData.h"
25 #include "AliHLTTPCTrackSegmentData.h"
26 #include "AliHLTTPCSpacePointData.h"
27 #include "AliHLTTPCTrackArray.h"
28 #include "AliHLTTPCFileHandler.h"
29
30 #if __GNUC__ >= 3
31 using namespace std;
32 #endif
33
34 /** \class AliHLTTPCFileHandler
35 <pre>
36 //_____________________________________________________________
37 // AliHLTTPCFileHandler
38 //
39 // The HLT ROOT <-> binary files handling class
40 //
41 // This class provides the interface between AliROOT files,
42 // and HLT binary files. It should be used for converting 
43 // TPC data stored in AliROOT format (outputfile from a simulation),
44 // into the data format currently used by in the HLT framework. 
45 // This enables the possibility to always use the same data format, 
46 // whether you are using a binary file as an input, or a AliROOT file.
47 //
48 // For example on how to create binary files from a AliROOT simulation,
49 // see example macro exa/Binary.C.
50 //
51 // For reading a AliROOT file into HLT format in memory, do the following:
52 //
53 // AliHLTTPCFileHandler file;
54 // file.Init(slice,patch);
55 // file.SetAliInput("galice.root");
56 // AliHLTTPCDigitRowData *dataPt = (AliHLTTPCDigitRowData*)file.AliDigits2Memory(nrows,eventnr);
57 // 
58 // All the data are then stored in memory and accessible via the pointer dataPt.
59 // Accesing the data is then identical to the example 1) showed in AliHLTTPCMemHandler class.
60 //
61 // For converting the data back, and writing it to a new AliROOT file do:
62 //
63 // AliHLTTPCFileHandler file;
64 // file.Init(slice,patch);
65 // file.SetAliInput("galice.root");
66 // file.Init(slice,patch,NumberOfRowsInPatch);
67 // file.AliDigits2RootFile(dataPt,"new_galice.root");
68 // file.CloseAliInput();
69 </pre>
70 */
71
72 ClassImp(AliHLTTPCFileHandler)
73
74 AliHLTTPCFileHandler::AliHLTTPCFileHandler(Bool_t b)
75   :
76   fInAli(NULL),
77 #ifdef use_newio
78   fUseRunLoader(kFALSE),
79 #endif
80   fParam(NULL),
81   fMC(NULL),
82   fDigits(NULL),
83   fDigitsTree(NULL),
84   fIndexCreated(kFALSE),
85   fUseStaticIndex(b)
86 {
87   //Default constructor
88
89   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++)
90     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++) 
91       fIndex[i][j]=-1;
92
93   if(fUseStaticIndex&&!fgStaticIndexCreated) CleanStaticIndex();
94 }
95
96 AliHLTTPCFileHandler::AliHLTTPCFileHandler(const AliHLTTPCFileHandler& ref)
97   :
98   fInAli(NULL),
99 #ifdef use_newio
100   fUseRunLoader(kFALSE),
101 #endif
102   fParam(NULL),
103   fMC(NULL),
104   fDigits(NULL),
105   fDigitsTree(NULL),
106   fIndexCreated(kFALSE),
107   fUseStaticIndex(ref.fUseStaticIndex)
108 {
109   HLTFatal("copy constructor untested");
110 }
111
112 AliHLTTPCFileHandler& AliHLTTPCFileHandler::operator=(const AliHLTTPCFileHandler&)
113
114   HLTFatal("assignment operator untested");
115   return *this;
116 }
117
118 AliHLTTPCFileHandler::~AliHLTTPCFileHandler()
119 {
120   //Destructor
121   if(fMC) CloseMCOutput();
122   FreeDigitsTree();
123   if(fInAli) CloseAliInput();
124 }
125
126 // of course on start up the index is not created
127 Bool_t AliHLTTPCFileHandler::fgStaticIndexCreated=kFALSE;
128 Int_t  AliHLTTPCFileHandler::fgStaticIndex[36][159]; 
129
130 void AliHLTTPCFileHandler::CleanStaticIndex() 
131
132   // use this static call to clean static index after
133   // running over one event
134   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
135     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
136       fgStaticIndex[i][j]=-1;
137   }
138   fgStaticIndexCreated=kFALSE;
139 }
140
141 Int_t AliHLTTPCFileHandler::SaveStaticIndex(Char_t *prefix,Int_t event) 
142
143   // use this static call to store static index after
144   if(!fgStaticIndexCreated) return -1;
145
146   Char_t fname[1024];
147   if(prefix)
148     sprintf(fname,"%s-%d.txt",prefix,event);
149   else
150     sprintf(fname,"TPC.Digits.staticindex-%d.txt",event);
151
152   ofstream file(fname,ios::trunc);
153   if(!file.good()) return -1;
154
155   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
156     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
157       file << fgStaticIndex[i][j] << " ";
158     file << endl;
159   }
160   file.close();
161   return 0;
162 }
163
164 Int_t AliHLTTPCFileHandler::LoadStaticIndex(Char_t *prefix,Int_t event) 
165
166   // use this static call to store static index after
167   if(fgStaticIndexCreated){
168       LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::LoadStaticIndex","Inxed")
169         <<"Static index already created, will overwrite"<<ENDLOG;
170       CleanStaticIndex();
171   }
172
173   Char_t fname[1024];
174   if(prefix)
175     sprintf(fname,"%s-%d.txt",prefix,event);
176   else
177     sprintf(fname,"TPC.Digits.staticindex-%d.txt",event);
178
179   ifstream file(fname);
180   if(!file.good()) return -1;
181
182   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
183     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
184       file >> fgStaticIndex[i][j];
185   }
186   file.close();
187
188   fgStaticIndexCreated=kTRUE;
189   return 0;
190 }
191
192 void AliHLTTPCFileHandler::FreeDigitsTree()
193
194   //free digits tree
195   if(!fDigitsTree)
196     {
197       LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::FreeDigitsTree()","Pointer")
198         <<"Cannot free digitstree, it is not present"<<ENDLOG;
199       return;
200     }
201   delete fDigits;
202   fDigits=0;
203 #ifndef use_newio
204   fDigitsTree->Delete();
205 #endif
206   fDigitsTree=0;
207
208   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
209     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
210       fIndex[i][j]=-1;
211   }
212   fIndexCreated=kFALSE;
213 }
214
215 Bool_t AliHLTTPCFileHandler::SetMCOutput(Char_t *name)
216
217   //set mc input
218   fMC = fopen(name,"w");
219   if(!fMC){
220     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
221       <<"Pointer to File = 0x0 "<<ENDLOG;
222     return kFALSE;
223   }
224   return kTRUE;
225 }
226
227 Bool_t AliHLTTPCFileHandler::SetMCOutput(FILE *file)
228
229   //set mc output
230   fMC = file;
231   if(!fMC){
232     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
233       <<"Pointer to File = 0x0 "<<ENDLOG;
234     return kFALSE;
235   }
236   return kTRUE;
237 }
238
239 void AliHLTTPCFileHandler::CloseMCOutput()
240
241   //close mc output
242   if(!fMC){
243     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseMCOutPut","File Close")
244       <<"Nothing to Close"<<ENDLOG;
245     return;
246   }
247   fclose(fMC);
248   fMC =0;
249 }
250
251 Bool_t AliHLTTPCFileHandler::SetAliInput()
252
253   //set ali input
254 #ifdef use_newio
255   fInAli->CdGAFile();
256   fParam = (AliTPCParam*)gFile->Get("75x40_100x60_150x60");
257   if(!fParam){
258     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
259       <<"No TPC parameters found in \""<<gFile->GetName()
260       <<"\", creating standard parameters "
261       <<"which might not be what you want!"<<ENDLOG;
262     fParam = new AliTPCParamSR;
263   }
264   if(!fParam){ 
265     LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
266       <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<gFile->GetName()<<ENDLOG;
267     return kFALSE;
268   }
269 #else
270   if(!fInAli->IsOpen()){
271     LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
272       <<"Ali File "<<fInAli->GetName()<<" does not exist"<<ENDLOG;
273     return kFALSE;
274   }
275   fParam = (AliTPCParam*)fInAli->Get(AliHLTTPCTransform::GetParamName());
276   if(!fParam){
277     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
278       <<"No TPC parameters found in \""<<fInAli->GetName()
279       <<"\", creating standard parameters "
280       <<"which might not be what you want!"<<ENDLOG;
281     fParam = new AliTPCParamSR;
282   }
283   if(!fParam){ 
284     LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
285       <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<fInAli->GetName()<<ENDLOG;
286     return kFALSE;
287   }
288 #endif
289
290   return kTRUE;
291 }
292
293 Bool_t AliHLTTPCFileHandler::SetAliInput(Char_t *name)
294
295   //Open the AliROOT file with name.
296 #ifdef use_newio
297   fInAli= AliRunLoader::Open(name);
298 #else
299   fInAli= new TFile(name,"READ");
300 #endif
301   if(!fInAli){
302     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
303     <<"Pointer to fInAli = 0x0 "<<ENDLOG;
304     return kFALSE;
305   }
306   return SetAliInput();
307 }
308
309 #ifdef use_newio
310 Bool_t AliHLTTPCFileHandler::SetAliInput(AliRunLoader *runLoader)
311
312   //set ali input as runloader
313   fInAli=runLoader;
314   fUseRunLoader = kTRUE;
315   if(!fInAli){
316     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
317     <<"Pointer to AliRunLoader = 0x0 "<<ENDLOG;
318     return kFALSE;
319   }
320   return SetAliInput();
321 }
322 #endif
323
324 #ifdef use_newio
325 Bool_t AliHLTTPCFileHandler::SetAliInput(TFile */*file*/)
326 {
327   //Specify already opened AliROOT file to use as an input.
328   LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::SetAliInput","File Open")
329     <<"This function is not supported for NEWIO, check ALIHLT_USENEWIO settings in Makefile.conf"<<ENDLOG;
330   return kFALSE;
331 }
332 #else
333 Bool_t AliHLTTPCFileHandler::SetAliInput(TFile *file)
334
335   //Specify already opened AliROOT file to use as an input.
336   fInAli=file;
337   if(!fInAli){
338     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
339     <<"Pointer to fInAli = 0x0 "<<ENDLOG;
340     return kFALSE;
341   }
342   return SetAliInput();
343 }
344 #endif
345
346 void AliHLTTPCFileHandler::CloseAliInput()
347
348   //close ali input
349 #ifdef use_newio
350   if(fUseRunLoader) return;
351 #endif
352   if(!fInAli){
353     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseAliInput","RunLoader")
354       <<"Nothing to Close"<<ENDLOG;
355     return;
356   }
357 #ifndef use_newio
358   if(fInAli->IsOpen()) fInAli->Close();
359 #endif
360
361   delete fInAli;
362   fInAli = 0;
363 }
364
365 Bool_t AliHLTTPCFileHandler::IsDigit(Int_t event)
366 {
367   //Check if there is a TPC digit tree in the current file.
368   //Return kTRUE if tree was found, and kFALSE if not found.
369   
370   if(!fInAli){
371     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::IsDigit","File")
372     <<"Pointer to fInAli = 0x0 "<<ENDLOG;
373     return kTRUE;  //maybe you are using binary input which is Digits!
374   }
375 #ifdef use_newio
376   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
377   if(!tpcLoader){
378     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandlerNewIO::IsDigit","File")
379     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
380     return kFALSE;
381   }
382   fInAli->GetEvent(event);
383   tpcLoader->LoadDigits();
384   TTree *t=tpcLoader->TreeD();
385 #else
386   Char_t name[1024];
387   sprintf(name,"TreeD_%s_%d",AliHLTTPCTransform::GetParamName(),event);
388   TTree *t=(TTree*)fInAli->Get(name);
389 #endif
390   if(t){
391     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
392     <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
393     return kTRUE;
394   }
395   else{
396     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
397     <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
398     return kFALSE;
399   }
400 }
401
402 ///////////////////////////////////////// Digit IO  
403 Bool_t AliHLTTPCFileHandler::AliDigits2Binary(Int_t event,Bool_t altro)
404 {
405   //save alidigits as binary
406   Bool_t out = kTRUE;
407   UInt_t nrow;
408   AliHLTTPCDigitRowData* data = 0;
409   if(altro)
410     data = AliAltroDigits2Memory(nrow,event);
411   else
412     data = AliDigits2Memory(nrow,event);
413   out = Memory2Binary(nrow,data);
414   Free();
415   return out;
416 }
417
418 Bool_t AliHLTTPCFileHandler::AliDigits2CompBinary(Int_t event,Bool_t altro)
419 {
420   //Convert AliROOT TPC data, into HLT data format.
421   //event specifies the event you want in the aliroot file.
422   
423   Bool_t out = kTRUE;
424   UInt_t ndigits=0;
425   AliHLTTPCDigitRowData *digits=0;
426   if(altro)
427     digits = AliAltroDigits2Memory(ndigits,event);
428   else
429     digits = AliDigits2Memory(ndigits,event);
430   out = Memory2CompBinary(ndigits,digits);
431   Free();
432   return out;
433 }
434
435 Bool_t AliHLTTPCFileHandler::CreateIndex()
436 {
437   //create the access index or copy from static index
438   fIndexCreated=kFALSE;
439
440   if(!fgStaticIndexCreated || !fUseStaticIndex) { //we have to create index 
441     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
442       <<"Starting to create index, this can take a while."<<ENDLOG;
443
444     for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
445       Int_t sector, row;
446       Int_t lslice,lrow;
447       fDigitsTree->GetEvent(n);
448       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
449       if(!AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row)){
450         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::CreateIndex","Slice/Row")
451           <<AliHLTTPCLog::kDec<<"Index could not be created. Wrong values "
452           <<sector<<" "<<row<<ENDLOG;
453         return kFALSE;
454       }
455       if(fIndex[lslice][lrow]==-1) {
456         fIndex[lslice][lrow]=n;
457       }
458     }
459     if(fUseStaticIndex) { // create static index
460       for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
461         for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
462           fgStaticIndex[i][j]=fIndex[i][j];
463       }
464       fgStaticIndexCreated=kTRUE; //remember that index has been created
465     }
466
467   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
468     <<"Index successfully created."<<ENDLOG;
469
470   } else if(fUseStaticIndex) { //simply copy static index
471     for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
472       for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
473         fIndex[i][j]=fgStaticIndex[i][j];
474     }
475
476   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
477     <<"Index successfully taken from static copy."<<ENDLOG;
478   }
479   fIndexCreated=kTRUE;
480   return kTRUE;
481 }
482
483 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event)
484 {
485   //Read data from AliROOT file into memory, and store it in the HLT data format.
486   //Returns a pointer to the data.
487
488   AliHLTTPCDigitRowData *data = 0;
489   nrow=0;
490   
491   if(!fInAli){
492     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
493     <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
494     return 0; 
495   }
496
497 #ifndef use_newio
498   if(!fInAli->IsOpen()){
499     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
500     <<"No Input avalible: TFile not opened"<<ENDLOG;
501     return 0;
502   }
503 #endif
504
505   if(!fDigitsTree)
506     if(!GetDigitsTree(event)) return 0;
507
508   UShort_t dig;
509   Int_t time,pad,sector,row;
510   Int_t lslice,lrow;
511   Int_t nrows=0;
512   Int_t ndigitcount=0;
513   Int_t entries = (Int_t)fDigitsTree->GetEntries();
514   if(entries==0) {
515     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","ndigits")
516       <<"No TPC digits (entries==0)!"<<ENDLOG;
517     nrow = (UInt_t)(fRowMax-fRowMin+1);
518     Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
519     data=(AliHLTTPCDigitRowData*) Allocate(size);
520     AliHLTTPCDigitRowData *tempPt = data;
521     for(Int_t r=fRowMin;r<=fRowMax;r++){
522       tempPt->fRow = r;
523       tempPt->fNDigit = 0;
524       tempPt++;
525     }
526     return data;
527   }
528
529   Int_t * ndigits = new Int_t[fRowMax+1];
530   Float_t xyz[3];
531
532   for(Int_t r=fRowMin;r<=fRowMax;r++){
533     Int_t n=fIndex[fSlice][r];
534     if(n!=-1){ //data on that row
535       fDigitsTree->GetEvent(n);
536       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
537       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
538
539       if(lrow!=r){
540         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
541           <<AliHLTTPCLog::kDec<<"Rows in slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
542         continue;
543       }
544
545       ndigits[lrow] = 0;
546       fDigits->First();
547       do {
548         time=fDigits->CurrentRow();
549         pad=fDigits->CurrentColumn();
550         dig = fDigits->GetDigit(time,pad);
551         if(dig <= fParam->GetZeroSup()) continue;
552         if(dig >= AliHLTTPCTransform::GetADCSat())
553           dig = AliHLTTPCTransform::GetADCSat();
554       
555         AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
556         //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
557         //        continue; // why 230???
558
559         ndigits[lrow]++; //for this row only
560         ndigitcount++;   //total number of digits to be published
561
562       } while (fDigits->Next());
563       //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
564     }
565     nrows++;
566   }
567
568   Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
569     + nrows*sizeof(AliHLTTPCDigitRowData);
570
571   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
572     <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
573   
574   data=(AliHLTTPCDigitRowData*) Allocate(size);
575   nrow = (UInt_t)nrows;
576   AliHLTTPCDigitRowData *tempPt = data;
577
578   for(Int_t r=fRowMin;r<=fRowMax;r++){
579     Int_t n=fIndex[fSlice][r];
580     tempPt->fRow = r;
581     tempPt->fNDigit = 0;
582
583     if(n!=-1){//data on that row
584       fDigitsTree->GetEvent(n);
585       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
586       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
587       if(lrow!=r){
588         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
589           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
590         continue;
591       }
592
593       tempPt->fNDigit = ndigits[lrow];
594
595       Int_t localcount=0;
596       fDigits->First();
597       do {
598         time=fDigits->CurrentRow();
599         pad=fDigits->CurrentColumn();
600         dig = fDigits->GetDigit(time,pad);
601         if (dig <= fParam->GetZeroSup()) continue;
602         if(dig >= AliHLTTPCTransform::GetADCSat())
603           dig = AliHLTTPCTransform::GetADCSat();
604
605         //Exclude data outside cone:
606         AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
607         //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
608         //        continue; // why 230???
609
610         if(localcount >= ndigits[lrow])
611           LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliDigits2Binary","Memory")
612             <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
613             <<ndigits[lrow]<<ENDLOG;
614         
615         tempPt->fDigitData[localcount].fCharge=dig;
616         tempPt->fDigitData[localcount].fPad=pad;
617         tempPt->fDigitData[localcount].fTime=time;
618 #ifdef do_mc
619         tempPt->fDigitData[localcount].fTrackID[0] = fDigits->GetTrackID(time,pad,0);
620         tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
621         tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
622 #endif
623         localcount++;
624       } while (fDigits->Next());
625     }
626     Byte_t *tmp = (Byte_t*)tempPt;
627     Int_t size = sizeof(AliHLTTPCDigitRowData)
628                                       + ndigits[lrow]*sizeof(AliHLTTPCDigitData);
629     tmp += size;
630     tempPt = (AliHLTTPCDigitRowData*)tmp;
631   }
632   delete [] ndigits;
633   return data;
634 }
635
636 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
637 {
638   //Read data from AliROOT file into memory, and store it in the HLT data format.
639   //Returns a pointer to the data.
640   //This functions filter out single timebins, which is noise. The timebins which
641   //are removed are timebins which have the 4 zero neighbours; 
642   //(pad-1,time),(pad+1,time),(pad,time-1),(pad,time+1).
643   
644   AliHLTTPCDigitRowData *data = 0;
645   nrow=0;
646   
647   if(!fInAli){
648     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
649     <<"No Input avalible: Pointer to TFile == NULL"<<ENDLOG;
650     return 0; 
651   }
652 #ifndef use_newio
653   if(!fInAli->IsOpen()){
654     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
655     <<"No Input avalible: TFile not opened"<<ENDLOG;
656     return 0;
657   }
658 #endif
659   if(eventmerge == kTRUE && event >= 1024)
660     {
661       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","TrackIDs")
662         <<"Too many events if you want to merge!"<<ENDLOG;
663       return 0;
664     }
665   delete fDigits;
666   fDigits=0;
667 #ifdef use_newio 
668   /* Dont understand why we have to do 
669      reload the tree, but otherwise the code crashes */
670   fDigitsTree=0;
671   if(!GetDigitsTree(event)) return 0;
672 #else
673   if(!fDigitsTree){
674     if(!GetDigitsTree(event)) return 0;
675   }
676 #endif
677
678   UShort_t dig;
679   Int_t time,pad,sector,row;
680   Int_t nrows=0;
681   Int_t ndigitcount=0;
682   Int_t entries = (Int_t)fDigitsTree->GetEntries();
683   if(entries==0) {
684     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","ndigits")
685       <<"No TPC digits (entries==0)!"<<ENDLOG;
686     nrow = (UInt_t)(fRowMax-fRowMin+1);
687     Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
688     data=(AliHLTTPCDigitRowData*) Allocate(size);
689     AliHLTTPCDigitRowData *tempPt = data;
690     for(Int_t r=fRowMin;r<=fRowMax;r++){
691       tempPt->fRow = r;
692       tempPt->fNDigit = 0;
693       tempPt++;
694     }
695     return data;
696   }
697   Int_t * ndigits = new Int_t[fRowMax+1];
698   Int_t lslice,lrow;
699   Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
700   Float_t xyz[3];
701
702   for(Int_t r=fRowMin;r<=fRowMax;r++){
703     Int_t n=fIndex[fSlice][r];
704
705     ndigits[r] = 0;
706
707     if(n!=-1){//data on that row
708       fDigitsTree->GetEvent(n);
709       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
710       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
711       //cout << lslice << " " << fSlice << " " << lrow << " " << r << " " << sector << " " << row << endl;
712       if((lslice!=fSlice)||(lrow!=r)){
713         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
714           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
715         continue;
716       }
717
718       fDigits->ExpandBuffer();
719       fDigits->ExpandTrackBuffer();
720       for(Int_t i=0; i<fDigits->GetNCols(); i++){
721         for(Int_t j=0; j<fDigits->GetNRows(); j++){
722           pad=i;
723           time=j;
724           dig = fDigits->GetDigitFast(time,pad);
725           if(dig <= zerosupval) continue;
726           if(dig >= AliHLTTPCTransform::GetADCSat())
727             dig = AliHLTTPCTransform::GetADCSat();
728
729           //Check for single timebins, and remove them because they are noise for sure.
730           if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
731             if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
732                fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
733                fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
734                fDigits->GetDigitFast(time,pad+1)<=zerosupval)
735               continue;
736               
737           //Boundaries:
738           if(i==0) //pad==0
739             {
740               if(j < fDigits->GetNRows()-1 && j > 0) 
741                 {
742                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
743                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
744                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
745                     continue;
746                 }
747               else if(j > 0)
748                 {
749                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
750                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
751                     continue;
752                 }
753             }
754           if(j==0)
755             {
756               if(i < fDigits->GetNCols()-1 && i > 0)
757                 {
758                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
759                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
760                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
761                     continue;
762                 }
763               else if(i > 0)
764                 {
765                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
766                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
767                     continue;
768                 }
769             }
770
771           if(i==fDigits->GetNCols()-1)
772             {
773               if(j>0 && j<fDigits->GetNRows()-1)
774                 {
775                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
776                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
777                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
778                     continue;
779                 }
780               else if(j==0 && j<fDigits->GetNRows()-1)
781                 {
782                   if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
783                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
784                     continue;
785                 }
786               else 
787                 {
788                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
789                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
790                     continue;
791                 }
792             }
793         
794           if(j==fDigits->GetNRows()-1)
795             {
796               if(i>0 && i<fDigits->GetNCols()-1)
797                 {
798                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
799                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
800                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
801                     continue;
802                 }
803               else if(i==0 && fDigits->GetNCols()-1)
804                 {
805                   if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
806                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
807                     continue;
808                 }
809               else 
810                 {
811                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
812                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
813                     continue;
814                 }
815             }
816
817           AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
818           //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
819           //      continue; 
820               
821           ndigits[lrow]++; //for this row only
822           ndigitcount++;   //total number of digits to be published
823         }
824       }
825     }
826     nrows++;
827   }
828   
829   Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
830     + nrows*sizeof(AliHLTTPCDigitRowData);
831
832   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Digits")
833     <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
834   
835   data=(AliHLTTPCDigitRowData*) Allocate(size);
836   nrow = (UInt_t)nrows;
837   AliHLTTPCDigitRowData *tempPt = data;
838  
839   for(Int_t r=fRowMin;r<=fRowMax;r++){
840     Int_t n=fIndex[fSlice][r];
841     tempPt->fRow = r;
842     tempPt->fNDigit = 0;
843     if(n!=-1){ //no data on that row
844       fDigitsTree->GetEvent(n);
845       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
846       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
847
848       if(lrow!=r){
849         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
850           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
851         continue;
852       }
853
854       tempPt->fNDigit = ndigits[lrow];
855
856       Int_t localcount=0;
857       fDigits->ExpandBuffer();
858       fDigits->ExpandTrackBuffer();
859       for(Int_t i=0; i<fDigits->GetNCols(); i++){
860         for(Int_t j=0; j<fDigits->GetNRows(); j++){
861           pad=i;
862           time=j;
863           dig = fDigits->GetDigitFast(time,pad);
864           if(dig <= zerosupval) continue;
865           if(dig >= AliHLTTPCTransform::GetADCSat())
866             dig = AliHLTTPCTransform::GetADCSat();
867               
868           //Check for single timebins, and remove them because they are noise for sure.
869           if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
870             if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
871                fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
872                fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
873                fDigits->GetDigitFast(time,pad+1)<=zerosupval)
874               continue;
875           
876           //Boundaries:
877           if(i==0) //pad ==0
878             {
879               if(j < fDigits->GetNRows()-1 && j > 0) 
880                 {
881                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
882                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
883                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
884                     continue;
885                 }
886               else if(j > 0)
887                 {
888                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
889                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
890                     continue;
891                 }
892             }
893           if(j==0)
894             {
895               if(i < fDigits->GetNCols()-1 && i > 0)
896                 {
897                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
898                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
899                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
900                     continue;
901                 }
902               else if(i > 0)
903                 {
904                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
905                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
906                     continue;
907                 }
908             }
909         
910           if(i == fDigits->GetNCols()-1)
911             {
912               if(j>0 && j<fDigits->GetNRows()-1)
913                 {
914                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
915                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
916                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
917                     continue;
918                 }
919               else if(j==0 && j<fDigits->GetNRows()-1)
920                 {
921                   if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
922                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
923                     continue;
924                 }
925               else 
926                 {
927                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
928                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
929                     continue;
930                 }
931             }
932           if(j==fDigits->GetNRows()-1)
933             {
934               if(i>0 && i<fDigits->GetNCols()-1)
935                 {
936                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
937                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
938                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
939                     continue;
940                 }
941               else if(i==0 && fDigits->GetNCols()-1)
942                 {
943                   if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
944                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
945                     continue;
946                 }
947               else 
948                 {
949                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
950                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
951                     continue;
952                 }
953             }
954         
955           AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
956           //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
957           //        continue;
958           
959           if(localcount >= ndigits[lrow])
960             LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliAltroDigits2Binary","Memory")
961               <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
962               <<ndigits[lrow]<<ENDLOG;
963         
964           tempPt->fDigitData[localcount].fCharge=dig;
965           tempPt->fDigitData[localcount].fPad=pad;
966           tempPt->fDigitData[localcount].fTime=time;
967 #ifdef do_mc
968           tempPt->fDigitData[localcount].fTrackID[0] = (fDigits->GetTrackIDFast(time,pad,0)-2);
969           tempPt->fDigitData[localcount].fTrackID[1] = (fDigits->GetTrackIDFast(time,pad,1)-2);
970           tempPt->fDigitData[localcount].fTrackID[2] = (fDigits->GetTrackIDFast(time,pad,2)-2);
971           if(eventmerge == kTRUE) //careful track mc info will be touched
972             {//Event are going to be merged, so event number is stored in the upper 10 bits.
973               tempPt->fDigitData[localcount].fTrackID[0] += 128; //leave some room
974               tempPt->fDigitData[localcount].fTrackID[1] += 128; //for neg. numbers
975               tempPt->fDigitData[localcount].fTrackID[2] += 128;
976               tempPt->fDigitData[localcount].fTrackID[0] += ((event&0x3ff)<<22);
977               tempPt->fDigitData[localcount].fTrackID[1] += ((event&0x3ff)<<22);
978               tempPt->fDigitData[localcount].fTrackID[2] += ((event&0x3ff)<<22);
979             }
980 #endif
981           localcount++;
982         }
983       }
984     }
985     Byte_t *tmp = (Byte_t*)tempPt;
986     Int_t size = sizeof(AliHLTTPCDigitRowData)
987       + ndigits[r]*sizeof(AliHLTTPCDigitData);
988     tmp += size;
989     tempPt = (AliHLTTPCDigitRowData*)tmp;
990   }
991   delete [] ndigits;
992   return data;
993 }
994  
995 Bool_t AliHLTTPCFileHandler::GetDigitsTree(Int_t event)
996 {
997   //Connects to the TPC digit tree in the AliROOT file.
998 #ifdef use_newio
999   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1000   if(!tpcLoader){
1001     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::GetDigitsTree","File")
1002     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1003     return kFALSE;
1004   }
1005   fInAli->GetEvent(event);
1006   tpcLoader->LoadDigits();
1007   fDigitsTree = tpcLoader->TreeD();
1008 #else  
1009   fInAli->cd();
1010   Char_t dname[100];
1011   sprintf(dname,"TreeD_%s_%d",AliHLTTPCTransform::GetParamName(),event);
1012   fDigitsTree = (TTree*)fInAli->Get(dname);
1013 #endif
1014   if(!fDigitsTree) 
1015     {
1016       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::GetDigitsTree","Digits Tree")
1017         <<AliHLTTPCLog::kHex<<"Error getting digitstree "<<(void*)fDigitsTree<<ENDLOG;
1018       return kFALSE;
1019     }
1020   fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
1021
1022   if(!fIndexCreated) return CreateIndex();
1023   else return kTRUE;
1024 }
1025
1026 void AliHLTTPCFileHandler::AliDigits2RootFile(AliHLTTPCDigitRowData *rowPt,Char_t *new_digitsfile)
1027 {
1028   //Write the data stored in rowPt, into a new AliROOT file.
1029   //The data is stored in the AliROOT format 
1030   //This is specially a nice thing if you have modified data, and wants to run it  
1031   //through the offline reconstruction chain.
1032   //The arguments is a pointer to the data, and the name of the new AliROOT file.
1033   //Remember to pass the original AliROOT file (the one that contains the original
1034   //simulated data) to this object, in order to retrieve the MC id's of the digits.
1035
1036   if(!fInAli)
1037     {
1038       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1039         <<"No rootfile "<<ENDLOG;
1040       return;
1041     }
1042   if(!fParam)
1043     {
1044       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1045         <<"No parameter object. Run on rootfile "<<ENDLOG;
1046       return;
1047     }
1048
1049 #ifdef use_newio
1050   //Get the original digitstree:
1051   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1052   if(!tpcLoader){
1053     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1054     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1055     return;
1056   }
1057   tpcLoader->LoadDigits();
1058   TTree *t=tpcLoader->TreeD();
1059
1060   AliTPCDigitsArray *old_array = new AliTPCDigitsArray();
1061   old_array->Setup(fParam);
1062   old_array->SetClass("AliSimDigits");
1063
1064   Bool_t ok = old_array->ConnectTree(t);
1065   if(!ok)
1066     {
1067       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1068         << "No digits tree object" << ENDLOG;
1069       return;
1070     }
1071
1072   tpcLoader->SetDigitsFileName(new_digitsfile);
1073   tpcLoader->MakeDigitsContainer();
1074     
1075   //setup a new one, or connect it to the existing one:
1076   AliTPCDigitsArray *arr = new AliTPCDigitsArray(); 
1077   arr->SetClass("AliSimDigits");
1078   arr->Setup(fParam);
1079   arr->MakeTree(tpcLoader->TreeD());
1080 #else
1081   
1082   //Get the original digitstree:
1083   Char_t dname[100];
1084   sprintf(dname,"TreeD_%s_0",AliHLTTPCTransform::GetParamName());
1085
1086   fInAli->cd();
1087   AliTPCDigitsArray *old_array = new AliTPCDigitsArray();
1088   old_array->Setup(fParam);
1089   old_array->SetClass("AliSimDigits");
1090
1091   Bool_t ok = old_array->ConnectTree(dname);
1092   if(!ok)
1093     {
1094       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1095         <<"No digits tree object." <<ENDLOG;
1096       return;
1097     }
1098
1099   Bool_t create=kFALSE;
1100   TFile *digFile;
1101   
1102   if(gSystem->AccessPathName(new_digitsfile))
1103     {
1104       LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
1105         <<"Creating new file "<<new_digitsfile<<ENDLOG;
1106       create = kTRUE;
1107       digFile = TFile::Open(new_digitsfile,"RECREATE");
1108       fParam->Write(fParam->GetTitle());
1109     }
1110   else
1111     {
1112       create = kFALSE;
1113       digFile = TFile::Open(new_digitsfile,"UPDATE");
1114       
1115     }
1116   if(!digFile->IsOpen())
1117     {
1118       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","Rootfile")
1119         <<"Error opening rootfile "<<new_digitsfile<<ENDLOG;
1120       return;
1121     }
1122   
1123   digFile->cd();
1124     
1125   //setup a new one, or connect it to the existing one:
1126   AliTPCDigitsArray *arr = new AliTPCDigitsArray(); 
1127   arr->SetClass("AliSimDigits");
1128   arr->Setup(fParam);
1129   if(create)
1130     arr->MakeTree();
1131   else
1132     {
1133       Bool_t ok = arr->ConnectTree(dname);
1134       if(!ok)
1135         {
1136           LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","Rootfile")
1137             <<"No digits tree object in existing file"<<ENDLOG;
1138           return;
1139         }
1140     }
1141 #endif
1142
1143   Int_t digcounter=0,trackID[3];
1144
1145   for(Int_t i=fRowMin; i<=fRowMax; i++)
1146     {
1147       
1148       if((Int_t)rowPt->fRow != i) 
1149         LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
1150           <<"Mismatching row numbering "<<(Int_t)rowPt->fRow<<" "<<i<<ENDLOG;
1151             
1152       Int_t sector,row;
1153       AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
1154       
1155       AliSimDigits *old_dig = (AliSimDigits*)old_array->LoadRow(sector,row);
1156       AliSimDigits * dig = (AliSimDigits*)arr->CreateRow(sector,row);
1157       old_dig->ExpandBuffer();
1158       old_dig->ExpandTrackBuffer();
1159       dig->ExpandBuffer();
1160       dig->ExpandTrackBuffer();
1161       
1162       if(!old_dig)
1163         LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
1164           <<"No padrow " << sector << " " << row <<ENDLOG;
1165
1166       AliHLTTPCDigitData *digPt = rowPt->fDigitData;
1167       digcounter=0;
1168       for(UInt_t j=0; j<rowPt->fNDigit; j++)
1169         {
1170           Short_t charge = (Short_t)digPt[j].fCharge;
1171           Int_t pad = (Int_t)digPt[j].fPad;
1172           Int_t time = (Int_t)digPt[j].fTime;
1173           
1174           if(charge == 0) //Only write the digits that has not been removed
1175             {
1176               LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
1177                 <<"Zero charge" <<ENDLOG;
1178               continue;
1179             }
1180
1181           digcounter++;
1182           
1183           //Tricks to get and set the correct track id's. 
1184           for(Int_t t=0; t<3; t++)
1185             {
1186               Int_t label = old_dig->GetTrackIDFast(time,pad,t);
1187               if(label > 1)
1188                 trackID[t] = label - 2;
1189               else if(label==0)
1190                 trackID[t] = -2;
1191               else
1192                 trackID[t] = -1;
1193             }
1194           
1195           dig->SetDigitFast(charge,time,pad);
1196           
1197           for(Int_t t=0; t<3; t++)
1198             ((AliSimDigits*)dig)->SetTrackIDFast(trackID[t],time,pad,t);
1199           
1200         }
1201       //cout<<"Wrote "<<digcounter<<" on row "<<i<<endl;
1202       UpdateRowPointer(rowPt);
1203       arr->StoreRow(sector,row);
1204       arr->ClearRow(sector,row);  
1205       old_array->ClearRow(sector,row);
1206     }
1207
1208   char treeName[100];
1209   sprintf(treeName,"TreeD_%s_0",fParam->GetTitle());
1210   
1211 #ifdef use_newio
1212   arr->GetTree()->SetName(treeName);
1213   arr->GetTree()->AutoSave();
1214   tpcLoader->WriteDigits("OVERWRITE");
1215 #else
1216   digFile->cd();
1217   arr->GetTree()->SetName(treeName);
1218   arr->GetTree()->AutoSave();
1219   digFile->Close();
1220 #endif
1221   delete arr;
1222   delete old_array;
1223 }
1224
1225 ///////////////////////////////////////// Point IO  
1226 Bool_t AliHLTTPCFileHandler::AliPoints2Binary(Int_t eventn)
1227 {
1228   //points to binary
1229   Bool_t out = kTRUE;
1230   UInt_t npoint;
1231   AliHLTTPCSpacePointData *data = AliPoints2Memory(npoint,eventn);
1232   out = Memory2Binary(npoint,data);
1233   Free();
1234   return out;
1235 }
1236
1237 AliHLTTPCSpacePointData * AliHLTTPCFileHandler::AliPoints2Memory(UInt_t & npoint,Int_t eventn)
1238 {
1239   //points to memory
1240   AliHLTTPCSpacePointData *data = 0;
1241   npoint=0;
1242   if(!fInAli){
1243     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1244     <<"No Input avalible: no object fInAli"<<ENDLOG;
1245     return 0;
1246   }
1247 #ifndef use_newio
1248   if(!fInAli->IsOpen()){
1249     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1250     <<"No Input avalible: TFile not opend"<<ENDLOG;
1251     return 0;
1252   }
1253 #endif
1254
1255   TDirectory *savedir = gDirectory;
1256 #ifdef use_newio
1257   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1258   if(!tpcLoader){
1259     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1260     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1261     return 0;
1262   }
1263   fInAli->GetEvent(eventn);
1264   tpcLoader->LoadRecPoints();
1265
1266   AliTPCClustersArray carray;
1267   carray.Setup(fParam);
1268   carray.SetClusterType("AliTPCcluster");
1269   Bool_t clusterok = carray.ConnectTree(tpcLoader->TreeR());
1270 #else
1271   fInAli->cd();
1272   
1273   Char_t cname[100];
1274   sprintf(cname,"TreeC_TPC_%d",eventn);
1275   AliTPCClustersArray carray;
1276   carray.Setup(fParam);
1277   carray.SetClusterType("AliTPCcluster");
1278   Bool_t clusterok = carray.ConnectTree(cname);
1279 #endif
1280
1281   if(!clusterok) return 0;
1282
1283   AliTPCClustersRow ** clusterrow = 
1284                new AliTPCClustersRow*[ (int)carray.GetTree()->GetEntries()];
1285   Int_t *rows = new int[ (int)carray.GetTree()->GetEntries()];
1286   Int_t *sects = new int[  (int)carray.GetTree()->GetEntries()];
1287   Int_t sum=0;
1288
1289   Int_t lslice,lrow;
1290   for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1291     AliSegmentID *s = carray.LoadEntry(i);
1292     Int_t sector,row;
1293     fParam->AdjustSectorRow(s->GetID(),sector,row);
1294     rows[i] = row;
1295     sects[i] = sector;
1296     clusterrow[i] = 0;
1297     AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1298     if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
1299     clusterrow[i] = carray.GetRow(sector,row);
1300     if(clusterrow[i])
1301       sum+=clusterrow[i]->GetArray()->GetEntriesFast();
1302   }
1303   UInt_t size = sum*sizeof(AliHLTTPCSpacePointData);
1304
1305   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1306   <<AliHLTTPCLog::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
1307
1308   data = (AliHLTTPCSpacePointData *) Allocate(size);
1309   npoint = sum;
1310   UInt_t n=0; 
1311   Int_t pat=fPatch;
1312   if(fPatch==-1)
1313     pat=0;
1314   for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1315     if(!clusterrow[i]) continue;
1316     Int_t row = rows[i];
1317     Int_t sector = sects[i];
1318     AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1319     Int_t entries_in_row = clusterrow[i]->GetArray()->GetEntriesFast();
1320     for(Int_t j = 0;j<entries_in_row;j++){
1321       AliTPCcluster *c = (AliTPCcluster*)(*clusterrow[i])[j];
1322       data[n].fZ = c->GetZ();
1323       data[n].fY = c->GetY();
1324       data[n].fX = fParam->GetPadRowRadii(sector,row);
1325       data[n].fCharge = (UInt_t)c->GetQ();
1326       data[n].fID = n+((fSlice&0x7f)<<25)+((pat&0x7)<<22);//uli
1327       data[n].fPadRow = lrow;
1328       data[n].fSigmaY2 = c->GetSigmaY2();
1329       data[n].fSigmaZ2 = c->GetSigmaZ2();
1330 #ifdef do_mc
1331       data[n].fTrackID[0] = c->GetLabel(0);
1332       data[n].fTrackID[1] = c->GetLabel(1);
1333       data[n].fTrackID[2] = c->GetLabel(2);
1334 #endif
1335       if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
1336       n++;
1337     }
1338   }
1339   for(Int_t i=0;i<carray.GetTree()->GetEntries();i++){
1340     Int_t row = rows[i];
1341     Int_t sector = sects[i];
1342     if(carray.GetRow(sector,row))
1343       carray.ClearRow(sector,row);
1344   }
1345
1346   delete [] clusterrow;
1347   delete [] rows;
1348   delete [] sects;
1349   savedir->cd();   
1350
1351   return data;
1352 }
1353