ATLAS Offline Software
Loading...
Searching...
No Matches
TrackParticleRetriever.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "GaudiKernel/IToolSvc.h"
7#include "GaudiKernel/TypeNameString.h"
8
10
12
13#include "AthLinks/ElementLink.h"
15
16namespace JiveXML {
17
24 TrackParticleRetriever::TrackParticleRetriever(const std::string& type,const std::string& name,const IInterface* parent):
25 AthAlgTool(type,name,parent),
26 m_typeName("Track"){
27
28 //Declare the interface
29 declareInterface<IDataRetriever>(this);
30
31 //Properties
32 declareProperty("PriorityTrackCollection", m_PriorityTrackCollection = "TrackParticleCandidate",
33 "Track collections to retrieve first, shown as default in Atlantis");
34 declareProperty("OtherTrackCollections" , m_OtherTrackCollections , "Track collections to retrieve, all if empty");
35 declareProperty("DoWriteHLT" , m_doWriteHLT = false, "Wether to write HLTAutoKey objects");
36 }
37
38
40
44// vectors with measurement, maximum 3 for TrackParticle (perigee, calo entry, muon entry)
45// info from Ed Moyse Oct09
47 DataVect& polylineX, DataVect& polylineY, DataVect& polylineZ, DataVect& numPolyline){
48
49 DataVect myPositionX;
50 DataVect myPositionY;
51 DataVect myPositionZ;
52
53 int numPoly = 0 ;
54
55// Migration Dec'13: Not yet done here ! Need equivalent code
56// to access spacepoints. jpt 13Dec13
57
58 unsigned int i = 0;
59 const std::vector<const Trk::TrackParameters*>& trackpars =track->trackParameters();
60
61 if (!trackpars.empty() && trackpars.size() == 3 ) { //polylines with less than 3 entries not useful
62
63 bool needresorting = trackpars.at(0)!=track->perigee();//Needed since TrackParticles are (at the moment)
64 //created with the first parameter put last
65 for ( i=0; i<trackpars.size(); i++){
66 const Amg::Vector3D& pos = trackpars.at(i)->position();
67 myPositionX.push_back(DataType(pos.x()/10.));
68 myPositionY.push_back(DataType(pos.y()/10.));
69 myPositionZ.push_back(DataType(pos.z()/10.));
70 //std::cout << " Polyline # " << i << " x: " << pos.x() << std::endl;
71 ++numPoly;
72 }
73 if (needresorting){ // swapping vector around. Is this too naive ?
74 polylineX.push_back( myPositionX.at( trackpars.size()-1 ) );
75 polylineY.push_back( myPositionY.at( trackpars.size()-1 ) );
76 polylineZ.push_back( myPositionZ.at( trackpars.size()-1 ) );
77 polylineX.push_back( myPositionX.at( trackpars.size()-3 ) );
78 polylineY.push_back( myPositionY.at( trackpars.size()-3 ) );
79 polylineZ.push_back( myPositionZ.at( trackpars.size()-3 ) );
80 polylineX.push_back( myPositionX.at( trackpars.size()-2 ) );
81 polylineY.push_back( myPositionY.at( trackpars.size()-2 ) );
82 polylineZ.push_back( myPositionZ.at( trackpars.size()-2 ) );
83 }
84 }
85
86 // std::cout << " numPolyline" << numPoly << std::endl;
87
88 //Store counter as well
89 numPolyline.push_back(DataType(numPoly));
90 }
91} // end TrackRetrieverHelpers namespace
92
100 StatusCode TrackParticleRetriever::retrieve(ToolHandle<IFormatTool> &FormatTool) {
101
102 //be verbose
103 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Retrieving AOD TrackParticle" << endmsg;
104
105 //Generate a list of requested track collections
106 typedef std::pair< Rec::TrackParticleContainer , std::string > tracksNamePair;
107 std::vector< tracksNamePair > requestedTrackColls;
108
109 //First try to get hold of the priority track collection
110 const Rec::TrackParticleContainer* tracks = NULL ;
111 if (evtStore()->retrieve(tracks, m_PriorityTrackCollection).isFailure()){
112 if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Unable to retrieve requested priority track collection "
114 } else {
115 //Add this to the list of requested collections
116 requestedTrackColls.push_back(tracksNamePair(*tracks,m_PriorityTrackCollection));
117 }
118
119 //If we have been given an explicit list, try to retrieve these in the order
120 //they were given
121
122 std::vector<std::string>::iterator CollNameItr = m_OtherTrackCollections.begin();
123 for ( ; CollNameItr != m_OtherTrackCollections.end(); ++CollNameItr){
124 const Rec::TrackParticleContainer* tracks = NULL ;
125 if (evtStore()->retrieve(tracks, (*CollNameItr)).isFailure()){
126 if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Unable to retrieve requested track collection " << (*CollNameItr) << endmsg;
127 continue ;
128 }
129
130// This fails for me, compilation error. Leave it out for now.
131// But this means some collections are written out twice ! jpt 24Jul09
132// This is copy/paste from TrackRetriever, works with TrackCollection,
133// but _not_ with Rec::TrackParticleContainer in completely identical code.
134 //Check if this collection is not already in the list
135// if (std::find(requestedTrackColls.begin(), requestedTrackColls.end(),
136// tracksNamePair(*tracks,*CollNameItr) ) == requestedTrackColls.end()){
137 //Add this to the list of requested collections
138 requestedTrackColls.push_back( tracksNamePair(*tracks,(*CollNameItr)) );
139// }
140 }
141
142 //If no collections had been requested explicitly, loop over all of them
143 if (m_OtherTrackCollections.empty()) {
144
145 //Get an iterator over all other track collections
146 SG::ConstIterator<Rec::TrackParticleContainer> trackCollIter, trackCollEnd;
147 if ((evtStore()->retrieve(trackCollIter, trackCollEnd)).isFailure()){
148 if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Unable to retrieve track collection iterator" << endmsg;
149 return StatusCode::SUCCESS;
150 }
151
152 //Next loop over all collections
153 for (; trackCollIter!=trackCollEnd; ++trackCollIter) {
154
155 //hack to avoid double, as 'find' (further below) fails.
156 if ( trackCollIter.key() == m_PriorityTrackCollection ){ continue; }
157
158 //Check if this is an HLT-AutoKey collection
159 if ((trackCollIter.key().find("HLT",0) != std::string::npos) && (!m_doWriteHLT)){
160 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Ignoring HLT-AutoKey collection " << trackCollIter.key() << endmsg;
161 continue ;
162 }
163
164 // Veto AtlfastTrackParticles as they have different parameter access method.
165 // Retrieving them will lead to runtime crash currently. jpt 04Aug07
166 if ( (trackCollIter.key() =="AtlfastTrackParticles")) {
167 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Always ignoring collection " << trackCollIter.key() << endmsg;
168 continue ;
169 }
170
171 //Next try to retrieve the actual collection
172 if (evtStore()->retrieve(tracks,trackCollIter.key()).isFailure()){
173 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Unable to retrieve collection " << trackCollIter.key() << endmsg;
174 continue ;
175 }
176
177// this fails for me, leave it out. jpt 24Jul09
178 //Check if this collection is not already in the list
179// if (std::find(requestedTrackColls.begin(), requestedTrackColls.end(),tracksNamePair(*tracks,trackCollIter.key())) != requestedTrackColls.end())
180// continue ;
181 //Add this to the list of requested collections
182 requestedTrackColls.push_back(tracksNamePair(*tracks,trackCollIter.key()));
183 } //loop over all track collections
184 }
185
190
191 //Loop over the collection list we have assembled above
192 std::vector<tracksNamePair>::iterator tracksNamePairItr = requestedTrackColls.begin();
193 for ( ; tracksNamePairItr != requestedTrackColls.end(); ++tracksNamePairItr){
194
195 //save some typing by getting a handle on the collection pointer
196 const Rec::TrackParticleContainer* tpc =&((*tracksNamePairItr).first);
197 std::string collectionName = (*tracksNamePairItr).second;
198
199 //Some sanity checks
200 if ( tpc->size() == 0){
201 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Ignoring empty track collection " << collectionName << endmsg;
202 } else {
203 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Retrieving data for track collection " << collectionName << endmsg;
204 }
205
206 // Make a list of track-wise entries and reserve enough space
207 DataVect id; id.reserve(tpc->size());
208 DataVect chi2; chi2.reserve(tpc->size());
209 DataVect numDoF; numDoF.reserve(tpc->size());
210 DataVect trackAuthor; trackAuthor.reserve(tpc->size());
211 DataVect label; label.reserve(tpc->size());
212
213 //Store wether this collection has perigee parameters
214 DataVect pt; pt.reserve(tpc->size());
215 DataVect d0; d0.reserve(tpc->size());
216 DataVect z0; z0.reserve(tpc->size());
217 DataVect phi0; phi0.reserve(tpc->size());
218 DataVect cotTheta; cotTheta.reserve(tpc->size());
219 DataVect covMatrix; covMatrix.reserve(tpc->size() * 15 );
220
221 DataVect numPolyline; numPolyline.reserve(tpc->size());
222 DataVect polylineX;
223 DataVect polylineY;
224 DataVect polylineZ;
225
226 std::string labelStr = "unknownHits";
227
228 // Now loop over all tracks in the collection
230 for (tpcItr=tpc->begin(); tpcItr!=tpc->end(); ++tpcItr) {
231
235 id.push_back(DataType(id.size())); //<! simple counter starting from 0
236 chi2.push_back(DataType((*tpcItr)->fitQuality()->chiSquared()));
237 numDoF.push_back(DataType((*tpcItr)->fitQuality()->numberDoF()));
238 trackAuthor.push_back( (*tpcItr)->info().trackFitter() );
239
240 const Trk::TrackSummary* tSum = (*tpcItr)->trackSummary();
241 if(tSum){
242 int nPixelHits = tSum->get(Trk::numberOfPixelHits);
243 int nSCTHits = tSum->get(Trk::numberOfSCTHits);
244 int nBLayerHits = tSum->get(Trk::numberOfInnermostPixelLayerHits);
245 int nTRTHits = tSum->get(Trk::numberOfTRTHits);
246 labelStr = "_PixelHits"+DataType( nPixelHits ).toString() + "_SCTHits"+DataType( nSCTHits ).toString() +
247 "_BLayerHits"+DataType( nBLayerHits ).toString() + "_TRTHits"+DataType( nTRTHits ).toString() ;
248 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Author: " << (*tpcItr)->info().trackFitter() << " Pixel hits: " << nPixelHits
249 << ", SCT hits: " << nSCTHits << " BLayer hits: " << nBLayerHits
250 << ", TRT hits: " << nTRTHits << ", pT[GeV]= " << (*tpcItr)->perigee()->pT()/1000. << endmsg;
251 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Label: " << labelStr << endmsg;
252 }
253
254 if (((*tpcItr)->perigee()->parameters())[Trk::qOverP]==0) {
255 pt.push_back(DataType(9999.));
256 } else {
257 pt.push_back(DataType((*tpcItr)->perigee()->charge() * (*tpcItr)->perigee()->pT()/1000.));
258 }
259
260 d0.push_back(DataType(((*tpcItr)->perigee()->parameters())[Trk::d0]/CLHEP::cm));
261 z0.push_back(DataType((*tpcItr)->perigee()->parameters()[Trk::z0]/CLHEP::cm));
262 phi0.push_back(DataType((*tpcItr)->perigee()->parameters()[Trk::phi0]));
263
264 if ((*tpcItr)->perigee()->parameters()[Trk::theta] == 0.) {
265 cotTheta.push_back(DataType(9999.));
266 } else {
267 cotTheta.push_back(DataType(1./tan((*tpcItr)->perigee()->parameters()[Trk::theta])));
268 }
269
270 // CLHEP->Eigen migration. jpt Dec'13
271 // https://twiki.cern.ch/twiki/bin/viewauth/Atlas/MigrationCLHEPtoEigen
272 // https://twiki.cern.ch/twiki/bin/viewauth/Atlas/MigrationToUpdatedEDM#Changes_to_TrkParameters
273
275 AmgSymMatrix(5) covVert;
276 //covVert.clear();
277 const Trk::Perigee* per =
278 dynamic_cast<const Trk::Perigee*>((*tpcItr)->perigee());
279 const AmgSymMatrix(5)* covariance = per ? per->covariance() : NULL;
280 if (per && covariance) {
281 // do trafo to old format
282 double measuredTheta = (*tpcItr)->perigee()->parameters()[Trk::theta];
283 double measuredQoverp = (*tpcItr)->perigee()->parameters()[Trk::qOverP];
284 const Trk::JacobianThetaPToCotThetaPt theJac( measuredTheta, measuredQoverp );
285 covVert = covariance->similarity(theJac);
286 }else{
287 for ( int ii=0; ii<20; ii++){ // placeholder. Do this nicer.
288 covVert(ii) = 0.;
289 }
290 }
291 //Scale covariance matrix values to get good resolution with fixed
292 //precision in JiveXML data
293
294 const long scale = 10000;
295// Migration: Now only has diagonal elements from covariance matrix ?
296 covMatrix.push_back(DataType(covVert(0)*scale/100.)); // 5 elements
297 covMatrix.push_back(DataType(covVert(1)*scale/100.));
298 covMatrix.push_back(DataType(covVert(2)*scale/100.));
299 covMatrix.push_back(DataType(covVert(3)*scale/100.));
300 covMatrix.push_back(DataType(covVert(4)*scale/100.));
301
302// Used to be 15 elements before migration, so need to put 10 placeholders
303 for ( int i=0; i<10; i++){
304 covMatrix.push_back(DataType( 0. ));
305 }
306/*
307 covMatrix.push_back(DataType(covVert[0][0]*scale/100.)); // 15 elements (diagonal +1half)
308 covMatrix.push_back(DataType(covVert[1][0]*scale/100.));
309 covMatrix.push_back(DataType(covVert[1][1]*scale/100.));
310 covMatrix.push_back(DataType(covVert[2][0]*scale/10.));
311 covMatrix.push_back(DataType(covVert[2][1]*scale/10.));
312 covMatrix.push_back(DataType(covVert[2][2]*scale/1.));
313 covMatrix.push_back(DataType(covVert[3][0]*scale/10.));
314 covMatrix.push_back(DataType(covVert[3][1]*scale/10.));
315 covMatrix.push_back(DataType(covVert[3][2]*scale/1.));
316 covMatrix.push_back(DataType(covVert[3][3]*scale/1.));
317 covMatrix.push_back(DataType(covVert[4][0]*scale/0.01));
318 covMatrix.push_back(DataType(covVert[4][1]*scale/0.01));
319 covMatrix.push_back(DataType(covVert[4][2]*scale/0.001));
320 covMatrix.push_back(DataType(covVert[4][3]*scale/0.001));
321 covMatrix.push_back(DataType(covVert[4][4]*scale/0.000001));
322*/
323 TrackParticleRetrieverHelpers::getPolylineFromTrackParticle( (*tpcItr),polylineX,polylineY,polylineZ,numPolyline);
324
325 } // end loop over tracks in collection
326
327 //Now fill everything in a datamap
329 // Start with mandatory entries
330 DataMap["id"] = id;
331 DataMap["chi2"] = chi2;
332 DataMap["numDoF"] = numDoF;
333 DataMap["trackAuthor"] = trackAuthor;
334 DataMap["numPolyline"] = numPolyline;
335 // DataMap["label"] = labelStr; // need to add into event.dtd first
336
337 // if perigee parameters are not available, leave the corresponding subtags empty.
338 // This way atlantis knows that such tracks can only be displayed as polylines.
339 if (pt.size() > 0){
340 DataMap["pt"] = pt;
341 DataMap["d0"] = d0;
342 DataMap["z0"] = z0;
343 DataMap["phi0"] = phi0;
344 DataMap["cotTheta"] = cotTheta;
345 DataMap["covMatrix multiple=\"15\""] = covMatrix;
346 }
347
348 // vectors with measurement, maximum 3 for TrackParticle (perigee, calo entry, muon entry)
349 if ( polylineX.size() > 0){
350 std::string numPolyPerTrack = DataType(polylineX.size()/((double)id.size())).toString();
351 DataMap["polylineX multiple=\"" + numPolyPerTrack + "\""] = polylineX;
352 DataMap["polylineY multiple=\"" + numPolyPerTrack + "\""] = polylineY;
353 DataMap["polylineZ multiple=\"" + numPolyPerTrack + "\""] = polylineZ;
354 }
355
356 //forward data to formating tool
357 if ( FormatTool->AddToEvent(dataTypeName(), collectionName, &DataMap).isFailure())
358 return StatusCode::RECOVERABLE;
359
360 //Be verbose
361 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << dataTypeName() << " collection " << collectionName << " retrieved with " << id.size() << " entries"<< endmsg;
362 } //loop over track collections
363
364 //All collections retrieved okay
365 return StatusCode::SUCCESS;
366
367 } //retrieve
368} //namespace JiveXML
#define endmsg
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
An STL vector of pointers that by default owns its pointed-to elements.
#define AmgSymMatrix(dim)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
virtual std::string dataTypeName() const
Return the name of the data type.
virtual StatusCode retrieve(ToolHandle< IFormatTool > &FormatTool)
Retrieve all the data.
std::string m_PriorityTrackCollection
First track collections to retrieve, shown as default in Atlantis.
const std::string m_typeName
The data type that is generated by this retriever.
bool m_doWriteHLT
Wether to write HLTAutoKey objects.
std::vector< std::string > m_OtherTrackCollections
Track collections to retrieve in the sequence they are given, all if empty.
TrackParticleRetriever(const std::string &type, const std::string &name, const IInterface *parent)
Standard Constructor.
a const_iterator facade to DataHandle.
Definition SGIterator.h:164
const std::string & key() const
Get the key string with which the current object was stored.
This is the 5x5 jacobian for the transformation of track parameters and errors having the new standar...
A summary of the information contained by a track.
int get(const SummaryType &type) const
returns the summary information for the passed SummaryType.
double chi2(TH1 *h0, TH1 *h1)
std::string label(const std::string &format, int i)
Definition label.h:19
Eigen::Matrix< double, 3, 1 > Vector3D
void getPolylineFromTrackParticle(const Rec::TrackParticle *track, DataVect &polylineX, DataVect &polylineY, DataVect &polylineZ, DataVect &numPolyline)
Get polyline hits if available.
This header is shared inbetween the C-style server thread and the C++ Athena ServerSvc.
std::map< std::string, DataVect > DataMap
Definition DataType.h:59
std::vector< DataType > DataVect
Defines a map with a key and a vector of DataType objects e.g.
Definition DataType.h:58
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ phi0
Definition ParamDefs.h:65
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
@ numberOfPixelHits
number of pixel layers on track with absence of hits
@ numberOfInnermostPixelLayerHits
these are the hits in the 1st pixel layer