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