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