]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCFileHandler.cxx
Merge branch 'workdir'
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCFileHandler.cxx
1 // $Id$
2 // Original: AliHLTFileHandler.cxx,v 1.49 2005/06/23 17:46:55 hristov 
3
4 //**************************************************************************
5 //* This file is property of and copyright by the ALICE HLT Project        * 
6 //* ALICE Experiment at CERN, All rights reserved.                         *
7 //*                                                                        *
8 //* Primary Authors: U. Frankenfeld, A. Vestbo, C. Loizides                *
9 //*                  Matthias Richter <Matthias.Richter@ift.uib.no>        *
10 //*                  for The ALICE HLT Project.                            *
11 //*                                                                        *
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 //**************************************************************************
20
21 /// @file   AliHLTTPCFileHandler.cxx
22 /// @author U. Frankenfeld, A. Vestbo, C. Loizides, maintained by
23 ///         Matthias Richter
24 /// @date   
25 /// @brief  file input for the TPC tracking code before migration to the
26 ///         HLT component framework
27
28 // see below for class documentation
29 // or
30 // refer to README to build package
31 // or
32 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
33
34 #include <cassert>
35 #include <TClonesArray.h>
36 #include <TSystem.h>
37 #include <TMath.h>
38
39 #include "AliLoader.h"
40 #include <AliRunLoader.h>
41 #include <TObject.h>
42 #include <TFile.h>
43 #include <TTree.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"
51
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"
61
62 #if __GNUC__ >= 3
63 using namespace std;
64 #endif
65
66 /**
67 <pre>
68 //_____________________________________________________________
69 // AliHLTTPCFileHandler
70 //
71 // The HLT ROOT <-> binary files handling class
72 //
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.
79 //
80 // For example on how to create binary files from a AliROOT simulation,
81 // see example macro exa/Binary.C.
82 //
83 // For reading a AliROOT file into HLT format in memory, do the following:
84 //
85 // AliHLTTPCFileHandler file;
86 // file.Init(slice,patch);
87 // file.SetAliInput("galice.root");
88 // AliHLTTPCDigitRowData *dataPt = (AliHLTTPCDigitRowData*)file.AliDigits2Memory(nrows,eventnr);
89 // 
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.
92 //
93 // For converting the data back, and writing it to a new AliROOT file do:
94 //
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();
101 </pre>
102 */
103
104 ClassImp(AliHLTTPCFileHandler)
105
106 AliHLTTPCFileHandler::AliHLTTPCFileHandler(Bool_t b)
107   :
108   fInAli(NULL),
109   fUseRunLoader(kFALSE),
110   fParam(NULL),
111   fDigits(NULL),
112   fDigitsTree(NULL),
113   fMC(NULL),
114   fIndexCreated(kFALSE),
115   fUseStaticIndex(b)
116 {
117   //Default constructor
118
119   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++)
120     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++) 
121       fIndex[i][j]=-1;
122
123   if(fUseStaticIndex&&!fgStaticIndexCreated) CleanStaticIndex();
124 }
125
126 AliHLTTPCFileHandler::~AliHLTTPCFileHandler()
127 {
128   //Destructor
129   if(fMC) CloseMCOutput();
130   FreeDigitsTree();
131   if(fInAli) CloseAliInput();
132 }
133
134 // of course on start up the index is not created
135 Bool_t AliHLTTPCFileHandler::fgStaticIndexCreated=kFALSE;
136 Int_t  AliHLTTPCFileHandler::fgStaticIndex[36][159]; 
137
138 void AliHLTTPCFileHandler::CleanStaticIndex() 
139
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;
145   }
146   fgStaticIndexCreated=kFALSE;
147 }
148
149 Int_t AliHLTTPCFileHandler::SaveStaticIndex(Char_t *prefix,Int_t event) 
150
151   // use this static call to store static index after
152   if(!fgStaticIndexCreated) return -1;
153
154   const int fnamelen=1024;
155   Char_t fname[fnamelen];
156   if(prefix)
157     snprintf(fname,fnamelen, "%s-%d.txt",prefix,event);
158   else
159     snprintf(fname,fnamelen, "TPC.Digits.staticindex-%d.txt",event);
160
161   ofstream file(fname,ios::trunc);
162   if(!file.good()) return -1;
163
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] << " ";
167     file << endl;
168   }
169   file.close();
170   return 0;
171 }
172
173 Int_t AliHLTTPCFileHandler::LoadStaticIndex(Char_t *prefix,Int_t event) 
174
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;
179       CleanStaticIndex();
180   }
181
182   const int fnamelen=1024;
183   Char_t fname[fnamelen];
184   if(prefix)
185     snprintf(fname,fnamelen,"%s-%d.txt",prefix,event);
186   else
187     snprintf(fname,fnamelen,"TPC.Digits.staticindex-%d.txt",event);
188
189   ifstream file(fname);
190   if(!file.good()) return -1;
191
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];
195   }
196   file.close();
197
198   fgStaticIndexCreated=kTRUE;
199   return 0;
200 }
201
202 void AliHLTTPCFileHandler::FreeDigitsTree()
203
204   //free digits tree
205   if (fDigits) {
206     delete fDigits;
207   }
208   fDigits=0;
209   fDigitsTree=0;
210
211   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
212     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
213       fIndex[i][j]=-1;
214   }
215   fIndexCreated=kFALSE;
216 }
217
218 Bool_t AliHLTTPCFileHandler::SetMCOutput(Char_t *name)
219
220   //set mc input
221   fMC = fopen(name,"w");
222   if(!fMC){
223     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
224       <<"Pointer to File = 0x0 "<<ENDLOG;
225     return kFALSE;
226   }
227   return kTRUE;
228 }
229
230 Bool_t AliHLTTPCFileHandler::SetMCOutput(FILE *file)
231
232   //set mc output
233   fMC = file;
234   if(!fMC){
235     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
236       <<"Pointer to File = 0x0 "<<ENDLOG;
237     return kFALSE;
238   }
239   return kTRUE;
240 }
241
242 void AliHLTTPCFileHandler::CloseMCOutput()
243
244   //close mc output
245   if(!fMC){
246     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseMCOutPut","File Close")
247       <<"Nothing to Close"<<ENDLOG;
248     return;
249   }
250   fclose(fMC);
251   fMC =0;
252 }
253
254 Bool_t AliHLTTPCFileHandler::SetAliInput()
255
256   //set ali input
257
258   // fParam is in all cases an external object
259   const char* cdbEntry="TPC/Calib/Parameters";
260   AliCDBManager* pMan=AliCDBManager::Instance();
261   if (pMan) {
262     AliCDBEntry *pEntry = pMan->Get(cdbEntry);
263     if (pEntry==NULL || 
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;
268     }
269   }
270   if (!fParam) {
271   // the old solution until Nov 2008
272   fInAli->CdGAFile();
273   fParam = (AliTPCParam*)gFile->Get("75x40_100x60_150x60");
274   if(!fParam){
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;
280   }
281   }
282   if(!fParam){ 
283     LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
284       <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<gFile->GetName()<<ENDLOG;
285     return kFALSE;
286   }
287
288   return kTRUE;
289 }
290
291 Bool_t AliHLTTPCFileHandler::SetAliInput(Char_t *name)
292
293   //Open the AliROOT file with name.
294   fInAli= AliRunLoader::Open(name);
295   if(!fInAli){
296     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
297     <<"Pointer to fInAli = 0x0 "<<ENDLOG;
298     return kFALSE;
299   }
300   return SetAliInput();
301 }
302
303 Bool_t AliHLTTPCFileHandler::SetAliInput(AliRunLoader *runLoader)
304
305   //set ali input as runloader
306   if(!runLoader){
307     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
308       <<"invalid agument: pointer to AliRunLoader NULL "<<ENDLOG;
309     return kFALSE;
310   }
311   if (fInAli!=NULL && fInAli!=runLoader) {
312     LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
313     <<"Pointer to AliRunLoader already set"<<ENDLOG;
314     return kFALSE;
315   }
316   fInAli=runLoader;
317   fUseRunLoader = kTRUE;
318   return SetAliInput();
319 }
320
321 void AliHLTTPCFileHandler::CloseAliInput()
322
323   //close ali input
324   if(fUseRunLoader) return;
325   if(!fInAli){
326     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseAliInput","RunLoader")
327       <<"Nothing to Close"<<ENDLOG;
328     return;
329   }
330
331   delete fInAli;
332   fInAli = 0;
333 }
334
335 Bool_t AliHLTTPCFileHandler::IsDigit(Int_t event)
336 {
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.
339   
340   if(!fInAli){
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!
344   }
345   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
346   if(!tpcLoader){
347     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandlerNewIO::IsDigit","File")
348     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
349     return kFALSE;
350   }
351   fInAli->GetEvent(event);
352   tpcLoader->LoadDigits();
353   TTree *t=tpcLoader->TreeD();
354   if(t){
355     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
356     <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
357     return kTRUE;
358   }
359   else{
360     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
361     <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
362     return kFALSE;
363   }
364 }
365
366 ///////////////////////////////////////// Digit IO  
367 Bool_t AliHLTTPCFileHandler::AliDigits2BinaryFile(Int_t event,Bool_t altro)
368 {
369   //save alidigits as binary
370   Bool_t out = kTRUE;
371   UInt_t nrow;
372   AliHLTTPCDigitRowData* data = 0;
373   if(altro)
374     data = AliAltroDigits2Memory(nrow,event);
375   else
376     data = AliDigits2Memory(nrow,event);
377   out = Memory2BinaryFile(nrow,data);
378   Free();
379   return out;
380 }
381
382 Bool_t AliHLTTPCFileHandler::AliDigits2CompBinary(Int_t event,Bool_t altro)
383 {
384   //Convert AliROOT TPC data, into HLT data format.
385   //event specifies the event you want in the aliroot file.
386   
387   Bool_t out = kTRUE;
388   UInt_t ndigits=0;
389   AliHLTTPCDigitRowData *digits=0;
390   if(altro)
391     digits = AliAltroDigits2Memory(ndigits,event);
392   else
393     digits = AliDigits2Memory(ndigits,event);
394   out = Memory2CompBinary(ndigits,digits);
395   Free();
396   return out;
397 }
398
399 Bool_t AliHLTTPCFileHandler::CreateIndex()
400 {
401   //create the access index or copy from static index
402   fIndexCreated=kFALSE;
403
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;
407
408     //Int_t lslice,lrow;
409     for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
410       Int_t sector, row;
411       Int_t lslice,lrow;
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;
418         return kFALSE;
419       }
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;
427       }
428     }
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];
435       }
436       fgStaticIndexCreated=kTRUE; //remember that index has been created
437     }
438
439   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
440     <<"Index successfully created."<<ENDLOG;
441
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];
446     }
447
448   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
449     <<"Index successfully taken from static copy."<<ENDLOG;
450   }
451   fIndexCreated=kTRUE;
452   return kTRUE;
453 }
454
455 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event, Byte_t* tgtBuffer, UInt_t *pTgtSize)
456 {
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.
460
461   AliHLTTPCDigitRowData *data = 0;
462   nrow=0;
463   
464   if(!fInAli){
465     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
466     <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
467     return 0; 
468   }
469
470   if(!fDigitsTree)
471     if(!GetDigitsTree(event)) return 0;
472
473   UShort_t dig;
474   Int_t time,pad,sector,row;
475   Int_t nrows=0;
476   Int_t ndigitcount=0;
477   Int_t entries = (Int_t)fDigitsTree->GetEntries();
478   if(entries==0) {
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);
486       } else {
487       }
488     } else {
489       data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(size));
490     }
491     AliHLTTPCDigitRowData *tempPt = data;
492     if (data) {
493     if (pTgtSize) *pTgtSize=size;
494     for(Int_t r=fRowMin;r<=fRowMax;r++){
495       tempPt->fRow = r;
496       tempPt->fNDigit = 0;
497       tempPt++;
498     }
499     }
500     return data;
501   }
502
503   Int_t * ndigits = new Int_t[fRowMax+1];
504   memset(ndigits, 0, (fRowMax+1)*sizeof(Int_t));
505   Float_t xyz[3];
506
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
511   // in the TPC
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
517       Int_t lslice,lrow;
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;
523
524       if(lrow!=r){
525         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
526           <<AliHLTTPCLog::kDec<<"Rows in slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
527         continue;
528       }
529
530       ndigits[lrow] = 0;
531       for (bool bHaveData=fDigits->First();
532            bHaveData;
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();
540
541         // if we switch to AliTPCTransform, this maybe needs to be 
542         // adjusted as well
543         AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
544         //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
545         //        continue; // why 230???
546
547         ndigits[lrow]++; //for this row only
548         ndigitcount++;   //total number of digits to be published
549
550       }
551       //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
552     }
553     //see comment below//nrows++;
554   }
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;
563
564   UInt_t bufferSize = sizeof(AliHLTTPCDigitData)*ndigitcount
565     + nrows*sizeof(AliHLTTPCDigitRowData);
566
567   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
568     << "Found "<<ndigitcount<<" Digits in " << nrows << " rows out of [" << fRowMin << "," << fRowMax <<"]"<<ENDLOG;
569
570   if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
571     if (bufferSize<=*pTgtSize) {
572       data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
573     } else {
574     }
575   } else if (bufferSize>0) {
576     data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(bufferSize));
577   }
578   if (pTgtSize) *pTgtSize=bufferSize;
579   if (data==NULL) {
580     delete [] ndigits;
581     return NULL;
582   }
583   nrow = (UInt_t)nrows;
584   AliHLTTPCDigitRowData *tempPt = data;
585   memset(data, 0, bufferSize);
586
587   for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
588     Int_t n=fIndex[fSlice][r];
589
590     AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
591     tempPt->fRow = row;
592     tempPt->fNDigit = 0;
593
594     if(n!=-1){//data on that row
595       Int_t lslice,lrow;
596       fDigitsTree->GetEvent(n);
597       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
598       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
599       if(lrow!=r){
600         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
601           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
602         continue;
603       }
604
605       // set the correct row no and digit count
606       tempPt->fRow = row;
607       tempPt->fNDigit = ndigits[lrow];
608
609       Int_t localcount=0;
610       for (bool bHaveData=fDigits->First();
611            bHaveData;
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();
619
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???
624
625         if(localcount >= ndigits[lrow])
626           LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliDigits2Binary","Memory")
627             <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
628             <<ndigits[lrow]<<ENDLOG;
629         
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);
636         localcount++;
637       }
638     }
639
640     Byte_t *tmp = (Byte_t*)tempPt;
641     Int_t blockSize = sizeof(AliHLTTPCDigitRowData)
642       + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
643     tmp += blockSize;
644     tempPt = (AliHLTTPCDigitRowData*)tmp;
645   }
646   assert((Byte_t*)tempPt==((Byte_t*)data)+bufferSize);
647   delete [] ndigits;
648   return data;
649 }
650
651 int AliHLTTPCFileHandler::AliDigits2Altro(Int_t event, Byte_t* tgtBuffer, UInt_t tgtSize)
652 {
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
656   int iResult=0;
657
658   if(!fInAli){
659     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Altro","File")
660     <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
661     return 0; 
662   }
663
664   if (!tgtBuffer) {
665     return -EINVAL;
666   }
667
668   if(!fDigitsTree)
669     if(!GetDigitsTree(event)) return 0;
670
671   UShort_t dig;
672   Int_t time=0;
673   Int_t pad=0;
674   Int_t sector=0;
675
676   AliHLTTPCMapping mapper(fPatch);
677   AliHLTAltroEncoder encoder;
678   encoder.SetBuffer(tgtBuffer, tgtSize);
679
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
684   // in the TPC
685   // This loop filters the pad rows according to the slice no set via Init
686
687   assert(fRowMax<fgkNRow);
688   for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow && iResult>=0;r++){
689     Int_t n=fIndex[fSlice][r];
690
691     Int_t row=0;
692     Int_t rowOffset=0;
693     AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
694     AliHLTTPCTransform::Slice2Sector(fSlice,AliHLTTPCTransform::GetFirstRow(fPatch),sector,rowOffset);
695
696     if(n!=-1){//data on that row
697       Int_t lslice,lrow;
698       fDigitsTree->GetEvent(n);
699       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
700       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
701       if(lrow!=r){
702         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Altro","Row")
703           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
704         continue;
705       }
706
707       Int_t channelAddress=-1;
708       fDigits->First();
709       do {
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();
716         
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);
722       }
723     }
724   }
725
726   if (iResult>=0) {
727     iResult=(encoder.GetTotal40bitWords()*5)/4;
728   }
729
730   return iResult;
731 }
732
733 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
734 {
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).
740   
741   AliHLTTPCDigitRowData *data = 0;
742   nrow=0;
743   
744   if(!fInAli){
745     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
746     <<"No Input avalible: Pointer to TFile == NULL"<<ENDLOG;
747     return 0; 
748   }
749   if(eventmerge == kTRUE && event >= 1024)
750     {
751       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","TrackIDs")
752         <<"Too many events if you want to merge!"<<ENDLOG;
753       return 0;
754     }
755   delete fDigits;
756   fDigits=0;
757   /* Dont understand why we have to do 
758      reload the tree, but otherwise the code crashes */
759   fDigitsTree=0;
760   if(!GetDigitsTree(event)) return 0;
761
762   UShort_t dig;
763   Int_t time,pad,sector,row;
764   Int_t nrows=0;
765   Int_t ndigitcount=0;
766   Int_t entries = (Int_t)fDigitsTree->GetEntries();
767   if(entries==0) {
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++){
775       tempPt->fRow = r;
776       tempPt->fNDigit = 0;
777       tempPt++;
778     }
779     return data;
780   }
781   Int_t * ndigits = new Int_t[fRowMax+1];
782   Int_t lslice,lrow;
783   Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
784   Float_t xyz[3];
785
786   for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
787     Int_t n=fIndex[fSlice][r];
788
789     ndigits[r] = 0;
790
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;
799         continue;
800       }
801
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++){
806           pad=i;
807           time=j;
808           dig = fDigits->GetDigitFast(time,pad);
809           if(dig <= zerosupval) continue;
810           if(dig >= AliHLTTPCTransform::GetADCSat())
811             dig = AliHLTTPCTransform::GetADCSat();
812
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)
819               continue;
820               
821           //Boundaries:
822           if(i==0) //pad==0
823             {
824               if(j < fDigits->GetNRows()-1 && j > 0) 
825                 {
826                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
827                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
828                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
829                     continue;
830                 }
831               else if(j > 0)
832                 {
833                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
834                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
835                     continue;
836                 }
837             }
838           if(j==0)
839             {
840               if(i < fDigits->GetNCols()-1 && i > 0)
841                 {
842                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
843                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
844                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
845                     continue;
846                 }
847               else if(i > 0)
848                 {
849                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
850                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
851                     continue;
852                 }
853             }
854
855           if(i==fDigits->GetNCols()-1)
856             {
857               if(j>0 && j<fDigits->GetNRows()-1)
858                 {
859                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
860                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
861                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
862                     continue;
863                 }
864               else if(j==0 && j<fDigits->GetNRows()-1)
865                 {
866                   if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
867                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
868                     continue;
869                 }
870               else 
871                 {
872                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
873                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
874                     continue;
875                 }
876             }
877         
878           if(j==fDigits->GetNRows()-1)
879             {
880               if(i>0 && i<fDigits->GetNCols()-1)
881                 {
882                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
883                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
884                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
885                     continue;
886                 }
887               else if(i==0 && fDigits->GetNCols()-1)
888                 {
889                   if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
890                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
891                     continue;
892                 }
893               else 
894                 {
895                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
896                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
897                     continue;
898                 }
899             }
900
901           AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
902           //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
903           //      continue; 
904               
905           ndigits[lrow]++; //for this row only
906           ndigitcount++;   //total number of digits to be published
907         }
908       }
909     }
910     nrows++;
911   }
912   
913   Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
914     + nrows*sizeof(AliHLTTPCDigitRowData);
915
916   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Digits")
917     <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
918   
919   data=(AliHLTTPCDigitRowData*) Allocate(size);
920   nrow = (UInt_t)nrows;
921   AliHLTTPCDigitRowData *tempPt = data;
922  
923   for(Int_t r=fRowMin;r<=fRowMax;r++){
924     Int_t n=fIndex[fSlice][r];
925     tempPt->fRow = r;
926     tempPt->fNDigit = 0;
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);
931
932       if(lrow!=r){
933         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
934           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
935         continue;
936       }
937
938       tempPt->fNDigit = ndigits[lrow];
939
940       Int_t localcount=0;
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++){
945           pad=i;
946           time=j;
947           dig = fDigits->GetDigitFast(time,pad);
948           if(dig <= zerosupval) continue;
949           if(dig >= AliHLTTPCTransform::GetADCSat())
950             dig = AliHLTTPCTransform::GetADCSat();
951               
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)
958               continue;
959           
960           //Boundaries:
961           if(i==0) //pad ==0
962             {
963               if(j < fDigits->GetNRows()-1 && j > 0) 
964                 {
965                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
966                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
967                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
968                     continue;
969                 }
970               else if(j > 0)
971                 {
972                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
973                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
974                     continue;
975                 }
976             }
977           if(j==0)
978             {
979               if(i < fDigits->GetNCols()-1 && i > 0)
980                 {
981                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
982                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
983                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
984                     continue;
985                 }
986               else if(i > 0)
987                 {
988                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
989                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
990                     continue;
991                 }
992             }
993         
994           if(i == fDigits->GetNCols()-1)
995             {
996               if(j>0 && j<fDigits->GetNRows()-1)
997                 {
998                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
999                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1000                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1001                     continue;
1002                 }
1003               else if(j==0 && j<fDigits->GetNRows()-1)
1004                 {
1005                   if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1006                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1007                     continue;
1008                 }
1009               else 
1010                 {
1011                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
1012                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1013                     continue;
1014                 }
1015             }
1016           if(j==fDigits->GetNRows()-1)
1017             {
1018               if(i>0 && i<fDigits->GetNCols()-1)
1019                 {
1020                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1021                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1022                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1023                     continue;
1024                 }
1025               else if(i==0 && fDigits->GetNCols()-1)
1026                 {
1027                   if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1028                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1029                     continue;
1030                 }
1031               else 
1032                 {
1033                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1034                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1035                     continue;
1036                 }
1037             }
1038         
1039           AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
1040           //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
1041           //        continue;
1042           
1043           if(localcount >= ndigits[lrow])
1044             LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliAltroDigits2Binary","Memory")
1045               <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
1046               <<ndigits[lrow]<<ENDLOG;
1047         
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);
1062             }
1063           localcount++;
1064         }
1065       }
1066     }
1067     Byte_t *tmp = (Byte_t*)tempPt;
1068     tmp += sizeof(AliHLTTPCDigitRowData)
1069       + ndigits[r]*sizeof(AliHLTTPCDigitData);
1070     tempPt = (AliHLTTPCDigitRowData*)tmp;
1071   }
1072   delete [] ndigits;
1073   return data;
1074 }
1075  
1076 Bool_t AliHLTTPCFileHandler::GetDigitsTree(Int_t event)
1077 {
1078   //Connects to the TPC digit tree in the AliROOT file.
1079   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1080   if(!tpcLoader){
1081     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::GetDigitsTree","File")
1082     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1083     return kFALSE;
1084   }
1085   fInAli->GetEvent(event);
1086   tpcLoader->LoadDigits();
1087   fDigitsTree = tpcLoader->TreeD();
1088   if(!fDigitsTree) 
1089     {
1090       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::GetDigitsTree","Digits Tree")
1091         <<AliHLTTPCLog::kHex<<"Error getting digitstree "<<(void*)fDigitsTree<<ENDLOG;
1092       return kFALSE;
1093     }
1094   fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
1095
1096   if(!fIndexCreated) return CreateIndex();
1097   else return kTRUE;
1098 }
1099
1100 ///////////////////////////////////////// Point IO  
1101 Bool_t AliHLTTPCFileHandler::AliPoints2Binary(Int_t eventn)
1102 {
1103   //points to binary
1104   Bool_t out = kTRUE;
1105   UInt_t npoint;
1106   AliHLTTPCSpacePointData *data = AliPoints2Memory(npoint,eventn);
1107   out = Memory2Binary(npoint,data);
1108   Free();
1109   return out;
1110 }
1111
1112 #if 0
1113 // Is this really still used : JMT 2013-03-03
1114 AliHLTTPCSpacePointData * AliHLTTPCFileHandler::AliPoints2Memory(UInt_t & npoint,Int_t eventn)
1115 {
1116   //points to memory
1117   AliHLTTPCSpacePointData *data = 0;
1118   npoint=0;
1119   if(!fInAli){
1120     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1121     <<"No Input avalible: no object fInAli"<<ENDLOG;
1122     return 0;
1123   }
1124
1125   TDirectory *savedir = gDirectory;
1126   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1127   if(!tpcLoader){
1128     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1129     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1130     return 0;
1131   }
1132   fInAli->GetEvent(eventn);
1133   tpcLoader->LoadRecPoints();
1134
1135   AliTPCClustersArray carray;
1136   carray.Setup(fParam);
1137   carray.SetClusterType("AliTPCclusterMI");
1138   Bool_t clusterok = carray.ConnectTree(tpcLoader->TreeR());
1139
1140   if(!clusterok) return 0;
1141
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()];
1146   Int_t sum=0;
1147
1148   Int_t lslice,lrow;
1149   for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1150     AliSegmentID *s = carray.LoadEntry(i);
1151     Int_t sector,row;
1152     fParam->AdjustSectorRow(s->GetID(),sector,row);
1153     rows[i] = row;
1154     sects[i] = sector;
1155     clusterrow[i] = 0;
1156     AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1157     if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
1158     clusterrow[i] = carray.GetRow(sector,row);
1159     if(clusterrow[i])
1160       sum+=clusterrow[i]->GetArray()->GetEntriesFast();
1161   }
1162   UInt_t size = sum*sizeof(AliHLTTPCSpacePointData);
1163
1164   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1165   <<AliHLTTPCLog::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
1166
1167   data = (AliHLTTPCSpacePointData *) Allocate(size);
1168   npoint = sum;
1169   UInt_t n=0; 
1170   Int_t pat=fPatch;
1171   if(fPatch==-1)
1172     pat=0;
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();
1189 #ifdef do_mc
1190       data[n].fTrackID[0] = c->GetLabel(0);
1191       data[n].fTrackID[1] = c->GetLabel(1);
1192       data[n].fTrackID[2] = c->GetLabel(2);
1193 #endif
1194       if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
1195       n++;
1196     }
1197   }
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);
1203   }
1204
1205   delete [] clusterrow;
1206   delete [] rows;
1207   delete [] sects;
1208   savedir->cd();   
1209
1210   return data;
1211 }
1212 #endif