]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCFileHandler.cxx
minor coverity defect: added protection for self-assignment
[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 <AliTPCClustersArray.h>
47 #include <AliTPCcluster.h>
48 #include <AliTPCClustersRow.h>
49 #include <AliSimDigits.h>
50 #include "AliCDBManager.h"
51 #include "AliCDBEntry.h"
52
53 #include "AliHLTTPCLogging.h"
54 #include "AliHLTTPCTransform.h"
55 #include "AliHLTTPCDigitData.h"
56 //#include "AliHLTTPCTrackSegmentData.h"
57 #include "AliHLTTPCSpacePointData.h"
58 //#include "AliHLTTPCTrackArray.h"
59 #include "AliHLTTPCFileHandler.h"
60 #include "AliHLTTPCMapping.h"
61 #include "AliHLTAltroEncoder.h"
62
63 #if __GNUC__ >= 3
64 using namespace std;
65 #endif
66
67 /**
68 <pre>
69 //_____________________________________________________________
70 // AliHLTTPCFileHandler
71 //
72 // The HLT ROOT <-> binary files handling class
73 //
74 // This class provides the interface between AliROOT files,
75 // and HLT binary files. It should be used for converting 
76 // TPC data stored in AliROOT format (outputfile from a simulation),
77 // into the data format currently used by in the HLT framework. 
78 // This enables the possibility to always use the same data format, 
79 // whether you are using a binary file as an input, or a AliROOT file.
80 //
81 // For example on how to create binary files from a AliROOT simulation,
82 // see example macro exa/Binary.C.
83 //
84 // For reading a AliROOT file into HLT format in memory, do the following:
85 //
86 // AliHLTTPCFileHandler file;
87 // file.Init(slice,patch);
88 // file.SetAliInput("galice.root");
89 // AliHLTTPCDigitRowData *dataPt = (AliHLTTPCDigitRowData*)file.AliDigits2Memory(nrows,eventnr);
90 // 
91 // All the data are then stored in memory and accessible via the pointer dataPt.
92 // Accesing the data is then identical to the example 1) showed in AliHLTTPCMemHandler class.
93 //
94 // For converting the data back, and writing it to a new AliROOT file do:
95 //
96 // AliHLTTPCFileHandler file;
97 // file.Init(slice,patch);
98 // file.SetAliInput("galice.root");
99 // file.Init(slice,patch,NumberOfRowsInPatch);
100 // file.AliDigits2RootFile(dataPt,"new_galice.root");
101 // file.CloseAliInput();
102 </pre>
103 */
104
105 ClassImp(AliHLTTPCFileHandler)
106
107 AliHLTTPCFileHandler::AliHLTTPCFileHandler(Bool_t b)
108   :
109   fInAli(NULL),
110   fUseRunLoader(kFALSE),
111   fParam(NULL),
112   fDigits(NULL),
113   fDigitsTree(NULL),
114   fMC(NULL),
115   fIndexCreated(kFALSE),
116   fUseStaticIndex(b)
117 {
118   //Default constructor
119
120   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++)
121     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++) 
122       fIndex[i][j]=-1;
123
124   if(fUseStaticIndex&&!fgStaticIndexCreated) CleanStaticIndex();
125 }
126
127 AliHLTTPCFileHandler::~AliHLTTPCFileHandler()
128 {
129   //Destructor
130   if(fMC) CloseMCOutput();
131   FreeDigitsTree();
132   if(fInAli) CloseAliInput();
133 }
134
135 // of course on start up the index is not created
136 Bool_t AliHLTTPCFileHandler::fgStaticIndexCreated=kFALSE;
137 Int_t  AliHLTTPCFileHandler::fgStaticIndex[36][159]; 
138
139 void AliHLTTPCFileHandler::CleanStaticIndex() 
140
141   // use this static call to clean static index after
142   // running over one event
143   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
144     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
145       fgStaticIndex[i][j]=-1;
146   }
147   fgStaticIndexCreated=kFALSE;
148 }
149
150 Int_t AliHLTTPCFileHandler::SaveStaticIndex(Char_t *prefix,Int_t event) 
151
152   // use this static call to store static index after
153   if(!fgStaticIndexCreated) return -1;
154
155   const int fnamelen=1024;
156   Char_t fname[fnamelen];
157   if(prefix)
158     snprintf(fname,fnamelen, "%s-%d.txt",prefix,event);
159   else
160     snprintf(fname,fnamelen, "TPC.Digits.staticindex-%d.txt",event);
161
162   ofstream file(fname,ios::trunc);
163   if(!file.good()) return -1;
164
165   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
166     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
167       file << fgStaticIndex[i][j] << " ";
168     file << endl;
169   }
170   file.close();
171   return 0;
172 }
173
174 Int_t AliHLTTPCFileHandler::LoadStaticIndex(Char_t *prefix,Int_t event) 
175
176   // use this static call to store static index after
177   if(fgStaticIndexCreated){
178       LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::LoadStaticIndex","Inxed")
179         <<"Static index already created, will overwrite"<<ENDLOG;
180       CleanStaticIndex();
181   }
182
183   const int fnamelen=1024;
184   Char_t fname[fnamelen];
185   if(prefix)
186     snprintf(fname,fnamelen,"%s-%d.txt",prefix,event);
187   else
188     snprintf(fname,fnamelen,"TPC.Digits.staticindex-%d.txt",event);
189
190   ifstream file(fname);
191   if(!file.good()) return -1;
192
193   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
194     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
195       file >> fgStaticIndex[i][j];
196   }
197   file.close();
198
199   fgStaticIndexCreated=kTRUE;
200   return 0;
201 }
202
203 void AliHLTTPCFileHandler::FreeDigitsTree()
204
205   //free digits tree
206   if (fDigits) {
207     delete fDigits;
208   }
209   fDigits=0;
210   fDigitsTree=0;
211
212   for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
213     for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
214       fIndex[i][j]=-1;
215   }
216   fIndexCreated=kFALSE;
217 }
218
219 Bool_t AliHLTTPCFileHandler::SetMCOutput(Char_t *name)
220
221   //set mc input
222   fMC = fopen(name,"w");
223   if(!fMC){
224     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
225       <<"Pointer to File = 0x0 "<<ENDLOG;
226     return kFALSE;
227   }
228   return kTRUE;
229 }
230
231 Bool_t AliHLTTPCFileHandler::SetMCOutput(FILE *file)
232
233   //set mc output
234   fMC = file;
235   if(!fMC){
236     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
237       <<"Pointer to File = 0x0 "<<ENDLOG;
238     return kFALSE;
239   }
240   return kTRUE;
241 }
242
243 void AliHLTTPCFileHandler::CloseMCOutput()
244
245   //close mc output
246   if(!fMC){
247     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseMCOutPut","File Close")
248       <<"Nothing to Close"<<ENDLOG;
249     return;
250   }
251   fclose(fMC);
252   fMC =0;
253 }
254
255 Bool_t AliHLTTPCFileHandler::SetAliInput()
256
257   //set ali input
258
259   // fParam is in all cases an external object
260   const char* cdbEntry="TPC/Calib/Parameters";
261   AliCDBManager* pMan=AliCDBManager::Instance();
262   if (pMan) {
263     AliCDBEntry *pEntry = pMan->Get(cdbEntry);
264     if (pEntry==NULL || 
265         pEntry->GetObject()==NULL ||
266         (fParam=dynamic_cast<AliTPCParam*>(pEntry->GetObject()))==NULL) {
267       LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
268         <<"can not load AliTPCParam object from OCDB entry " << cdbEntry <<ENDLOG;
269     }
270   }
271   if (!fParam) {
272   // the old solution until Nov 2008
273   fInAli->CdGAFile();
274   fParam = (AliTPCParam*)gFile->Get("75x40_100x60_150x60");
275   if(!fParam){
276     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
277       <<"No TPC parameters found in \""<<gFile->GetName()
278       <<"\", creating standard parameters "
279       <<"which might not be what you want!"<<ENDLOG;
280     fParam = new AliTPCParamSR;
281   }
282   }
283   if(!fParam){ 
284     LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
285       <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<gFile->GetName()<<ENDLOG;
286     return kFALSE;
287   }
288
289   return kTRUE;
290 }
291
292 Bool_t AliHLTTPCFileHandler::SetAliInput(Char_t *name)
293
294   //Open the AliROOT file with name.
295   fInAli= AliRunLoader::Open(name);
296   if(!fInAli){
297     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
298     <<"Pointer to fInAli = 0x0 "<<ENDLOG;
299     return kFALSE;
300   }
301   return SetAliInput();
302 }
303
304 Bool_t AliHLTTPCFileHandler::SetAliInput(AliRunLoader *runLoader)
305
306   //set ali input as runloader
307   if(!runLoader){
308     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
309       <<"invalid agument: pointer to AliRunLoader NULL "<<ENDLOG;
310     return kFALSE;
311   }
312   if (fInAli!=NULL && fInAli!=runLoader) {
313     LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
314     <<"Pointer to AliRunLoader already set"<<ENDLOG;
315     return kFALSE;
316   }
317   fInAli=runLoader;
318   fUseRunLoader = kTRUE;
319   return SetAliInput();
320 }
321
322 void AliHLTTPCFileHandler::CloseAliInput()
323
324   //close ali input
325   if(fUseRunLoader) return;
326   if(!fInAli){
327     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseAliInput","RunLoader")
328       <<"Nothing to Close"<<ENDLOG;
329     return;
330   }
331
332   delete fInAli;
333   fInAli = 0;
334 }
335
336 Bool_t AliHLTTPCFileHandler::IsDigit(Int_t event)
337 {
338   //Check if there is a TPC digit tree in the current file.
339   //Return kTRUE if tree was found, and kFALSE if not found.
340   
341   if(!fInAli){
342     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::IsDigit","File")
343     <<"Pointer to fInAli = 0x0 "<<ENDLOG;
344     return kTRUE;  //maybe you are using binary input which is Digits!
345   }
346   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
347   if(!tpcLoader){
348     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandlerNewIO::IsDigit","File")
349     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
350     return kFALSE;
351   }
352   fInAli->GetEvent(event);
353   tpcLoader->LoadDigits();
354   TTree *t=tpcLoader->TreeD();
355   if(t){
356     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
357     <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
358     return kTRUE;
359   }
360   else{
361     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
362     <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
363     return kFALSE;
364   }
365 }
366
367 ///////////////////////////////////////// Digit IO  
368 Bool_t AliHLTTPCFileHandler::AliDigits2BinaryFile(Int_t event,Bool_t altro)
369 {
370   //save alidigits as binary
371   Bool_t out = kTRUE;
372   UInt_t nrow;
373   AliHLTTPCDigitRowData* data = 0;
374   if(altro)
375     data = AliAltroDigits2Memory(nrow,event);
376   else
377     data = AliDigits2Memory(nrow,event);
378   out = Memory2BinaryFile(nrow,data);
379   Free();
380   return out;
381 }
382
383 Bool_t AliHLTTPCFileHandler::AliDigits2CompBinary(Int_t event,Bool_t altro)
384 {
385   //Convert AliROOT TPC data, into HLT data format.
386   //event specifies the event you want in the aliroot file.
387   
388   Bool_t out = kTRUE;
389   UInt_t ndigits=0;
390   AliHLTTPCDigitRowData *digits=0;
391   if(altro)
392     digits = AliAltroDigits2Memory(ndigits,event);
393   else
394     digits = AliDigits2Memory(ndigits,event);
395   out = Memory2CompBinary(ndigits,digits);
396   Free();
397   return out;
398 }
399
400 Bool_t AliHLTTPCFileHandler::CreateIndex()
401 {
402   //create the access index or copy from static index
403   fIndexCreated=kFALSE;
404
405   if(!fgStaticIndexCreated || !fUseStaticIndex) { //we have to create index 
406     LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
407       <<"Starting to create index, this can take a while."<<ENDLOG;
408
409     //Int_t lslice,lrow;
410     for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
411       Int_t sector, row;
412       Int_t lslice,lrow;
413       fDigitsTree->GetEvent(n);
414       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
415       if(!AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row)){
416         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::CreateIndex","Slice/Row")
417           <<AliHLTTPCLog::kDec<<"Index could not be created. Wrong values "
418           <<sector<<" "<<row<<ENDLOG;
419         return kFALSE;
420       }
421       // this is just to make sure the same array dimensions are
422       // used as in the AliHLTTPCTransform class. The check for
423       // correct bounds is done in AliHLTTPCTransform::Sector2Slice
424       assert(lslice>=0 && lslice<fgkNSlice);
425       assert(lrow>=0 && lrow<fgkNRow);
426       if(fIndex[lslice][lrow]==-1) {
427         fIndex[lslice][lrow]=n;
428       }
429     }
430     assert(AliHLTTPCTransform::GetNSlice()==fgkNSlice);
431     assert(AliHLTTPCTransform::GetNRows()==fgkNRow);
432     if(fUseStaticIndex) { // create static index
433       for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
434         for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
435           fgStaticIndex[islice][irow]=fIndex[islice][irow];
436       }
437       fgStaticIndexCreated=kTRUE; //remember that index has been created
438     }
439
440   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
441     <<"Index successfully created."<<ENDLOG;
442
443   } else if(fUseStaticIndex) { //simply copy static index
444     for(Int_t islice=0;islice<AliHLTTPCTransform::GetNSlice() && islice<fgkNSlice;islice++){
445       for(Int_t irow=0;irow<AliHLTTPCTransform::GetNRows() && irow<fgkNRow;irow++)
446         fIndex[islice][irow]=fgStaticIndex[islice][irow];
447     }
448
449   LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
450     <<"Index successfully taken from static copy."<<ENDLOG;
451   }
452   fIndexCreated=kTRUE;
453   return kTRUE;
454 }
455
456 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event, Byte_t* tgtBuffer, UInt_t *pTgtSize)
457 {
458   //Read data from AliROOT file into memory, and store it in the HLT data format
459   //in the provided buffer or an allocated buffer.
460   //Returns a pointer to the data.
461
462   AliHLTTPCDigitRowData *data = 0;
463   nrow=0;
464   
465   if(!fInAli){
466     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
467     <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
468     return 0; 
469   }
470
471   if(!fDigitsTree)
472     if(!GetDigitsTree(event)) return 0;
473
474   UShort_t dig;
475   Int_t time,pad,sector,row;
476   Int_t nrows=0;
477   Int_t ndigitcount=0;
478   Int_t entries = (Int_t)fDigitsTree->GetEntries();
479   if(entries==0) {
480     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","ndigits")
481       <<"No TPC digits (entries==0)!"<<ENDLOG;
482     nrow = (UInt_t)(fRowMax-fRowMin+1);
483     UInt_t size = nrow*sizeof(AliHLTTPCDigitRowData);
484     if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
485       if (size<=*pTgtSize) {
486         data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
487       } else {
488       }
489     } else {
490       data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(size));
491     }
492     AliHLTTPCDigitRowData *tempPt = data;
493     if (data) {
494     if (pTgtSize) *pTgtSize=size;
495     for(Int_t r=fRowMin;r<=fRowMax;r++){
496       tempPt->fRow = r;
497       tempPt->fNDigit = 0;
498       tempPt++;
499     }
500     }
501     return data;
502   }
503
504   Int_t * ndigits = new Int_t[fRowMax+1];
505   memset(ndigits, 0, (fRowMax+1)*sizeof(Int_t));
506   Float_t xyz[3];
507
508   // The digits of the current event have been indexed: all digits are organized in
509   // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
510   // are stored in the digit tree.
511   // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
512   // in the TPC
513   // This loop filters the pad rows according to the slice no set via Init
514   assert(fRowMax<fgkNRow);
515   for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
516     Int_t n=fIndex[fSlice][r];
517     if(n!=-1){ // there is data on that row available
518       Int_t lslice,lrow;
519       fDigitsTree->GetEvent(n);
520       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
521       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
522 //       LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
523 //      << "Sector "<<sector<<" Row " << row << " Slice " << lslice << " lrow " << lrow<<ENDLOG;
524
525       if(lrow!=r){
526         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
527           <<AliHLTTPCLog::kDec<<"Rows in slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
528         continue;
529       }
530
531       ndigits[lrow] = 0;
532       for (bool bHaveData=fDigits->First();
533            bHaveData;
534            bHaveData=fDigits->Next()) {
535         time=fDigits->CurrentRow();
536         pad=fDigits->CurrentColumn();
537         dig = fDigits->GetDigit(time,pad);
538         if(dig <= fParam->GetZeroSup()) continue;
539         if(dig >= AliHLTTPCTransform::GetADCSat())
540           dig = AliHLTTPCTransform::GetADCSat();
541
542         // if we switch to AliTPCTransform, this maybe needs to be 
543         // adjusted as well
544         AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
545         //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
546         //        continue; // why 230???
547
548         ndigits[lrow]++; //for this row only
549         ndigitcount++;   //total number of digits to be published
550
551       }
552       //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
553     }
554     //see comment below//nrows++;
555   }
556   // Matthias 05.11.2007
557   // The question is whether we should always return a AliHLTTPCDigitRowData
558   // for each row, even the empty ones or only for the ones filled with data.
559   // the AliHLTTPCDigitReaderUnpacked as the counnterpart so far assumes 
560   // empty RawData structs for empty rows. But some of the code here implies
561   // the latter approach, e.g. the count of nrows in the loop above (now
562   // commented). At least the two loops were not consistent, it's fixed now.
563   nrows=fRowMax-fRowMin+1;
564
565   UInt_t bufferSize = sizeof(AliHLTTPCDigitData)*ndigitcount
566     + nrows*sizeof(AliHLTTPCDigitRowData);
567
568   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
569     << "Found "<<ndigitcount<<" Digits in " << nrows << " rows out of [" << fRowMin << "," << fRowMax <<"]"<<ENDLOG;
570
571   if (tgtBuffer!=NULL && pTgtSize!=NULL && *pTgtSize>0) {
572     if (bufferSize<=*pTgtSize) {
573       data=reinterpret_cast<AliHLTTPCDigitRowData*>(tgtBuffer);
574     } else {
575     }
576   } else if (bufferSize>0) {
577     data=reinterpret_cast<AliHLTTPCDigitRowData*>(Allocate(bufferSize));
578   }
579   if (pTgtSize) *pTgtSize=bufferSize;
580   if (data==NULL) {
581     delete [] ndigits;
582     return NULL;
583   }
584   nrow = (UInt_t)nrows;
585   AliHLTTPCDigitRowData *tempPt = data;
586   memset(data, 0, bufferSize);
587
588   for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
589     Int_t n=fIndex[fSlice][r];
590
591     AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
592     tempPt->fRow = row;
593     tempPt->fNDigit = 0;
594
595     if(n!=-1){//data on that row
596       Int_t lslice,lrow;
597       fDigitsTree->GetEvent(n);
598       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
599       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
600       if(lrow!=r){
601         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
602           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
603         continue;
604       }
605
606       // set the correct row no and digit count
607       tempPt->fRow = row;
608       tempPt->fNDigit = ndigits[lrow];
609
610       Int_t localcount=0;
611       for (bool bHaveData=fDigits->First();
612            bHaveData;
613            bHaveData=fDigits->Next()) {
614         time=fDigits->CurrentRow();
615         pad=fDigits->CurrentColumn();
616         dig = fDigits->GetDigit(time,pad);
617         if (dig <= fParam->GetZeroSup()) continue;
618         if(dig >= AliHLTTPCTransform::GetADCSat())
619           dig = AliHLTTPCTransform::GetADCSat();
620
621         //Exclude data outside cone:
622         AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
623         //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
624         //        continue; // why 230???
625
626         if(localcount >= ndigits[lrow])
627           LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliDigits2Binary","Memory")
628             <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
629             <<ndigits[lrow]<<ENDLOG;
630         
631         tempPt->fDigitData[localcount].fCharge=dig;
632         tempPt->fDigitData[localcount].fPad=pad;
633         tempPt->fDigitData[localcount].fTime=time;
634         tempPt->fDigitData[localcount].fTrackID[0] = fDigits->GetTrackID(time,pad,0);
635         tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
636         tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
637         localcount++;
638       }
639     }
640
641     Byte_t *tmp = (Byte_t*)tempPt;
642     Int_t blockSize = sizeof(AliHLTTPCDigitRowData)
643       + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
644     tmp += blockSize;
645     tempPt = (AliHLTTPCDigitRowData*)tmp;
646   }
647   assert((Byte_t*)tempPt==((Byte_t*)data)+bufferSize);
648   delete [] ndigits;
649   return data;
650 }
651
652 int AliHLTTPCFileHandler::AliDigits2Altro(Int_t event, Byte_t* tgtBuffer, UInt_t tgtSize)
653 {
654   //Read data from AliROOT file into memory, and store it in the ALTRO data format
655   //in the provided buffer 
656   //Returns: size of the encoded data in bytes
657   int iResult=0;
658
659   if(!fInAli){
660     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Altro","File")
661     <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
662     return 0; 
663   }
664
665   if (!tgtBuffer) {
666     return -EINVAL;
667   }
668
669   if(!fDigitsTree)
670     if(!GetDigitsTree(event)) return 0;
671
672   UShort_t dig;
673   Int_t time=0;
674   Int_t pad=0;
675   Int_t sector=0;
676
677   AliHLTTPCMapping mapper(fPatch);
678   AliHLTAltroEncoder encoder;
679   encoder.SetBuffer(tgtBuffer, tgtSize);
680
681   // The digits of the current event have been indexed: all digits are organized in
682   // rows, all digits of one row are stored in a AliSimDigits object (fDigit) which
683   // are stored in the digit tree.
684   // The index map relates the AliSimDigits objects in the tree to dedicated pad rows
685   // in the TPC
686   // This loop filters the pad rows according to the slice no set via Init
687
688   assert(fRowMax<fgkNRow);
689   for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow && iResult>=0;r++){
690     Int_t n=fIndex[fSlice][r];
691
692     Int_t row=0;
693     Int_t rowOffset=0;
694     AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
695     AliHLTTPCTransform::Slice2Sector(fSlice,AliHLTTPCTransform::GetFirstRow(fPatch),sector,rowOffset);
696
697     if(n!=-1){//data on that row
698       Int_t lslice,lrow;
699       fDigitsTree->GetEvent(n);
700       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
701       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
702       if(lrow!=r){
703         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Altro","Row")
704           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
705         continue;
706       }
707
708       Int_t channelAddress=-1;
709       fDigits->First();
710       do {
711         time=fDigits->CurrentRow();
712         pad=fDigits->CurrentColumn();
713         dig = fDigits->GetDigit(time,pad);
714         if (dig <= fParam->GetZeroSup()) continue;
715         if(dig >= AliHLTTPCTransform::GetADCSat())
716           dig = AliHLTTPCTransform::GetADCSat();
717         
718         channelAddress=mapper.GetHwAddress(row-rowOffset, pad);
719         iResult=encoder.AddChannelSignal(dig, time, channelAddress);
720       } while (fDigits->Next() && iResult>=0);
721       if (iResult>=0 && channelAddress>=0) {
722         iResult=encoder.SetChannel(channelAddress);
723       }
724     }
725   }
726
727   if (iResult>=0) {
728     iResult=(encoder.GetTotal40bitWords()*5)/4;
729   }
730
731   return iResult;
732 }
733
734 AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
735 {
736   //Read data from AliROOT file into memory, and store it in the HLT data format.
737   //Returns a pointer to the data.
738   //This functions filter out single timebins, which is noise. The timebins which
739   //are removed are timebins which have the 4 zero neighbours; 
740   //(pad-1,time),(pad+1,time),(pad,time-1),(pad,time+1).
741   
742   AliHLTTPCDigitRowData *data = 0;
743   nrow=0;
744   
745   if(!fInAli){
746     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
747     <<"No Input avalible: Pointer to TFile == NULL"<<ENDLOG;
748     return 0; 
749   }
750   if(eventmerge == kTRUE && event >= 1024)
751     {
752       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","TrackIDs")
753         <<"Too many events if you want to merge!"<<ENDLOG;
754       return 0;
755     }
756   delete fDigits;
757   fDigits=0;
758   /* Dont understand why we have to do 
759      reload the tree, but otherwise the code crashes */
760   fDigitsTree=0;
761   if(!GetDigitsTree(event)) return 0;
762
763   UShort_t dig;
764   Int_t time,pad,sector,row;
765   Int_t nrows=0;
766   Int_t ndigitcount=0;
767   Int_t entries = (Int_t)fDigitsTree->GetEntries();
768   if(entries==0) {
769     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","ndigits")
770       <<"No TPC digits (entries==0)!"<<ENDLOG;
771     nrow = (UInt_t)(fRowMax-fRowMin+1);
772     Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
773     data=(AliHLTTPCDigitRowData*) Allocate(size);
774     AliHLTTPCDigitRowData *tempPt = data;
775     for(Int_t r=fRowMin;r<=fRowMax;r++){
776       tempPt->fRow = r;
777       tempPt->fNDigit = 0;
778       tempPt++;
779     }
780     return data;
781   }
782   Int_t * ndigits = new Int_t[fRowMax+1];
783   Int_t lslice,lrow;
784   Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
785   Float_t xyz[3];
786
787   for(Int_t r=fRowMin;r<=fRowMax && r<fgkNRow;r++){
788     Int_t n=fIndex[fSlice][r];
789
790     ndigits[r] = 0;
791
792     if(n!=-1){//data on that row
793       fDigitsTree->GetEvent(n);
794       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
795       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
796       //cout << lslice << " " << fSlice << " " << lrow << " " << r << " " << sector << " " << row << endl;
797       if((lslice!=fSlice)||(lrow!=r)){
798         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
799           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
800         continue;
801       }
802
803       fDigits->ExpandBuffer();
804       fDigits->ExpandTrackBuffer();
805       for(Int_t i=0; i<fDigits->GetNCols(); i++){
806         for(Int_t j=0; j<fDigits->GetNRows(); j++){
807           pad=i;
808           time=j;
809           dig = fDigits->GetDigitFast(time,pad);
810           if(dig <= zerosupval) continue;
811           if(dig >= AliHLTTPCTransform::GetADCSat())
812             dig = AliHLTTPCTransform::GetADCSat();
813
814           //Check for single timebins, and remove them because they are noise for sure.
815           if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
816             if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
817                fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
818                fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
819                fDigits->GetDigitFast(time,pad+1)<=zerosupval)
820               continue;
821               
822           //Boundaries:
823           if(i==0) //pad==0
824             {
825               if(j < fDigits->GetNRows()-1 && j > 0) 
826                 {
827                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
828                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
829                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
830                     continue;
831                 }
832               else if(j > 0)
833                 {
834                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
835                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
836                     continue;
837                 }
838             }
839           if(j==0)
840             {
841               if(i < fDigits->GetNCols()-1 && i > 0)
842                 {
843                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
844                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
845                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
846                     continue;
847                 }
848               else if(i > 0)
849                 {
850                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
851                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
852                     continue;
853                 }
854             }
855
856           if(i==fDigits->GetNCols()-1)
857             {
858               if(j>0 && j<fDigits->GetNRows()-1)
859                 {
860                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
861                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
862                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
863                     continue;
864                 }
865               else if(j==0 && j<fDigits->GetNRows()-1)
866                 {
867                   if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
868                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
869                     continue;
870                 }
871               else 
872                 {
873                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
874                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
875                     continue;
876                 }
877             }
878         
879           if(j==fDigits->GetNRows()-1)
880             {
881               if(i>0 && i<fDigits->GetNCols()-1)
882                 {
883                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
884                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
885                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
886                     continue;
887                 }
888               else if(i==0 && fDigits->GetNCols()-1)
889                 {
890                   if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
891                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
892                     continue;
893                 }
894               else 
895                 {
896                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
897                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
898                     continue;
899                 }
900             }
901
902           AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
903           //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
904           //      continue; 
905               
906           ndigits[lrow]++; //for this row only
907           ndigitcount++;   //total number of digits to be published
908         }
909       }
910     }
911     nrows++;
912   }
913   
914   Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
915     + nrows*sizeof(AliHLTTPCDigitRowData);
916
917   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Digits")
918     <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
919   
920   data=(AliHLTTPCDigitRowData*) Allocate(size);
921   nrow = (UInt_t)nrows;
922   AliHLTTPCDigitRowData *tempPt = data;
923  
924   for(Int_t r=fRowMin;r<=fRowMax;r++){
925     Int_t n=fIndex[fSlice][r];
926     tempPt->fRow = r;
927     tempPt->fNDigit = 0;
928     if(n!=-1){ //no data on that row
929       fDigitsTree->GetEvent(n);
930       fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
931       AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
932
933       if(lrow!=r){
934         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
935           <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
936         continue;
937       }
938
939       tempPt->fNDigit = ndigits[lrow];
940
941       Int_t localcount=0;
942       fDigits->ExpandBuffer();
943       fDigits->ExpandTrackBuffer();
944       for(Int_t i=0; i<fDigits->GetNCols(); i++){
945         for(Int_t j=0; j<fDigits->GetNRows(); j++){
946           pad=i;
947           time=j;
948           dig = fDigits->GetDigitFast(time,pad);
949           if(dig <= zerosupval) continue;
950           if(dig >= AliHLTTPCTransform::GetADCSat())
951             dig = AliHLTTPCTransform::GetADCSat();
952               
953           //Check for single timebins, and remove them because they are noise for sure.
954           if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
955             if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
956                fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
957                fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
958                fDigits->GetDigitFast(time,pad+1)<=zerosupval)
959               continue;
960           
961           //Boundaries:
962           if(i==0) //pad ==0
963             {
964               if(j < fDigits->GetNRows()-1 && j > 0) 
965                 {
966                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
967                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
968                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
969                     continue;
970                 }
971               else if(j > 0)
972                 {
973                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
974                      fDigits->GetDigitFast(time,pad+1)<=zerosupval)
975                     continue;
976                 }
977             }
978           if(j==0)
979             {
980               if(i < fDigits->GetNCols()-1 && i > 0)
981                 {
982                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
983                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
984                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
985                     continue;
986                 }
987               else if(i > 0)
988                 {
989                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
990                      fDigits->GetDigitFast(time+1,pad)<=zerosupval)
991                     continue;
992                 }
993             }
994         
995           if(i == fDigits->GetNCols()-1)
996             {
997               if(j>0 && j<fDigits->GetNRows()-1)
998                 {
999                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
1000                      fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1001                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1002                     continue;
1003                 }
1004               else if(j==0 && j<fDigits->GetNRows()-1)
1005                 {
1006                   if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
1007                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1008                     continue;
1009                 }
1010               else 
1011                 {
1012                   if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
1013                      fDigits->GetDigitFast(time,pad-1)<=zerosupval)
1014                     continue;
1015                 }
1016             }
1017           if(j==fDigits->GetNRows()-1)
1018             {
1019               if(i>0 && i<fDigits->GetNCols()-1)
1020                 {
1021                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1022                      fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1023                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1024                     continue;
1025                 }
1026               else if(i==0 && fDigits->GetNCols()-1)
1027                 {
1028                   if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
1029                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1030                     continue;
1031                 }
1032               else 
1033                 {
1034                   if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
1035                      fDigits->GetDigitFast(time-1,pad)<=zerosupval)
1036                     continue;
1037                 }
1038             }
1039         
1040           AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
1041           //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
1042           //        continue;
1043           
1044           if(localcount >= ndigits[lrow])
1045             LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliAltroDigits2Binary","Memory")
1046               <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
1047               <<ndigits[lrow]<<ENDLOG;
1048         
1049           tempPt->fDigitData[localcount].fCharge=dig;
1050           tempPt->fDigitData[localcount].fPad=pad;
1051           tempPt->fDigitData[localcount].fTime=time;
1052           tempPt->fDigitData[localcount].fTrackID[0] = (fDigits->GetTrackIDFast(time,pad,0)-2);
1053           tempPt->fDigitData[localcount].fTrackID[1] = (fDigits->GetTrackIDFast(time,pad,1)-2);
1054           tempPt->fDigitData[localcount].fTrackID[2] = (fDigits->GetTrackIDFast(time,pad,2)-2);
1055           if(eventmerge == kTRUE) //careful track mc info will be touched
1056             {//Event are going to be merged, so event number is stored in the upper 10 bits.
1057               tempPt->fDigitData[localcount].fTrackID[0] += 128; //leave some room
1058               tempPt->fDigitData[localcount].fTrackID[1] += 128; //for neg. numbers
1059               tempPt->fDigitData[localcount].fTrackID[2] += 128;
1060               tempPt->fDigitData[localcount].fTrackID[0] += ((event&0x3ff)<<22);
1061               tempPt->fDigitData[localcount].fTrackID[1] += ((event&0x3ff)<<22);
1062               tempPt->fDigitData[localcount].fTrackID[2] += ((event&0x3ff)<<22);
1063             }
1064           localcount++;
1065         }
1066       }
1067     }
1068     Byte_t *tmp = (Byte_t*)tempPt;
1069     tmp += sizeof(AliHLTTPCDigitRowData)
1070       + ndigits[r]*sizeof(AliHLTTPCDigitData);
1071     tempPt = (AliHLTTPCDigitRowData*)tmp;
1072   }
1073   delete [] ndigits;
1074   return data;
1075 }
1076  
1077 Bool_t AliHLTTPCFileHandler::GetDigitsTree(Int_t event)
1078 {
1079   //Connects to the TPC digit tree in the AliROOT file.
1080   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1081   if(!tpcLoader){
1082     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::GetDigitsTree","File")
1083     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1084     return kFALSE;
1085   }
1086   fInAli->GetEvent(event);
1087   tpcLoader->LoadDigits();
1088   fDigitsTree = tpcLoader->TreeD();
1089   if(!fDigitsTree) 
1090     {
1091       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::GetDigitsTree","Digits Tree")
1092         <<AliHLTTPCLog::kHex<<"Error getting digitstree "<<(void*)fDigitsTree<<ENDLOG;
1093       return kFALSE;
1094     }
1095   fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
1096
1097   if(!fIndexCreated) return CreateIndex();
1098   else return kTRUE;
1099 }
1100
1101 ///////////////////////////////////////// Point IO  
1102 Bool_t AliHLTTPCFileHandler::AliPoints2Binary(Int_t eventn)
1103 {
1104   //points to binary
1105   Bool_t out = kTRUE;
1106   UInt_t npoint;
1107   AliHLTTPCSpacePointData *data = AliPoints2Memory(npoint,eventn);
1108   out = Memory2Binary(npoint,data);
1109   Free();
1110   return out;
1111 }
1112
1113 AliHLTTPCSpacePointData * AliHLTTPCFileHandler::AliPoints2Memory(UInt_t & npoint,Int_t eventn)
1114 {
1115   //points to memory
1116   AliHLTTPCSpacePointData *data = 0;
1117   npoint=0;
1118   if(!fInAli){
1119     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1120     <<"No Input avalible: no object fInAli"<<ENDLOG;
1121     return 0;
1122   }
1123
1124   TDirectory *savedir = gDirectory;
1125   AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
1126   if(!tpcLoader){
1127     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1128     <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
1129     return 0;
1130   }
1131   fInAli->GetEvent(eventn);
1132   tpcLoader->LoadRecPoints();
1133
1134   AliTPCClustersArray carray;
1135   carray.Setup(fParam);
1136   carray.SetClusterType("AliTPCcluster");
1137   Bool_t clusterok = carray.ConnectTree(tpcLoader->TreeR());
1138
1139   if(!clusterok) return 0;
1140
1141   AliTPCClustersRow ** clusterrow = 
1142                new AliTPCClustersRow*[ (int)carray.GetTree()->GetEntries()];
1143   Int_t *rows = new int[ (int)carray.GetTree()->GetEntries()];
1144   Int_t *sects = new int[  (int)carray.GetTree()->GetEntries()];
1145   Int_t sum=0;
1146
1147   Int_t lslice,lrow;
1148   for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1149     AliSegmentID *s = carray.LoadEntry(i);
1150     Int_t sector,row;
1151     fParam->AdjustSectorRow(s->GetID(),sector,row);
1152     rows[i] = row;
1153     sects[i] = sector;
1154     clusterrow[i] = 0;
1155     AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1156     if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
1157     clusterrow[i] = carray.GetRow(sector,row);
1158     if(clusterrow[i])
1159       sum+=clusterrow[i]->GetArray()->GetEntriesFast();
1160   }
1161   UInt_t size = sum*sizeof(AliHLTTPCSpacePointData);
1162
1163   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliPoints2Memory","File")
1164   <<AliHLTTPCLog::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
1165
1166   data = (AliHLTTPCSpacePointData *) Allocate(size);
1167   npoint = sum;
1168   UInt_t n=0; 
1169   Int_t pat=fPatch;
1170   if(fPatch==-1)
1171     pat=0;
1172   for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
1173     if(!clusterrow[i]) continue;
1174     Int_t row = rows[i];
1175     Int_t sector = sects[i];
1176     AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
1177     Int_t entriesInRow = clusterrow[i]->GetArray()->GetEntriesFast();
1178     for(Int_t j = 0;j<entriesInRow;j++){
1179       AliTPCcluster *c = (AliTPCcluster*)(*clusterrow[i])[j];
1180       data[n].fZ = c->GetZ();
1181       data[n].fY = c->GetY();
1182       data[n].fX = fParam->GetPadRowRadii(sector,row);
1183       data[n].fCharge = (UInt_t)c->GetQ();
1184       data[n].SetID( fSlice, pat, n );
1185       data[n].fPadRow = lrow;
1186       data[n].fSigmaY2 = c->GetSigmaY2();
1187       data[n].fSigmaZ2 = c->GetSigmaZ2();
1188 #ifdef do_mc
1189       data[n].fTrackID[0] = c->GetLabel(0);
1190       data[n].fTrackID[1] = c->GetLabel(1);
1191       data[n].fTrackID[2] = c->GetLabel(2);
1192 #endif
1193       if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
1194       n++;
1195     }
1196   }
1197   for(Int_t i=0;i<carray.GetTree()->GetEntries();i++){
1198     Int_t row = rows[i];
1199     Int_t sector = sects[i];
1200     if(carray.GetRow(sector,row))
1201       carray.ClearRow(sector,row);
1202   }
1203
1204   delete [] clusterrow;
1205   delete [] rows;
1206   delete [] sects;
1207   savedir->cd();   
1208
1209   return data;
1210 }
1211