]>
Commit | Line | Data |
---|---|---|
d64429af | 1 | //$Id$ |
2 | ||
3cfb9c56 | 3 | #ifndef ALIHLTGLOBALTRACKMATCHER_H |
4 | #define ALIHLTGLOBALTRACKMATCHER_H | |
434146d0 | 5 | |
6 | ||
3cfb9c56 | 7 | //* This file is property of and copyright by the ALICE HLT Project * |
8 | //* ALICE Experiment at CERN, All rights reserved. * | |
9 | //* See cxx source for full Copyright notice * | |
10 | ||
11 | /** @file AliHLTGlobalTrackMatcher.h | |
12 | @author Svein Lindal (svein.lindal@fys.uio.no) | |
13 | @date | |
b3e7198f | 14 | @brief The HLT class matching TPC tracks to calorimeter clusters |
3cfb9c56 | 15 | */ |
16 | ||
17 | ||
e5b4e619 | 18 | |
3cfb9c56 | 19 | #include "AliHLTLogging.h" |
20 | #include "AliESDtrack.h" | |
2a24cbbe | 21 | #include "TObjArray.h" |
22 | #include "TArrayI.h" | |
52426eff | 23 | #include "TVector3.h" |
5d8d9319 | 24 | #include "AliTrackerBase.h" // Marcel: for EMCal track-matching |
3cfb9c56 | 25 | |
a46c7ba5 | 26 | class AliHLTGlobalTrackMatcher : public AliHLTLogging{ |
b3e7198f | 27 | |
3cfb9c56 | 28 | public: |
29 | AliHLTGlobalTrackMatcher(); | |
b3e7198f | 30 | |
a46c7ba5 | 31 | /** destructor */ |
3cfb9c56 | 32 | virtual ~AliHLTGlobalTrackMatcher(); |
33 | ||
a46c7ba5 | 34 | //Main function, loops over tracks and calls appropriate functions to establish matches |
2a24cbbe | 35 | template <class T> |
9d967c45 | 36 | Int_t Match( TObjArray * trackArray, vector<T*> &phosClustersVector, vector<T*> &emcalClustersVector, Double_t bz, Int_t Method ); |
5d8d9319 | 37 | |
a46c7ba5 | 38 | private: |
39 | ||
434146d0 | 40 | void DoInit(); |
bad7877b | 41 | |
5d8d9319 | 42 | |
2a24cbbe | 43 | //Loops over clusters and decides if track is a good match to any of these |
44 | template <class T> | |
45 | Int_t MatchTrackToClusters( AliExternalTrackParam * track, vector<T*> &clustersVector, Int_t nClusters, Float_t * bestMatch, Double_t bz); | |
bad7877b | 46 | |
5d8d9319 | 47 | template <class T> |
9d967c45 | 48 | Int_t MatchTrackToEMCalClusters( AliExternalTrackParam * track, vector<T*> &clustersVector, Int_t nClusters, Float_t * bestMatch, Double_t bz, Int_t Method); // EMCal Track-Matching from recoUtils::ExtrapolateTracktoCluster |
5d8d9319 | 49 | |
2a24cbbe | 50 | //Add track Id to cluster's list of matching tracks |
51 | Int_t AddTrackToCluster(Int_t tId, Int_t* clustersArray, Bool_t bestMatch, Int_t nMatches); | |
52 | Int_t AddTrackToCluster(Int_t tId, TArrayI* clustersArray, Bool_t bestMatch, Int_t nMatches); | |
53 | ||
54 | //Projects track to detector volume and decides if it's anywhere near calorimeter volume | |
55 | Bool_t IsTrackCloseToDetector(AliExternalTrackParam * track, Double_t bz, Double_t fMaxX, Bool_t ySign, Double_t fMaxZ, Double_t dRadius); | |
56 | ||
57 | // Geometrical cut off values used to decide whether track is anywhere near calorimeter volumes | |
a46c7ba5 | 58 | Float_t fPhosMaxZ; // max Z track (cm) |
59 | Float_t fPhosMaxX; // max X track (cm) | |
60 | Float_t fEmcalMaxZ; // max Z track (cm) | |
61 | Float_t fEmcalMaxX; // max X track (cm) | |
62 | ||
63 | Float_t fMatchDistance; // Square of maximum distance where track is considered a match to cluster (cm^2) | |
5d8d9319 | 64 | Float_t fMatchDistanceEMCal; // Square of maximum distance where track is considered a match to cluster (EtaxPhi space) |
3cfb9c56 | 65 | |
a46c7ba5 | 66 | const Double_t fPhosRadius; // Radial position of PHOS |
67 | const Double_t fEmcalRadius; // Radial position of EMCAL | |
bad7877b | 68 | |
9d967c45 | 69 | Float_t fStep; // Step for EMCal Extrapolation Calculation |
70 | Float_t fMass; // Mass for EMCal Extrapolation hipothesis | |
71 | ||
bc72e5b9 | 72 | AliHLTGlobalTrackMatcher(const AliHLTGlobalTrackMatcher & ); |
73 | AliHLTGlobalTrackMatcher & operator = (const AliHLTGlobalTrackMatcher &); | |
74 | ||
2a24cbbe | 75 | ClassDef(AliHLTGlobalTrackMatcher,1) |
3cfb9c56 | 76 | }; |
77 | ||
2a24cbbe | 78 | |
79 | template <class T> | |
9d967c45 | 80 | Int_t AliHLTGlobalTrackMatcher::Match( TObjArray * trackArray, vector<T*> &phosClustersVector, vector<T*> &emcalClustersVector, Double_t bz, Int_t Method ) { |
81 | //Method for extrapolation EMcal | |
2a24cbbe | 82 | //See above for documentation |
83 | ||
84 | Int_t nTracks = trackArray->GetEntriesFast(); | |
ec54c698 | 85 | Int_t nPhosClusters = phosClustersVector.size(); |
86 | Int_t nEmcalClusters = emcalClustersVector.size(); | |
a46c7ba5 | 87 | |
ec54c698 | 88 | |
4502b5bb | 89 | //HLTError("tracks phos emcal %d %d %d", nTracks, nPhosClusters, nEmcalClusters); |
90 | ||
ec54c698 | 91 | //See if there are tracks and clusters to match |
2a24cbbe | 92 | if ( nTracks <= 0 ) { |
2a24cbbe | 93 | return 0; |
ec54c698 | 94 | } else if ( (nEmcalClusters <= 0) && (nPhosClusters <= 0)) { |
2a24cbbe | 95 | return 0; |
96 | } | |
97 | ||
e5b4e619 | 98 | |
a46c7ba5 | 99 | Float_t bestMatchPhos[nPhosClusters]; |
100 | for(int ic = 0; ic < nPhosClusters; ic++) { | |
101 | bestMatchPhos[ic] = 999999; | |
2a24cbbe | 102 | } |
ec54c698 | 103 | |
104 | Float_t bestMatchEmcal[nEmcalClusters]; | |
105 | for(int ic = 0; ic < nEmcalClusters; ic++) { | |
106 | bestMatchEmcal[ic] = 999999; | |
107 | } | |
108 | ||
a46c7ba5 | 109 | //Loop over tracks |
2a24cbbe | 110 | for (int it = 0; it < nTracks; it++ ) { |
111 | AliExternalTrackParam * track = static_cast<AliExternalTrackParam*>(trackArray->At(it)); | |
a46c7ba5 | 112 | |
9d967c45 | 113 | if ( IsTrackCloseToDetector(track, bz, fEmcalMaxX, kTRUE, fEmcalMaxZ, fEmcalRadius ) ) { |
114 | if(Method!=1&&Method!=2){ | |
115 | HLTError("\n Method %d is not valid",Method); | |
116 | return 0; // No method defined | |
117 | } | |
118 | MatchTrackToEMCalClusters( track, emcalClustersVector, nEmcalClusters, bestMatchEmcal, bz,Method); //With Method | |
119 | ||
120 | } else if ( IsTrackCloseToDetector(track, bz, fPhosMaxX, kFALSE, fPhosMaxZ, fPhosRadius ) ) { | |
e5b4e619 | 121 | MatchTrackToClusters( track, phosClustersVector, nPhosClusters, bestMatchPhos, bz); |
e5b4e619 | 122 | } |
ec54c698 | 123 | } |
e5b4e619 | 124 | |
2a24cbbe | 125 | return 0; |
a46c7ba5 | 126 | } |
2a24cbbe | 127 | |
5d8d9319 | 128 | //MARCEL |
129 | template <class T> | |
9d967c45 | 130 | Int_t AliHLTGlobalTrackMatcher::MatchTrackToEMCalClusters( AliExternalTrackParam * track, vector<T*> &clustersVector, Int_t nClusters, Float_t * bestMatch, Double_t bz, Int_t Method ) { |
131 | ||
5d8d9319 | 132 | //See header file for documentation |
133 | Int_t iResult = 0; | |
5d8d9319 | 134 | Float_t clusterPosition[3]; |
5d8d9319 | 135 | |
136 | for(int ic = 0; ic < nClusters; ic++) { | |
137 | ||
9d967c45 | 138 | T * cluster = clustersVector.at(ic); |
139 | ||
140 | if(cluster->E()<1.)continue; | |
141 | /* The lines below correspond to the method for Track-matching from RecoUtils:ExtrapolatetoCluster | |
142 | In principle, the method ExtrapolateToCluster should be called directly from RecoUtils. The problems is that This method requires AliVCluster | |
143 | which would have to be created inside the GlobalMatcher, since the information this class obtains from the Cluster comes from the | |
144 | data struct with the cluster information. In order to avoid the whole creation of a AliVCluster object, the code from RecoUtils | |
5d8d9319 | 145 | was brought here in the same way it is written there. |
146 | */ | |
147 | cluster->GetPosition(clusterPosition); | |
9d967c45 | 148 | TVector3 vec(clusterPosition[0],clusterPosition[1],clusterPosition[2]); |
149 | if(clusterPosition[1]<0.) continue; | |
150 | if(TMath::Abs(track->Eta()-vec.Eta())>0.3) continue; | |
151 | ||
5d8d9319 | 152 | AliExternalTrackParam *trkParam = new AliExternalTrackParam(*track);//Retrieve the starting point every time before the extrapolation |
d6b5dbb4 | 153 | Double_t trkPos[3] = {0, 0, 0}; |
5d8d9319 | 154 | Double_t alpha = ((int)(vec.Phi()*TMath::RadToDeg()/20)+0.5)*20*TMath::DegToRad(); |
155 | vec.RotateZ(-alpha); //Rotate the cluster to the local extrapolation coordinate system | |
156 | trkParam->Rotate(alpha); //Rotate the track to the same local extrapolation system | |
9d967c45 | 157 | if(1==Method&&!trkParam->GetXYZAt(vec.X(), bz, trkPos)) continue; // Simpler extrapolation |
158 | if(2==Method){ | |
159 | if(!AliTrackerBase::PropagateTrackToBxByBz(trkParam, vec.X(), fMass, fStep,kFALSE, 0.8, -1)) continue; | |
160 | trkParam->GetXYZ(trkPos); //Get the extrapolated global position | |
161 | } | |
0d976277 | 162 | |
5d8d9319 | 163 | TVector3 clsPosVec(clusterPosition[0],clusterPosition[1],clusterPosition[2]); |
164 | TVector3 trkPosVec(trkPos[0],trkPos[1],trkPos[2]); | |
5d8d9319 | 165 | |
9d967c45 | 166 | // track cluster matching |
167 | Double_t tmpPhi = clsPosVec.DeltaPhi(trkPosVec); // tmpPhi is between -pi and pi | |
168 | Double_t tmpEta = clsPosVec.Eta()-trkPosVec.Eta(); // track cluster matching | |
169 | Double_t match=TMath::Sqrt(tmpEta*tmpEta + tmpPhi*tmpPhi);//MARCEL | |
170 | ||
5d8d9319 | 171 | if( match > fMatchDistanceEMCal )continue; |
172 | ||
173 | if (match < bestMatch[ic]) { | |
174 | bestMatch[ic] = match; | |
175 | cluster->SetEmcCpvDistance(TMath::Sqrt(match)); | |
176 | Double_t dx=tmpPhi; | |
177 | Double_t dz=tmpEta; | |
178 | cluster->SetTrackDistance(dx,dz); | |
179 | } | |
180 | //Add track to cluster's array of matching tracks | |
181 | Int_t nTracksMatched = cluster->GetNTracksMatched(); | |
182 | iResult = AddTrackToCluster(track->GetID(), cluster->GetTracksMatched(), match < bestMatch[ic], nTracksMatched); | |
183 | } | |
184 | ||
185 | return iResult; | |
186 | } | |
e5b4e619 | 187 | |
2a24cbbe | 188 | template <class T> |
189 | Int_t AliHLTGlobalTrackMatcher::MatchTrackToClusters( AliExternalTrackParam * track, vector<T*> &clustersVector, Int_t nClusters, Float_t * bestMatch, Double_t bz) { | |
a46c7ba5 | 190 | |
2a24cbbe | 191 | //See header file for documentation |
192 | Int_t iResult = 0; | |
e5b4e619 | 193 | |
2a24cbbe | 194 | Float_t clusterPosition[3]; |
195 | Double_t trackPosition[3]; | |
a46c7ba5 | 196 | |
e5b4e619 | 197 | for(int ic = 0; ic < nClusters; ic++) { |
2a24cbbe | 198 | |
e5b4e619 | 199 | T * cluster = clustersVector.at(ic); |
200 | ||
201 | //Get cluster global coordinates | |
202 | cluster->GetPosition(clusterPosition); | |
203 | ||
204 | Double_t rCluster = TMath::Sqrt(clusterPosition[0]*clusterPosition[0] + clusterPosition[1]*clusterPosition[1]); | |
205 | ||
206 | //Rotate tracking system to the angle of the cluster | |
207 | TVector3 cVec(clusterPosition); | |
208 | if (! (track->Rotate(cVec.Phi())) ) { | |
209 | continue; | |
210 | } | |
211 | ||
212 | if(! (track->GetXYZAt(rCluster, bz, trackPosition)) ) { | |
213 | continue; | |
214 | } | |
d64429af | 215 | |
216 | //Calculate track - cluster residuals | |
217 | Double_t match = 0; | |
218 | for(int i = 0; i < 3; i++) { | |
e5b4e619 | 219 | Double_t dd = trackPosition[i] - clusterPosition[i]; |
d64429af | 220 | match += dd*dd; |
e5b4e619 | 221 | } |
5d8d9319 | 222 | |
e5b4e619 | 223 | |
e5b4e619 | 224 | if( match > fMatchDistance ) { |
225 | continue; | |
226 | } | |
227 | ||
228 | if (match < bestMatch[ic]) { | |
d64429af | 229 | |
e5b4e619 | 230 | bestMatch[ic] = match; |
231 | cluster->SetEmcCpvDistance(TMath::Sqrt(match)); | |
d64429af | 232 | |
233 | Double_t dx = trackPosition[0] - clusterPosition[0]; | |
234 | Double_t dy = trackPosition[1] - clusterPosition[1]; | |
235 | Double_t dz = trackPosition[2] - clusterPosition[2]; | |
236 | cluster->SetTrackDistance( ((dx > 0) ? 1 : -1 )*TMath::Sqrt(dx*dx + dy*dy), dz); | |
2a24cbbe | 237 | } |
e5b4e619 | 238 | |
239 | //Add track to cluster's array of matching tracks | |
240 | Int_t nTracksMatched = cluster->GetNTracksMatched(); | |
241 | iResult = AddTrackToCluster(track->GetID(), cluster->GetTracksMatched(), match < bestMatch[ic], nTracksMatched); | |
242 | } | |
2a24cbbe | 243 | |
244 | return iResult; | |
245 | } | |
246 | ||
3cfb9c56 | 247 | #endif |