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();
76 cout<<"AliL3Modeller is assuming local hough tracksegments!"<<endl;
78 cout<<"AliL3Modeller is assuming global tracks!"<<endl;
83 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
85 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
87 track->Init(fSlice,fPatch);
89 //Only if the tracks has been merged across sector boundaries:
91 //track->Rotate(fSlice,kTRUE); //!!!!!!!!!!!!!!!!!!!
93 track->CalculateHelix();
96 CalculateCrossingPoints();
101 AliL3DigitRowData *digits=0;
103 fMemHandler = new AliL3FileHandler();
104 fMemHandler->Init(slice,patch);
107 sprintf(fname,"%s/digitfile.root",fPath);
108 fMemHandler->SetAliInput(fname);
109 digits = fMemHandler->AliDigits2Memory(ndigits);
113 sprintf(fname,"%sdigits_%d_%d.raw",fPath,fSlice,fPatch);
114 if(!fMemHandler->SetBinaryInput(fname))
116 cerr<<"AliL3Modeller::Init : Error opening file "<<fname<<endl;
119 digits=(AliL3DigitRowData*)fMemHandler->CompBinary2Memory(ndigits);
122 fMemHandler = new AliL3MemHandler();
123 fMemHandler->Init(slice,patch);
126 cerr<<"AliL3Modeller::Init : Compile with AliROOT if you want rootfile as input"<<endl;
131 sprintf(fname,"%sdigits_%d_%d.raw",fPath,fSlice,fPatch);
132 if(!fMemHandler->SetBinaryInput(fname))
134 cerr<<"AliL3Modeller::Init : Error opening file "<<fname<<endl;
138 digits=(AliL3DigitRowData*)fMemHandler->CompBinary2Memory(ndigits);
141 SetInputData(digits);
144 void AliL3Modeller::FindClusters()
149 cerr<<"AliL3Modeller::Process : No tracks"<<endl;
154 cerr<<"AliL3Modeller::Process : No data "<<endl;
158 AliL3DigitRowData *rowPt = fRowData;
159 AliL3DigitData *digPt=0;
161 Int_t ntimes = AliL3Transform::GetNTimeBins()+1;
162 Int_t npads = AliL3Transform::GetNPads(AliL3Transform::GetLastRow(fPatch))+1;//Max num of pads.
163 Int_t bounds = ntimes*npads;
164 Digit *row = new Digit[bounds];
167 Int_t pad,time,index;
171 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
174 memset((void*)row,0,ntimes*npads*sizeof(Digit));
175 digPt = (AliL3DigitData*)rowPt->fDigitData;
176 //cout<<"Loading row "<<i<<" with "<<(Int_t)rowPt->fNDigit<<" digits"<<endl;
177 for(UInt_t j=0; j<rowPt->fNDigit; j++)
180 time = digPt[j].fTime;
181 charge = digPt[j].fCharge;
182 row[ntimes*pad+time].fCharge = charge;
183 row[ntimes*pad+time].fUsed = kFALSE;
184 //cout<<"Row "<<i<<" pad "<<pad<<" time "<<time<<" charge "<<charge<<endl;
187 for(Int_t k=0; k<fTracks->GetNTracks(); k++)
189 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(k);
192 if(track->GetPadHit(i)<0 || track->GetTimeHit(i)<0 || track->GetOverlap(i)>=0)
194 track->SetCluster(i,0,0,0,0,0,0); //The track has left the patch.
198 Int_t hitpad = (Int_t)rint(track->GetPadHit(i));
199 Int_t hittime = (Int_t)rint(track->GetTimeHit(i));
200 //cout<<"Checking track on row "<<i<<" with pad "<<hitpad<<" time "<<hittime<<endl;
206 memset(&cluster,0,sizeof(Cluster));
209 while(1)//Process this padrow
211 if(pad < 0 || pad >= AliL3Transform::GetNPads(i))
213 //cout<<"Pad = "<<pad<<" on row "<<i<<endl;
214 FillCluster(track,&cluster,i,npads);
221 while(1) //Process sequence on this pad:
224 index = ntimes*pad + time;
225 if(index < 0 || index >= bounds)
227 cerr<<"AliL3Modeller::FindClusters : Index out of range : "<<index
228 <<" on row "<<i<<" pad "<<pad<<" time "<<time<<endl;
232 charge = row[index].fCharge;
233 if(charge==0 && timesign==-1) //zero charge on this timebin, perform checks:
235 if(seq_charge==0 && abs(time-hittime) <= fTimeOverlap) //No charge found on this pad, look further.
240 else //Boundary reached, or we have found one end of the sequence,->start looking in the other time direction
247 else if(charge==0 && timesign==1)//zero charge on this timebin, perform checks:
249 if(seq_charge==0 && abs(time-hittime) <= fTimeOverlap)//No charge found on this pad, look further
254 else //Boundary reached, or we have found the other end of the sequence, stop looking on this pad.
256 //if(fCurrentPadRow==31)
257 // cerr<<"Breaking off at pad "<<pad<<" and time "<<time<<endl;
262 if(row[ntimes*pad+time].fUsed==kTRUE) //Don't use digits several times. This leads to mult. rec.tracks.
268 seq_charge += charge;
270 //Update the cluster parameters with this timebin
271 cluster.fTime += time*charge;
272 cluster.fPad += pad*charge;
273 cluster.fCharge += charge;
274 cluster.fSigmaY2 += pad*pad*charge;
275 cluster.fSigmaZ2 += time*time*charge;
277 row[ntimes*pad+time].fUsed = kTRUE;
282 if(seq_charge)//There was something on this pad, so keep looking on the neighbouring pad
287 else //Nothing more on this pad, goto next pad
291 if(cluster.fCharge==0 && abs(pad-hitpad) <= fPadOverlap && pad > 0)
293 pad--; //In this case, we haven't found anything yet,
294 } //so we will try to expand our search within the natural boundaries.
305 if(cluster.fCharge==0 && abs(pad-hitpad) <= fPadOverlap && pad < AliL3Transform::GetNPads(i)-2)
307 pad++; //In this case, we haven't found anything yet,
308 continue; //so we will try to expand our search within the natural boundaries.
310 else //We are out of range, or cluster if finished.
312 //if(fCurrentPadRow==31)
313 //cout<<"Out of range; charge "<<cluster.fCharge<<" paddiff "<<abs(pad-hitpad)<<endl;
314 FillCluster(track,&cluster,i,npads);
318 else //Nothing more in this cluster
320 //if(fCurrentPadRow==31)
321 //cout<<"Filling final cluster"<<endl;
322 FillCluster(track,&cluster,i,npads);
327 //cout<<"done"<<endl;
329 FillZeros(rowPt,row);
330 fMemHandler->UpdateRowPointer(rowPt);
333 cout<<"done processing"<<endl;
337 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
339 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
341 if(track->GetNClusters() != AliL3Transform::GetNRows(fPatch))
342 cerr<<endl<<"Mismatching hitcounts; nclusters: "<<track->GetNClusters()<<" nrows "<<AliL3Transform::GetNRows(fPatch)<<endl<<endl;
347 void AliL3Modeller::FillCluster(AliL3ModelTrack *track,Cluster *cluster,Int_t row,Int_t npads)
349 if(cluster->fCharge==0)
351 track->SetCluster(row,0,0,0,0,0,0);
354 Float_t fcharge = (Float_t)cluster->fCharge;
355 Float_t fpad = ((Float_t)cluster->fPad/fcharge);
356 Float_t ftime = ((Float_t)cluster->fTime/fcharge);
357 Float_t sigmaY2,sigmaZ2;
358 CalcClusterWidth(cluster,sigmaY2,sigmaZ2);
359 track->SetCluster(row,fpad,ftime,fcharge,sigmaY2,sigmaZ2,npads);
362 void AliL3Modeller::FillZeros(AliL3DigitRowData *rowPt,Digit *row)
364 //Fill zero where data has been used.
366 Int_t ntimes = AliL3Transform::GetNTimeBins()+1;
367 AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
368 for(UInt_t j=0; j<rowPt->fNDigit; j++)
370 Int_t pad = digPt[j].fPad;
371 Int_t time = digPt[j].fTime;
372 if(row[ntimes*pad+time].fUsed==kTRUE)
373 digPt[j].fCharge = 0;
377 void AliL3Modeller::WriteRemaining()
379 //Write remaining (nonzero) digits to file.
381 AliL3DigitRowData *rowPt;
382 rowPt = (AliL3DigitRowData*)fRowData;
384 Int_t ndigits[(AliL3Transform::GetNRows(fPatch))];
385 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
387 AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
388 ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]=0;
389 for(UInt_t j=0; j<rowPt->fNDigit; j++)
391 if(digPt[j].fCharge==0) continue;
393 ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]++;
395 //cout<<"Difference "<<(int)ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]<<" "<<(int)rowPt->fNDigit<<endl;
396 fMemHandler->UpdateRowPointer(rowPt);
399 Int_t size = digitcount*sizeof(AliL3DigitData) + AliL3Transform::GetNRows(fPatch)*sizeof(AliL3DigitRowData);
400 Byte_t *data = new Byte_t[size];
402 AliL3DigitRowData *tempPt = (AliL3DigitRowData*)data;
403 rowPt = (AliL3DigitRowData*)fRowData;
405 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
409 tempPt->fNDigit = ndigits[(i-AliL3Transform::GetFirstRow(fPatch))];
410 AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
411 for(UInt_t j=0; j<rowPt->fNDigit; j++)
413 if(digPt[j].fCharge==0) continue;
414 if(localcount >= ndigits[(i-AliL3Transform::GetFirstRow(fPatch))])
416 cerr<<"AliL3Modeller::WriteRemaining : Digitarray out of range!!"<<endl;
419 tempPt->fDigitData[localcount].fCharge = digPt[j].fCharge;
420 tempPt->fDigitData[localcount].fPad = digPt[j].fPad;
421 tempPt->fDigitData[localcount].fTime = digPt[j].fTime;
425 if(ndigits[(i-AliL3Transform::GetFirstRow(fPatch))] != localcount)
427 cerr<<"AliL3Modeller::WriteRemaining : Mismatch in digitcount"<<endl;
430 fMemHandler->UpdateRowPointer(rowPt);
431 Byte_t *tmp = (Byte_t*)tempPt;
432 Int_t size = sizeof(AliL3DigitRowData) + ndigits[(i-AliL3Transform::GetFirstRow(fPatch))]*sizeof(AliL3DigitData);
434 tempPt = (AliL3DigitRowData*)tmp;
438 AliL3MemHandler *mem = new AliL3MemHandler();
439 sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,fSlice,fPatch);
440 mem->SetBinaryOutput(fname);
441 mem->Memory2CompBinary((UInt_t)AliL3Transform::GetNRows(fPatch),(AliL3DigitRowData*)data);
442 mem->CloseBinaryOutput();
448 void AliL3Modeller::CalculateCrossingPoints()
450 cout<<"Calculating crossing points on "<<fTracks->GetNTracks()<<" tracks"<<endl;
453 cerr<<"AliL3Modeller::CalculateCrossingPoints(): No tracks"<<endl;
459 for(Int_t i=AliL3Transform::GetLastRow(fPatch); i>=AliL3Transform::GetFirstRow(fPatch); i--)
461 for(Int_t j=0; j<fTracks->GetNTracks(); j++)
463 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(j);
466 if(!track->GetCrossingPoint(i,hit))
468 cerr<<"AliL3Modeller::CalculateCrossingPoints : Track "<<j<<" does not intersect row "<<i<<" :"<<endl<<
469 "First point "<<track->GetFirstPointX()<<
470 " nhits "<<track->GetNHits()<<endl;//" tgl "<<track->GetTgl()<<" psi "<<track->GetPsi()<<" charge "<<track->GetCharge()<<endl;
471 //"Center "<<track->GetCenterX()<<" "<<track->GetCenterY()<<endl<<endl<<
476 //cout<<"X "<<hit[0]<<" Y "<<hit[1]<<" Z "<<hit[2]<<" tgl "<<track->GetTgl()<<endl;
478 AliL3Transform::Slice2Sector(fSlice,i,sector,row);
479 AliL3Transform::Local2Raw(hit,sector,row);
480 //cout<<"Pad "<<hit[1]<<" time "<<hit[2]<<" in sector "<<sector<<" row "<<row<<endl;
481 if(hit[1]<0 || hit[1]>AliL3Transform::GetNPads(i) ||
482 hit[2]<0 || hit[2]>AliL3Transform::GetNTimeBins())
483 {//Track is leaving the patch, so flag the track hits (<0)
484 track->SetPadHit(i,-1);
485 track->SetTimeHit(i,-1);
490 track->SetPadHit(i,hit[1]);
491 track->SetTimeHit(i,hit[2]);
493 //if(hit[1]<0 || hit[2]>445)
494 //if(hit[2]<0 || hit[2]>445)
495 //cout<<"pad "<<hit[1]<<" time "<<hit[2]<<" pt "<<track->GetPt()<<" psi "<<track->GetPsi()<<" tgl "<<track->GetTgl()<<" firstpoint "<<track->GetFirstPointX()<<" "<<track->GetFirstPointY()<<" "<<track->GetFirstPointZ()<<endl;
496 //cout<<"Crossing pad "<<hit[1]<<" time "<<hit[2]<<endl;
500 cout<<"And there are "<<fTracks->GetNTracks()<<" tracks remaining"<<endl;
503 void AliL3Modeller::CheckForOverlaps()
505 //Flag the tracks that overlap
507 cout<<"Checking for overlaps...";
509 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
511 AliL3ModelTrack *track1 = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
512 if(!track1) continue;
513 for(Int_t j=i+1; j<fTracks->GetNTracks(); j++)
515 AliL3ModelTrack *track2 = (AliL3ModelTrack*)fTracks->GetCheckedTrack(j);
516 if(!track2) continue;
517 for(Int_t k=AliL3Transform::GetFirstRow(fPatch); k<=AliL3Transform::GetLastRow(fPatch); k++)
519 if(track1->GetPadHit(k)<0 || track1->GetTimeHit(k)<0 ||
520 track2->GetPadHit(k)<0 || track2->GetTimeHit(k)<0)
523 if(track1->GetOverlap(k)>=0 || track2->GetOverlap(k)>=0) continue;
525 if(abs((Int_t)rint(track1->GetPadHit(k))-(Int_t)rint(track2->GetPadHit(k))) <= fPadOverlap &&
526 abs((Int_t)rint(track1->GetTimeHit(k))-(Int_t)rint(track2->GetTimeHit(k))) <= fTimeOverlap)
528 track2->SetOverlap(k,i);
529 //track1->SetOverlap(k,j);
535 cout<<"found "<<counter<<" done"<<endl;
539 void AliL3Modeller::CalcClusterWidth(Cluster *cl,Float_t &sigmaY2,Float_t &sigmaZ2)
544 padw = AliL3Transform::GetPadPitchWidth(fPatch);
546 Float_t charge = (Float_t)cl->fCharge;
547 Float_t pad = (Float_t)cl->fPad/charge;
548 Float_t time = (Float_t)cl->fTime/charge;
549 Float_t s2 = (Float_t)cl->fSigmaY2/charge - pad*pad;
551 //Save the sigmas in pad and time:
553 sigmaY2 = (s2);// + 1./12);//*padw*padw;
555 /*Constants added by offline
558 sigmaY2 = sigmaY2*0.108;
560 sigmaY2 = sigmaY2*2.07;
564 s2 = (Float_t)cl->fSigmaZ2/charge - time*time;
565 timew = AliL3Transform::GetZWidth();
566 sigmaZ2 = (s2);// +1./12);//*timew*timew;
570 /*Constants added by offline
573 sigmaZ2 = sigmaZ2*0.169;
575 sigmaZ2 = sigmaZ2*1.77;