]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/comp/AliL3ClusterFitter.cxx
Moved to the latest version of the HLT code in Bergen.
[u/mrichter/AliRoot.git] / HLT / comp / AliL3ClusterFitter.cxx
CommitLineData
3e87ef69 1// @(#) $Id$
6b8f6f6e 2
3// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
3e87ef69 4//*-- Copyright &copy ALICE HLT Group
6b8f6f6e 5
6#include "AliL3StandardIncludes.h"
3e87ef69 7
8#include "AliL3Logging.h"
6b8f6f6e 9#include "AliL3ClusterFitter.h"
10#include "AliL3FitUtilities.h"
6b8f6f6e 11#include "AliL3DigitData.h"
12#include "AliL3ModelTrack.h"
13#include "AliL3TrackArray.h"
14#include "AliL3MemHandler.h"
3e87ef69 15#include "AliL3HoughTrack.h"
16#include "AliL3SpacePointData.h"
17#include "AliL3Compress.h"
6b8f6f6e 18
19#if GCCVERSION == 3
20using namespace std;
21#endif
22
23//_____________________________________________________________
24//
25// AliL3ClusterFitter
26//
27
28
29ClassImp(AliL3ClusterFitter)
30
3e87ef69 31Int_t AliL3ClusterFitter::fBadFitError=0;
32Int_t AliL3ClusterFitter::fFitError=0;
33Int_t AliL3ClusterFitter::fResultError=0;
34Int_t AliL3ClusterFitter::fFitRangeError=0;
35
6b8f6f6e 36AliL3ClusterFitter::AliL3ClusterFitter()
37{
6b8f6f6e 38 plane=0;
39 fNmaxOverlaps = 3;
6f388e0d 40 fChiSqMax[0]=fChiSqMax[1]=fChiSqMax[2]=12;
3e87ef69 41 fRowMin=-1;
42 fRowMax=-1;
43 fFitted=0;
44 fFailed=0;
45 fYInnerWidthFactor=1;
46 fZInnerWidthFactor=1;
47 fYOuterWidthFactor=1;
48 fZOuterWidthFactor=1;
49 fSeeds=0;
50 fProcessTracks=0;
51 fClusters=0;
52 fNMaxClusters=0;
53 fNClusters=0;
b2a02bce 54 fEvent=0;
3e87ef69 55}
56
57AliL3ClusterFitter::AliL3ClusterFitter(Char_t *path)
58{
59 strcpy(fPath,path);
60 plane=0;
61 fNmaxOverlaps = 3;
6f388e0d 62 fChiSqMax[0]=fChiSqMax[1]=fChiSqMax[2]=12;
3e87ef69 63 fRowMin=-1;
64 fRowMax=-1;
65 fFitted=0;
66 fFailed=0;
67 fYInnerWidthFactor=1;
68 fZInnerWidthFactor=1;
69 fYOuterWidthFactor=1;
70 fZOuterWidthFactor=1;
71 fSeeds=0;
72 fProcessTracks=0;
73 fNMaxClusters=100000;
74 fClusters=0;
75 fNClusters=0;
b2a02bce 76 fEvent=0;
6b8f6f6e 77}
78
79AliL3ClusterFitter::~AliL3ClusterFitter()
80{
3e87ef69 81 if(fSeeds)
82 delete fSeeds;
83 if(fClusters)
84 delete [] fClusters;
85}
86
87void AliL3ClusterFitter::Init(Int_t slice,Int_t patch,Int_t *rowrange,AliL3TrackArray *tracks)
88{
89 //Assuming tracklets found by the line transform
90
91 fSlice=slice;
92 fPatch=patch;
93
94 if(rowrange[0] > AliL3Transform::GetLastRow(patch) || rowrange[1] < AliL3Transform::GetFirstRow(patch))
95 cerr<<"AliL3ClusterFitter::Init : Wrong rows "<<rowrange[0]<<" "<<rowrange[1]<<endl;
96 fRowMin=rowrange[0];
97 fRowMax=rowrange[1];
98
99 if(fRowMin < 0)
100 fRowMin = 0;
101 if(fRowMax > AliL3Transform::GetLastRow(fPatch))
102 fRowMax = AliL3Transform::GetLastRow(fPatch);
103
104 fFitted=fFailed=0;
105
106 Int_t ntimes = AliL3Transform::GetNTimeBins()+1;
107 Int_t npads = AliL3Transform::GetNPads(AliL3Transform::GetLastRow(fPatch))+1;//Max num of pads.
108 Int_t bounds = ntimes*npads;
109 if(fRow)
110 delete [] fRow;
111 fRow = new Digit[bounds];
112 if(fTracks)
113 delete fTracks;
114
115 fTracks = new AliL3TrackArray("AliL3ModelTrack");
116
117 for(Int_t i=0; i<tracks->GetNTracks(); i++)
118 {
119 AliL3HoughTrack *track = (AliL3HoughTrack*)tracks->GetCheckedTrack(i);
120 if(!track) continue;
121 AliL3ModelTrack *mtrack = (AliL3ModelTrack*)fTracks->NextTrack();
122 mtrack->Init(slice,patch);
123 mtrack->SetTgl(track->GetTgl());
124 mtrack->SetRowRange(rowrange[0],rowrange[1]);
125 for(Int_t j=fRowMin; j<=fRowMax; j++)
126 {
127 Float_t hit[3];
128 track->GetLineCrossingPoint(j,hit);
129 hit[0] += AliL3Transform::Row2X(track->GetFirstRow());
130 Float_t R = sqrt(hit[0]*hit[0] + hit[1]*hit[1]);
131 hit[2] = R*track->GetTgl();
132 Int_t se,ro;
133 AliL3Transform::Slice2Sector(slice,j,se,ro);
134 AliL3Transform::Local2Raw(hit,se,ro);
135 if(hit[1]<0 || hit[1]>=AliL3Transform::GetNPads(j) || hit[2]<0 || hit[2]>=AliL3Transform::GetNTimeBins())
136 {
137 mtrack->SetPadHit(j,-1);
138 mtrack->SetTimeHit(j,-1);
139 continue;
140 }
141 mtrack->SetPadHit(j,hit[1]);
142 mtrack->SetTimeHit(j,hit[2]);
143 mtrack->SetCrossingAngleLUT(j,fabs(track->GetPsiLine() - AliL3Transform::Pi()/2));
144 //if(mtrack->GetCrossingAngleLUT(j) > AliL3Transform::Deg2Rad(20))
145 // cout<<"Angle "<<mtrack->GetCrossingAngleLUT(j)<<" psiline "<<track->GetPsiLine()*180/3.1415<<endl;
146 mtrack->CalculateClusterWidths(j);
147 }
148 }
149 // cout<<"Copied "<<fTracks->GetNTracks()<<" tracks "<<endl;
150}
151
152void AliL3ClusterFitter::Init(Int_t slice,Int_t patch)
153{
154 fSlice=slice;
155 fPatch=patch;
b2a02bce 156
3e87ef69 157 fRowMin=AliL3Transform::GetFirstRow(patch);
158 fRowMax=AliL3Transform::GetLastRow(patch);
159
160 fFitted=fFailed=0;
161
162 Int_t ntimes = AliL3Transform::GetNTimeBins()+1;
163 Int_t npads = AliL3Transform::GetNPads(AliL3Transform::GetLastRow(fPatch))+1;//Max num of pads.
164 Int_t bounds = ntimes*npads;
165 if(fRow)
166 delete [] fRow;
167 fRow = new Digit[bounds];
168 if(fTracks)
169 delete fTracks;
170 fTracks = new AliL3TrackArray("AliL3ModelTrack");
171
172}
173
b2a02bce 174void AliL3ClusterFitter::LoadLocalSegments()
175{
176 Char_t filename[1024];
177 sprintf(filename,"%s/hough/tracks_ho_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
178 AliL3MemHandler mem;
179 mem.SetBinaryInput(filename);
180 mem.Binary2TrackArray(fTracks);
181 mem.CloseBinaryInput();
182
183 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
184 {
185 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
186 if(!track) continue;
187
188 track->CalculateHelix();
189
190 track->Init(fSlice,fPatch);
191
192 for(Int_t j=fRowMin; j<=fRowMax; j++)
193 {
194 //Calculate the crossing point between track and padrow
195
196 Float_t xyz_cross[3];
197 if(!track->GetCrossingPoint(j,xyz_cross))
198 continue;
199
200 Int_t sector,row;
201 AliL3Transform::Slice2Sector(fSlice,j,sector,row);
202 AliL3Transform::Local2Raw(xyz_cross,sector,row);
203
204 if(xyz_cross[1] < 0 || xyz_cross[1] >= AliL3Transform::GetNPads(j) ||
205 xyz_cross[2] < 0 || xyz_cross[2] >= AliL3Transform::GetNTimeBins()) //track goes out of range
206 continue;
207
208 track->SetPadHit(j,xyz_cross[1]);
209 track->SetTimeHit(j,xyz_cross[2]);
210
211 Float_t crossingangle = track->GetCrossingAngle(j);
212 track->SetCrossingAngleLUT(j,crossingangle);
213 track->CalculateClusterWidths(j);
214 track->GetClusterModel(j)->fSlice = fSlice;
215
216 }
217 }
218}
6b8f6f6e 219
b2a02bce 220void AliL3ClusterFitter::LoadSeeds(Int_t *rowrange,Bool_t offline,Int_t eventnr)
3e87ef69 221{
b2a02bce 222 //Function assumes _global_ tracks written to a single file.
3e87ef69 223
224 cout<<"Loading the seeds"<<endl;
225 Char_t fname[1024];
b2a02bce 226 fEvent = eventnr;
3e87ef69 227
228 if(offline)
b2a02bce 229 sprintf(fname,"%s/offline/tracks_%d.raw",fPath,fEvent);
3e87ef69 230 else
b2a02bce 231 sprintf(fname,"%s/hough/tracks_%d.raw",fPath,fEvent);
3e87ef69 232
233 cout<<"AliL3ClusterFitter::LoadSeeds : Loading input tracks from "<<fname<<endl;
234
235 AliL3MemHandler tfile;
236 tfile.SetBinaryInput(fname);
237
238 if(fSeeds)
239 delete fSeeds;
240 fSeeds = new AliL3TrackArray("AliL3ModelTrack");
6f388e0d 241
3e87ef69 242 tfile.Binary2TrackArray(fSeeds);
243 tfile.CloseBinaryInput();
244
245 //if(!offline)
246 //fSeeds->QSort();
247
248 Int_t clustercount=0;
249 for(Int_t i=0; i<fSeeds->GetNTracks(); i++)
250 {
251 AliL3ModelTrack *track = (AliL3ModelTrack*)fSeeds->GetCheckedTrack(i);
252 if(!track) continue;
253
254 if(!offline)
255 {
6f388e0d 256 if(i==0) cerr<<"AliL3ClusterFitter::LoadSeeds : Cutting on pt of 4 GeV!!"<<endl;
b2a02bce 257 if(track->GetPt() > 4.)
3e87ef69 258 {
259 fSeeds->Remove(i);
260 continue;
261 }
3e87ef69 262 }
263 clustercount += track->GetNHits();
264 track->CalculateHelix();
265
266 Int_t nhits = track->GetNHits();
267 UInt_t *hitids = track->GetHitNumbers();
268
269 Int_t origslice = (hitids[nhits-1]>>25)&0x7f;//Slice of innermost point
6f388e0d 270 /*
271 if(i==0) cerr<<"Cluster fitter only in HALF TPC!!!"<<endl;
272 if(origslice > 17)
273 {
274 fSeeds->Remove(i);
275 continue;
276 }
277 */
3e87ef69 278 track->Init(origslice,-1);
279 Int_t slice = origslice;
280
281 //for(Int_t j=rowrange[1]; j>=rowrange[0]; j--)
282 for(Int_t j=rowrange[0]; j<=rowrange[1]; j++)
283 {
284
285 //Calculate the crossing point between track and padrow
286 Float_t angle = 0; //Perpendicular to padrow in local coordinates
287 AliL3Transform::Local2GlobalAngle(&angle,slice);
288 if(!track->CalculateReferencePoint(angle,AliL3Transform::Row2X(j)))
289 {
b2a02bce 290 //cerr<<"No crossing in slice "<<slice<<" padrow "<<j<<endl;
3e87ef69 291 continue;
292 //track->Print();
293 //exit(5);
294 }
295 Float_t xyz_cross[3] = {track->GetPointX(),track->GetPointY(),track->GetPointZ()};
296
297 Int_t sector,row;
298 AliL3Transform::Slice2Sector(slice,j,sector,row);
299 AliL3Transform::Global2Raw(xyz_cross,sector,row);
300 //cout<<"Examining slice "<<slice<<" row "<<j<<" pad "<<xyz_cross[1]<<" time "<<xyz_cross[2]<<endl;
301 if(xyz_cross[1] < 0 || xyz_cross[1] >= AliL3Transform::GetNPads(j)) //Track leaves the slice
302 {
303 newslice:
304
305 Int_t tslice=slice;
306 Float_t lastcross=xyz_cross[1];
307 if(xyz_cross[1] > 0)
308 {
309 if(slice == 17)
310 slice=0;
311 else if(slice == 35)
312 slice = 18;
313 else
314 slice += 1;
315 }
316 else
317 {
318 if(slice == 0)
319 slice = 17;
320 else if(slice==18)
321 slice = 35;
322 else
323 slice -= 1;
324 }
325 if(slice < 0 || slice>35)
326 {
327 cerr<<"Wrong slice "<<slice<<" on row "<<j<<endl;
328 exit(5);
329 }
330 //cout<<"Track leaving, trying slice "<<slice<<endl;
331 angle=0;
332 AliL3Transform::Local2GlobalAngle(&angle,slice);
333 if(!track->CalculateReferencePoint(angle,AliL3Transform::Row2X(j)))
334 {
335 cerr<<"No crossing in slice "<<slice<<" padrow "<<j<<endl;
336 continue;
337 //track->Print();
338 //exit(5);
339 }
340 xyz_cross[0] = track->GetPointX();
341 xyz_cross[1] = track->GetPointY();
342 xyz_cross[2] = track->GetPointZ();
343 Int_t sector,row;
344 AliL3Transform::Slice2Sector(slice,j,sector,row);
345 AliL3Transform::Global2Raw(xyz_cross,sector,row);
346 if(xyz_cross[1] < 0 || xyz_cross[1] >= AliL3Transform::GetNPads(j)) //track is in the borderline
347 {
348 if(xyz_cross[1] > 0 && lastcross > 0 || xyz_cross[1] < 0 && lastcross < 0)
349 goto newslice;
350 else
351 {
352 slice = tslice;//Track is on the border of two slices
353 continue;
354 }
355 }
356 }
357
358 if(xyz_cross[2] < 0 || xyz_cross[2] >= AliL3Transform::GetNTimeBins())//track goes out of range
359 continue;
360
361 if(xyz_cross[1] < 0 || xyz_cross[1] >= AliL3Transform::GetNPads(j))
362 {
363 cerr<<"Slice "<<slice<<" padrow "<<j<<" pad "<<xyz_cross[1]<<" time "<<xyz_cross[2]<<endl;
364 track->Print();
365 exit(5);
366 }
367
368 track->SetPadHit(j,xyz_cross[1]);
369 track->SetTimeHit(j,xyz_cross[2]);
370 angle=0;
371 AliL3Transform::Local2GlobalAngle(&angle,slice);
372 Float_t crossingangle = track->GetCrossingAngle(j,slice);
373 track->SetCrossingAngleLUT(j,crossingangle);
374
375 track->CalculateClusterWidths(j);
376
377 track->GetClusterModel(j)->fSlice = slice;
378
379 }
b2a02bce 380 memset(track->GetHitNumbers(),0,159*sizeof(UInt_t));//Reset the hitnumbers
3e87ef69 381 track->SetNHits(0);
382 }
383 fSeeds->Compress();
384
3e87ef69 385 cout<<"Loaded "<<fSeeds->GetNTracks()<<" seeds and "<<clustercount<<" clusters"<<endl;
6b8f6f6e 386}
387
388void AliL3ClusterFitter::FindClusters()
389{
390 if(!fTracks)
391 {
392 cerr<<"AliL3ClusterFitter::Process : No tracks"<<endl;
393 return;
394 }
395 if(!fRowData)
396 {
397 cerr<<"AliL3ClusterFitter::Process : No data "<<endl;
398 return;
399 }
400
401 AliL3DigitRowData *rowPt = fRowData;
402 AliL3DigitData *digPt=0;
403
404 Int_t pad,time;
405 Short_t charge;
3e87ef69 406
407 if(fRowMin < 0)
408 {
409 fRowMin = AliL3Transform::GetFirstRow(fPatch);
410 fRowMax = AliL3Transform::GetLastRow(fPatch);
411 }
6b8f6f6e 412 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
413 {
3e87ef69 414 if((Int_t)rowPt->fRow < fRowMin)
415 {
416 AliL3MemHandler::UpdateRowPointer(rowPt);
417 continue;
418 }
419 else if((Int_t)rowPt->fRow > fRowMax)
420 break;
421 else if((Int_t)rowPt->fRow != i)
422 {
423 cerr<<"AliL3ClusterFitter::FindClusters : Mismatching row numbering "<<i<<" "<<rowPt->fRow<<endl;
424 exit(5);
425 }
6b8f6f6e 426 fCurrentPadRow = i;
427 memset((void*)fRow,0,(AliL3Transform::GetNTimeBins()+1)*(AliL3Transform::GetNPads(i)+1)*sizeof(Digit));
428 digPt = (AliL3DigitData*)rowPt->fDigitData;
3e87ef69 429
6b8f6f6e 430 for(UInt_t j=0; j<rowPt->fNDigit; j++)
431 {
432 pad = digPt[j].fPad;
433 time = digPt[j].fTime;
434 charge = digPt[j].fCharge;
435 fRow[(AliL3Transform::GetNTimeBins()+1)*pad+time].fCharge = charge;
436 fRow[(AliL3Transform::GetNTimeBins()+1)*pad+time].fUsed = kFALSE;
437 //cout<<"Row "<<i<<" pad "<<pad<<" time "<<time<<" charge "<<charge<<endl;
438 }
439
3e87ef69 440 for(Int_t it=0; it<2; it++)
6b8f6f6e 441 {
3e87ef69 442 if(it==0)
6b8f6f6e 443 {
3e87ef69 444 fProcessTracks = fSeeds;
445 fSeeding = kTRUE;
446 }
447 else
448 {
449 fProcessTracks = fTracks;
450 fSeeding = kFALSE;
451 }
452 if(!fProcessTracks)
453 continue;
454
455 for(Int_t k=0; k<fProcessTracks->GetNTracks(); k++)
456 {
457 AliL3ModelTrack *track = (AliL3ModelTrack*)fProcessTracks->GetCheckedTrack(k);
458 if(!track) continue;
459
460 if(fSeeding)
461 if(track->GetClusterModel(i)->fSlice != fSlice) continue;
462
463 if(track->GetPadHit(i) < 0 || track->GetPadHit(i) > AliL3Transform::GetNPads(i)-1 ||
464 track->GetTimeHit(i) < 0 || track->GetTimeHit(i) > AliL3Transform::GetNTimeBins()-1)
465 {
466 track->SetCluster(i,0,0,0,0,0,0);
467 continue;
468 }
469
470 if(CheckCluster(k) == kFALSE)
471 fFailed++;
6b8f6f6e 472 }
6b8f6f6e 473 }
6b8f6f6e 474 AliL3MemHandler::UpdateRowPointer(rowPt);
475 }
3e87ef69 476
477 fSeeding = kTRUE;
478 AddClusters();
479 fSeeding = kFALSE;
480 AddClusters();
481
482 cout<<"Fitted "<<fFitted<<" clusters, failed "<<fFailed<<endl;
483 cout<<"Distribution:"<<endl;
484 cout<<"Bad fit "<<fBadFitError<<endl;
485 cout<<"Fit error "<<fFitError<<endl;
486 cout<<"Result error "<<fResultError<<endl;
487 cout<<"Fit range error "<<fFitRangeError<<endl;
488
6b8f6f6e 489}
490
3e87ef69 491Bool_t AliL3ClusterFitter::CheckCluster(Int_t trackindex)
6b8f6f6e 492{
3e87ef69 493 //Check if this is a single or overlapping cluster
6b8f6f6e 494
3e87ef69 495 AliL3ModelTrack *track = (AliL3ModelTrack*)fProcessTracks->GetCheckedTrack(trackindex);
6b8f6f6e 496
3e87ef69 497 Int_t row = fCurrentPadRow;
498
499 if(track->IsSet(row)) //A fit has already be performed on this one
500 return kTRUE;
501
502 //Define the cluster region of this hit:
503 Int_t padr[2]={999,-1};
504 Int_t timer[2]={999,-1};
505
506 if(!SetFitRange(track,padr,timer))
6b8f6f6e 507 {
3e87ef69 508 track->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
509
510 if(fDebug)
511 cout<<"Failed to fit cluster at row "<<row<<" pad "<<(Int_t)rint(track->GetPadHit(row))<<" time "
512 <<(Int_t)rint(track->GetTimeHit(row))<<" hitcharge "
513 <<fRow[(AliL3Transform::GetNTimeBins()+1)*(Int_t)rint(track->GetPadHit(row))+(Int_t)rint(track->GetTimeHit(row))].fCharge<<endl;
514 fFitRangeError++;
515 return kFALSE;
6b8f6f6e 516 }
3e87ef69 517
518 //Check if any other track contributes to this cluster:
6f388e0d 519
3e87ef69 520 for(Int_t t=trackindex+1; t<fProcessTracks->GetNTracks(); t++)
521 {
522 AliL3ModelTrack *tr = (AliL3ModelTrack*)fProcessTracks->GetCheckedTrack(t);
523 if(!tr) continue;
524 if(fSeeding)
525 if(tr->GetClusterModel(row)->fSlice != fSlice) continue;
b2a02bce 526
6f388e0d 527 if(tr->GetPadHit(row) > padr[0] && tr->GetPadHit(row) < padr[1] &&
528 tr->GetTimeHit(row) > timer[0] && tr->GetTimeHit(row) < timer[1])
529 {
530 if(SetFitRange(tr,padr,timer))
531 track->SetOverlap(row,t);
532 }
533 /*
b2a02bce 534 Int_t xyw = (Int_t)ceil(sqrt(tr->GetParSigmaY2(row))*GetYWidthFactor());
535 Int_t zw = (Int_t)ceil(sqrt(tr->GetParSigmaZ2(row))*GetZWidthFactor());
3e87ef69 536 if(
537 (tr->GetPadHit(row) - xyw > padr[0] && tr->GetPadHit(row) - xyw < padr[1] &&
538 tr->GetTimeHit(row) - zw > timer[0] && tr->GetTimeHit(row) - zw < timer[1]) ||
539
540 (tr->GetPadHit(row) + xyw > padr[0] && tr->GetPadHit(row) + xyw < padr[1] &&
541 tr->GetTimeHit(row) - zw > timer[0] && tr->GetTimeHit(row) - zw < timer[1]) ||
542
543 (tr->GetPadHit(row) - xyw > padr[0] && tr->GetPadHit(row) - xyw < padr[1] &&
544 tr->GetTimeHit(row) + zw > timer[0] && tr->GetTimeHit(row) + zw < timer[1]) ||
545
546 (tr->GetPadHit(row) + xyw > padr[0] && tr->GetPadHit(row) + xyw < padr[1] &&
547 tr->GetTimeHit(row) + zw > timer[0] && tr->GetTimeHit(row) + zw < timer[1])
548 )
549 {
6f388e0d 550
3e87ef69 551 if(SetFitRange(tr,padr,timer)) //Expand the cluster fit range
6f388e0d 552 {
553 track->SetOverlap(row,t); //Set overlap
554 }
3e87ef69 555 }
6f388e0d 556 */
3e87ef69 557 }
558
559 if(fDebug)
560 cout<<"Fitting cluster with "<<track->GetNOverlaps(fCurrentPadRow)<<" overlaps"<<endl;
6f388e0d 561
3e87ef69 562 FitClusters(track,padr,timer);
6f388e0d 563 //CalculateWeightedMean(track,padr,timer);
3e87ef69 564 return kTRUE;
565}
566
567Bool_t AliL3ClusterFitter::SetFitRange(AliL3ModelTrack *track,Int_t *padrange,Int_t *timerange)
568{
569 Int_t row = fCurrentPadRow;
570 Int_t nt = AliL3Transform::GetNTimeBins()+1;
6b8f6f6e 571
3e87ef69 572 Int_t nsearchbins=0;
b2a02bce 573 if(row < AliL3Transform::GetNRowLow())
3e87ef69 574 nsearchbins=25;
b2a02bce 575 else if(row < AliL3Transform::GetNRowLow() + AliL3Transform::GetNRowUp1())
6f388e0d 576 nsearchbins=25;
3e87ef69 577 else
6f388e0d 578 nsearchbins=25;
b2a02bce 579
580 /*
3e87ef69 581 Int_t padloop[49] = {0,0,0,-1,1,-1,1,-1,1,0,0,-1,1,-1,1 ,2,-2,2,-2,2,-2,2,-2,2,-2
582 ,0,1,2,3,3,3,3,3,3,3
583 ,2,1,0,-1,-2,-3
584 ,-3,-3,-3,-3,-3,-3,-1,-1};
585 Int_t timeloop[49] = {0,1,-1,0,0,1,1,-1,-1,2,-2,2,2,-2,-2 ,0,0,1,1,-1,-1,2,2,-2,-2
b2a02bce 586 ,-3,-3,-3,-3,-2,-1,0,1,2,3
3e87ef69 587 ,3,3,3,3,3,3,2,1,0,-1,-2,-3,-3,-3};
b2a02bce 588 */
589
590 Int_t padloop[49] = {0,0,0,-1,1,-1,1,-1,1,0,0,-1,1,-1,1 ,2,-2,2,-2,2,-2,2,-2,2,-2
591 ,-3,3,-3,3,-3,3,-3,3,-3,3
592 ,0,0,-1,-1,1,1,-2,-2,2,2,-3,-3,3,3};
593 Int_t timeloop[49] = {0,1,-1,0,0,1,1,-1,-1,2,-2,2,2,-2,-2 ,0,0,1,1,-1,-1,2,2,-2,-2
594 ,0,0,-1,-1,1,1,-2,-2,2,2
595 ,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3};
3e87ef69 596
597 Int_t padhit = (Int_t)rint(track->GetPadHit(row));
598 Int_t timehit = (Int_t)rint(track->GetTimeHit(row));
599 Int_t padmax=-1;
600 Int_t timemax=-1;
6b8f6f6e 601
3e87ef69 602 for(Int_t index=0; index<nsearchbins; index++)
6b8f6f6e 603 {
3e87ef69 604 if(IsMaximum(padhit + padloop[index],timehit + timeloop[index]))
6b8f6f6e 605 {
3e87ef69 606 padmax = padhit + padloop[index];
607 timemax = timehit + timeloop[index];
608 break;
6b8f6f6e 609 }
6b8f6f6e 610 }
611
b2a02bce 612
3e87ef69 613 //Define the cluster region of this hit:
614 //The region we look for, is centered at the local maxima
615 //and expanded around using the parametrized cluster width
616 //according to track parameters.
b2a02bce 617
6f388e0d 618 Int_t xyw = 3;
619 Int_t zw = 5;
b2a02bce 620
3e87ef69 621 if(padmax>=0 && timemax>=0)
6b8f6f6e 622 {
3e87ef69 623 //Set the hit to the local maxima of the cluster.
624 //Store the maxima in the cluster model structure,
625 //-only temporary, it will be overwritten when calling SetCluster.
626
627 track->GetClusterModel(row)->fDPad = padmax;
628 track->GetClusterModel(row)->fDTime = timemax;
6f388e0d 629
630 Int_t i=padmax,j=timemax;
631 for(Int_t pdir=-1; pdir<=1; pdir+=2)
3e87ef69 632 {
6f388e0d 633 i=padmax;
634 while(abs(padmax-i) < xyw)
3e87ef69 635 {
6f388e0d 636 Bool_t chargeonpad=kFALSE;
637 for(Int_t tdir=-1; tdir<=1; tdir+=2)
3e87ef69 638 {
6f388e0d 639 j=timemax;
640 while(abs(timemax-j) < zw)
641 {
642 if(i<0 || i>=AliL3Transform::GetNPads(row) || j<0 || j>=AliL3Transform::GetNTimeBins()) break;
643 if(fRow[nt*i+j].fCharge)
644 {
645 if(i < padrange[0]) padrange[0]=i;
646 if(i > padrange[1]) padrange[1]=i;
647 if(j < timerange[0]) timerange[0]=j;
648 if(j > timerange[1]) timerange[1]=j;
649 chargeonpad=kTRUE;
650 }
651 else
652 break;
653 j+=tdir;
654 }
3e87ef69 655 }
6f388e0d 656 if(!chargeonpad)
657 break;
658 i+=pdir;
3e87ef69 659 }
660 }
6f388e0d 661 /*
662 for(Int_t i=padmax-xyw; i<=padmax+xyw; i++)
663 {
664 for(Int_t j=timemax-zw; j<=timemax+zw; j++)
665 {
666 if(i<0 || i>=AliL3Transform::GetNPads(row) || j<0 || j>=AliL3Transform::GetNTimeBins()) continue;
667 if(fRow[nt*i+j].fCharge)
668 {
669 if(i < padrange[0]) padrange[0]=i;
670 if(i > padrange[1]) padrange[1]=i;
671 if(j < timerange[0]) timerange[0]=j;
672 if(j > timerange[1]) timerange[1]=j;
673 }
674 }
675 }
676 */
677
3e87ef69 678 if(fDebug)
679 cout<<"New padrange "<<padrange[0]<<" "<<padrange[1]<<" "<<" time "<<timerange[0]<<" "<<timerange[1]<<endl;
680 return kTRUE;
6b8f6f6e 681 }
3e87ef69 682 return kFALSE;
683}
684
685Bool_t AliL3ClusterFitter::IsMaximum(Int_t pad,Int_t time)
686{
687 if(pad<0 || pad >= AliL3Transform::GetNPads(fCurrentPadRow) ||
688 time<0 || time >= AliL3Transform::GetNTimeBins())
689 return kFALSE;
690 Int_t nt = AliL3Transform::GetNTimeBins()+1;
691 if(fRow[nt*pad+time].fUsed == kTRUE) return kFALSE; //Peak has been assigned before
692 Int_t charge = fRow[nt*pad+time].fCharge;
6f388e0d 693 if(charge == 1024 || charge==0) return kFALSE;
694 //if(charge == 0) return kFALSE;
6b8f6f6e 695
b2a02bce 696 //fRow[nt*pad+time].fUsed = kTRUE;
697 //return kTRUE;
6f388e0d 698
b2a02bce 699 if(charge < fRow[nt*(pad-1)+(time-1)].fCharge) return kFALSE;
3e87ef69 700 if(charge < fRow[nt*(pad)+(time-1)].fCharge) return kFALSE;
b2a02bce 701 if(charge < fRow[nt*(pad+1)+(time-1)].fCharge) return kFALSE;
3e87ef69 702 if(charge < fRow[nt*(pad-1)+(time)].fCharge) return kFALSE;
703 if(charge < fRow[nt*(pad+1)+(time)].fCharge) return kFALSE;
b2a02bce 704 if(charge < fRow[nt*(pad-1)+(time+1)].fCharge) return kFALSE;
3e87ef69 705 if(charge < fRow[nt*(pad)+(time+1)].fCharge) return kFALSE;
b2a02bce 706 if(charge < fRow[nt*(pad+1)+(time+1)].fCharge) return kFALSE;
3e87ef69 707 fRow[nt*pad+time].fUsed = kTRUE;
708 return kTRUE;
6b8f6f6e 709}
710
6f388e0d 711void AliL3ClusterFitter::CalculateWeightedMean(AliL3ModelTrack *track,Int_t *padrange,Int_t *timerange)
712{
1f1942b8 713 Float_t sum=0;
714 Int_t npads=0;
6f388e0d 715 Float_t pad=0,time=0;
716 Int_t nt = AliL3Transform::GetNTimeBins()+1;
717 for(Int_t i=padrange[0]; i<=padrange[1]; i++)
718 {
719 Int_t lsum=0;
720 for(Int_t j=timerange[0]; j<=timerange[1]; j++)
721 {
722 lsum += fRow[nt*(i-1)+(j-1)].fCharge;
723 time += j*fRow[nt*(i-1)+(j-1)].fCharge;
724 }
725 if(lsum)
726 npads++;
727 pad += i * lsum;
728 }
729 if(sum)
730 {
731 pad /= sum;
732 time /= sum;
733 track->SetCluster(fCurrentPadRow,pad,time,sum,0,0,npads);
734 }
735 else
736 track->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
737}
738
3e87ef69 739void AliL3ClusterFitter::FitClusters(AliL3ModelTrack *track,Int_t *padrange,Int_t *timerange)
6b8f6f6e 740{
741 //Handle single and overlapping clusters
6b8f6f6e 742
6f388e0d 743 /*
744 if( (Int_t)rint(track->GetClusterModel(fCurrentPadRow)->fDPad) <= 1 ||
745 (Int_t)rint(track->GetClusterModel(fCurrentPadRow)->fDPad) >= AliL3Transform::GetNPads(fCurrentPadRow)-2 ||
746 (Int_t)rint(track->GetClusterModel(fCurrentPadRow)->fDTime) <= 1 ||
747 (Int_t)rint(track->GetClusterModel(fCurrentPadRow)->fDTime) >= AliL3Transform::GetNTimeBins()-2)
748 {
749 CalculateWeightedMean(track,padrange,timerange);
750 return;
751 }
752 */
6b8f6f6e 753 Int_t size = FIT_PTS;
754 Int_t max_tracks = FIT_MAXPAR/NUM_PARS;
755 if(track->GetNOverlaps(fCurrentPadRow) > max_tracks)
756 {
757 cerr<<"AliL3ClusterFitter::FitOverlappingClusters : Too many overlapping tracks"<<endl;
758 return;
759 }
760 Int_t *overlaps = track->GetOverlaps(fCurrentPadRow);
761
762 //Check if at least one cluster is not already fitted
763 Bool_t all_fitted=kTRUE;
3e87ef69 764
6b8f6f6e 765 Int_t k=-1;
766 while(k < track->GetNOverlaps(fCurrentPadRow))
767 {
768 AliL3ModelTrack *tr=0;
769 if(k==-1)
3e87ef69 770 tr = track;
6b8f6f6e 771 else
3e87ef69 772 tr = (AliL3ModelTrack*)fProcessTracks->GetCheckedTrack(overlaps[k]);
6b8f6f6e 773 k++;
774 if(!tr) continue;
3e87ef69 775 if(!tr->IsSet(fCurrentPadRow) && !tr->IsPresent(fCurrentPadRow))//cluster has not been set and is not present
6b8f6f6e 776 {
777 all_fitted = kFALSE;
778 break;
779 }
780 }
781 if(all_fitted)
782 {
3e87ef69 783 if(fDebug)
784 cout<<"But all the clusters were already fitted on row "<<fCurrentPadRow<<endl;
6b8f6f6e 785 return;
786 }
787
3e87ef69 788 //Allocate fit parameters array; this is interface to the C code
6b8f6f6e 789 plane = new DPOINT[FIT_PTS];
790 memset(plane,0,FIT_PTS*sizeof(DPOINT));
791
792 Double_t x[FIT_PTS],y[FIT_PTS],s[FIT_PTS];
793
794 //Fill the fit parameters:
795 Double_t a[FIT_MAXPAR];
796 Int_t lista[FIT_MAXPAR];
797 Double_t dev[FIT_MAXPAR],chisq_f;
798
6b8f6f6e 799 Int_t fit_pars=0;
800
6b8f6f6e 801 Int_t n_overlaps=0;
802 k=-1;
3e87ef69 803
6b8f6f6e 804 //Fill the overlapping tracks:
805 while(k < track->GetNOverlaps(fCurrentPadRow))
806 {
807 AliL3ModelTrack *tr=0;
808 if(k==-1)
809 tr = track;
810 else
3e87ef69 811 tr = (AliL3ModelTrack*)fProcessTracks->GetCheckedTrack(overlaps[k]);
6b8f6f6e 812 k++;
813 if(!tr) continue;
814
3e87ef69 815 if(tr->IsSet(fCurrentPadRow) && !tr->IsPresent(fCurrentPadRow)) continue;//Cluster fit failed before
816
817 //Use the local maxima as the input to the fitting routine.
818 //The local maxima is temporary stored in the cluster model:
b2a02bce 819 Int_t hitpad = (Int_t)rint(tr->GetClusterModel(fCurrentPadRow)->fDPad);
820 Int_t hittime = (Int_t)rint(tr->GetClusterModel(fCurrentPadRow)->fDTime);
6b8f6f6e 821 Int_t charge = fRow[(AliL3Transform::GetNTimeBins()+1)*hitpad + hittime].fCharge;
6b8f6f6e 822
3e87ef69 823 if(fDebug)
824 cout<<"Fitting track cluster, pad "<<tr->GetPadHit(fCurrentPadRow)<<" time "
825 <<tr->GetTimeHit(fCurrentPadRow)<<" charge "<<charge<<" at local maxima in pad "<<hitpad
826 <<" time "<<hittime<<" xywidth "<<sqrt(tr->GetParSigmaY2(fCurrentPadRow))
827 <<" zwidth "<<sqrt(tr->GetParSigmaZ2(fCurrentPadRow))<<endl;
828
829 if(charge==0)
6b8f6f6e 830 {
3e87ef69 831 cerr<<"Charge still zero!"<<endl;
832 exit(5);
6b8f6f6e 833 }
3e87ef69 834
835 a[n_overlaps*NUM_PARS+2] = hitpad;
836 a[n_overlaps*NUM_PARS+4] = hittime;
6b8f6f6e 837
3e87ef69 838 if(!tr->IsSet(fCurrentPadRow)) //Cluster is not fitted before
6b8f6f6e 839 {
840 a[n_overlaps*NUM_PARS+1] = charge;
3e87ef69 841 a[n_overlaps*NUM_PARS+3] = sqrt(tr->GetParSigmaY2(fCurrentPadRow)) * GetYWidthFactor();
842 a[n_overlaps*NUM_PARS+5] = sqrt(tr->GetParSigmaZ2(fCurrentPadRow)) * GetZWidthFactor();
6f388e0d 843 //a[n_overlaps*NUM_PARS+6] = sqrt(tr->GetParSigmaZ2(fCurrentPadRow)) * GetZWidthFactor();
6b8f6f6e 844 lista[n_overlaps*NUM_PARS + 1] = 1;
845 lista[n_overlaps*NUM_PARS + 2] = 1;
846 lista[n_overlaps*NUM_PARS + 3] = 0;
847 lista[n_overlaps*NUM_PARS + 4] = 1;
848 lista[n_overlaps*NUM_PARS + 5] = 0;
6f388e0d 849 //lista[n_overlaps*NUM_PARS + 6] = 0;
850 fit_pars += 3; //<-------------------
6b8f6f6e 851 }
3e87ef69 852 else //Cluster was fitted before
6b8f6f6e 853 {
3e87ef69 854 if(!tr->IsPresent(fCurrentPadRow))
855 {
856 cerr<<"AliL3ClusterFitter::FindClusters : Cluster not present; there is a bug here"<<endl;
857 exit(5);
858 }
6b8f6f6e 859 Int_t charge;
860 Float_t xywidth,zwidth,pad,time;
861 tr->GetPad(fCurrentPadRow,pad);
862 tr->GetTime(fCurrentPadRow,time);
863 tr->GetClusterCharge(fCurrentPadRow,charge);
864 xywidth = sqrt(tr->GetParSigmaY2(fCurrentPadRow));
865 zwidth = sqrt(tr->GetParSigmaZ2(fCurrentPadRow));
3e87ef69 866 if(fDebug)
6f388e0d 867 cout<<endl<<"Cluster had been fitted before, pad "<<pad<<" time "<<time<<" charge "<<charge<<" width "<<xywidth<<" "<<zwidth<<endl;
6b8f6f6e 868
869 a[n_overlaps*NUM_PARS+2] = pad;
870 a[n_overlaps*NUM_PARS+4] = time;
871 a[n_overlaps*NUM_PARS+1] = charge;
6f388e0d 872 a[n_overlaps*NUM_PARS+3] = xywidth * GetYWidthFactor();
873 a[n_overlaps*NUM_PARS+5] = zwidth * GetZWidthFactor();
874 //a[n_overlaps*NUM_PARS+6] = zwidth * GetZWidthFactor();
6b8f6f6e 875
876 lista[n_overlaps*NUM_PARS + 1] = 1;
877 lista[n_overlaps*NUM_PARS + 2] = 0;
878 lista[n_overlaps*NUM_PARS + 3] = 0;
879 lista[n_overlaps*NUM_PARS + 4] = 0;
880 lista[n_overlaps*NUM_PARS + 5] = 0;
6f388e0d 881 //lista[n_overlaps*NUM_PARS + 6] = 0;
6b8f6f6e 882 fit_pars += 1;
883 }
884 n_overlaps++;
885 }
886
887 if(n_overlaps==0) //No clusters here
3e87ef69 888 {
889 delete [] plane;
890 return;
891 }
6b8f6f6e 892
6b8f6f6e 893 Int_t pad_num=0;
894 Int_t time_num_max=0;
895 Int_t ndata=0;
896 Int_t tot_charge=0;
3e87ef69 897 if(fDebug)
898 cout<<"Padrange "<<padrange[0]<<" "<<padrange[1]<<" timerange "<<timerange[0]<<" "<<timerange[1]<<endl;
899 for(Int_t i=padrange[0]; i<=padrange[1]; i++)
6b8f6f6e 900 {
901 Int_t max_charge = 0;
902 Int_t time_num=0;
3e87ef69 903 for(Int_t j=timerange[0]; j<=timerange[1]; j++)
6b8f6f6e 904 {
905 Int_t charge = fRow[(AliL3Transform::GetNTimeBins()+1)*i + j].fCharge;
906
907 if(charge <= 0) continue;
908
3e87ef69 909 time_num++;
6b8f6f6e 910 if(charge > max_charge)
911 {
912 max_charge = charge;
3e87ef69 913 //time_num++;
6b8f6f6e 914 }
3e87ef69 915 if(fDebug)
916 cout<<"Filling padrow "<<fCurrentPadRow<<" pad "<<i<<" time "<<j<<" charge "<<charge<<endl;
6b8f6f6e 917 tot_charge += charge;
918 ndata++;
919 if(ndata >= size)
3e87ef69 920 {
921 cerr<<"Too many points; row "<<fCurrentPadRow<<" padrange "<<padrange[0]<<" "<<padrange[1]<<" timerange "
922 <<timerange[0]<<" "<<timerange[1]<<endl;
923 exit(5);
924 }
925
6b8f6f6e 926 plane[ndata].u = (Double_t)i;
927 plane[ndata].v = (Double_t)j;
928 x[ndata]=ndata;
929 y[ndata]=charge;
930 s[ndata]= 1 + sqrt((Double_t)charge);
931 }
932 if(max_charge) //there was charge on this pad
933 pad_num++;
934 if(time_num_max < time_num)
935 time_num_max = time_num;
936 }
6f388e0d 937
3e87ef69 938 if(pad_num <= 1 || time_num_max <=1 || n_overlaps > fNmaxOverlaps || ndata <= fit_pars) //too few to do fit
6b8f6f6e 939 {
3e87ef69 940 SetClusterfitFalse(track);
941 if(fDebug)
942 cout<<"Too few digits or too many overlaps: "<<pad_num<<" "<<time_num_max<<" "<<n_overlaps<<" ndata "<<ndata<<" fit_pars "<<fit_pars<<endl;
943 delete [] plane;
6b8f6f6e 944 return;
945 }
3e87ef69 946
6b8f6f6e 947
948 Int_t npars = n_overlaps * NUM_PARS;
3e87ef69 949 if(fDebug)
950 cout<<"Number of overlapping clusters "<<n_overlaps<<endl;
6b8f6f6e 951 Int_t ret = lev_marq_fit( x, y, s, ndata, a, lista, dev, npars, &chisq_f, f2gauss5 );
3e87ef69 952
953 if(ret<0)
6b8f6f6e 954 {
3e87ef69 955 SetClusterfitFalse(track);
956 fFailed++;
957 fFitError++;
958 delete [] plane;
959 return;
960 //exit(5);
6b8f6f6e 961 }
962
963 chisq_f /= (ndata-fit_pars);
3e87ef69 964 if(fDebug)
965 cout<<"Chisq "<<chisq_f<<endl;
966
b2a02bce 967 Bool_t overlapping=kFALSE;
968 if(track->GetNOverlaps(fCurrentPadRow) > 0)//There is a overlap
969 overlapping=kTRUE;
970
6b8f6f6e 971 k=-1;
972 n_overlaps=0;
973 while(k < track->GetNOverlaps(fCurrentPadRow))
974 {
975 AliL3ModelTrack *tr=0;
976 if(k==-1)
977 tr = track;
978 else
3e87ef69 979 tr = (AliL3ModelTrack*)fProcessTracks->GetCheckedTrack(overlaps[k]);
6b8f6f6e 980 k++;
981 if(!tr) continue;
6b8f6f6e 982 if(!tr->IsPresent(fCurrentPadRow))
983 {
3e87ef69 984 if(tr->IsSet(fCurrentPadRow)) continue;//This cluster has been set before
985
6f388e0d 986 Int_t lpatch;
987 if(fCurrentPadRow < AliL3Transform::GetNRowLow())
988 lpatch=0;
989 else if(fCurrentPadRow < AliL3Transform::GetNRowLow() + AliL3Transform::GetNRowUp1())
990 lpatch=1;
991 else
992 lpatch=2;
993
994 //if(chisq_f < fChiSqMax[(Int_t)overlapping])//cluster fit is good enough
995 if(chisq_f < fChiSqMax[lpatch])//cluster fit is good enough
6b8f6f6e 996 {
6f388e0d 997 tot_charge = (Int_t)(2*AliL3Transform::Pi() * a[n_overlaps*NUM_PARS+1] * a[n_overlaps*NUM_PARS+3] * a[n_overlaps*NUM_PARS+5]);
3e87ef69 998 Float_t fpad = a[n_overlaps*NUM_PARS+2];
999 Float_t ftime = a[n_overlaps*NUM_PARS+4];
1000 if(tot_charge < 0 || fpad < -1 || fpad > AliL3Transform::GetNPads(fCurrentPadRow) ||
1001 ftime < -1 || ftime > AliL3Transform::GetNTimeBins())
1002 {
1003 if(fDebug)
1004 cout<<"AliL3ClusterFitter::Fatal result(s) in fit; in slice "<<fSlice<<" row "<<fCurrentPadRow
1005 <<"; pad "<<fpad<<" time "<<ftime<<" charge "<<tot_charge<<" xywidth "<<a[n_overlaps*NUM_PARS+3]
1006 <<" zwidth "<<a[n_overlaps*NUM_PARS+5]<<" peakcharge "<<a[n_overlaps*NUM_PARS+1]<<endl;
1007 tr->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
1008 fFailed++;
1009 fResultError++;
1010 continue;
1011 }
1012
1013 tr->SetCluster(fCurrentPadRow,fpad,ftime,tot_charge,0,0,pad_num);
6f388e0d 1014 /*
1015 tr->SetCluster(fCurrentPadRow,fpad,ftime,tot_charge,
1016 pow(a[n_overlaps*NUM_PARS+3],2),
1017 pow(a[n_overlaps*NUM_PARS+5],2),pad_num);
1018 */
3e87ef69 1019 if(fDebug)
6f388e0d 1020 {
1021 cout<<"Setting cluster in slice "<<fSlice<<" row "<<fCurrentPadRow<<" pad "<<a[n_overlaps*NUM_PARS+2]<<" time "<<a[n_overlaps*NUM_PARS+4]
1022 <<" padwidth "<<a[n_overlaps*NUM_PARS+3]<<" timewidth "<<a[n_overlaps*NUM_PARS+5]
1023 <<" charge "<<tot_charge<<endl;
1024 }
3e87ef69 1025 /*
1026 //Set the digits to used:
1027 for(Int_t i=padrange[0]; i<=padrange[1]; i++)
1028 for(Int_t j=timerange[0]; j<=timerange[1]; j++)
1029 fRow[(AliL3Transform::GetNTimeBins()+1)*i + j].fUsed = kTRUE;
1030 */
1031 fFitted++;
6b8f6f6e 1032 }
1033 else //fit was too bad
3e87ef69 1034 {
1035 if(fDebug)
1036 cout<<"Cluster fit was too bad"<<endl;
1037 tr->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
1038 fBadFitError++;
1039 fFailed++;
1040 }
6b8f6f6e 1041 }
1042 n_overlaps++;
1043 }
1044
1045 delete [] plane;
6b8f6f6e 1046}
1047
3e87ef69 1048void AliL3ClusterFitter::SetClusterfitFalse(AliL3ModelTrack *track)
1049{
1050 //Cluster fit failed, so set the clusters to all the participating
1051 //tracks to zero.
1052
1053 Int_t i=-1;
1054 Int_t *overlaps = track->GetOverlaps(fCurrentPadRow);
1055 while(i < track->GetNOverlaps(fCurrentPadRow))
1056 {
1057 AliL3ModelTrack *tr=0;
1058 if(i==-1)
1059 tr = track;
1060 else
1061 tr = (AliL3ModelTrack*)fProcessTracks->GetCheckedTrack(overlaps[i]);
1062 i++;
1063 if(!tr) continue;
1064
b2a02bce 1065 //Set the digit data to unused, so it can be fitted to another bastard:
1066 Int_t hitpad = (Int_t)rint(tr->GetClusterModel(fCurrentPadRow)->fDPad);
1067 Int_t hittime = (Int_t)rint(tr->GetClusterModel(fCurrentPadRow)->fDTime);
1068 fRow[(AliL3Transform::GetNTimeBins()+1)*hitpad + hittime].fUsed = kFALSE;
1069
3e87ef69 1070 tr->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
1071 }
b2a02bce 1072
3e87ef69 1073}
1074
1075
1076void AliL3ClusterFitter::AddClusters()
1077{
1078 if(!fClusters)
1079 {
1080 fClusters = new AliL3SpacePointData[fNMaxClusters];
1081 fNClusters=0;
1082 }
1083
1084 if(fDebug)
1085 cout<<"Writing cluster in slice "<<fSlice<<" patch "<<fPatch<<endl;
1086
1087 AliL3TrackArray *tracks=0;
1088 if(fSeeding==kTRUE)
1089 tracks = fSeeds;
1090 else
1091 tracks = fTracks;
1092
1093 if(!tracks)
1094 return;
1095
1096 for(Int_t i=0; i<tracks->GetNTracks(); i++)
1097 {
1098 AliL3ModelTrack *tr = (AliL3ModelTrack*)tracks->GetCheckedTrack(i);
1099 if(!tr) continue;
1100
1101 UInt_t *hitids = tr->GetHitNumbers();
1102 Int_t nhits = tr->GetNHits();
1103 for(Int_t i=fRowMax; i>=fRowMin; i--)
1104 {
1105 if(fSeeding)
1106 if(tr->GetClusterModel(i)->fSlice != fSlice) continue;
1107 if(!tr->IsPresent(i)) continue;
1108 fCurrentPadRow = i;
1109 Float_t pad,time,xywidth,zwidth;
1110 Int_t charge;
1111 tr->GetPad(i,pad);
1112 tr->GetTime(i,time);
1113 tr->GetClusterCharge(i,charge);
1114
1115 if(pad < -1 || pad >= AliL3Transform::GetNPads(i) ||
1116 time < -1 || time >= AliL3Transform::GetNTimeBins())
1117 {
1118 continue;
1119 cout<<"slice "<<fSlice<<" row "<<i<<" pad "<<pad<<" time "<<time<<endl;
1120 tr->Print();
1121 exit(5);
1122 }
6f388e0d 1123
3e87ef69 1124 tr->CalculateClusterWidths(i,kTRUE); //Parametrize errors
1125
1f1942b8 1126 tr->GetSigmaY2(i,xywidth);
1127 tr->GetSigmaZ2(i,zwidth);
3e87ef69 1128 Float_t xyz[3];
1129 Int_t sector,row;
1130 AliL3Transform::Slice2Sector(fSlice,i,sector,row);
1131
b2a02bce 1132 AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
3e87ef69 1133
1134 if(fNClusters >= fNMaxClusters)
1135 {
1136 cerr<<"AliL3ClusterFitter::AddClusters : Too many clusters "<<fNClusters<<endl;
1137 exit(5);
1138 }
b2a02bce 1139
3e87ef69 1140 fClusters[fNClusters].fX = xyz[0];
1141 fClusters[fNClusters].fY = xyz[1];
1142 fClusters[fNClusters].fZ = xyz[2];
1143 fClusters[fNClusters].fCharge = charge;
1144 fClusters[fNClusters].fPadRow = i;
1145 Int_t pa = AliL3Transform::GetPatch(i);
1146 if(xywidth==0 || zwidth==0)
1147 cerr<<"AliL3ClusterFitter::AddClusters : Cluster with zero width"<<endl;
1148 if(xywidth>0)
1149 fClusters[fNClusters].fSigmaY2 = xywidth*pow(AliL3Transform::GetPadPitchWidth(pa),2);
1150 else
1151 fClusters[fNClusters].fSigmaY2 = 1;
1152 if(zwidth>0)
1153 fClusters[fNClusters].fSigmaZ2 = zwidth*pow(AliL3Transform::GetZWidth(),2);
1154 else
1155 fClusters[fNClusters].fSigmaZ2 = 1;
1156 Int_t pat=fPatch;
1157 if(fPatch==-1)
1158 pat=0;
1159 fClusters[fNClusters].fID = fNClusters + ((fSlice&0x7f)<<25)+((pat&0x7)<<22);
1160
b2a02bce 1161 if(nhits >= AliL3Transform::GetNRows())
3e87ef69 1162 {
1163 cerr<<"AliL3ClusterFitter::AddClusters : Cluster counter of out range "<<nhits<<endl;
1164 exit(5);
1165 }
1166 hitids[nhits++] = fClusters[fNClusters].fID;
1167
1168#ifdef do_mc
1169 Int_t trackID[3];
1170 Int_t fpad = (Int_t)rint(pad);
1171 Int_t ftime = (Int_t)rint(time);
1172 if(fpad < 0)
1173 fpad=0;
1174 if(fpad >= AliL3Transform::GetNPads(i))
1175 fpad = AliL3Transform::GetNPads(i)-1;
1176 if(ftime<0)
1177 ftime=0;
1178 if(ftime >= AliL3Transform::GetNTimeBins())
1179 ftime = AliL3Transform::GetNTimeBins()-1;
1180 GetTrackID(fpad,ftime,trackID);
1181 fClusters[fNClusters].fTrackID[0] = trackID[0];
1182 fClusters[fNClusters].fTrackID[1] = trackID[1];
1183 fClusters[fNClusters].fTrackID[2] = trackID[2];
1184#endif
1185 //cout<<"Setting id "<<trackID[0]<<" on pad "<<pad<<" time "<<time<<" row "<<i<<endl;
1186 fNClusters++;
1187 }
1188
1189 //Copy back the number of assigned clusters
1190 tr->SetNHits(nhits);
b2a02bce 1191
3e87ef69 1192 }
1193}
1194
b2a02bce 1195void AliL3ClusterFitter::WriteTracks(Int_t min_hits)
3e87ef69 1196{
1197 if(!fSeeds)
1198 return;
1199
b2a02bce 1200 AliL3TrackArray *fakes = new AliL3TrackArray();
3e87ef69 1201
1202 Int_t clustercount=0;
1203 for(Int_t i=0; i<fSeeds->GetNTracks(); i++)
1204 {
1205 AliL3ModelTrack *tr = (AliL3ModelTrack*)fSeeds->GetCheckedTrack(i);
1206 if(!tr) continue;
b2a02bce 1207 if(tr->GetNHits() < min_hits)
1208 {
1209 fakes->AddLast(tr);
1210 fSeeds->Remove(i);
1211 }
3e87ef69 1212 clustercount += tr->GetNHits();
3e87ef69 1213 }
b2a02bce 1214
3e87ef69 1215 cout<<"Writing "<<clustercount<<" clusters"<<endl;
1216 fSeeds->Compress();
1217 AliL3MemHandler mem;
1218 Char_t filename[1024];
b2a02bce 1219 sprintf(filename,"%s/fitter/tracks_%d.raw",fPath,fEvent);
3e87ef69 1220 mem.SetBinaryOutput(filename);
1221 mem.TrackArray2Binary(fSeeds);
1222 mem.CloseBinaryOutput();
1223
b2a02bce 1224 //Write the fake tracks to its own file
1225 mem.Free();
1226 sprintf(filename,"%s/fitter/tracks_fakes_%d.raw",fPath,fEvent);
1227 mem.SetBinaryOutput(filename);
1228 mem.TrackArray2Binary(fakes);
1229 mem.CloseBinaryOutput();
1230 delete fakes;
3e87ef69 1231}
1232
b2a02bce 1233void AliL3ClusterFitter::WriteClusters(Bool_t global)
3e87ef69 1234{
1235 AliL3MemHandler mem;
1236 if(fDebug)
1237 cout<<"Write "<<fNClusters<<" clusters to file"<<endl;
1238 Char_t filename[1024];
b2a02bce 1239 sprintf(filename,"%s/fitter/points_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
3e87ef69 1240 mem.SetBinaryOutput(filename);
b2a02bce 1241 if(global == kTRUE)
1242 mem.Transform(fNClusters,fClusters,fSlice);
3e87ef69 1243 mem.Memory2Binary(fNClusters,fClusters);
1244 mem.CloseBinaryOutput();
1245 mem.Free();
1246
1247 delete [] fClusters;
1248 fClusters=0;
1249 fNClusters=0;
1250}
b2a02bce 1251