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