Faster algorithms.
[u/mrichter/AliRoot.git] / TPC / AliSimDigits.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.4  2000/10/05 16:01:49  kowal2
19 Corrected for memory leaks.
20
21 Revision 1.3  2000/06/30 12:07:49  kowal2
22 Updated from the TPC-PreRelease branch
23
24 Revision 1.2.4.3  2000/06/26 07:39:42  kowal2
25 Changes to obey the coding rules
26
27 Revision 1.2.4.2  2000/06/25 08:38:41  kowal2
28 Splitted from AliTPCtracking
29
30 Revision 1.2.4.1  2000/06/14 16:45:13  kowal2
31 Improved algorithms. Compiler warnings removed.
32
33 Revision 1.2  2000/04/17 09:37:33  kowal2
34 removed obsolete AliTPCDigitsDisplay.C
35
36 Revision 1.1.4.2  2000/04/10 11:37:42  kowal2
37
38 Digits handling in a new data structure
39
40 */
41
42 //
43
44 ///////////////////////////////////////////////////////////////////////////////
45 //                                                                           //
46 //  Alice segment manager object                                             //
47 //                                
48 //  AliSimDigits object   (derived from AliDigits)                            //
49 //  provide additional track information to digit                            //
50 //  
51 //   Origin: Marian Ivanov  GSI Darmstadt                                     //
52 //
53 //                                                                           //
54 //                                                                          //
55 ///////////////////////////////////////////////////////////////////////////////
56
57 #include "TClass.h"
58 #include <iostream.h>
59 #include "TError.h"
60 #include "AliSegmentID.h"
61 #include "AliH2F.h"
62 #include "AliArrayI.h"
63 #include "AliArrayS.h"
64 #include "AliDigits.h"
65 #include "AliSimDigits.h"
66 #include "AliTPC.h"
67 #include <TClonesArray.h>
68
69
70
71 //_____________________________________________________________________________
72 //_____________________________________________________________________________
73 //_____________________________________________________________________________
74 ClassImp(AliSimDigits)
75
76 AliSimDigits::AliSimDigits()
77 {
78   //  AliDigits::Invalite();
79   fTracks = 0;
80   fTrIndex = 0;  
81   InvalidateTrack();
82 }
83 AliSimDigits::~AliSimDigits()
84 {
85
86   if (fTracks != 0) {
87     delete fTracks;
88   }
89   if (fTrIndex != 0) { 
90     delete fTrIndex;
91   } 
92
93 }
94
95 void AliSimDigits::InvalidateTrack() 
96
97   //
98   //set default (invalid parameters)
99   if ( fTracks != 0) delete fTracks;
100   fTracks = new AliArrayI;
101   if ( fTrIndex  != 0) delete fTrIndex;
102   fTrIndex = new AliArrayI;
103
104   for (Int_t i = 0; i<3; i++){
105     fTracks->Set(0);
106     fTrIndex->Set(0);
107   }
108 }
109
110 void  AliSimDigits::AllocateTrack(Int_t length)
111 {
112   //
113   //construct empty buffer fElements and fTracks with size fNrows x fNcols x
114   //length 
115   InvalidateTrack();
116   fNlevel = length;
117   fTracks->Set(fNcols*fNrows*fNlevel);
118   fTrIndex->Set(0); 
119   fTrBufType =0;
120 }
121
122 Int_t AliSimDigits::GetTrackID(Int_t row, Int_t column, Int_t level) 
123 {
124   //
125   //Get track ID 
126   if (fTrBufType == 0) return  GetTrackIDFast(row, column,level);
127   if (fTrBufType == 1) return  GetTrackID1(row, column,level); 
128   if (fTrBufType == 2) return  GetTrackID2(row, column,level); 
129   return 0;
130 }
131
132 void AliSimDigits::ExpandTrackBuffer()
133 {  
134   //
135   //expand buffer to two dimensional array 
136   if (fTrBufType<0)  {
137     Error("ExpandBuffer", "buffer doesn't exist");
138     return;
139   }
140   if (fTrBufType==0)      return;  //buffer expanded
141   if (fTrBufType==1)  {ExpandTrackBuffer1(); return;}
142   if (fTrBufType==2)  ExpandTrackBuffer2();
143  
144 }
145
146 void AliSimDigits::CompresTrackBuffer(Int_t bufType)
147 {
148   //
149   //compres buffer according buffertype algorithm
150   //
151   if (fTrBufType<0)  {
152     Error("CompressBuffer", "buffer doesn't exist");
153     return;
154   }
155   if (fTrBufType == bufType) return;
156   //
157   if (fTrBufType>0) ExpandTrackBuffer();
158   if (fTrBufType !=0)  {
159     Error("CompressBuffer", "buffer doesn't exist");
160     return;
161   }
162   //compress buffer of type 1
163   
164   if (bufType==1)      {CompresTrackBuffer1();return;}
165   if (bufType==2)      CompresTrackBuffer2();
166    
167 }
168
169 Int_t  AliSimDigits::GetTrackID1(Int_t row, Int_t column, Int_t level)
170 {
171   //return  track ID of digits - for buffer compresion 2
172   Int_t i,n1,n2;
173   i = level*fNcols+column;
174   if ( (i+1)>=fTrIndex->fN) n2 = fTracks->fN;
175   else 
176     n2 = fTrIndex->At(i+1);
177   n1 = fTrIndex->At(i);
178   Int_t rownew = 0;
179   Int_t rowold=0;
180   Int_t id;
181   for (i = n1;(i<n2);i++){
182     id = 0;
183     Int_t num = fTracks->At(i);
184     if (num<0) {
185       rownew-=num;  
186       rowold = rownew;
187       i++;
188       if (i<n2){
189         num = fTracks->At(i);
190         rownew+=num;
191         i++;
192         id = fTracks->At(i);
193       }
194     }
195     else {
196       rowold = rownew;
197       rownew+=num;
198       i++;
199       id = fTracks->At(i);
200     }
201     id-=2;
202     if ( (row>=rowold) && (row<=rownew) ) return id;
203     if (row < rownew ) return -2; //empty track
204   }
205   return -2;
206 }
207
208 void  AliSimDigits::ExpandTrackBuffer1()
209 {
210   //
211   //expand  track compressed according algorithm 1 (track id comression independent to the digit compression)
212   // !!in expanded tracks we don't use fTrIndex array
213   //  
214   fTrBufType = 0;
215   Int_t i,j;
216   Int_t all   = fNrows*fNcols;  //total number of digits
217   Int_t elems = all*fNlevel;  //length of the buffer
218
219   AliArrayI * buf = new AliArrayI;
220   buf->Set(elems);
221   fTrIndex->Set(0);
222   //
223   Int_t level = 0;
224   Int_t col=0;
225   Int_t row = 0;
226   Int_t n=fTracks->fN;
227   //
228   for (i=0;i<n;i++){
229     //oposite signa means how many unwrited (under threshold) values
230     Int_t num = fTracks->At(i);
231     if (num<0) row-=num;   //negative number mean number of zeroes (no tracks of gibven level no need to write to array) 
232     else {
233       i++;
234       Int_t id =  fTracks->At(i);
235       for (j = 0; j<num; j++,row++) (*buf)[level*all+col*fNrows+row]=id;       
236     }
237     if (row>=fNrows) {
238       row=0;
239       col++;
240     }
241     if (col>=fNcols) {
242       col=0;
243       level++;
244     }    
245   }//end of loop over digits
246   delete fTracks;
247   fTracks = buf;
248 }
249
250 void  AliSimDigits::CompresTrackBuffer1()
251 {
252   //
253   //comress track according algorithm 1 (track id comression independent to the digit compression)
254   //
255   fTrBufType = 1;  
256
257   AliArrayI *  buf = new AliArrayI;   //create  new buffer 
258   buf->Set(fNrows*fNcols*fNlevel); //lets have the nearly the "worst case"
259   AliArrayI *  index = new AliArrayI;
260   index->Set(fNcols*fNlevel);
261   //  Int_t * pindex = 
262
263   
264   Int_t icurrent=-1;  //current index
265   Int_t izero;      //number of zero
266   Int_t inum;      //number of digits  with the same current track id  
267   Int_t lastID =0;  //last track id  
268   
269   Int_t *cbuff=fTracks->GetArray(); //MI change
270
271   for (Int_t lev =0; lev<fNlevel; lev++){    //loop over levels 
272     for (Int_t col = 0; col<fNcols; col++){    //loop over columns
273       izero = 0;
274       inum =  0;
275       lastID = 0;
276       (*index)[lev*fNcols+col]=icurrent+1;//set collumn pointer
277       Int_t id=0;  //current id
278       for (Int_t row = 0; row< fNrows;row++){ //loop over rows        
279         id = *cbuff;  //MI change
280         //      id = GetTrackIDFast(row,col,lev);
281         if (id <= 0) {
282           if ( inum> 0 ) { //if we have some tracks in buffer
283             icurrent++;
284             if ((icurrent+1)>=buf->fN) buf->Expand(icurrent*2);
285             (*buf)[icurrent] = inum;
286             icurrent++;
287             (*buf)[icurrent] = lastID;  
288             inum = 0;      
289             lastID = 0;
290           }
291           izero++;
292         }
293         else
294           if (id != lastID) 
295             if ( izero > 0 ) { 
296               //if we have currently izero count of non tracks digits
297               icurrent++;         
298               if (icurrent>=buf->fN) buf->Expand(icurrent*2);
299               (*buf)[icurrent]= -izero;  //write how many under zero
300               inum++;
301               izero = 0;             
302               lastID = id;
303             }
304             else{ 
305               //if we change track id from another track id         
306               icurrent++;         
307               if ((icurrent+1)>=buf->fN) buf->Expand(icurrent*2);
308               (*buf)[icurrent] = inum;
309               icurrent++;
310               (*buf)[icurrent] = lastID;        
311               lastID = id;
312               inum = 1;      
313               izero = 0;
314             }   
315           else {          
316             inum++;
317           }
318         cbuff++;  //MI change
319       }//end of loop over row
320       if ( izero > 0 ) { 
321         //if we have currently izero count of non tracks digits
322         icurrent++;       
323         if (icurrent>=buf->fN) buf->Expand(icurrent*2);
324         (*buf)[icurrent]= -izero;  //write how many under zero  
325       }
326       if ( inum> 0 ) { //if we have some tracks in buffer
327         icurrent++;
328         if ((icurrent+1)>=buf->fN) buf->Expand(icurrent*2);
329         (*buf)[icurrent] = inum;
330         icurrent++;
331         (*buf)[icurrent] = id;  
332       }      
333     }//end of loop over columns
334   }//end of loop over differnet track level  
335   buf->Expand(icurrent+1);
336   delete fTracks;
337   fTracks = buf;
338   delete fTrIndex;
339   fTrIndex = index;
340 }
341
342
343
344 void  AliSimDigits::ExpandTrackBuffer2()
345 {
346   //
347   //comress track according algorithm 2 (track id comression according  digit compression)
348   fTrBufType = 0;
349 }
350
351 void  AliSimDigits::CompresTrackBuffer2()
352 {
353   //
354   //comress track according algorithm 2 (track id comression according  digit compression)
355   fTrBufType = 2;
356 }
357
358
359 Int_t  AliSimDigits::GetTrackID2(Int_t row, Int_t column, Int_t level)
360 {
361   //returnb track id of digits - for buffer compresion 2
362   return -2;
363 }
364
365
366
367 AliH2F *  AliSimDigits::DrawTracks( const char *option,Int_t level, 
368                               Float_t x1, Float_t x2, Float_t y1, Float_t y2)
369 {
370   //
371   //draw digits in given array
372   //  
373   //make digits histo 
374   char ch[30];
375   sprintf(ch,"Track Segment_%d level %d ",GetID(),level );
376   if ( (fNrows<1)|| (fNcols<1)) {
377     return 0;
378   }
379   AliH2F * his  = new AliH2F("Track histo",ch,fNrows,0,fNrows,fNcols,0,fNcols);
380   ExpandTrackBuffer();
381   //set histogram  values
382   for (Int_t i = 0; i<fNrows;i++)    
383     for (Int_t j = 0; j<fNcols;j++)
384         his->Fill(i,j,GetTrackIDFast(i,j,level));
385   if (x1>=0) {
386       AliH2F *h2fsub = his->GetSubrange2d(x1,x2,y1,y2);
387       delete his;
388       his=h2fsub;
389   }
390   if (his==0) return 0;
391   if (option!=0) his->Draw(option);
392   else his->Draw();
393   return his;  
394 }
395
396 TClonesArray *  AliSimDigits::GenerTPCClonesArray(TClonesArray * arr)
397 {
398   //
399   //generate TClonnesArray of digits
400   //
401   TClonesArray * digits;
402   if (arr==0)  digits=new TClonesArray("AliTPCdigit",300);
403   else digits = arr; 
404   Int_t index = digits->GetEntriesFast();
405   for (Int_t row =0; row<fNrows; row++)
406     for (Int_t col =0; col<fNcols; col++){
407       Int_t amp = GetDigit(row,col);
408       if (amp>GetThreshold()){
409         AliTPCdigit dig;
410         dig.fPad = col;
411         dig.fTime = row;
412         dig.fSignal= amp;
413         dig.fPadRow =fSegmentID;
414         dig.fSector =fSegmentID;
415         dig.fTracks[0]= GetTrackID(row,col,0);
416         dig.fTracks[1]= GetTrackID(row,col,1);
417         dig.fTracks[2]= GetTrackID(row,col,2);
418         TClonesArray &ldigits = *digits;
419         new(ldigits[index++]) AliTPCdigit(dig);
420       }
421     }    
422   return digits;
423 }
424