f078d002 |
1 | // $Id$ |
2 | |
3 | //************************************************************************** |
4 | //* This file is property of and copyright by the ALICE HLT Project * |
5 | //* ALICE Experiment at CERN, All rights reserved. * |
6 | //* * |
7 | //* Primary Authors: Timur Pocheptsov <Timur.Pocheptsov@cern.ch> * |
8 | //* for The ALICE HLT Project. * |
9 | //* * |
10 | //* Permission to use, copy, modify and distribute this software and its * |
11 | //* documentation strictly for non-commercial purposes is hereby granted * |
12 | //* without fee, provided that the above copyright notice appears in all * |
13 | //* copies and that both the copyright notice and this permission notice * |
14 | //* appear in the supporting documentation. The authors make no claims * |
15 | //* about the suitability of this software for any purpose. It is * |
16 | //* provided "as is" without express or implied warranty. * |
17 | //************************************************************************** |
18 | |
19 | /// @file AliHLTV0FinderComponent.cxx |
20 | /// @author Timur Pocheptsov |
21 | /// @date 2010-12-26 |
22 | /// @brief V0 finder component |
23 | /// |
24 | |
25 | #include "TString.h" |
26 | |
27 | #include "AliHLTDataTypes.h" |
28 | #include "AliHLTV0FinderComponent.h" |
29 | |
30 | ClassImp(AliHLTV0FinderComponent) |
31 | |
32 | const double AliHLTV0FinderComponent::fgDaughterPrimDeviation = 2.5; |
33 | const double AliHLTV0FinderComponent::fgPrimDeviation = 3.5; |
34 | const double AliHLTV0FinderComponent::fgChi = 3.5; |
35 | const double AliHLTV0FinderComponent::fgDecayLengthInSigmas = 3.; |
36 | |
37 | //________________________________________________________________________ |
38 | AliHLTV0FinderComponent::AliHLTV0FinderComponent() |
39 | : fPrimaryVtx(), |
40 | fPrimaryTracks(), |
41 | fNPrimaryTracks(0), |
42 | fMinPrimID(0), |
43 | fMaxPrimID(0), |
44 | fDaughterPrimDeviation(fgDaughterPrimDeviation), |
45 | fPrimDeviation(fgPrimDeviation), |
46 | fChi(fgChi), |
47 | fDecayLengthInSigmas(fgDecayLengthInSigmas), |
48 | fPosPID(211), |
49 | fNegPID(211), |
50 | fV0s(), |
51 | fGammaFinder(false) |
52 | { |
53 | //Default ctor. |
54 | } |
55 | |
56 | //________________________________________________________________________ |
57 | const char* AliHLTV0FinderComponent::GetComponentID() |
58 | { |
59 | //Component's "name". |
60 | return "V0Finder"; |
61 | } |
62 | |
63 | //________________________________________________________________________ |
64 | void AliHLTV0FinderComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list) |
65 | { |
66 | //Input to the primary vertex finder: |
67 | //a)tracks from ESD object; |
68 | //b)hlt tracks (ITS) |
69 | //c)hlt tracks (TPC) |
70 | //d)primary vertex (AliKFVertex) |
71 | //e)indices of primary tracks. |
72 | list.clear(); |
73 | //Input tracks. |
74 | list.push_back(kAliHLTDataTypeESDObject); |
75 | list.push_back(kAliHLTDataTypeTrack | kAliHLTDataOriginITS); |
76 | list.push_back(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC); |
77 | //Input from primary finder: |
78 | //Primary vertex. |
79 | list.push_back(kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut); |
80 | //Primary tracks' indices. |
81 | list.push_back(kAliHLTDataTypePrimaryFinder | kAliHLTDataOriginOut); |
82 | } |
83 | |
84 | //________________________________________________________________________ |
85 | AliHLTComponentDataType AliHLTV0FinderComponent::GetOutputDataType() |
86 | { |
87 | //Data type of output. |
88 | return kAliHLTMultipleDataType; |
89 | } |
90 | |
91 | //________________________________________________________________________ |
92 | int AliHLTV0FinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) |
93 | { |
94 | //Output type for V0 finder. |
95 | tgtList.clear(); |
96 | //Indices of tracks, participating in V0s. |
97 | tgtList.push_back(kAliHLTDataTypeV0Finder | kAliHLTDataOriginOut); |
98 | |
99 | return tgtList.size(); |
100 | } |
101 | |
102 | //________________________________________________________________________ |
103 | void AliHLTV0FinderComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) |
104 | { |
105 | //These numbers are complete crap. |
106 | constBase = 80000; |
107 | inputMultiplier = 2.; |
108 | } |
109 | |
110 | //________________________________________________________________________ |
111 | AliHLTComponent* AliHLTV0FinderComponent::Spawn() |
112 | { |
113 | //Create primary vertex finder componet. |
114 | return new AliHLTV0FinderComponent; |
115 | } |
116 | |
117 | //________________________________________________________________________ |
118 | int AliHLTV0FinderComponent::DoInit(int /*argc*/, const char** /*argv*/) |
119 | { |
120 | //1. Default parameters. |
121 | fDaughterPrimDeviation = fgDaughterPrimDeviation; |
122 | fPrimDeviation = fgPrimDeviation; |
123 | fChi = fgChi; |
124 | fDecayLengthInSigmas = fgDecayLengthInSigmas; |
125 | fPosPID = 211; |
126 | fNegPID = 211; |
127 | fGammaFinder = false; |
128 | |
129 | //Part with OCDB and command line arguments is commented |
130 | //until OCDB is updated. |
131 | /* |
132 | //2. Parameters from OCDB. |
133 | TString cdbPath("HLT/ConfigHLT/"); |
134 | cdbPath += GetComponentID(); |
135 | |
136 | int res = ConfigureFromCDBTObjString(cdbPath); |
137 | if (res < 0) |
138 | return res; |
139 | |
140 | //3. "Command line" parameters. |
141 | if (argc) |
142 | res = ConfigureFromArgumentString(argc, argv); |
143 | |
144 | return res;*/ |
145 | return 0; |
146 | } |
147 | |
148 | //________________________________________________________________________ |
149 | int AliHLTV0FinderComponent::ScanConfigurationArgument(int argc, const char** argv) |
150 | { |
151 | //Scan one argument and its parameters from the list |
152 | //Return number of processed entries. |
153 | //Possible arguments: |
154 | //-daughterPrimDeviation num |
155 | //-primDeviation num |
156 | //-chi num |
157 | //-decayLengthInSigmas num |
158 | //-posPID int_num |
159 | //-negPid int_num |
160 | //-gammaFinder 0/1 |
161 | |
162 | AliHLTUtility::CmdLineParser parser; |
163 | parser.Add("-daughterPrimDeviation", &fDaughterPrimDeviation); |
164 | parser.Add("-primDeviation", &fPrimDeviation); |
165 | parser.Add("-chi", &fChi); |
166 | parser.Add("-decayLengthInSigmas", &fDecayLengthInSigmas); |
167 | parser.Add("-posPID", &fPosPID); |
168 | parser.Add("-negPID", &fNegPID); |
169 | parser.Add("-gammaFinder", &fGammaFinder); |
170 | |
171 | const int nParsed = parser.Parse(argc, argv, 0); |
172 | if (nParsed < 0) { |
173 | HLTError(parser.GetError().Data()); |
174 | return -EPROTO; |
175 | } |
176 | |
177 | return nParsed; |
178 | } |
179 | |
180 | //________________________________________________________________________ |
181 | int AliHLTV0FinderComponent::DoDeinit() |
182 | { |
183 | //Reset parameters to default. |
184 | fDaughterPrimDeviation = fgDaughterPrimDeviation; |
185 | fPrimDeviation = fgPrimDeviation; |
186 | fChi = fgChi; |
187 | fDecayLengthInSigmas = fgDecayLengthInSigmas; |
188 | fPosPID = 211; |
189 | fNegPID = 211; |
190 | fGammaFinder = false; |
191 | |
192 | return 0; |
193 | } |
194 | |
195 | //________________________________________________________________________ |
196 | int AliHLTV0FinderComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/, |
197 | AliHLTComponentTriggerData& /*trigData*/) |
198 | { |
199 | //Find primary vertex. |
200 | if (GetFirstInputBlock(kAliHLTDataTypeSOR) || GetFirstInputBlock(kAliHLTDataTypeEOR)) |
201 | return 0; |
202 | |
203 | //Clean all previous track infos. |
204 | fTrackInfos.clear(); |
205 | fPrimaryTracks.clear(); |
206 | |
207 | //Initialize KF package. |
208 | AliKFParticle::SetField(GetBz()); |
209 | |
210 | if (!ReadPrimaryVertex()) |
211 | return 0; |
212 | |
213 | if (!ReadTracks()) |
214 | return 0; |
215 | |
216 | FindV0s(); |
217 | |
218 | return DoOutput(); |
219 | } |
220 | |
221 | //________________________________________________________________________ |
222 | bool AliHLTV0FinderComponent::ReadPrimaryVertex() |
223 | { |
224 | //Primary finder produces primary vertex (AliKFVertex) and |
225 | //indices for primary tracks. |
226 | //1. Try to extract primary vertex. |
227 | const TObject* obj = GetFirstInputObject(kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut); |
228 | const AliKFVertex* kfVtx = dynamic_cast<const AliKFVertex*>(obj); |
229 | |
230 | if (!kfVtx) { |
231 | HLTError("V0 finder requires KF vertex (primary vertex) as input"); |
232 | return false; |
233 | } |
234 | |
235 | //2. Try to read primary track indices. |
236 | const AliHLTComponentBlockData* p = GetFirstInputBlock(kAliHLTDataTypePrimaryFinder |
237 | | kAliHLTDataOriginOut); |
238 | if (!p || !p->fSize || !p->fPtr) { |
239 | HLTError("Array of primary track indices expected"); |
240 | return false; |
241 | } |
242 | |
243 | //Data block from primary finder |
244 | const PrimaryFinderBlock* blk = static_cast<PrimaryFinderBlock*>(p->fPtr); |
245 | //Track ids must be positive integers. |
246 | if (blk->fMinPrimID < 0 || blk->fMaxPrimID < 0) { |
247 | HLTError("Got negative track ID from primary finder, internal HLT error"); |
248 | return false; |
249 | } |
250 | |
251 | //3. Got correct data, modify the component's state. |
252 | //KF vertex. |
253 | fPrimaryVtx = *kfVtx; |
254 | //Primary tracks. |
255 | fNPrimaryTracks = blk->fNPrimaryTracks; |
256 | fMinPrimID = blk->fMinPrimID; |
257 | fMaxPrimID = blk->fMaxPrimID; |
258 | |
259 | fPrimaryTracks.assign(fMaxPrimID + 1, 0); |
260 | for (int i = 0; i < fNPrimaryTracks; ++i) |
261 | fPrimaryTracks[blk->fPrimTrackIds[i]] = 1; |
262 | |
263 | return true; |
264 | } |
265 | |
266 | //________________________________________________________________________ |
267 | bool AliHLTV0FinderComponent::ReadTracks() |
268 | { |
269 | //The logic, how vertex finder reads input tracks, |
270 | //is taken from the original global vertexer. |
271 | //First, try to read tracks from ESD event. |
272 | ReadESDTracks(); |
273 | if (fTrackInfos.size()) { |
274 | FindPrimaryDeviations(); |
275 | return true; |
276 | } |
277 | |
278 | //No good esd tracks, try: |
279 | ReadHLTTracks(kAliHLTDataTypeTrack | kAliHLTDataOriginITS); |
280 | if (fTrackInfos.size()) { |
281 | FindPrimaryDeviations(); |
282 | return true; |
283 | } |
284 | |
285 | //If no good its tracks, try: |
286 | ReadHLTTracks(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC); |
287 | if (fTrackInfos.size()) { |
288 | FindPrimaryDeviations(); |
289 | return true; |
290 | } |
291 | |
292 | HLTError("No input tracks found for V0 finder"); |
293 | |
294 | return false; |
295 | } |
296 | |
297 | //________________________________________________________________________ |
298 | void AliHLTV0FinderComponent::FindPrimaryDeviations() |
299 | { |
300 | //Quite a tricky part. |
301 | for (VectorSize_t i = 0; i < fTrackInfos.size(); ++i) { |
302 | AliHLTTrackInfo& info = fTrackInfos[i]; |
303 | if (IsPrimaryTrack(info.fID)) { |
304 | info.fPrimUsed = true; |
305 | //The way primary deviation is computed in primary finder: |
306 | if (fNPrimaryTracks <= 20) { |
307 | AliKFVertex tmp(fPrimaryVtx - info.fParticle); |
308 | info.fPrimDeviation = info.fParticle.GetDeviationFromVertex(tmp); |
309 | } else |
310 | info.fPrimDeviation = info.fParticle.GetDeviationFromVertex(fPrimaryVtx); |
311 | } else { |
312 | info.fPrimUsed = false; |
313 | info.fPrimDeviation = info.fParticle.GetDeviationFromVertex(fPrimaryVtx); |
314 | } |
315 | } |
316 | } |
317 | |
318 | //________________________________________________________________________ |
319 | bool AliHLTV0FinderComponent::IsPrimaryTrack(int id)const |
320 | { |
321 | if (id < fMinPrimID || id > fMaxPrimID) |
322 | return false; |
323 | |
324 | return fPrimaryTracks[id]; |
325 | } |
326 | |
327 | //________________________________________________________________________ |
328 | void AliHLTV0FinderComponent::FindV0s() |
329 | { |
330 | //Here's the core. |
331 | if (fPrimaryVtx.GetNContributors() < 3) |
332 | return; |
333 | |
334 | fV0s.clear(); |
335 | fV0s.push_back(0); //Number of v0s. |
336 | |
337 | for (int iTr = 0, ei = fTrackInfos.size(); iTr < ei; ++iTr) { |
338 | AliHLTTrackInfo& info = fTrackInfos[iTr]; |
339 | if (info.fParticle.GetQ() > 0) |
340 | continue; |
341 | if (info.fPrimDeviation < fDaughterPrimDeviation) |
342 | continue; |
343 | |
344 | for (int jTr = 0; jTr < ei; ++jTr) { |
345 | AliHLTTrackInfo& jnfo = fTrackInfos[jTr]; |
346 | if (jnfo.fParticle.GetQ() < 0) |
347 | continue; |
348 | if (jnfo.fPrimDeviation < fDaughterPrimDeviation) |
349 | continue; |
350 | |
351 | //Check if the particles fit |
352 | if (info.fParticle.GetDeviationFromParticle(jnfo.fParticle) > fChi) |
353 | continue; |
354 | |
355 | //Construct V0 mother |
356 | AliKFParticle v0(info.fParticle, jnfo.fParticle /*, bGammaFinder*/); |
357 | //Check V0 Chi^2 |
358 | if (v0.GetChi2() < 0. || v0.GetChi2() > fChi * fChi * v0.GetNDF()) |
359 | continue; |
360 | |
361 | //Subtruct daughters from primary vertex |
362 | AliKFVertex primVtxCopy(fPrimaryVtx); |
363 | |
364 | if (info.fPrimUsed) { |
365 | if (primVtxCopy.GetNContributors() <= 2) |
366 | continue; |
367 | primVtxCopy -= info.fParticle; |
368 | } |
369 | |
370 | if (jnfo.fPrimUsed) { |
371 | if (primVtxCopy.GetNContributors() <= 2) |
372 | continue; |
373 | primVtxCopy -= jnfo.fParticle; |
374 | } |
375 | |
376 | //Check v0 Chi^2 deviation from primary vertex |
377 | if (v0.GetDeviationFromVertex(primVtxCopy) > fPrimDeviation) |
378 | continue; |
379 | //Add V0 to primary vertex to improve the primary vertex resolution |
380 | primVtxCopy += v0; |
381 | //Set production vertex for V0 |
382 | v0.SetProductionVertex(primVtxCopy); |
383 | //Get V0 decay length with estimated error |
384 | double length = 0., sigmaLength = 0.; |
385 | if (v0.GetDecayLength(length, sigmaLength)) |
386 | continue; |
387 | //Reject V0 if it decays too close[sigma] to the primary vertex |
388 | if (length < fDecayLengthInSigmas * sigmaLength) |
389 | continue; |
390 | //Keep v0 |
391 | fV0s.push_back(iTr); |
392 | fV0s.push_back(jTr); |
393 | |
394 | fV0s[0] += 1; |
395 | } |
396 | } |
397 | } |
398 | |
399 | //________________________________________________________________________ |
400 | int AliHLTV0FinderComponent::DoOutput() |
401 | { |
402 | //Save V0s' track pairs' indices. |
403 | if (!fV0s.size() || !fV0s[0]) { |
404 | HLTInfo("No v0s were found"); |
405 | return 0; |
406 | } |
407 | |
408 | //Indices of primary tracks. |
409 | return PushBack(&fV0s[0], fV0s.size() * sizeof(int), |
410 | kAliHLTDataTypeV0Finder | kAliHLTDataOriginOut); |
411 | } |