3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Timur Pocheptsov <Timur.Pocheptsov@cern.ch> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /// @file AliHLTPrimaryVertexFinderComponent.cxx
20 /// @author Timur Pocheptsov
22 /// @brief Primary vertex finder component
31 #include "AliHLTPrimaryVertexFinderComponent.h"
32 #include "AliExternalTrackParam.h"
33 #include "AliHLTDataTypes.h"
35 ClassImp(AliHLTPrimaryVertexFinderComponent)
37 const double AliHLTPrimaryVertexFinderComponent::fgDefaultDeviation = 4.;
39 //________________________________________________________________________
40 AliHLTPrimaryVertexFinderComponent::AliHLTPrimaryVertexFinderComponent()
43 fFitTracksToVertex(true),
44 fConstrainedTrackDeviation(fgDefaultDeviation)
49 //________________________________________________________________________
50 const char* AliHLTPrimaryVertexFinderComponent::GetComponentID()
53 return "PrimaryVertexFinder";
56 //________________________________________________________________________
57 void AliHLTPrimaryVertexFinderComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
59 //Input to the primary vertex finder:
60 //a)tracks from ESD object;
65 list.push_back(kAliHLTDataTypeESDObject);
66 list.push_back(kAliHLTDataTypeTrack | kAliHLTDataOriginITS);
67 list.push_back(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC);
70 //________________________________________________________________________
71 AliHLTComponentDataType AliHLTPrimaryVertexFinderComponent::GetOutputDataType()
73 //Data type of output.
74 return kAliHLTMultipleDataType;
77 //________________________________________________________________________
78 int AliHLTPrimaryVertexFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
80 //Types for outputs from primary vertex finder (for V0 finder).
83 //Indices of tracks, participating in a primary.
84 list.push_back(kAliHLTDataTypePrimaryFinder | kAliHLTDataOriginOut);
85 //KFVertex - primary vertex.
86 list.push_back(kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut);
91 //________________________________________________________________________
92 void AliHLTPrimaryVertexFinderComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
94 //These numbers are complete crap.
99 //________________________________________________________________________
100 AliHLTComponent* AliHLTPrimaryVertexFinderComponent::Spawn()
102 //Create primary vertex finder componet.
103 return new AliHLTPrimaryVertexFinderComponent;
106 //________________________________________________________________________
107 int AliHLTPrimaryVertexFinderComponent::DoInit(int /*argc*/, const char** /*argv*/)
110 //1. Default parameters.
111 fFitTracksToVertex = true;
112 fConstrainedTrackDeviation = fgDefaultDeviation;
114 //2. Parameters from OCDB.
115 TString cdbPath("HLT/ConfigHLT/");
116 cdbPath += GetComponentID();
118 //This part will be uncommented as soon as
119 //OCDB object is added.
121 int res = ConfigureFromCDBTObjString(cdbPath);
126 //3. "Command line" parameters.
128 res = ConfigureFromArgumentString(argc, argv);
135 //________________________________________________________________________
136 int AliHLTPrimaryVertexFinderComponent::ScanConfigurationArgument(int argc, const char** argv)
138 //Scan the name of option and its parameters from the list.
139 //Return number of processed entries.
140 //Possible arguments:
141 //-fitTracksToVertex 1/0
142 //-constrainedTrackDeviation value
143 AliHLTUtility::CmdLineParser parser;
144 parser.Add("-fitTrackToVertex", &fFitTracksToVertex);
145 parser.Add("-constrainedTrackDeviation", &fConstrainedTrackDeviation);
147 const int nParsed = parser.Parse(argc, argv, 0);
149 HLTError(parser.GetError().Data());
156 //________________________________________________________________________
157 int AliHLTPrimaryVertexFinderComponent::DoDeinit()
159 //Reset parameters to default.
160 fFitTracksToVertex = true;
161 fConstrainedTrackDeviation = fgDefaultDeviation;
166 //________________________________________________________________________
167 int AliHLTPrimaryVertexFinderComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/,
168 AliHLTComponentTriggerData& /*trigData*/)
170 //Find primary vertex.
172 if (GetFirstInputBlock(kAliHLTDataTypeSOR) || GetFirstInputBlock(kAliHLTDataTypeEOR))
176 //Clean all previous track infos and output block.
178 fPrimaryOutput.clear();
180 //Initialize KF package.
181 AliKFParticle::SetField(GetBz());
183 //The logic, how vertex finder reads input tracks,
184 //is taken from the original global vertexer.
185 //First, try to read tracks from ESD event.
186 //Both positive and negative PID are 211 ("default").
187 //Other hypotesis are not possible here.
188 ReadESDTracks(211, 211);
189 //If no good esd tracks or no esd at all:
190 if (!fTrackInfos.size())
191 ReadHLTTracks(kAliHLTDataTypeTrack | kAliHLTDataOriginITS, 211, 211);
192 //If no good its tracks:
193 if (!fTrackInfos.size())
194 ReadHLTTracks(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC, 211, 211);
196 if (!fTrackInfos.size()) {
197 HLTWarning("No input tracks found");
209 struct VertexDeviation
211 int fI; //Index in fTrackInfos array.
212 double fD; //Deviation from primary vertex.
214 bool operator < (const VertexDeviation& rhs) const
222 //________________________________________________________________________
223 void AliHLTPrimaryVertexFinderComponent::FindPrimaryVertex()
225 //Find event's primary vertex.
227 ///////////////////////////////////////////////////////////////////////
228 //Some changes must be done here to read the initial guess (?)
229 //for primary vertex.
230 //Select rough region (in sigmas) in which the vertex could be found,
231 //all tracks outside these limits are rejected from the primary vertex finding.
232 fPrimaryVtx.Initialize();
233 fPrimaryVtx.SetBeamConstraint(0., 0., 0., 3., 3., 5.3);
234 ////////////////////////////////////////////////////////////////////////
236 std::vector<const AliKFParticle*> vSelected(fTrackInfos.size());
237 std::vector<VertexDeviation> devs(fTrackInfos.size());
240 for (VectorSize_t i = 0; i < fTrackInfos.size(); ++i) {
241 const AliKFParticle& p = fTrackInfos[i].fParticle;
242 const double chi = p.GetDeviationFromVertex(fPrimaryVtx);
243 if (chi > fConstrainedTrackDeviation)
246 devs[nSelected].fI = i;
247 devs[nSelected].fD = chi;
248 vSelected[nSelected] = &fTrackInfos[i].fParticle;
253 while (nSelected > 2) {
254 //Primary vertex finder with rejection of outliers
255 for (int i = 0; i < nSelected; ++i)
256 vSelected[i] = &fTrackInfos[devs[i].fI].fParticle;
258 const double xv = fPrimaryVtx.GetX();
259 const double yv = fPrimaryVtx.GetY();
260 const double zv = fPrimaryVtx.GetZ(); //Values from the previous iteration.
262 fPrimaryVtx.Initialize();
263 fPrimaryVtx.SetBeamConstraint(0, 0, 0, 3., 3., 5.3);
264 fPrimaryVtx.SetVtxGuess(xv, yv, zv);
266 // refilled for every iteration
267 //0: pointer to production vertex, -1. : mass, true : constrained.
268 fPrimaryVtx.Construct(&vSelected[0], nSelected, 0, -1., true);
270 for (int it = 0; it < nSelected; ++it) {
271 const AliKFParticle& p = fTrackInfos[devs[it].fI].fParticle;
272 if (nSelected <= 20) {
273 //Exclude the current track from the sample and recalculate the vertex
274 AliKFVertex tmp(fPrimaryVtx - p);
275 devs[it].fD = p.GetDeviationFromVertex(tmp);
277 devs[it].fD = p.GetDeviationFromVertex(fPrimaryVtx);
281 //Sort tracks with increasing chi2 (used for rejection)
282 std::sort(&devs[0], &devs[0] + nSelected);
284 //Remove 30% of the tracks (done for performance, only if there are more than 20 tracks)
285 int nRemove = int(0.3 * nSelected);
286 if (nSelected - nRemove <= 20)
287 nRemove = 1;// removal based on the chi2 of every track
289 int firstRemove = nSelected - nRemove;
290 while (firstRemove < nSelected) {
291 if (devs[firstRemove].fD >= fConstrainedTrackDeviation)
296 if (firstRemove >= nSelected)
299 nSelected = firstRemove;
302 if (nSelected < 3) {//No vertex for less than 3 contributors.
303 fPrimaryVtx.NDF() = -3;
304 fPrimaryVtx.Chi2() = 0.;
309 //Prepare output block.
310 fPrimaryOutput.resize(sizeof(PrimaryFinderBlock) + sizeof(int) * (nSelected - 1));
311 PrimaryFinderBlock* out = reinterpret_cast<PrimaryFinderBlock*>(&fPrimaryOutput[0]);
313 out->fFitTracksFlag = fFitTracksToVertex;
314 out->fNPrimaryTracks = nSelected;
316 int minID = fTrackInfos[devs[0].fI].fID;
318 for (int i = 0; i < nSelected; ++i) {
319 const int id = fTrackInfos[devs[i].fI].fID;
320 minID = TMath::Min(minID, id);
321 maxID = TMath::Max(maxID, id);
322 out->fPrimTrackIds[i] = id;
325 out->fMinPrimID = minID;
326 out->fMaxPrimID = maxID;
330 //________________________________________________________________________
331 int AliHLTPrimaryVertexFinderComponent::DoOutput()
333 //Primary vertex finder output.
334 if (!fPrimaryOutput.size()) {
336 //Messages? return values?
337 HLTWarning("No primary vertex was found");
341 //1. indices of primary tracks;
342 //int - type of PushBack's parameter.
343 const int iResult = PushBack(&fPrimaryOutput[0], fPrimaryOutput.size(),
344 kAliHLTDataTypePrimaryFinder | kAliHLTDataOriginOut);
347 //2. primary vertex (AliKFVertex).
348 return PushBack(&fPrimaryVtx, kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut, 0);