Uninitilized variable (Marian)
[u/mrichter/AliRoot.git] / TPC / AliTPCclustererMI.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 //          Implementation of the TPC clusterer
20 //
21 //  1. The Input data for reconstruction - Options
22 //      1.a Simulated data  - TTree - invoked Digits2Clusters()
23 //      1.b Raw data        - Digits2Clusters(AliRawReader* rawReader); 
24 //
25 //  2. The Output data
26 //      2.a TTree with clusters - if  SetOutput(TTree * tree) invoked
27 //      2.b TObjArray           - Faster option for HLT
28 //
29 //  3. Reconstruction setup
30 //     see AliTPCRecoParam for list of parameters 
31 //     The reconstruction parameterization taken from the 
32 //     AliTPCReconstructor::GetRecoParam()
33 //     Possible to setup it in reconstruction macro  AliTPCReconstructor::SetRecoParam(...)
34 //     
35 //
36 //
37 //   Origin: Marian Ivanov 
38 //-------------------------------------------------------
39
40 #include "Riostream.h"
41 #include <TF1.h>
42 #include <TFile.h>
43 #include <TGraph.h>
44 #include <TH1F.h>
45 #include <TObjArray.h>
46 #include <TRandom.h>
47 #include <TTree.h>
48 #include <TTreeStream.h>
49
50 #include "AliDigits.h"
51 #include "AliLoader.h"
52 #include "AliLog.h"
53 #include "AliMathBase.h"
54 #include "AliRawEventHeaderBase.h"
55 #include "AliRawReader.h"
56 #include "AliRunLoader.h"
57 #include "AliSimDigits.h"
58 #include "AliTPCCalPad.h"
59 #include "AliTPCCalROC.h"
60 #include "AliTPCClustersArray.h"
61 #include "AliTPCClustersRow.h"
62 #include "AliTPCParam.h"
63 #include "AliTPCRawStream.h"
64 #include "AliTPCRecoParam.h"
65 #include "AliTPCReconstructor.h"
66 #include "AliTPCcalibDB.h"
67 #include "AliTPCclusterInfo.h"
68 #include "AliTPCclusterMI.h"
69 #include "AliTPCTransform.h"
70 #include "AliTPCclustererMI.h"
71
72 ClassImp(AliTPCclustererMI)
73
74
75
76 AliTPCclustererMI::AliTPCclustererMI(const AliTPCParam* par, const AliTPCRecoParam * recoParam):
77   fBins(0),
78   fSigBins(0),
79   fNSigBins(0),
80   fLoop(0),
81   fMaxBin(0),
82   fMaxTime(0),
83   fMaxPad(0),
84   fSector(-1),
85   fRow(-1),
86   fSign(0),
87   fRx(0),
88   fPadWidth(0),
89   fPadLength(0),
90   fZWidth(0),
91   fPedSubtraction(kFALSE),
92   fEventHeader(0),
93   fTimeStamp(0),
94   fEventType(0),
95   fInput(0),
96   fOutput(0),
97   fOutputArray(0),
98   fRowCl(0),
99   fRowDig(0),
100   fParam(0),
101   fNcluster(0),
102   fDebugStreamer(0),
103   fRecoParam(0),
104   fBDumpSignal(kFALSE)
105 {
106   //
107   // COSNTRUCTOR
108   // param     - tpc parameters for given file
109   // recoparam - reconstruction parameters 
110   //
111   fInput =0;
112   fParam = par;
113   if (recoParam) {
114     fRecoParam = recoParam;
115   }else{
116     //set default parameters if not specified
117     fRecoParam = AliTPCReconstructor::GetRecoParam();
118     if (!fRecoParam)  fRecoParam = AliTPCRecoParam::GetLowFluxParam();
119   }
120   fDebugStreamer = new TTreeSRedirector("TPCsignal.root");
121   Int_t nPoints = fRecoParam->GetLastBin()-fRecoParam->GetFirstBin();
122   fRowCl= new AliTPCClustersRow();
123   fRowCl->SetClass("AliTPCclusterMI");
124   fRowCl->SetArray(1);
125
126 }
127 //______________________________________________________________
128 AliTPCclustererMI::AliTPCclustererMI(const AliTPCclustererMI &param)
129               :TObject(param),
130   fBins(0),
131   fSigBins(0),
132   fNSigBins(0),
133   fLoop(0),
134   fMaxBin(0),
135   fMaxTime(0),
136   fMaxPad(0),
137   fSector(-1),
138   fRow(-1),
139   fSign(0),
140   fRx(0),
141   fPadWidth(0),
142   fPadLength(0),
143   fZWidth(0),
144   fPedSubtraction(kFALSE),
145   fEventHeader(0),
146   fTimeStamp(0),
147   fEventType(0),
148   fInput(0),
149   fOutput(0),
150   fOutputArray(0),
151   fRowCl(0),
152   fRowDig(0),
153   fParam(0),
154   fNcluster(0),
155   fDebugStreamer(0),
156   fRecoParam(0),
157   fBDumpSignal(kFALSE)
158 {
159   //
160   // dummy
161   //
162   fMaxBin = param.fMaxBin;
163 }
164 //______________________________________________________________
165 AliTPCclustererMI & AliTPCclustererMI::operator =(const AliTPCclustererMI & param)
166 {
167   //
168   // assignment operator - dummy
169   //
170   fMaxBin=param.fMaxBin;
171   return (*this);
172 }
173 //______________________________________________________________
174 AliTPCclustererMI::~AliTPCclustererMI(){
175   //
176   //
177   //
178   if (fDebugStreamer) delete fDebugStreamer;
179   if (fOutputArray){
180     //fOutputArray->Delete();
181     delete fOutputArray;
182   }
183 }
184
185 void AliTPCclustererMI::SetInput(TTree * tree)
186 {
187   //
188   // set input tree with digits
189   //
190   fInput = tree;  
191   if  (!fInput->GetBranch("Segment")){
192     cerr<<"AliTPC::Digits2Clusters(): no porper input tree !\n";
193     fInput=0;
194     return;
195   }
196 }
197
198 void AliTPCclustererMI::SetOutput(TTree * tree) 
199 {
200   //
201   // Set the output tree
202   // If not set the ObjArray used - Option for HLT 
203   //
204   if (!tree) return;
205   fOutput= tree;
206   AliTPCClustersRow clrow;
207   AliTPCClustersRow *pclrow=&clrow;  
208   clrow.SetClass("AliTPCclusterMI");
209   clrow.SetArray(1); // to make Clones array
210   fOutput->Branch("Segment","AliTPCClustersRow",&pclrow,32000,200);    
211 }
212
213
214 void AliTPCclustererMI::FillRow(){
215   //
216   // fill the output container - 
217   // 2 Options possible
218   //          Tree       
219   //          TObjArray
220   //
221   if (fOutput) fOutput->Fill();
222   if (!fOutput){
223     //
224     if (!fOutputArray) fOutputArray = new TObjArray(fParam->GetNRowsTotal());
225     if (fRowCl) fOutputArray->AddAt(fRowCl->Clone(), fRowCl->GetID());
226   }
227 }
228
229 Float_t  AliTPCclustererMI::GetSigmaY2(Int_t iz){
230   // sigma y2 = in digits  - we don't know the angle
231   Float_t z = iz*fParam->GetZWidth()+fParam->GetNTBinsL1()*fParam->GetZWidth();
232   Float_t sd2 = (z*fParam->GetDiffL()*fParam->GetDiffL())/
233     (fPadWidth*fPadWidth);
234   Float_t sres = 0.25;
235   Float_t res = sd2+sres;
236   return res;
237 }
238
239
240 Float_t  AliTPCclustererMI::GetSigmaZ2(Int_t iz){
241   //sigma z2 = in digits - angle estimated supposing vertex constraint
242   Float_t z = iz*fZWidth+fParam->GetNTBinsL1()*fParam->GetZWidth();
243   Float_t sd2 = (z*fParam->GetDiffL()*fParam->GetDiffL())/(fZWidth*fZWidth);
244   Float_t angular = fPadLength*(fParam->GetZLength(fSector)-z)/(fRx*fZWidth);
245   angular*=angular;
246   angular/=12.;
247   Float_t sres = fParam->GetZSigma()/fZWidth;
248   sres *=sres;
249   Float_t res = angular +sd2+sres;
250   return res;
251 }
252
253 void AliTPCclustererMI::MakeCluster(Int_t k,Int_t max,Float_t *bins, UInt_t /*m*/,
254 AliTPCclusterMI &c) 
255 {
256   //
257   //  k    - Make cluster at position k  
258   //  bins - 2 D array of signals mapped to 1 dimensional array - 
259   //  max  - the number of time bins er one dimension
260   //  c    - refernce to cluster to be filled
261   //
262   Int_t i0=k/max;  //central pad
263   Int_t j0=k%max;  //central time bin
264
265   // set pointers to data
266   //Int_t dummy[5] ={0,0,0,0,0};
267   Float_t * matrix[5]; //5x5 matrix with digits  - indexing i = 0 ..4  j = -2..2
268   for (Int_t di=-2;di<=2;di++){
269     matrix[di+2]  =  &bins[k+di*max];
270   }
271   //build matrix with virtual charge
272   Float_t sigmay2= GetSigmaY2(j0);
273   Float_t sigmaz2= GetSigmaZ2(j0);
274
275   Float_t vmatrix[5][5];
276   vmatrix[2][2] = matrix[2][0];
277   c.SetType(0);
278   c.SetMax((UShort_t)(vmatrix[2][2])); // write maximal amplitude
279   for (Int_t di =-1;di <=1;di++)
280     for (Int_t dj =-1;dj <=1;dj++){
281       Float_t amp = matrix[di+2][dj];
282       if ( (amp<2) && (fLoop<2)){
283         // if under threshold  - calculate virtual charge
284         Float_t ratio = TMath::Exp(-1.2*TMath::Abs(di)/sigmay2)*TMath::Exp(-1.2*TMath::Abs(dj)/sigmaz2);
285         amp = ((matrix[2][0]-2)*(matrix[2][0]-2)/(matrix[-di+2][-dj]+2))*ratio;
286         if (amp>2) amp = 2;
287         vmatrix[2+di][2+dj]=amp;
288         vmatrix[2+2*di][2+2*dj]=0;
289         if ( (di*dj)!=0){       
290           //DIAGONAL ELEMENTS
291           vmatrix[2+2*di][2+dj] =0;
292           vmatrix[2+di][2+2*dj] =0;
293         }
294         continue;
295       }
296       if (amp<4){
297         //if small  amplitude - below  2 x threshold  - don't consider other one        
298         vmatrix[2+di][2+dj]=amp;
299         vmatrix[2+2*di][2+2*dj]=0;  // don't take to the account next bin
300         if ( (di*dj)!=0){       
301           //DIAGONAL ELEMENTS
302           vmatrix[2+2*di][2+dj] =0;
303           vmatrix[2+di][2+2*dj] =0;
304         }
305         continue;
306       }
307       //if bigger then take everything
308       vmatrix[2+di][2+dj]=amp;
309       vmatrix[2+2*di][2+2*dj]= matrix[2*di+2][2*dj] ;      
310       if ( (di*dj)!=0){       
311           //DIAGONAL ELEMENTS
312           vmatrix[2+2*di][2+dj] = matrix[2*di+2][dj];
313           vmatrix[2+di][2+2*dj] = matrix[2+di][dj*2];
314         }      
315     }
316
317
318   
319   Float_t sumw=0;
320   Float_t sumiw=0;
321   Float_t sumi2w=0;
322   Float_t sumjw=0;
323   Float_t sumj2w=0;
324   //
325   for (Int_t i=-2;i<=2;i++)
326     for (Int_t j=-2;j<=2;j++){
327       Float_t amp = vmatrix[i+2][j+2];
328
329       sumw    += amp;
330       sumiw   += i*amp;
331       sumi2w  += i*i*amp;
332       sumjw   += j*amp;
333       sumj2w  += j*j*amp;
334     }    
335   //   
336   Float_t meani = sumiw/sumw;
337   Float_t mi2   = sumi2w/sumw-meani*meani;
338   Float_t meanj = sumjw/sumw;
339   Float_t mj2   = sumj2w/sumw-meanj*meanj;
340   //
341   Float_t ry = mi2/sigmay2;
342   Float_t rz = mj2/sigmaz2;
343   
344   //
345   if ( ( (ry<0.6) || (rz<0.6) ) && fLoop==2) return;
346   if ( (ry <1.2) && (rz<1.2) || (!fRecoParam->GetDoUnfold())) {
347     //
348     //if cluster looks like expected or Unfolding not switched on
349     //standard COG is used
350     //+1.2 deviation from expected sigma accepted
351     //    c.fMax = FitMax(vmatrix,meani,meanj,TMath::Sqrt(sigmay2),TMath::Sqrt(sigmaz2));
352
353     meani +=i0;
354     meanj +=j0;
355     //set cluster parameters
356     c.SetQ(sumw);
357     c.SetPad(meani-2.5);
358     c.SetTimeBin(meanj-3);
359     c.SetSigmaY2(mi2);
360     c.SetSigmaZ2(mj2);
361     c.SetType(0);
362     AddCluster(c,(Float_t*)vmatrix,k);
363     return;     
364   }
365   //
366   //unfolding when neccessary  
367   //
368   
369   Float_t * matrix2[7]; //7x7 matrix with digits  - indexing i = 0 ..6  j = -3..3
370   Float_t dummy[7]={0,0,0,0,0,0};
371   for (Int_t di=-3;di<=3;di++){
372     matrix2[di+3] =  &bins[k+di*max];
373     if ((k+di*max)<3)  matrix2[di+3] = &dummy[3];
374     if ((k+di*max)>fMaxBin-3)  matrix2[di+3] = &dummy[3];
375   }
376   Float_t vmatrix2[5][5];
377   Float_t sumu;
378   Float_t overlap;
379   UnfoldCluster(matrix2,vmatrix2,meani,meanj,sumu,overlap);
380   //
381   //  c.fMax = FitMax(vmatrix2,meani,meanj,TMath::Sqrt(sigmay2),TMath::Sqrt(sigmaz2));
382   meani +=i0;
383   meanj +=j0;
384   //set cluster parameters
385   c.SetQ(sumu);
386   c.SetPad(meani-2.5);
387   c.SetTimeBin(meanj-3);
388   c.SetSigmaY2(mi2);
389   c.SetSigmaZ2(mj2);
390   c.SetType(Char_t(overlap)+1);
391   AddCluster(c,(Float_t*)vmatrix,k);
392
393   //unfolding 2
394   meani-=i0;
395   meanj-=j0;
396   if (gDebug>4)
397     printf("%f\t%f\n", vmatrix2[2][2], vmatrix[2][2]);
398 }
399
400
401
402 void AliTPCclustererMI::UnfoldCluster(Float_t * matrix2[7], Float_t recmatrix[5][5], Float_t & meani, Float_t & meanj, 
403                                       Float_t & sumu, Float_t & overlap )
404 {
405   //
406   //unfold cluster from input matrix
407   //data corresponding to cluster writen in recmatrix
408   //output meani and meanj
409
410   //take separatelly y and z
411
412   Float_t sum3i[7] = {0,0,0,0,0,0,0};
413   Float_t sum3j[7] = {0,0,0,0,0,0,0};
414
415   for (Int_t k =0;k<7;k++)
416     for (Int_t l = -1; l<=1;l++){
417       sum3i[k]+=matrix2[k][l];
418       sum3j[k]+=matrix2[l+3][k-3];
419     }
420   Float_t mratio[3][3]={{1,1,1},{1,1,1},{1,1,1}};
421   //
422   //unfold  y 
423   Float_t sum3wi    = 0;  //charge minus overlap
424   Float_t sum3wio   = 0;  //full charge
425   Float_t sum3iw    = 0;  //sum for mean value
426   for (Int_t dk=-1;dk<=1;dk++){
427     sum3wio+=sum3i[dk+3];
428     if (dk==0){
429       sum3wi+=sum3i[dk+3];     
430     }
431     else{
432       Float_t ratio =1;
433       if (  ( ((sum3i[dk+3]+3)/(sum3i[3]-3))+1 < (sum3i[2*dk+3]-3)/(sum3i[dk+3]+3))||
434            sum3i[dk+3]<=sum3i[2*dk+3] && sum3i[dk+3]>2 ){
435         Float_t xm2 = sum3i[-dk+3];
436         Float_t xm1 = sum3i[+3];
437         Float_t x1  = sum3i[2*dk+3];
438         Float_t x2  = sum3i[3*dk+3];    
439         Float_t w11   = TMath::Max((Float_t)(4.*xm1-xm2),(Float_t)0.000001);      
440         Float_t w12   = TMath::Max((Float_t)(4 *x1 -x2),(Float_t)0.);
441         ratio = w11/(w11+w12);   
442         for (Int_t dl=-1;dl<=1;dl++)
443           mratio[dk+1][dl+1] *= ratio;
444       }
445       Float_t amp = sum3i[dk+3]*ratio;
446       sum3wi+=amp;
447       sum3iw+= dk*amp;      
448     }
449   }
450   meani = sum3iw/sum3wi;
451   Float_t overlapi = (sum3wio-sum3wi)/sum3wio;
452
453
454
455   //unfold  z 
456   Float_t sum3wj    = 0;  //charge minus overlap
457   Float_t sum3wjo   = 0;  //full charge
458   Float_t sum3jw    = 0;  //sum for mean value
459   for (Int_t dk=-1;dk<=1;dk++){
460     sum3wjo+=sum3j[dk+3];
461     if (dk==0){
462       sum3wj+=sum3j[dk+3];     
463     }
464     else{
465       Float_t ratio =1;
466       if ( ( ((sum3j[dk+3]+3)/(sum3j[3]-3))+1 < (sum3j[2*dk+3]-3)/(sum3j[dk+3]+3)) ||
467            (sum3j[dk+3]<=sum3j[2*dk+3] && sum3j[dk+3]>2)){
468         Float_t xm2 = sum3j[-dk+3];
469         Float_t xm1 = sum3j[+3];
470         Float_t x1  = sum3j[2*dk+3];
471         Float_t x2  = sum3j[3*dk+3];    
472         Float_t w11   = TMath::Max((Float_t)(4.*xm1-xm2),(Float_t)0.000001);      
473         Float_t w12   = TMath::Max((Float_t)(4 *x1 -x2),(Float_t)0.);
474         ratio = w11/(w11+w12);   
475         for (Int_t dl=-1;dl<=1;dl++)
476           mratio[dl+1][dk+1] *= ratio;
477       }
478       Float_t amp = sum3j[dk+3]*ratio;
479       sum3wj+=amp;
480       sum3jw+= dk*amp;      
481     }
482   }
483   meanj = sum3jw/sum3wj;
484   Float_t overlapj = (sum3wjo-sum3wj)/sum3wjo;  
485   overlap = Int_t(100*TMath::Max(overlapi,overlapj)+3);  
486   sumu = (sum3wj+sum3wi)/2.;
487   
488   if (overlap ==3) {
489     //if not overlap detected remove everything
490     for (Int_t di =-2; di<=2;di++)
491       for (Int_t dj =-2; dj<=2;dj++){
492         recmatrix[di+2][dj+2] = matrix2[3+di][dj];
493       }
494   }
495   else{
496     for (Int_t di =-1; di<=1;di++)
497       for (Int_t dj =-1; dj<=1;dj++){
498         Float_t ratio =1;
499         if (mratio[di+1][dj+1]==1){
500           recmatrix[di+2][dj+2]     = matrix2[3+di][dj];
501           if (TMath::Abs(di)+TMath::Abs(dj)>1){
502             recmatrix[2*di+2][dj+2] = matrix2[3+2*di][dj];
503             recmatrix[di+2][2*dj+2] = matrix2[3+di][2*dj];
504           }       
505           recmatrix[2*di+2][2*dj+2] = matrix2[3+2*di][2*dj];
506         }
507         else
508           {
509             //if we have overlap in direction
510             recmatrix[di+2][dj+2] = mratio[di+1][dj+1]* matrix2[3+di][dj];    
511             if (TMath::Abs(di)+TMath::Abs(dj)>1){
512               ratio =  TMath::Min((Float_t)(recmatrix[di+2][dj+2]/(matrix2[3+0*di][1*dj]+1)),(Float_t)1.);
513               recmatrix[2*di+2][dj+2] = ratio*recmatrix[di+2][dj+2];
514               //
515               ratio =  TMath::Min((Float_t)(recmatrix[di+2][dj+2]/(matrix2[3+1*di][0*dj]+1)),(Float_t)1.);
516               recmatrix[di+2][2*dj+2] = ratio*recmatrix[di+2][dj+2];
517             }
518             else{
519               ratio =  recmatrix[di+2][dj+2]/matrix2[3][0];
520               recmatrix[2*di+2][2*dj+2] = ratio*recmatrix[di+2][dj+2];
521             }
522           }
523       }
524   }
525   if (gDebug>4) 
526     printf("%f\n", recmatrix[2][2]);
527   
528 }
529
530 Float_t AliTPCclustererMI::FitMax(Float_t vmatrix[5][5], Float_t y, Float_t z, Float_t sigmay, Float_t sigmaz)
531 {
532   //
533   // estimate max
534   Float_t sumteor= 0;
535   Float_t sumamp = 0;
536
537   for (Int_t di = -1;di<=1;di++)
538     for (Int_t dj = -1;dj<=1;dj++){
539       if (vmatrix[2+di][2+dj]>2){
540         Float_t teor = TMath::Gaus(di,y,sigmay*1.2)*TMath::Gaus(dj,z,sigmaz*1.2);
541         sumteor += teor*vmatrix[2+di][2+dj];
542         sumamp  += vmatrix[2+di][2+dj]*vmatrix[2+di][2+dj];
543       }
544     }    
545   Float_t max = sumamp/sumteor;
546   return max;
547 }
548
549 void AliTPCclustererMI::AddCluster(AliTPCclusterMI &c, Float_t * matrix, Int_t pos){
550   //
551   //
552   // Transform cluster to the rotated global coordinata
553   // Assign labels to the cluster
554   // add the cluster to the array
555   // for more details - See  AliTPCTranform::Transform(x,i,0,1) 
556   Float_t meani = c.GetPad();
557   Float_t meanj = c.GetTimeBin();
558
559   Int_t ki = TMath::Nint(meani);
560   if (ki<0) ki=0;
561   if (ki>=fMaxPad) ki = fMaxPad-1;
562   Int_t kj = TMath::Nint(meanj);
563   if (kj<0) kj=0;
564   if (kj>=fMaxTime-3) kj=fMaxTime-4;
565   // ki and kj shifted as integers coordinata
566   if (fRowDig) {
567     c.SetLabel(fRowDig->GetTrackIDFast(kj,ki,0)-2,0);
568     c.SetLabel(fRowDig->GetTrackIDFast(kj,ki,1)-2,1);
569     c.SetLabel(fRowDig->GetTrackIDFast(kj,ki,2)-2,2);
570   }
571   
572   c.SetRow(fRow);
573   c.SetDetector(fSector);
574   Float_t s2 = c.GetSigmaY2();
575   Float_t w=fParam->GetPadPitchWidth(fSector);
576   c.SetSigmaY2(s2*w*w);
577   s2 = c.GetSigmaZ2(); 
578   c.SetSigmaZ2(s2*fZWidth*fZWidth);
579   //
580   //
581   //
582   AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
583   if (!transform) {
584     AliFatal("Tranformations not in calibDB");
585   }
586   Double_t x[3]={c.GetRow(),c.GetPad(),c.GetTimeBin()};
587   Int_t i[1]={fSector};
588   transform->Transform(x,i,0,1);
589   c.SetX(x[0]);
590   c.SetY(x[1]);
591   c.SetZ(x[2]);
592   //
593   //
594   if (!fRecoParam->GetBYMirror()){
595     if (fSector%36>17){
596       c.SetY(-c.GetY());
597     }
598   }
599
600   if (ki<=1 || ki>=fMaxPad-1 || kj==1 || kj==fMaxTime-2) {
601     c.SetType(-(c.GetType()+3));  //edge clusters
602   }
603   if (fLoop==2) c.SetType(100);
604
605   TClonesArray * arr = fRowCl->GetArray();
606   AliTPCclusterMI * cl = new ((*arr)[fNcluster]) AliTPCclusterMI(c);
607   // if (fRecoParam->DumpSignal() &&matrix ) {
608 //     Int_t nbins=0;
609 //     Float_t *graph =0;
610 //     if (fRecoParam->GetCalcPedestal() && cl->GetMax()>fRecoParam->GetDumpAmplitudeMin() &&fBDumpSignal){
611 //       nbins = fMaxTime;
612 //       graph = &(fBins[fMaxTime*(pos/fMaxTime)]);
613 //     }
614 //     AliTPCclusterInfo * info = new AliTPCclusterInfo(matrix,nbins,graph);
615 //     cl->SetInfo(info);
616 //   }
617   if (!fRecoParam->DumpSignal()) {
618     cl->SetInfo(0);
619   }
620
621   fNcluster++;
622 }
623
624
625 //_____________________________________________________________________________
626 void AliTPCclustererMI::Digits2Clusters()
627 {
628   //-----------------------------------------------------------------
629   // This is a simple cluster finder.
630   //-----------------------------------------------------------------
631
632   if (!fInput) { 
633     Error("Digits2Clusters", "input tree not initialised");
634     return;
635   }
636  
637   AliTPCCalPad * gainTPC = AliTPCcalibDB::Instance()->GetPadGainFactor();
638   AliTPCCalPad * noiseTPC = AliTPCcalibDB::Instance()->GetPadNoise();
639   AliSimDigits digarr, *dummy=&digarr;
640   fRowDig = dummy;
641   fInput->GetBranch("Segment")->SetAddress(&dummy);
642   Stat_t nentries = fInput->GetEntries();
643   
644   fMaxTime=fRecoParam->GetLastBin()+6; // add 3 virtual time bins before and 3   after
645     
646   Int_t nclusters  = 0;
647
648   for (Int_t n=0; n<nentries; n++) {
649     fInput->GetEvent(n);
650     if (!fParam->AdjustSectorRow(digarr.GetID(),fSector,fRow)) {
651       cerr<<"AliTPC warning: invalid segment ID ! "<<digarr.GetID()<<endl;
652       continue;
653     }
654     Int_t row = fRow;
655     AliTPCCalROC * gainROC = gainTPC->GetCalROC(fSector);  // pad gains per given sector
656     AliTPCCalROC * noiseROC   = noiseTPC->GetCalROC(fSector); // noise per given sector
657     //
658
659     fRowCl->SetID(digarr.GetID());
660     if (fOutput) fOutput->GetBranch("Segment")->SetAddress(&fRowCl);
661     fRx=fParam->GetPadRowRadii(fSector,row);
662     
663     
664     const Int_t kNIS=fParam->GetNInnerSector(), kNOS=fParam->GetNOuterSector();
665     fZWidth = fParam->GetZWidth();
666     if (fSector < kNIS) {
667       fMaxPad = fParam->GetNPadsLow(row);
668       fSign = (fSector < kNIS/2) ? 1 : -1;
669       fPadLength = fParam->GetPadPitchLength(fSector,row);
670       fPadWidth = fParam->GetPadPitchWidth();
671     } else {
672       fMaxPad = fParam->GetNPadsUp(row);
673       fSign = ((fSector-kNIS) < kNOS/2) ? 1 : -1;
674       fPadLength = fParam->GetPadPitchLength(fSector,row);
675       fPadWidth  = fParam->GetPadPitchWidth();
676     }
677     
678     
679     fMaxBin=fMaxTime*(fMaxPad+6);  // add 3 virtual pads  before and 3 after
680     fBins    =new Float_t[fMaxBin];
681     fSigBins =new Int_t[fMaxBin];
682     fNSigBins = 0;
683     memset(fBins,0,sizeof(Float_t)*fMaxBin);
684     
685     if (digarr.First()) //MI change
686       do {
687         Float_t dig=digarr.CurrentDigit();
688         if (dig<=fParam->GetZeroSup()) continue;
689         Int_t j=digarr.CurrentRow()+3, i=digarr.CurrentColumn()+3;
690         Float_t gain = gainROC->GetValue(row,digarr.CurrentColumn());
691         Int_t bin = i*fMaxTime+j;
692         fBins[bin]=dig/gain;
693         fSigBins[fNSigBins++]=bin;
694       } while (digarr.Next());
695     digarr.ExpandTrackBuffer();
696
697     FindClusters(noiseROC);
698     FillRow();
699     fRowCl->GetArray()->Clear();    
700     nclusters+=fNcluster;    
701     delete[] fBins;
702     delete[] fSigBins;
703   }  
704
705   Info("Digits2Clusters", "Number of found clusters : %d", nclusters);
706 }
707
708 void AliTPCclustererMI::Digits2Clusters(AliRawReader* rawReader)
709 {
710 //-----------------------------------------------------------------
711 // This is a cluster finder for the TPC raw data.
712 // The method assumes NO ordering of the altro channels.
713 // The pedestal subtraction can be switched on and off
714 // using an option of the TPC reconstructor
715 //-----------------------------------------------------------------
716
717
718   fRowDig = NULL;
719   AliTPCROC * roc = AliTPCROC::Instance();
720   AliTPCCalPad * gainTPC = AliTPCcalibDB::Instance()->GetPadGainFactor();
721   AliTPCCalPad * pedestalTPC = AliTPCcalibDB::Instance()->GetPedestals();
722   AliTPCCalPad * noiseTPC = AliTPCcalibDB::Instance()->GetPadNoise();
723   AliTPCAltroMapping** mapping =AliTPCcalibDB::Instance()->GetMapping();
724   //
725   AliTPCRawStream input(rawReader,(AliAltroMapping**)mapping);
726   fEventHeader = (AliRawEventHeaderBase*)rawReader->GetEventHeader();
727   if (fEventHeader){
728     fTimeStamp = fEventHeader->Get("Timestamp");  
729     fEventType = fEventHeader->Get("Type");  
730   }
731
732
733   Int_t nclusters  = 0;
734   
735   fMaxTime = fRecoParam->GetLastBin() + 6; // add 3 virtual time bins before and 3 after
736   const Int_t kNIS = fParam->GetNInnerSector();
737   const Int_t kNOS = fParam->GetNOuterSector();
738   const Int_t kNS = kNIS + kNOS;
739   fZWidth = fParam->GetZWidth();
740   Int_t zeroSup = fParam->GetZeroSup();
741   //
742   //alocate memory for sector - maximal case
743   //
744   Float_t** allBins = NULL;
745   Int_t** allSigBins = NULL;
746   Int_t*  allNSigBins = NULL;
747   Int_t nRowsMax = roc->GetNRows(roc->GetNSector()-1);
748   Int_t nPadsMax = roc->GetNPads(roc->GetNSector()-1,nRowsMax-1);
749   allBins = new Float_t*[nRowsMax];
750   allSigBins = new Int_t*[nRowsMax];
751   allNSigBins = new Int_t[nRowsMax];
752   for (Int_t iRow = 0; iRow < nRowsMax; iRow++) {
753     //
754     Int_t maxBin = fMaxTime*(nPadsMax+6);  // add 3 virtual pads  before and 3 after
755     allBins[iRow] = new Float_t[maxBin];
756     memset(allBins[iRow],0,sizeof(Float_t)*maxBin);
757     allSigBins[iRow] = new Int_t[maxBin];
758     allNSigBins[iRow]=0;
759   }
760   //
761   // Loop over sectors
762   //
763   for(fSector = 0; fSector < kNS; fSector++) {
764
765     AliTPCCalROC * gainROC    = gainTPC->GetCalROC(fSector);  // pad gains per given sector
766     AliTPCCalROC * pedestalROC = pedestalTPC->GetCalROC(fSector);  // pedestal per given sector
767     AliTPCCalROC * noiseROC   = noiseTPC->GetCalROC(fSector);  // noise per given sector
768     //check the presence of the calibration
769     if (!noiseROC ||!pedestalROC ) {
770       AliError(Form("Missing calibration per sector\t%d\n",fSector));
771       continue;
772     }
773     Int_t nRows = 0;
774     Int_t nDDLs = 0, indexDDL = 0;
775     if (fSector < kNIS) {
776       nRows = fParam->GetNRowLow();
777       fSign = (fSector < kNIS/2) ? 1 : -1;
778       nDDLs = 2;
779       indexDDL = fSector * 2;
780     }
781     else {
782       nRows = fParam->GetNRowUp();
783       fSign = ((fSector-kNIS) < kNOS/2) ? 1 : -1;
784       nDDLs = 4;
785       indexDDL = (fSector-kNIS) * 4 + kNIS * 2;
786     }
787
788     for (Int_t iRow = 0; iRow < nRows; iRow++) {
789       Int_t maxPad;
790       if (fSector < kNIS)
791         maxPad = fParam->GetNPadsLow(iRow);
792       else
793         maxPad = fParam->GetNPadsUp(iRow);
794       
795       Int_t maxBin = fMaxTime*(maxPad+6);  // add 3 virtual pads  before and 3 after
796       memset(allBins[iRow],0,sizeof(Float_t)*maxBin);
797       allNSigBins[iRow] = 0;
798     }
799     
800     // Loas the raw data for corresponding DDLs
801     rawReader->Reset();
802     rawReader->Select("TPC",indexDDL,indexDDL+nDDLs-1);
803     Int_t digCounter=0;
804     // Begin loop over altro data
805     Bool_t calcPedestal = fRecoParam->GetCalcPedestal();
806     Float_t gain =1;
807     Int_t lastPad=-1;
808     while (input.Next()) {
809       if (input.GetSector() != fSector)
810         AliFatal(Form("Sector index mismatch ! Expected (%d), but got (%d) !",fSector,input.GetSector()));
811
812       
813       Int_t iRow = input.GetRow();
814       if (iRow < 0 || iRow >= nRows){
815         AliError(Form("Pad-row index (%d) outside the range (%d -> %d) !",
816                       iRow, 0, nRows -1));
817         continue;
818       }
819       //pad
820       Int_t iPad = input.GetPad();
821       if (iPad < 0 || iPad >= nPadsMax) {
822         AliError(Form("Pad index (%d) outside the range (%d -> %d) !",
823                       iPad, 0, nPadsMax-1));
824         continue;
825       }
826       if (iPad!=lastPad){
827         gain    = gainROC->GetValue(iRow,iPad);
828         lastPad = iPad;
829       }
830       iPad+=3;
831       //time
832       Int_t iTimeBin = input.GetTime();
833       if ( iTimeBin < fRecoParam->GetFirstBin() || iTimeBin >= fRecoParam->GetLastBin()){
834         continue;
835         AliFatal(Form("Timebin index (%d) outside the range (%d -> %d) !",
836                       iTimeBin, 0, iTimeBin -1));
837       }
838       iTimeBin+=3;
839
840       //signal
841       Float_t signal = input.GetSignal();
842       if (!calcPedestal && signal <= zeroSup) continue;      
843       if (!calcPedestal) {
844         Int_t bin = iPad*fMaxTime+iTimeBin;
845         allBins[iRow][bin] = signal/gain;
846         allSigBins[iRow][allNSigBins[iRow]++] = bin;
847       }else{
848         allBins[iRow][iPad*fMaxTime+iTimeBin] = signal;
849       }
850       allBins[iRow][iPad*fMaxTime+0]+=1.;  // pad with signal
851
852       // Temporary
853       digCounter++;
854     } // End of the loop over altro data
855     //
856     //
857     //
858     //
859     // Now loop over rows and perform pedestal subtraction
860     if (digCounter==0) continue;
861     //    if (calcPedestal) {
862     if (kTRUE) {
863       for (Int_t iRow = 0; iRow < nRows; iRow++) {
864         Int_t maxPad;
865         if (fSector < kNIS)
866           maxPad = fParam->GetNPadsLow(iRow);
867         else
868           maxPad = fParam->GetNPadsUp(iRow);
869
870         for (Int_t iPad = 3; iPad < maxPad + 3; iPad++) {
871           //
872           // Temporary fix for data production - !!!! MARIAN
873           // The noise calibration should take mean and RMS - currently the Gaussian fit used
874           // In case of double peak  - the pad should be rejected
875           //
876           // Line mean - if more than given digits over threshold - make a noise calculation
877           // and pedestal substration
878           if (!calcPedestal && allBins[iRow][iPad*fMaxTime+0]<50) continue;
879           //
880           if (allBins[iRow][iPad*fMaxTime+0] <1 ) continue;  // no data
881           Float_t *p = &allBins[iRow][iPad*fMaxTime+3];
882           //Float_t pedestal = TMath::Median(fMaxTime, p);      
883           Int_t id[3] = {fSector, iRow, iPad-3};
884           // calib values
885           Double_t rmsCalib=  noiseROC->GetValue(iRow,iPad-3);
886           Double_t pedestalCalib = pedestalROC->GetValue(iRow,iPad-3);
887           Double_t rmsEvent       = rmsCalib;
888           Double_t pedestalEvent  = pedestalCalib;
889           ProcesSignal(p, fMaxTime, id, rmsEvent, pedestalEvent);
890           if (rmsEvent<rmsCalib) rmsEvent = rmsCalib;   // take worst scenario
891           if (TMath::Abs(pedestalEvent-pedestalCalib)<1.0) pedestalEvent = pedestalCalib;  
892           
893           //
894           for (Int_t iTimeBin = 0; iTimeBin < fMaxTime; iTimeBin++) {
895             Int_t bin = iPad*fMaxTime+iTimeBin;
896             allBins[iRow][bin] -= pedestalEvent;
897             if (iTimeBin < AliTPCReconstructor::GetRecoParam()->GetFirstBin())  
898               allBins[iRow][bin] = 0;
899             if (iTimeBin > AliTPCReconstructor::GetRecoParam()->GetLastBin())  
900               allBins[iRow][bin] = 0;
901             if (allBins[iRow][iPad*fMaxTime+iTimeBin] < zeroSup)
902               allBins[iRow][bin] = 0;
903             if (allBins[iRow][bin] < 3.0*rmsEvent)   // 3 sigma cut on RMS
904               allBins[iRow][bin] = 0;
905             if (allBins[iRow][bin]) allSigBins[iRow][allNSigBins[iRow]++] = bin;
906           }
907         }
908       }
909     }
910     // Now loop over rows and find clusters
911     for (fRow = 0; fRow < nRows; fRow++) {
912       fRowCl->SetID(fParam->GetIndex(fSector, fRow));
913       if (fOutput) fOutput->GetBranch("Segment")->SetAddress(&fRowCl);
914
915       fRx = fParam->GetPadRowRadii(fSector, fRow);
916       fPadLength = fParam->GetPadPitchLength(fSector, fRow);
917       fPadWidth  = fParam->GetPadPitchWidth();
918       if (fSector < kNIS)
919         fMaxPad = fParam->GetNPadsLow(fRow);
920       else
921         fMaxPad = fParam->GetNPadsUp(fRow);
922       fMaxBin = fMaxTime*(fMaxPad+6);  // add 3 virtual pads  before and 3 after
923
924       fBins = allBins[fRow];
925       fSigBins = allSigBins[fRow];
926       fNSigBins = allNSigBins[fRow];
927
928       FindClusters(noiseROC);
929       FillRow();
930       fRowCl->GetArray()->Clear();    
931       nclusters += fNcluster;    
932     } // End of loop to find clusters
933   } // End of loop over sectors
934   
935   for (Int_t iRow = 0; iRow < nRowsMax; iRow++) {
936     delete [] allBins[iRow];
937     delete [] allSigBins[iRow];
938   }  
939   delete [] allBins;
940   delete [] allSigBins;
941   delete [] allNSigBins;
942   
943 //   if (rawReader->GetEventId() && fOutput ){
944 //     Info("Digits2Clusters", "File  %s Event\t%d\tNumber of found clusters : %d\n", fOutput->GetName(),*(rawReader->GetEventId()), nclusters);
945 //   }else{
946 //     Info("Digits2Clusters", "Event\t%d\tNumber of found clusters : %d\n",*(rawReader->GetEventId()), nclusters);
947     
948 //   }
949   
950 }
951
952 void AliTPCclustererMI::FindClusters(AliTPCCalROC * noiseROC)
953 {
954   
955   //
956   // add virtual charge at the edge   
957   //
958   Double_t kMaxDumpSize = 500000;
959   if (!fOutput) {
960     fBDumpSignal =kFALSE;
961   }else{
962     if (fRecoParam->GetCalcPedestal() && fOutput->GetZipBytes()< kMaxDumpSize) fBDumpSignal =kTRUE;   //dump signal flag
963   }
964    
965   fNcluster=0;
966   fLoop=1;
967   Int_t crtime = Int_t((fParam->GetZLength(fSector)-fRecoParam->GetCtgRange()*fRx)/fZWidth-fParam->GetNTBinsL1()-5);
968   Float_t minMaxCutAbs       = fRecoParam->GetMinMaxCutAbs();
969   Float_t minLeftRightCutAbs = fRecoParam->GetMinLeftRightCutAbs();
970   Float_t minUpDownCutAbs    = fRecoParam->GetMinUpDownCutAbs();
971   Float_t minMaxCutSigma       = fRecoParam->GetMinMaxCutSigma();
972   Float_t minLeftRightCutSigma = fRecoParam->GetMinLeftRightCutSigma();
973   Float_t minUpDownCutSigma    = fRecoParam->GetMinUpDownCutSigma();
974   for (Int_t iSig = 0; iSig < fNSigBins; iSig++) {
975     Int_t i = fSigBins[iSig];
976     if (i%fMaxTime<=crtime) continue;
977     Float_t *b = &fBins[i];
978     //absolute custs
979     if (b[0]<minMaxCutAbs) continue;   //threshold for maxima  
980     //
981     if (b[-1]+b[1]+b[-fMaxTime]+b[fMaxTime]<=0) continue;  // cut on isolated clusters 
982     if (b[-1]+b[1]<=0) continue;               // cut on isolated clusters
983     if (b[-fMaxTime]+b[fMaxTime]<=0) continue; // cut on isolated clusters
984     //
985     if ((b[0]+b[-1]+b[1])<minUpDownCutAbs) continue;   //threshold for up down  (TRF) 
986     if ((b[0]+b[-fMaxTime]+b[fMaxTime])<minLeftRightCutAbs) continue;   //threshold for left right (PRF)    
987     if (!IsMaximum(*b,fMaxTime,b)) continue;
988     //
989     Float_t noise = noiseROC->GetValue(fRow, i/fMaxTime);
990     if (noise>fRecoParam->GetMaxNoise()) continue;
991     // sigma cuts
992     if (b[0]<minMaxCutSigma*noise) continue;   //threshold form maxima  
993     if ((b[0]+b[-1]+b[1])<minUpDownCutSigma*noise) continue;   //threshold for up town TRF 
994     if ((b[0]+b[-fMaxTime]+b[fMaxTime])<minLeftRightCutSigma*noise) continue;   //threshold for left right (PRF)    
995   
996     AliTPCclusterMI c;   // default cosntruction  without info
997     Int_t dummy=0;
998     MakeCluster(i, fMaxTime, fBins, dummy,c);
999     
1000     //}
1001   }
1002 }
1003
1004
1005 Double_t AliTPCclustererMI::ProcesSignal(Float_t *signal, Int_t nchannels, Int_t id[3], Double_t &rmsEvent, Double_t &pedestalEvent){
1006   //
1007   // process signal on given pad - + streaming of additional information in special mode
1008   //
1009   // id[0] - sector
1010   // id[1] - row
1011   // id[2] - pad 
1012
1013   //
1014   // ESTIMATE pedestal and the noise
1015   // 
1016   const Int_t kPedMax = 100;
1017   Double_t kMaxDebugSize = 5000000.;
1018   Float_t  max    =  0;
1019   Float_t  maxPos =  0;
1020   Int_t    median =  -1;
1021   Int_t    count0 =  0;
1022   Int_t    count1 =  0;
1023   Float_t  rmsCalib   = rmsEvent;       // backup initial value ( from calib)
1024   Float_t  pedestalCalib = pedestalEvent;// backup initial value ( from calib)
1025   Int_t    firstBin = AliTPCReconstructor::GetRecoParam()->GetFirstBin();
1026   //
1027   UShort_t histo[kPedMax];
1028   memset(histo,0,kPedMax*sizeof(UShort_t));
1029   for (Int_t i=0; i<fMaxTime; i++){
1030     if (signal[i]<=0) continue;
1031     if (signal[i]>max && i>firstBin) {
1032       max = signal[i];
1033       maxPos = i;
1034     }
1035     if (signal[i]>kPedMax-1) continue;
1036     histo[int(signal[i]+0.5)]++;
1037     count0++;
1038   }
1039   //
1040   for (Int_t i=1; i<kPedMax; i++){
1041     if (count1<count0*0.5) median=i;
1042     count1+=histo[i];
1043   }
1044   // truncated mean  
1045   //
1046   Float_t count10=histo[median] ,mean=histo[median]*median,  rms=histo[median]*median*median ;
1047   Float_t count06=histo[median] ,mean06=histo[median]*median,  rms06=histo[median]*median*median ;
1048   Float_t count09=histo[median] ,mean09=histo[median]*median,  rms09=histo[median]*median*median ;
1049   //
1050   for (Int_t idelta=1; idelta<10; idelta++){
1051     if (median-idelta<=0) continue;
1052     if (median+idelta>kPedMax) continue;
1053     if (count06<0.6*count1){
1054       count06+=histo[median-idelta];
1055       mean06 +=histo[median-idelta]*(median-idelta);
1056       rms06  +=histo[median-idelta]*(median-idelta)*(median-idelta);
1057       count06+=histo[median+idelta];
1058       mean06 +=histo[median+idelta]*(median+idelta);
1059       rms06  +=histo[median+idelta]*(median+idelta)*(median+idelta);
1060     }
1061     if (count09<0.9*count1){
1062       count09+=histo[median-idelta];
1063       mean09 +=histo[median-idelta]*(median-idelta);
1064       rms09  +=histo[median-idelta]*(median-idelta)*(median-idelta);
1065       count09+=histo[median+idelta];
1066       mean09 +=histo[median+idelta]*(median+idelta);
1067       rms09  +=histo[median+idelta]*(median+idelta)*(median+idelta);
1068     }
1069     if (count10<0.95*count1){
1070       count10+=histo[median-idelta];
1071       mean +=histo[median-idelta]*(median-idelta);
1072       rms  +=histo[median-idelta]*(median-idelta)*(median-idelta);
1073       count10+=histo[median+idelta];
1074       mean +=histo[median+idelta]*(median+idelta);
1075       rms  +=histo[median+idelta]*(median+idelta)*(median+idelta);
1076     }
1077   }
1078   if (count10) {
1079     mean  /=count10;
1080     rms    = TMath::Sqrt(TMath::Abs(rms/count10-mean*mean));
1081   }
1082   if (count06) {
1083     mean06/=count06;
1084     rms06    = TMath::Sqrt(TMath::Abs(rms06/count06-mean06*mean06));
1085   }
1086   if (count09) {
1087     mean09/=count09;
1088     rms09    = TMath::Sqrt(TMath::Abs(rms09/count09-mean09*mean09));
1089   }
1090   rmsEvent = rms09;
1091   //
1092   pedestalEvent = median;
1093   if (AliLog::GetDebugLevel("","AliTPCclustererMI")==0) return median;
1094   //
1095   UInt_t uid[3] = {UInt_t(id[0]),UInt_t(id[1]),UInt_t(id[2])};
1096   //
1097   // Dump mean signal info
1098   //
1099   (*fDebugStreamer)<<"Signal"<<
1100     "TimeStamp="<<fTimeStamp<<
1101     "EventType="<<fEventType<<
1102     "Sector="<<uid[0]<<
1103     "Row="<<uid[1]<<
1104     "Pad="<<uid[2]<<
1105     "Max="<<max<<
1106     "MaxPos="<<maxPos<<
1107     //
1108     "Median="<<median<<
1109     "Mean="<<mean<<
1110     "RMS="<<rms<<      
1111     "Mean06="<<mean06<<
1112     "RMS06="<<rms06<<
1113     "Mean09="<<mean09<<
1114     "RMS09="<<rms09<<
1115     "RMSCalib="<<rmsCalib<<
1116     "PedCalib="<<pedestalCalib<<
1117     "\n";
1118   //
1119   // fill pedestal histogram
1120   //
1121   AliTPCROC * roc = AliTPCROC::Instance();
1122
1123   //
1124   //
1125   //
1126   Float_t kMin =fRecoParam->GetDumpAmplitudeMin();   // minimal signal to be dumped
1127   Float_t *dsignal = new Float_t[nchannels];
1128   Float_t *dtime   = new Float_t[nchannels];
1129   for (Int_t i=0; i<nchannels; i++){
1130     dtime[i] = i;
1131     dsignal[i] = signal[i];
1132   }
1133
1134   TGraph * graph=0;
1135   //
1136   // Big signals dumping
1137   //    
1138   if (max-median>kMin &&maxPos>AliTPCReconstructor::GetRecoParam()->GetFirstBin()) 
1139     (*fDebugStreamer)<<"SignalB"<<     // pads with signal
1140       "TimeStamp="<<fTimeStamp<<
1141       "EventType="<<fEventType<<
1142       "Sector="<<uid[0]<<
1143       "Row="<<uid[1]<<
1144       "Pad="<<uid[2]<<
1145       "Graph="<<graph<<
1146       "Max="<<max<<
1147       "MaxPos="<<maxPos<<       
1148       //
1149       "Median="<<median<<
1150       "Mean="<<mean<<
1151       "RMS="<<rms<<      
1152       "Mean06="<<mean06<<
1153       "RMS06="<<rms06<<
1154       "Mean09="<<mean09<<
1155       "RMS09="<<rms09<<
1156       "\n";
1157   delete graph;  
1158
1159   delete [] dsignal;
1160   delete [] dtime;
1161   if (rms06>fRecoParam->GetMaxNoise()) {
1162     pedestalEvent+=1024.;
1163     return 1024+median; // sign noisy channel in debug mode
1164   }
1165   return median;
1166 }
1167
1168
1169
1170
1171