3 // Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3Logging.h"
9 #include "AliL3GlobalMerger.h"
10 #include "AliL3Track.h"
11 #include "AliL3Transform.h"
12 #include "AliL3TrackArray.h"
14 /** \class AliL3GlobalMerger
16 //_____________________________________________________________
19 // The L3 Slice merger
24 ClassImp(AliL3GlobalMerger)
26 AliL3GlobalMerger::AliL3GlobalMerger()
28 //Default constructor. Use Setup to specify and setup the necessary parameters and arrays.
30 SetParameter(0,0,0,0,0);
37 AliL3GlobalMerger::~AliL3GlobalMerger()
42 void AliL3GlobalMerger::Setup(Int_t first,Int_t last)
44 //Used to setup the arrays and everything
46 fNSlices = last-first+1;
49 InitMerger(last-first+1);
52 void AliL3GlobalMerger::InitSlice(Int_t slice)
55 // Select Sector The following FillTracks call will
59 fCurrentTracks = fSlice - fFirst;
62 Double_t AliL3GlobalMerger::CheckTracks(AliL3Track *innertrack,AliL3Track *outertrack,Int_t slice)
64 //Compare the tracks by propagating the outermost track to the last and first point plane
65 //of the innermost track. This plane is defined by the padrow plane where these points
68 if(innertrack->GetCharge()!=outertrack->GetCharge()) return -1;
70 Float_t angle = 0;//perpendicular to the padrowplane (in local system)
71 AliL3Transform::Local2GlobalAngle(&angle,slice);
72 Double_t dx[2],dy[2],dz[2];
74 AliL3Track *tracks[2];
75 tracks[0] = innertrack;
76 tracks[1] = outertrack;
77 SortGlobalTracks(tracks,2);
78 innertrack = tracks[0];
79 outertrack = tracks[1];
83 point[0]=innertrack->GetLastPointX();
84 point[1]=innertrack->GetLastPointY();
85 point[2]=innertrack->GetLastPointZ();
86 AliL3Transform::Global2LocHLT(point,slice);
88 outertrack->CalculateReferencePoint(angle,point[0]);//local x = global distance to padrowplane
89 if(!outertrack->IsPoint()) return diff;
90 dx[0] = fabs(outertrack->GetPointX()-innertrack->GetLastPointX());
91 dy[0] = fabs(outertrack->GetPointY()-innertrack->GetLastPointY());
92 dz[0] = fabs(outertrack->GetPointZ()-innertrack->GetLastPointZ());
94 point[0]=innertrack->GetFirstPointX();
95 point[1]=innertrack->GetFirstPointY();
96 point[2]=innertrack->GetFirstPointZ();
97 AliL3Transform::Global2LocHLT(point,slice);
99 outertrack->CalculateReferencePoint(angle,point[0]);//local x = global distance to padrowplane
100 if(!outertrack->IsPoint()) return diff;
101 dx[1] = fabs(outertrack->GetPointX()-innertrack->GetFirstPointX());
102 dy[1] = fabs(outertrack->GetPointY()-innertrack->GetFirstPointY());
103 dz[1] = fabs(outertrack->GetPointZ()-innertrack->GetFirstPointZ());
105 diff=0;//This was a tough bug to find....
106 for(Int_t i=0; i<2; i++)
107 diff += sqrt(dx[i]*dx[i] + dy[i]*dy[i] + dz[i]*dz[i]);
111 void AliL3GlobalMerger::SlowMerge(Char_t *path)
113 //Tuning of parameters. This matches _all_ tracks between two neighbouring
114 //slices, and merges the ones which are closest in space. The difference
115 //is written to a ntuppel, which can be used as a input for the SetParameters
116 //when using normal Merge function.
119 void* ntuple=GetNtuple();
120 AliL3Track *track[2];
121 AliL3TrackArray *tout = GetOutTracks();
124 LOG(AliL3Log::kWarning,"AliL3GlobalMerger::SlowMerge","Slice Number")
125 <<"Need more than one Slice!"<<ENDLOG;
129 for(Int_t i=0; i<fNSlices; i++)
131 //if(fNSlices!=18 && i+1 == fNSlices) continue;
132 Int_t slice = fFirst + i;
133 AliL3TrackArray *ttt0=GetInTracks(i);
135 //if(slice2==fNSlices) slice2 =0;
137 //Make sure slices are on the same side of the TPC
138 if(slice2 == 18) slice2=0;
139 else if(slice2 == 36) slice2=18;
140 AliL3TrackArray *ttt1=GetInTracks(slice2);
141 //10 degrees -> the border of the slices in local coordinates
142 Float_t angle = AliL3Transform::Pi()/18;
143 AliL3Transform::Local2GlobalAngle(&angle,slice);
145 //In the two following cases, the angle is 2*pi, so set it back to 0 in order for
146 //the calculation of crossing points to be correct.
147 if(slice==17 || slice==35)
152 for(Int_t s0=0;s0<ttt0->GetNTracks();s0++)
154 AliL3Track *track0=ttt0->GetCheckedTrack(s0);
155 if(!track0) continue;
156 track0->CalculateHelix();
157 track0->CalculateEdgePoint(angle);
158 // if(track0->IsPoint()) AddTrack(tout,track0);
160 for(Int_t s1=0;s1<ttt1->GetNTracks();s1++)
162 AliL3Track *track1=ttt1->GetCheckedTrack(s1);
163 if(!track1) continue;
164 track1->CalculateHelix();
165 track1->CalculateEdgePoint(angle);
166 // if(track1->IsPoint()) AddTrack(tout,track1);
168 Bool_t merge = kTRUE;
171 Int_t min0=-1,min1=-1;
173 Int_t n0=ttt0->GetNTracks(),n1=ttt1->GetNTracks();
174 for(Int_t s0=0;s0<n0;s0++)
176 AliL3Track *track0=ttt0->GetCheckedTrack(s0);
177 if(!track0) continue;
178 if(!track0->IsPoint()) continue;
179 for(Int_t s1=0;s1<n1;s1++)
181 AliL3Track *track1=ttt1->GetCheckedTrack(s1);
182 if(!track1) continue;
183 if(!track1->IsPoint()) continue;
185 //Double_t diff = TrackDiff(track0,track1,angle);
186 Double_t diff = CheckTracks(track0,track1,slice);
187 //PrintDiff(track0,track1);
188 if(diff>=0&&diff<min)
198 AliL3Track *track0=ttt0->GetTrack(min0);
199 AliL3Track *track1=ttt1->GetTrack(min1);
202 SortGlobalTracks(track,2);
203 track1->CalculateEdgePoint((angle+AliL3Transform::Pi()/9));
204 if(track1->IsPoint())//Check if the track will cross the boundary of yet another slice.
205 MultiMerge(ttt1,track,2);
207 MultiMerge(tout,track,2);
208 track0->CalculateReferencePoint(angle);
209 track1->CalculateReferencePoint(angle);
210 //PrintDiff(track0,track1);
211 FillNtuple(ntuple,track0,track1);
220 LOG(AliL3Log::kInformational,"AliL3GlobalMerger::SlowMerge","Result")
221 <<AliL3Log::kDec<<"Merged Tracks: "<<tout->GetNTracks()<<" at:"
225 sprintf(fname,"%s/merge_parameters.root",path);
226 WriteNtuple(fname,ntuple);
229 void AliL3GlobalMerger::Merge()
231 //Normal merging procedure. Matches tracks which are within limits
232 //set by SetParameters. Parameters can be tuned by SlowMerge.
234 AliL3Track *track[2];
235 AliL3TrackArray *tout = GetOutTracks();
238 LOG(AliL3Log::kWarning,"AliL3GlobalMerger::Merge","Slice Number")
239 <<"Need more than one Slice!"<<ENDLOG;
242 for(Int_t i=0; i<fNSlices; i++)
244 //if(fNSlices!=18 && i+1 == fNSlices) continue;
245 Int_t slice = fFirst + i;
246 AliL3TrackArray *ttt0=GetInTracks(i);
248 //if(slice2==fNSlices) slice2 =0;
250 //Make sure slices are on the same side of the TPC
251 if(slice2 == 18) slice2=0;
252 else if(slice2 == 36) slice2=18;
253 AliL3TrackArray *ttt1=GetInTracks(slice2);
254 //10 degrees -> the border of the slices in local coordinates
255 Float_t angle = AliL3Transform::Pi()/18;
256 AliL3Transform::Local2GlobalAngle(&angle,slice);
258 //In the two following cases, the angle is 2*pi, so set it back to 0 in order for
259 //the calculation of crossing points to be correct.
260 if(slice==17 || slice==35)
265 Bool_t *ismatched0 = new Bool_t[ttt0->GetNTracks()];
266 Bool_t *ismatched1 = new Bool_t[ttt1->GetNTracks()];
268 for(Int_t s0=0;s0<ttt0->GetNTracks();s0++)
270 ismatched0[s0]=kFALSE;
271 AliL3Track *track0=ttt0->GetCheckedTrack(s0);
272 if(!track0) continue;
273 track0->CalculateHelix();
274 track0->CalculateEdgePoint(angle);
275 if(track0->IsPoint())
278 track0->CalculateReferencePoint(angle);
281 for(Int_t s1=0;s1<ttt1->GetNTracks();s1++)
283 ismatched1[s1]=kFALSE;
284 AliL3Track *track1=ttt1->GetCheckedTrack(s1);
285 if(!track1) continue;
286 track1->CalculateHelix();
287 track1->CalculateEdgePoint(angle);
288 if(track1->IsPoint())
291 track1->CalculateReferencePoint(angle);
294 for(Int_t s0=0;s0<ttt0->GetNTracks();s0++)
296 if(ismatched0[s0]) continue;
297 AliL3Track *track0=ttt0->GetCheckedTrack(s0);
298 if(!track0) continue;
299 if(!track0->IsPoint()) continue;
300 for(Int_t s1=0;s1<ttt1->GetNTracks();s1++)
302 if(ismatched1[s1]) continue;
303 AliL3Track *track1=ttt1->GetCheckedTrack(s1);
304 if(!track1) continue;
305 if(!track1->IsPoint()) continue;
306 if(IsRTrack(track0,track1))
310 SortGlobalTracks(track,2);
311 Double_t r0 = pow(track[0]->GetLastPointX(),2)+
312 pow(track[0]->GetLastPointY(),2);
313 Double_t r1 = pow(track[1]->GetFirstPointX(),2)+
314 pow(track[1]->GetFirstPointY(),2);
317 MultiMerge(tout,track,2);
318 ismatched0[s0]=kTRUE;
319 ismatched1[s1]=kTRUE;
324 The track is merged, so we will _not_ look for more matches.
325 Because there could easily be more matches, if a track is being
326 split within the sector....
332 LOG(AliL3Log::kInformational,"AliL3GlobalMerger::Merge","Result")
333 <<AliL3Log::kDec<<"slice0: "<<n0<<" slice1: "<<n1
334 <<" Merged Tracks: "<<tout->GetNTracks()<<ENDLOG;
335 delete [] ismatched0;
336 delete [] ismatched1;