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