3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ASV
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3Modeller.h"
9 #include "AliL3MemHandler.h"
11 #include "AliL3FileHandler.h"
13 #include "AliL3TrackArray.h"
14 #include "AliL3ModelTrack.h"
15 #include "AliL3DigitData.h"
16 #include "AliL3Transform.h"
22 //_____________________________________________________________
25 // Class for modeling TPC data.
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.
32 ClassImp(AliL3Modeller)
34 AliL3Modeller::AliL3Modeller()
45 AliL3Modeller::~AliL3Modeller()
53 void AliL3Modeller::Init(Int_t slice,Int_t patch,Char_t *trackdata,Char_t *path,Bool_t houghtracks,Bool_t binary)
58 sprintf(fPath,"%s",path);
60 fTracks = new AliL3TrackArray("AliL3ModelTrack");
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))
68 cerr<<"AliL3Modeller::Init : Error opening trackfile: "<<fname<<endl;
71 file->Binary2TrackArray(fTracks);
72 file->CloseBinaryInput();
79 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
81 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
83 track->Init(fSlice,fPatch);
85 //Only if the tracks has been merged across sector boundaries:
87 //track->Rotate(fSlice,kTRUE); //!!!!!!!!!!!!!!!!!!!
89 track->CalculateHelix();
92 CalculateCrossingPoints();
97 AliL3DigitRowData *digits=0;
99 fMemHandler = new AliL3FileHandler();
100 fMemHandler->Init(slice,patch);
103 sprintf(fname,"%s/digitfile.root",fPath);
104 fMemHandler->SetAliInput(fname);
105 digits = fMemHandler->AliDigits2Memory(ndigits);
109 sprintf(fname,"%sdigits_%d_%d.raw",fPath,fSlice,fPatch);
110 if(!fMemHandler->SetBinaryInput(fname))
112 cerr<<"AliL3Modeller::Init : Error opening file "<<fname<<endl;
115 digits=(AliL3DigitRowData*)fMemHandler->CompBinary2Memory(ndigits);
118 fMemHandler = new AliL3MemHandler();
119 fMemHandler->Init(slice,patch);
122 cerr<<"AliL3Modeller::Init : Compile with AliROOT if you want rootfile as input"<<endl;
127 sprintf(fname,"%sdigits_%d_%d.raw",fPath,fSlice,fPatch);
128 if(!fMemHandler->SetBinaryInput(fname))
130 cerr<<"AliL3Modeller::Init : Error opening file "<<fname<<endl;
134 digits=(AliL3DigitRowData*)fMemHandler->CompBinary2Memory(ndigits);
137 SetInputData(digits);
140 void AliL3Modeller::FindClusters()
142 cout<<"AliL3Modeller::FindClusters : Processing slice "<<fSlice<<" patch "<<fPatch<<endl;
145 cerr<<"AliL3Modeller::Process : No tracks"<<endl;
150 cerr<<"AliL3Modeller::Process : No data "<<endl;
154 AliL3DigitRowData *rowPt = fRowData;
155 AliL3DigitData *digPt=0;
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];
163 Int_t pad,time,index;
167 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); 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++)
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;
183 for(Int_t k=0; k<fTracks->GetNTracks(); k++)
185 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(k);
188 if(track->GetPadHit(i)<0 || track->GetTimeHit(i)<0 || track->GetOverlap(i)>=0)
190 track->SetCluster(i,0,0,0,0,0,0); //The track has left the patch.
194 Int_t hitpad = (Int_t)rint(track->GetPadHit(i));
195 Int_t hittime = (Int_t)rint(track->GetTimeHit(i));
196 //cout<<"Checking track on row "<<i<<" with pad "<<hitpad<<" time "<<hittime<<endl;
201 if(row[ntimes*pad + time].fCharge == 0 ||
202 row[ntimes*pad + time].fUsed == kTRUE) //Bad track, or cluster has already been included.
204 track->SetCluster(i,0,0,0,0,0,0);
211 memset(&cluster,0,sizeof(Cluster));
212 //cout<<"Processing padrow "<<i<<" with hittime "<<hittime<<" hitpad "<<hitpad<<" charge "<<row[ntimes*pad + time].fCharge<<" index "<<ntimes*pad + time<<endl;
214 Int_t last_mean = hittime;
215 while(1)//Process this padrow
217 if(pad < 0 || pad >= AliL3Transform::GetNPads(i))
219 //cout<<"Pad = "<<pad<<" on row "<<i<<endl;
220 FillCluster(track,&cluster,i,npads);
227 while(1) //Process sequence on this pad:
229 if(time < 0 || time >= AliL3Transform::GetNTimeBins())
232 index = ntimes*pad + time;
233 if(index < 0 || index >= bounds)
235 cerr<<"AliL3Modeller::FindClusters : Index out of range : "<<index
236 <<" on row "<<i<<" pad "<<pad<<" time "<<time<<endl;
240 charge = row[index].fCharge;
241 if(charge==0 && timesign==-1) //zero charge on this timebin, perform checks:
243 if(seq_charge==0 && abs(time-hittime) <= fTimeSearch) //No charge found on this pad, look further.
244 //if(seq_charge==0 && abs(time-last_mean) <= fTimeOverlap)
246 //cout<<"Sequence is zero, time "<<time<<" hittime "<<hittime<<" pad "<<pad<<" charge "<<charge<<" index "<<index<<endl;
257 else if(charge==0 && timesign==1)//zero charge on this timebin, perform checks:
259 if(seq_charge==0 && abs(time-hittime) <= fTimeSearch)//No charge found on this pad, look further
260 //if(seq_charge==0 && abs(time-last_mean) <=fTimeOverlap)
265 else //Boundary reached, or we have found the other end of the sequence, stop looking on this pad.
267 //if(fCurrentPadRow==31)
268 // cerr<<"Breaking off at pad "<<pad<<" and time "<<time<<endl;
273 if(row[ntimes*pad+time].fUsed==kTRUE) //Don't use digits several times. This leads to mult. rec.tracks.
279 seq_charge += charge;
281 //Update the cluster parameters with this timebin
282 cluster.fTime += time*charge;
283 cluster.fPad += pad*charge;
284 cluster.fCharge += charge;
285 cluster.fSigmaY2 += pad*pad*charge;
286 cluster.fSigmaZ2 += time*time*charge;
288 row[ntimes*pad+time].fUsed = kTRUE;
292 //Always compare with the current mean in time of the cluster under construction.
294 last_mean = (Int_t)rint((Float_t)(cluster.fTime/cluster.fCharge));
296 if(seq_charge)//There was something on this pad, so keep looking on the neighbouring pad
301 else //Nothing more on this pad, goto next pad
305 if(cluster.fCharge==0 && abs(pad-hitpad) <= fPadSearch && pad > 0)
307 //cout<<"Cluster is zero!"<<endl;
308 pad--; //In this case, we haven't found anything yet,
309 continue; //so we will try to expand our search within the natural boundaries.
321 if(cluster.fCharge==0 && abs(pad-hitpad) <= fPadSearch && pad < AliL3Transform::GetNPads(i)-2)
323 //cout<<"Cluster is zero "<<endl;
324 pad++; //In this case, we haven't found anything yet,
325 continue; //so we will try to expand our search within the natural boundaries.
327 else //We are out of range, or cluster if finished.
329 //if(fCurrentPadRow==31)
330 //cout<<"Out of range; charge "<<cluster.fCharge<<" paddiff "<<abs(pad-hitpad)<<endl;
331 FillCluster(track,&cluster,i,npads);
335 else //Nothing more in this cluster
337 //if(fCurrentPadRow==31)
338 //cout<<"Filling final cluster"<<endl;
339 FillCluster(track,&cluster,i,npads);
344 //cout<<"done"<<endl;
346 FillZeros(rowPt,row);
347 fMemHandler->UpdateRowPointer(rowPt);
350 //cout<<"done processing"<<endl;
354 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
356 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
358 if(track->GetNClusters() != AliL3Transform::GetNRows(fPatch))
359 cerr<<endl<<"Mismatching hitcounts; nclusters: "<<track->GetNClusters()<<" nrows "<<AliL3Transform::GetNRows(fPatch)<<endl<<endl;
364 void AliL3Modeller::FillCluster(AliL3ModelTrack *track,Cluster *cluster,Int_t row,Int_t npads)
366 if(cluster->fCharge==0)
368 track->SetCluster(row,0,0,0,0,0,0);
371 Float_t fcharge = (Float_t)cluster->fCharge;
372 Float_t fpad = ((Float_t)cluster->fPad/fcharge);
373 Float_t ftime = ((Float_t)cluster->fTime/fcharge);
374 Float_t sigmaY2,sigmaZ2;
375 CalcClusterWidth(cluster,sigmaY2,sigmaZ2);
376 track->SetCluster(row,fpad,ftime,fcharge,sigmaY2,sigmaZ2,npads);
379 void AliL3Modeller::FillZeros(AliL3DigitRowData *rowPt,Digit *row)
381 //Fill zero where data has been used.
383 Int_t ntimes = AliL3Transform::GetNTimeBins()+1;
384 AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
385 for(UInt_t j=0; j<rowPt->fNDigit; j++)
387 Int_t pad = digPt[j].fPad;
388 Int_t time = digPt[j].fTime;
389 if(row[ntimes*pad+time].fUsed==kTRUE)
390 digPt[j].fCharge = 0;
394 void AliL3Modeller::WriteRemaining()
396 //Write remaining (nonzero) digits to file.
398 AliL3DigitRowData *rowPt;
399 rowPt = (AliL3DigitRowData*)fRowData;
401 Int_t ndigits[(AliL3Transform::GetNRows(fPatch))];
402 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
404 AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
405 ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]=0;
406 for(UInt_t j=0; j<rowPt->fNDigit; j++)
408 if(digPt[j].fCharge==0) continue;
410 ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]++;
412 //cout<<"Difference "<<(int)ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]<<" "<<(int)rowPt->fNDigit<<endl;
413 fMemHandler->UpdateRowPointer(rowPt);
416 Int_t size = digitcount*sizeof(AliL3DigitData) + AliL3Transform::GetNRows(fPatch)*sizeof(AliL3DigitRowData);
417 Byte_t *data = new Byte_t[size];
419 AliL3DigitRowData *tempPt = (AliL3DigitRowData*)data;
420 rowPt = (AliL3DigitRowData*)fRowData;
422 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
426 tempPt->fNDigit = ndigits[(i-AliL3Transform::GetFirstRow(fPatch))];
427 AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
428 for(UInt_t j=0; j<rowPt->fNDigit; j++)
430 if(digPt[j].fCharge==0) continue;
431 if(localcount >= ndigits[(i-AliL3Transform::GetFirstRow(fPatch))])
433 cerr<<"AliL3Modeller::WriteRemaining : Digitarray out of range!!"<<endl;
436 tempPt->fDigitData[localcount].fCharge = digPt[j].fCharge;
437 tempPt->fDigitData[localcount].fPad = digPt[j].fPad;
438 tempPt->fDigitData[localcount].fTime = digPt[j].fTime;
442 if(ndigits[(i-AliL3Transform::GetFirstRow(fPatch))] != localcount)
444 cerr<<"AliL3Modeller::WriteRemaining : Mismatch in digitcount"<<endl;
447 fMemHandler->UpdateRowPointer(rowPt);
448 Byte_t *tmp = (Byte_t*)tempPt;
449 Int_t size = sizeof(AliL3DigitRowData) + ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]*sizeof(AliL3DigitData);
451 tempPt = (AliL3DigitRowData*)tmp;
455 AliL3MemHandler *mem = new AliL3MemHandler();
456 sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,fSlice,fPatch);
457 mem->SetBinaryOutput(fname);
458 mem->Memory2CompBinary((UInt_t)AliL3Transform::GetNRows(fPatch),(AliL3DigitRowData*)data);
459 mem->CloseBinaryOutput();
465 void AliL3Modeller::CalculateCrossingPoints()
467 //cout<<"Calculating crossing points on "<<fTracks->GetNTracks()<<" tracks"<<endl;
470 cerr<<"AliL3Modeller::CalculateCrossingPoints(): No tracks"<<endl;
476 for(Int_t i=AliL3Transform::GetLastRow(fPatch); i>=AliL3Transform::GetFirstRow(fPatch); i--)
478 for(Int_t j=0; j<fTracks->GetNTracks(); j++)
480 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(j);
483 if(!track->GetCrossingPoint(i,hit))
485 //cerr<<"AliL3Modeller::CalculateCrossingPoints : Track "<<j<<" does not intersect row "<<i<<" :"<<endl<<
486 //" pt "<<track->GetPt()<<
487 //" tgl "<<track->GetTgl()<<" psi "<<track->GetPsi()<<" charge "<<track->GetCharge()<<endl;
488 //"Center "<<track->GetCenterX()<<" "<<track->GetCenterY()<<endl<<endl<<
493 //cout<<"X "<<hit[0]<<" Y "<<hit[1]<<" Z "<<hit[2]<<" tgl "<<track->GetTgl()<<endl;
495 AliL3Transform::Slice2Sector(fSlice,i,sector,row);
496 AliL3Transform::Local2Raw(hit,sector,row);
497 //cout<<"Pad "<<hit[1]<<" time "<<hit[2]<<" in sector "<<sector<<" row "<<row<<endl;
498 if(hit[1]<0 || hit[1]>AliL3Transform::GetNPads(i) ||
499 hit[2]<0 || hit[2]>AliL3Transform::GetNTimeBins())
500 {//Track is leaving the patch, so flag the track hits (<0)
501 track->SetPadHit(i,-1);
502 track->SetTimeHit(i,-1);
507 track->SetPadHit(i,hit[1]);
508 track->SetTimeHit(i,hit[2]);
510 //if(hit[1]<0 || hit[2]>445)
511 //if(hit[2]<0 || hit[2]>445)
512 //cout<<"pad "<<hit[1]<<" time "<<hit[2]<<" pt "<<track->GetPt()<<" psi "<<track->GetPsi()<<" tgl "<<track->GetTgl()<<" firstpoint "<<track->GetFirstPointX()<<" "<<track->GetFirstPointY()<<" "<<track->GetFirstPointZ()<<endl;
513 //cout<<"Crossing pad "<<hit[1]<<" time "<<hit[2]<<endl;
517 //cout<<"And there are "<<fTracks->GetNTracks()<<" tracks remaining"<<endl;
520 void AliL3Modeller::CheckForOverlaps()
522 //Flag the tracks that overlap
524 //cout<<"Checking for overlaps...";
526 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
528 AliL3ModelTrack *track1 = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
529 if(!track1) continue;
530 for(Int_t j=i+1; j<fTracks->GetNTracks(); j++)
532 AliL3ModelTrack *track2 = (AliL3ModelTrack*)fTracks->GetCheckedTrack(j);
533 if(!track2) continue;
534 for(Int_t k=AliL3Transform::GetFirstRow(fPatch); k<=AliL3Transform::GetLastRow(fPatch); k++)
536 if(track1->GetPadHit(k)<0 || track1->GetTimeHit(k)<0 ||
537 track2->GetPadHit(k)<0 || track2->GetTimeHit(k)<0)
540 if(track1->GetOverlap(k)>=0 || track2->GetOverlap(k)>=0) continue;
542 if(abs((Int_t)rint(track1->GetPadHit(k))-(Int_t)rint(track2->GetPadHit(k))) <= fPadOverlap &&
543 abs((Int_t)rint(track1->GetTimeHit(k))-(Int_t)rint(track2->GetTimeHit(k))) <= fTimeOverlap)
545 track2->SetOverlap(k,i);
546 //track1->SetOverlap(k,j);
552 //cout<<"found "<<counter<<" done"<<endl;
556 void AliL3Modeller::CalcClusterWidth(Cluster *cl,Float_t &sigmaY2,Float_t &sigmaZ2)
561 padw = AliL3Transform::GetPadPitchWidth(fPatch);
563 Float_t charge = (Float_t)cl->fCharge;
564 Float_t pad = (Float_t)cl->fPad/charge;
565 Float_t time = (Float_t)cl->fTime/charge;
566 Float_t s2 = (Float_t)cl->fSigmaY2/charge - pad*pad;
568 //Save the sigmas in pad and time:
570 sigmaY2 = (s2);// + 1./12);//*padw*padw;
572 /*Constants added by offline
575 sigmaY2 = sigmaY2*0.108;
577 sigmaY2 = sigmaY2*2.07;
581 s2 = (Float_t)cl->fSigmaZ2/charge - time*time;
582 timew = AliL3Transform::GetZWidth();
583 sigmaZ2 = (s2);// +1./12);//*timew*timew;
587 /*Constants added by offline
590 sigmaZ2 = sigmaZ2*0.169;
592 sigmaZ2 = sigmaZ2*1.77;