]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/comp/AliL3Modeller.cxx
Added new function AliL3Modeller::CheckCluster. Function checks if the
[u/mrichter/AliRoot.git] / HLT / comp / AliL3Modeller.cxx
1 //$Id$
2
3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright &copy ASV
5
6 #include "AliL3StandardIncludes.h"
7
8 #include "AliL3Modeller.h"
9 #include "AliL3MemHandler.h"
10 #ifdef use_aliroot
11 #include "AliL3FileHandler.h"
12 #endif
13 #include "AliL3TrackArray.h"
14 #include "AliL3ModelTrack.h"
15 #include "AliL3DigitData.h"
16 #include "AliL3Transform.h"
17
18 #if GCCVERSION == 3
19 using namespace std;
20 #endif
21
22 //_____________________________________________________________
23 // AliL3Modeller
24 //
25 // Class for modeling TPC data.
26 // 
27 // This performs the cluster finding, based on track parameters.
28 // Basically it propagates the tracks to all padrows, and looks 
29 // for a corresponding cluster. For the moment only cog is calculated,
30 // and no deconvolution is done. 
31
32 ClassImp(AliL3Modeller)
33
34 AliL3Modeller::AliL3Modeller()
35 {
36   fMemHandler=0;
37   fTracks=0;
38   fTrackThreshold=0;
39   SetOverlap();
40   SetTrackThreshold();
41   SetSearchRange();
42 }
43
44
45 AliL3Modeller::~AliL3Modeller()
46 {
47   if(fMemHandler)
48     delete fMemHandler;
49   if(fTracks)
50     delete fTracks;
51 }
52
53 void AliL3Modeller::Init(Int_t slice,Int_t patch,Char_t *trackdata,Char_t *path,Bool_t houghtracks,Bool_t binary)
54 {
55   fSlice = slice;
56   fPatch = patch;
57
58   sprintf(fPath,"%s",path);
59   
60   fTracks = new AliL3TrackArray("AliL3ModelTrack");
61   
62   Char_t fname[100];
63   AliL3MemHandler *file = new AliL3MemHandler();
64   //sprintf(fname,"%s/tracks_tr_%d_0.raw",trackdata,fSlice); //output tracks from the tracker (no merging)
65   sprintf(fname,"%s/tracks_ho_%d.raw",trackdata,fSlice);
66   if(!file->SetBinaryInput(fname))
67     {
68       cerr<<"AliL3Modeller::Init : Error opening trackfile: "<<fname<<endl;
69       return;
70     }
71   file->Binary2TrackArray(fTracks);
72   file->CloseBinaryInput();
73   delete file;
74   
75
76   if(!houghtracks)
77     fTracks->QSort();
78   
79   for(Int_t i=0; i<fTracks->GetNTracks(); i++)
80     {
81       AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
82       if(!track) continue;
83       track->Init(fSlice,fPatch);
84
85       //Only if the tracks has been merged across sector boundaries:
86       //if(!houghtracks)
87       //track->Rotate(fSlice,kTRUE); //!!!!!!!!!!!!!!!!!!!
88       
89       track->CalculateHelix();
90     }    
91   
92   CalculateCrossingPoints();
93   
94   CheckForOverlaps();
95   
96   UInt_t ndigits=0;
97   AliL3DigitRowData *digits=0;
98 #ifdef use_aliroot
99   fMemHandler = new AliL3FileHandler();
100   fMemHandler->Init(slice,patch);
101   if(binary == kFALSE)
102     {
103       sprintf(fname,"%s/digitfile.root",fPath);
104       fMemHandler->SetAliInput(fname);
105       digits = fMemHandler->AliDigits2Memory(ndigits);
106     }
107   else
108     {
109       sprintf(fname,"%sdigits_%d_%d.raw",fPath,fSlice,fPatch);
110       if(!fMemHandler->SetBinaryInput(fname))
111         {
112           cerr<<"AliL3Modeller::Init : Error opening file "<<fname<<endl;
113           return;
114         }
115       digits=(AliL3DigitRowData*)fMemHandler->CompBinary2Memory(ndigits);
116     }
117 #else
118   fMemHandler = new AliL3MemHandler();
119   fMemHandler->Init(slice,patch);
120   if(binary == kFALSE)
121     {
122       cerr<<"AliL3Modeller::Init : Compile with AliROOT if you want rootfile as input"<<endl;
123       return;
124     }
125   else
126     {
127       sprintf(fname,"%sdigits_%d_%d.raw",fPath,fSlice,fPatch);
128       if(!fMemHandler->SetBinaryInput(fname))
129         {
130           cerr<<"AliL3Modeller::Init : Error opening file "<<fname<<endl;
131           return;
132         }
133     }
134   digits=(AliL3DigitRowData*)fMemHandler->CompBinary2Memory(ndigits);
135 #endif
136   
137   SetInputData(digits);
138 }
139
140 void AliL3Modeller::FindClusters()
141 {
142   cout<<"AliL3Modeller::FindClusters : Processing slice "<<fSlice<<" patch "<<fPatch<<endl;
143   if(!fTracks)
144     {
145       cerr<<"AliL3Modeller::Process : No tracks"<<endl;
146       return;
147     }
148   if(!fRowData)
149     {
150       cerr<<"AliL3Modeller::Process : No data "<<endl;
151       return;
152     }
153   
154   AliL3DigitRowData *rowPt = fRowData;
155   AliL3DigitData *digPt=0;
156
157   Int_t ntimes = AliL3Transform::GetNTimeBins()+1;
158   Int_t npads = AliL3Transform::GetNPads(AliL3Transform::GetLastRow(fPatch))+1;//Max num of pads.
159   Int_t bounds = ntimes*npads;
160   Digit *row = new Digit[bounds];
161   
162   Int_t seq_charge;
163   Int_t pad,time,index;
164   Short_t charge;
165   Cluster cluster;
166
167   for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
168     {
169       fCurrentPadRow = i;
170       memset((void*)row,0,ntimes*npads*sizeof(Digit));
171       digPt = (AliL3DigitData*)rowPt->fDigitData;
172       //cout<<"Loading row "<<i<<" with "<<(Int_t)rowPt->fNDigit<<" digits"<<endl;
173       for(UInt_t j=0; j<rowPt->fNDigit; j++)
174         {
175           pad = digPt[j].fPad;
176           time = digPt[j].fTime;
177           charge = digPt[j].fCharge;
178           row[ntimes*pad+time].fCharge = charge;
179           row[ntimes*pad+time].fUsed = kFALSE;
180           //cout<<"Row "<<i<<" pad "<<pad<<" time "<<time<<" charge "<<charge<<endl;
181         }
182       
183       for(Int_t k=0; k<fTracks->GetNTracks(); k++)
184         {
185           AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(k);
186           if(!track) continue;
187           
188           if(track->GetPadHit(i)<0 || track->GetTimeHit(i)<0 || track->GetOverlap(i)>=0)
189             {
190               track->SetCluster(i,0,0,0,0,0,0); //The track has left the patch.
191               continue;
192             }
193           
194           Int_t hitpad = (Int_t)rint(track->GetPadHit(i));
195           Int_t hittime = (Int_t)rint(track->GetTimeHit(i));
196
197           if(!CheckCluster(row,hitpad,hittime)) //Not a good cluster.
198             {
199               track->SetCluster(i,0,0,0,0,0,0); 
200               continue;
201             }
202
203           //cout<<"Checking track on row "<<i<<" with pad "<<hitpad<<" time "<<hittime<<endl;
204           pad = hitpad;
205           time = hittime;
206
207           Int_t padsign=-1;
208           Int_t timesign=-1;
209           
210           memset(&cluster,0,sizeof(Cluster));
211           //cout<<"Processing padrow "<<i<<" with hittime "<<hittime<<" hitpad "<<hitpad<<" charge "<<row[ntimes*pad + time].fCharge<<" index "<<ntimes*pad + time<<endl;
212           Int_t npads=0;
213           Int_t last_mean = hittime;
214           while(1)//Process this padrow
215             {
216               if(pad < 0 || pad >= AliL3Transform::GetNPads(i)) 
217                 {
218                   //cout<<"Pad = "<<pad<<" on row "<<i<<endl;
219                   FillCluster(track,&cluster,i,npads);
220                   break;
221                 }
222               seq_charge=0;
223               timesign=-1;
224               time = hittime;
225               
226               while(1) //Process sequence on this pad:
227                 {
228                   if(time < 0 || time >= AliL3Transform::GetNTimeBins()) 
229                     break;
230                 
231                   index = ntimes*pad + time;
232                   if(index < 0 || index >= bounds)
233                     {
234                       cerr<<"AliL3Modeller::FindClusters : Index out of range : "<<index
235                         <<" on row "<<i<<" pad "<<pad<<" time "<<time<<endl;
236                       break;
237                     }
238                   
239                   charge = row[index].fCharge;
240                   
241                   if(charge==0) //Empty timebin, so try and expand the search within the limits on this pad
242                     {
243                       if(seq_charge==0 && abs(time-hittime) <= fTimeSearch)//No sequence yet, keep looking
244                         {
245                           if(timesign==-1)
246                             time--;
247                           else
248                             time++;
249                           continue;
250                         }
251                       else if(timesign==-1) //Switch search direction
252                         {
253                           time = hittime + 1;
254                           timesign = 1;
255                           continue;
256                         }
257                       else //ok, boundary reached, this pad is done.
258                         break;
259                     }
260                   
261                   if(row[ntimes*pad+time].fUsed==kTRUE) //Don't use digits several times. This leads to mult. rec.tracks.
262                     {
263                       time += timesign;
264                       continue;
265                     }
266                   
267                   seq_charge += charge;
268                   
269                   //Update the cluster parameters with this timebin
270                   cluster.fTime += time*charge;
271                   cluster.fPad += pad*charge;
272                   cluster.fCharge += charge;
273                   cluster.fSigmaY2 += pad*pad*charge;
274                   cluster.fSigmaZ2 += time*time*charge;
275                   
276                   row[ntimes*pad+time].fUsed = kTRUE;
277                   time += timesign;
278                 }
279               
280               //Always compare with the current mean in time of the cluster under construction.
281               if(cluster.fCharge)
282                 last_mean = (Int_t)rint((Float_t)(cluster.fTime/cluster.fCharge));
283               
284               if(seq_charge)//There was something on this pad, so keep looking on the neighbouring pad
285                 {
286                   pad += padsign;
287                   npads++;
288                 }
289               else
290                 {
291                   if(cluster.fCharge==0 && abs(pad-hitpad) <= fPadSearch && pad > 0)
292                     {
293                       if(padsign==-1)
294                         pad--;
295                       else
296                         pad++;
297                       continue;
298                     }
299                   else if(padsign==-1)
300                     {
301                       pad = hitpad + 1;
302                       padsign = 1;
303                       continue;
304                     }
305                   else
306                     {
307                       FillCluster(track,&cluster,i,npads);
308                       break;
309                     }
310                 }
311             }
312           //cout<<"done"<<endl;
313         }
314       FillZeros(rowPt,row);
315       fMemHandler->UpdateRowPointer(rowPt);
316     }
317   delete [] row;
318   //cout<<"done processing"<<endl;
319   
320   
321   //Debug:
322   for(Int_t i=0; i<fTracks->GetNTracks(); i++)
323     {
324       AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
325       if(!track) continue;
326       if(track->GetNClusters() != AliL3Transform::GetNRows(fPatch))
327         cerr<<endl<<"Mismatching hitcounts; nclusters: "<<track->GetNClusters()<<" nrows "<<AliL3Transform::GetNRows(fPatch)<<endl<<endl;
328     }
329   
330 }
331
332 Bool_t AliL3Modeller::CheckCluster(Digit *row,Int_t hitpad,Int_t hittime)
333 {
334   Int_t ntimes = AliL3Transform::GetNTimeBins()+1;
335   Bool_t seq_was_falling=kFALSE;
336   Int_t last_seq_charge=0;
337   Int_t cluster_charge=0;
338   Int_t time,pad,charge,padsign=-1,timesign=-1;
339   time = hittime;
340   pad = hitpad;
341   //cout<<"Checking cluster "<<hitpad<<" hittime "<<hittime<<endl;
342   while(1)
343     {
344       
345       Bool_t last_was_falling=kFALSE;
346       Int_t last_charge=0;
347       Int_t seq_charge=0;
348       while(1)
349         {
350           
351           charge = row[(ntimes*pad+time)].fCharge;
352           //cout<<"Charge "<<charge<<" on pad "<<pad<<" time "<<time<<endl;
353           if(charge==0)
354             {
355               if(seq_charge==0 && abs(time-hittime) <= fTimeSearch)
356                 {
357                   if(timesign==-1)
358                     time--;
359                   else
360                     time++;
361                   continue;
362                 }
363               else if(timesign==-1)
364                 {
365                   last_charge = row[(ntimes*hitpad+hittime)].fCharge;
366                   time = hittime+1;
367                   timesign=1;
368                   if(last_charge < row[(ntimes*hitpad+(hittime-1))].fCharge)
369                     last_was_falling=kTRUE;
370                   else
371                     last_was_falling=kFALSE;
372                   continue;
373                 }
374               else
375                 break;
376             }
377
378           if(charge > last_charge)
379             {
380               if(last_was_falling) //This is a overlapping cluster.
381                 return kFALSE;
382             }
383           else
384             last_was_falling = kTRUE;
385
386           cluster_charge+=charge;
387           seq_charge += charge;
388           last_charge = charge;
389           time += timesign;
390         }
391       
392       if(seq_charge)
393         pad += padsign;
394       else
395         {
396           if(cluster_charge==0 && abs(pad-hitpad)<=fPadSearch && pad > 0)
397             {
398               if(padsign==-1)
399                 pad--;
400               else
401                 pad++;
402               continue;
403             }
404           else if(padsign==-1)
405             {
406               pad = hitpad+1;
407               padsign = 1;
408               seq_was_falling=kFALSE;
409               continue;
410             }
411           else
412             break;
413         }
414       
415       if(seq_charge > last_seq_charge)
416         {
417           if(seq_was_falling)
418             return kFALSE;
419           else
420             seq_was_falling=kTRUE;
421         }
422       last_seq_charge = seq_charge;
423     }
424   
425   return kTRUE;
426 }
427
428 void AliL3Modeller::FillCluster(AliL3ModelTrack *track,Cluster *cluster,Int_t row,Int_t npads)
429 {
430   if(cluster->fCharge==0)
431     {
432       track->SetCluster(row,0,0,0,0,0,0);
433       return;
434     }
435   Float_t fcharge = (Float_t)cluster->fCharge;
436   Float_t fpad = ((Float_t)cluster->fPad/fcharge);
437   Float_t ftime = ((Float_t)cluster->fTime/fcharge);
438   Float_t sigmaY2,sigmaZ2;
439   CalcClusterWidth(cluster,sigmaY2,sigmaZ2);
440   track->SetCluster(row,fpad,ftime,fcharge,sigmaY2,sigmaZ2,npads);
441 }
442
443 void AliL3Modeller::FillZeros(AliL3DigitRowData *rowPt,Digit *row)
444 {
445   //Fill zero where data has been used.
446   
447   Int_t ntimes = AliL3Transform::GetNTimeBins()+1;
448   AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
449   for(UInt_t j=0; j<rowPt->fNDigit; j++)
450     {
451       Int_t pad = digPt[j].fPad;
452       Int_t time = digPt[j].fTime;
453       if(row[ntimes*pad+time].fUsed==kTRUE)
454         digPt[j].fCharge = 0;
455     }
456 }
457
458 void AliL3Modeller::WriteRemaining()
459 {
460   //Write remaining (nonzero) digits to file.
461   
462   AliL3DigitRowData *rowPt;
463   rowPt = (AliL3DigitRowData*)fRowData;
464   Int_t digitcount=0;
465   Int_t ndigits[(AliL3Transform::GetNRows(fPatch))];
466   for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
467     {
468       AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
469       ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]=0;
470       for(UInt_t j=0; j<rowPt->fNDigit; j++)
471         {
472           if(digPt[j].fCharge==0) continue;
473           digitcount++;
474           ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]++;
475         }
476       //cout<<"Difference "<<(int)ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]<<" "<<(int)rowPt->fNDigit<<endl;
477       fMemHandler->UpdateRowPointer(rowPt);
478     }
479   
480   Int_t size = digitcount*sizeof(AliL3DigitData) + AliL3Transform::GetNRows(fPatch)*sizeof(AliL3DigitRowData);
481   Byte_t *data = new Byte_t[size];
482   memset(data,0,size);
483   AliL3DigitRowData *tempPt = (AliL3DigitRowData*)data;
484   rowPt = (AliL3DigitRowData*)fRowData;
485   
486   for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
487     {
488       Int_t localcount=0;
489       tempPt->fRow = i;
490       tempPt->fNDigit = ndigits[(i-AliL3Transform::GetFirstRow(fPatch))];
491       AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
492       for(UInt_t j=0; j<rowPt->fNDigit; j++)
493         {
494           if(digPt[j].fCharge==0) continue;
495           if(localcount >= ndigits[(i-AliL3Transform::GetFirstRow(fPatch))])
496             {
497               cerr<<"AliL3Modeller::WriteRemaining : Digitarray out of range!!"<<endl;
498               return;
499             }
500           tempPt->fDigitData[localcount].fCharge = digPt[j].fCharge;
501           tempPt->fDigitData[localcount].fPad = digPt[j].fPad;
502           tempPt->fDigitData[localcount].fTime = digPt[j].fTime;
503
504           localcount++;
505         }
506       if(ndigits[(i-AliL3Transform::GetFirstRow(fPatch))] != localcount)
507         {
508           cerr<<"AliL3Modeller::WriteRemaining : Mismatch in digitcount"<<endl;
509           return;
510         }
511       fMemHandler->UpdateRowPointer(rowPt);
512       Byte_t *tmp = (Byte_t*)tempPt;
513       Int_t size = sizeof(AliL3DigitRowData) + ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]*sizeof(AliL3DigitData);
514       tmp += size;
515       tempPt = (AliL3DigitRowData*)tmp;
516     }
517
518   Char_t fname[100];
519   AliL3MemHandler *mem = new AliL3MemHandler();
520   sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,fSlice,fPatch);
521   mem->SetBinaryOutput(fname);
522   mem->Memory2CompBinary((UInt_t)AliL3Transform::GetNRows(fPatch),(AliL3DigitRowData*)data);
523   mem->CloseBinaryOutput();
524   delete mem;
525   delete [] data;
526 }
527
528
529 void AliL3Modeller::CalculateCrossingPoints()
530 {
531   //cout<<"Calculating crossing points on "<<fTracks->GetNTracks()<<" tracks"<<endl;
532   if(!fTracks)
533     {
534       cerr<<"AliL3Modeller::CalculateCrossingPoints(): No tracks"<<endl;
535       return;
536     }
537   Float_t hit[3];
538   
539   Int_t sector,row;
540   for(Int_t i=AliL3Transform::GetLastRow(fPatch); i>=AliL3Transform::GetFirstRow(fPatch); i--)
541     {
542       for(Int_t j=0; j<fTracks->GetNTracks(); j++)
543         {
544           AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(j);
545           if(!track) continue;
546
547           if(!track->GetCrossingPoint(i,hit)) 
548             {
549               //cerr<<"AliL3Modeller::CalculateCrossingPoints : Track "<<j<<" does not intersect row "<<i<<" :"<<endl<<
550               //" pt "<<track->GetPt()<<
551               //" tgl "<<track->GetTgl()<<" psi "<<track->GetPsi()<<" charge "<<track->GetCharge()<<endl;
552                 //"Center "<<track->GetCenterX()<<" "<<track->GetCenterY()<<endl<<endl<<
553                 //"--------"<<endl;
554               fTracks->Remove(j);
555               continue;
556             }
557           //cout<<"X "<<hit[0]<<" Y "<<hit[1]<<" Z "<<hit[2]<<" tgl "<<track->GetTgl()<<endl;
558           
559           AliL3Transform::Slice2Sector(fSlice,i,sector,row);
560           AliL3Transform::Local2Raw(hit,sector,row);
561           //cout<<"Pad "<<hit[1]<<" time "<<hit[2]<<" in sector "<<sector<<" row "<<row<<endl;
562           if(hit[1]<0 || hit[1]>AliL3Transform::GetNPads(i) ||
563              hit[2]<0 || hit[2]>AliL3Transform::GetNTimeBins())
564             {//Track is leaving the patch, so flag the track hits (<0)
565               track->SetPadHit(i,-1);
566               track->SetTimeHit(i,-1);
567               continue;
568             }
569           
570           
571           track->SetPadHit(i,hit[1]);
572           track->SetTimeHit(i,hit[2]);
573           
574           //if(hit[1]<0 || hit[2]>445)
575           //if(hit[2]<0 || hit[2]>445)
576           //cout<<"pad "<<hit[1]<<" time "<<hit[2]<<" pt "<<track->GetPt()<<" psi "<<track->GetPsi()<<" tgl "<<track->GetTgl()<<" firstpoint "<<track->GetFirstPointX()<<" "<<track->GetFirstPointY()<<" "<<track->GetFirstPointZ()<<endl;
577           //cout<<"Crossing pad "<<hit[1]<<" time "<<hit[2]<<endl;
578         }
579     }
580   fTracks->Compress();
581   //cout<<"And there are "<<fTracks->GetNTracks()<<" tracks remaining"<<endl;
582 }
583
584 void AliL3Modeller::CheckForOverlaps()
585 {
586   //Flag the tracks that overlap
587   
588   //cout<<"Checking for overlaps...";
589   Int_t counter=0;
590   for(Int_t i=0; i<fTracks->GetNTracks(); i++)
591     {
592       AliL3ModelTrack *track1 = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
593       if(!track1) continue;
594       for(Int_t j=i+1; j<fTracks->GetNTracks(); j++)
595         {
596           AliL3ModelTrack *track2 = (AliL3ModelTrack*)fTracks->GetCheckedTrack(j);
597           if(!track2) continue;
598           for(Int_t k=AliL3Transform::GetFirstRow(fPatch); k<=AliL3Transform::GetLastRow(fPatch); k++)
599             {
600               if(track1->GetPadHit(k)<0 || track1->GetTimeHit(k)<0 ||
601                  track2->GetPadHit(k)<0 || track2->GetTimeHit(k)<0)
602                 continue;
603               
604               if(track1->GetOverlap(k)>=0 || track2->GetOverlap(k)>=0) continue;
605               
606               if(abs((Int_t)rint(track1->GetPadHit(k))-(Int_t)rint(track2->GetPadHit(k))) <= fPadOverlap &&
607                  abs((Int_t)rint(track1->GetTimeHit(k))-(Int_t)rint(track2->GetTimeHit(k))) <= fTimeOverlap)
608                 {
609                   track2->SetOverlap(k,i);
610                   //track1->SetOverlap(k,j);
611                   counter++;
612                 }
613             }
614         }
615     }
616   //cout<<"found "<<counter<<" done"<<endl;
617 }
618
619
620 void AliL3Modeller::CalcClusterWidth(Cluster *cl,Float_t &sigmaY2,Float_t &sigmaZ2)
621 {
622   
623   Float_t padw,timew;
624   
625   padw = AliL3Transform::GetPadPitchWidth(fPatch);
626   
627   Float_t charge = (Float_t)cl->fCharge;
628   Float_t pad = (Float_t)cl->fPad/charge;
629   Float_t time = (Float_t)cl->fTime/charge;
630   Float_t s2 = (Float_t)cl->fSigmaY2/charge - pad*pad;
631   
632   //Save the sigmas in pad and time:
633   
634   sigmaY2 = (s2);// + 1./12);//*padw*padw;
635   
636   /*Constants added by offline
637     if(s2 != 0)
638     {
639     sigmaY2 = sigmaY2*0.108;
640     if(fPatch<3)
641     sigmaY2 = sigmaY2*2.07;
642     }
643   */
644
645   s2 = (Float_t)cl->fSigmaZ2/charge - time*time;
646   timew = AliL3Transform::GetZWidth();
647   sigmaZ2 = (s2);// +1./12);//*timew*timew;
648   
649
650   
651   /*Constants added by offline
652     if(s2 != 0)
653     {
654     sigmaZ2 = sigmaZ2*0.169;
655     if(fPatch < 3)
656     sigmaZ2 = sigmaZ2*1.77;
657     }
658   */
659 }
660