hpstr
The Heavy Photon Search Toolkit for Reconstruction (hpstr) provides an interface to physics data from the HPS experiment saved in the LCIO format and converts it into an ROOT based format.
Loading...
Searching...
No Matches
utilities.cxx
Go to the documentation of this file.
1#include "utilities.h"
2#include <algorithm>
3#include <memory>
4/*
5 void utils::buildTrackCollection(std::vector<Track*>& tracks,
6 Event* event,
7 const char* LCTrackCollection)
8 {
9
10 EVENT::LCCollection* lc_tracks event->getLCCollection(LCTrackCollection);
11
12
13 }
14
15*/
16
17
18bool utils::hasCollection(EVENT::LCEvent* lc_event,const std::string& collection) {
19
20 if (!lc_event || collection.empty())
21 return false;
22
23 auto evColls = lc_event->getCollectionNames();
24 auto it = std::find(evColls->begin(),evColls->end(), collection);
25 if (it!=evColls->end())
26 return true;
27 return false;
28}
29
30
31Vertex* utils::buildVertex(EVENT::Vertex* lc_vertex) {
32
33 if (!lc_vertex)
34 return nullptr;
35
36 //TODO move the static cast outside?
37
38 Vertex* vertex = new Vertex();
39 vertex->setChi2 (lc_vertex->getChi2());
40 vertex->setProbability (lc_vertex->getProbability());
41 vertex->setID (lc_vertex->id());
42 vertex->setType (lc_vertex->getAlgorithmType());
43 vertex->setVtxParameters((std::vector<float>)lc_vertex->getParameters());
44
45 //TODO Rotate the covariance matrix!
46 vertex->setCovariance ((std::vector<float>)lc_vertex->getCovMatrix());
47 vertex->setType (lc_vertex->getAlgorithmType());
48 vertex->setPos (lc_vertex->getPosition(),false);
49
50
51 return vertex;
52}
53
54Particle* utils::buildParticle(EVENT::ReconstructedParticle* lc_particle,
55 std::string trackstate_location,
56 EVENT::LCCollection* gbl_kink_data,
57 EVENT::LCCollection* track_data)
58
59{
60
61 if (!lc_particle)
62 return nullptr;
63
64 Particle* part = new Particle();
65 // Set the charge of the HpsParticle
66 part->setCharge(lc_particle->getCharge());
67
68 // Set the HpsParticle type
69 part->setType(lc_particle->getType());
70
71 // Set the energy of the HpsParticle
72 part->setEnergy(lc_particle->getEnergy());
73
74 // Set the momentum of the HpsParticle
75 part->setMomentum(lc_particle->getMomentum());
76
77 // Set the mass of the HpsParticle
78 part->setMass(lc_particle->getMass());
79
80 // Set the goodness of PID for the HpsParticle
81 part->setGoodnessOfPID(lc_particle->getGoodnessOfPID());
82
83 // Set the PDG ID for the HpsParticle
84 part->setPDG(lc_particle->getParticleIDUsed()->getPDG());
85
86 // Set the Track for the HpsParticle
87 if (lc_particle->getTracks().size()>0)
88 {
89 Track * trkPtr = utils::buildTrack(lc_particle->getTracks()[0],trackstate_location, gbl_kink_data, track_data);
90 part->setTrack(trkPtr);
91 delete trkPtr;
92 }
93
94 // Set the Track for the HpsParticle
95 if (lc_particle->getClusters().size() > 0)
96 {
97 CalCluster * clusBuf = utils::buildCalCluster(lc_particle->getClusters()[0]);
98 part->setCluster(clusBuf);
99 delete clusBuf;
100 }
101
102 return part;
103}
104
105CalCluster* utils::buildCalCluster(EVENT::Cluster* lc_cluster)
106{
107
108 if (!lc_cluster)
109 return nullptr;
110
111 CalCluster* cluster = new CalCluster();
112 // Set the cluster position
113 cluster->setPosition(lc_cluster->getPosition());
114
115 // Set the cluster energy
116 cluster->setEnergy(lc_cluster->getEnergy());
117
118 // Get the ecal hits used to create the cluster
119 EVENT::CalorimeterHitVec lc_hits = lc_cluster->getCalorimeterHits();
120
121 // Loop over all of the Ecal hits and add them to the Ecal cluster. The
122 // seed hit is set to be the hit with the highest energy. The cluster time
123 // is set to be the hit time of the seed hit.
124 double senergy = 0;
125 double stime = 0;
126 for(int ihit = 0; ihit < (int) lc_hits.size(); ++ihit) {
127 // Get an Ecal hit
128 EVENT::CalorimeterHit* lc_hit = lc_hits[ihit];
129 if (senergy < lc_hit->getEnergy()) {
130 senergy = lc_hit->getEnergy();
131 stime = lc_hit->getTime();
132 }
133 }
134
135 // Set the time of the cluster
136 cluster->setTime(stime);
137
138 return cluster;
139}
140
141bool utils::IsSameTrack(Track* trk1, Track* trk2) {
142 double tol = 1e-6;
143 if (fabs(trk1->getD0() - trk2->getD0()) > tol ||
144 fabs(trk1->getPhi() - trk2->getPhi()) > tol ||
145 fabs(trk1->getOmega() - trk2->getOmega()) > tol ||
146 fabs(trk1->getTanLambda() - trk2->getTanLambda()) > tol ||
147 fabs(trk1->getZ0() - trk2->getZ0()) > tol ||
148 fabs(trk1->getChi2Ndf() - trk2->getChi2Ndf()) > tol
149 )
150 return false;
151
152 return true;
153}
154
155
156Track* utils::buildTrack(EVENT::Track* lc_track,
157 std::string trackstate_location,
158 EVENT::LCCollection* gbl_kink_data,
159 EVENT::LCCollection* track_data) {
160
161 if (!lc_track)
162 return nullptr;
163
164
165 // public final static int AtOther = 0; // Any location other than the ones defined below.
166 //public final static int AtPerigee = 1; //track state at perigee, which is what the track finder returns
167 //public final static int AtIP = 2; // this is at the target
168 //public final static int AtTarget = 2; // this is at the target
169 //public final static int AtFirstHit = 3;
170 //public final static int AtLastHit = 4;
171 //public final static int AtCalorimeter = 5;
172 //public final static int AtVertex = 6;
173 //public final static int LastLocation = AtVertex;
174
175 //TrackState Location maps
176 //V30 is the current version, so just get numbers from LCIO
177 std::map<std::string, int> trackstateLocationMapV30_ =
178 { {"",EVENT::TrackState::AtPerigee},
179 {"AtPerigee",EVENT::TrackState::AtPerigee},
180 {"AtIP",EVENT::TrackState::AtIP},
181 {"AtTarget",EVENT::TrackState::AtTarget},
182 {"AtFirstHit",EVENT::TrackState::AtFirstHit},
183 {"AtLastHit",EVENT::TrackState::AtLastHit},
184 {"AtCalorimeter",EVENT::TrackState::AtCalorimeter},
185 {"AtVertex",EVENT::TrackState::AtVertex},
186 {"LastLocation",EVENT::TrackState::LastLocation}
187 };
188 //V23 is the old map, so put numbers in by hand
189 std::map<std::string, int> trackstateLocationMapV23_ =
190 { {"",EVENT::TrackState::AtIP},
191 {"AtIP",1},
192 {"AtFirstHit",2},
193 {"AtLastHit",3},
194 {"AtCalorimeter",4},
195 {"AtVertex",5},
196 {"LastLocation",5}
197 };
198
199
200 Track* track = new Track();
201
202
203 //If using track AtPerigee or unset, get params from lc_track
204 // if (loc == trackstateLocationMap_[""]){
205 // Set the track parameters
206 //track->setTrackParameters(lc_track->getD0(),
207 // lc_track->getPhi(),
208 // lc_track->getOmega(),
209 // lc_track->getTanLambda(),
210 // lc_track->getZ0());
211
212 // Set the track covariance matrix
213 // track->setCov(static_cast<std::vector<float> > (lc_track->getCovMatrix()));
214 //}
215 //use getBLocal to check if it's V23 or V30
216 //V30 will have sensible BField
217 double bTmp = lc_track->getTrackState(1)->getBLocal();
218 std::map<std::string, int> trackstateLocationMap_;
219 if(abs(bTmp)<10.0)
220 trackstateLocationMap_=trackstateLocationMapV30_;
221 else
222 trackstateLocationMap_=trackstateLocationMapV23_;
223
224 int loc;
225 auto it = trackstateLocationMap_.find(trackstate_location);
226 if (it != trackstateLocationMap_.end()){
227 loc = it->second;
228 }
229 else{
230 std::cout << "[utilities]::ERROR Track State Location " << trackstate_location << " Doesn't Exist!" << std::endl;
231 std::cout << "Check map in utilities::buildTrack for defined locations" << std::endl;
232 return nullptr;
233 }
234 //If other TrackState specified, get track params from track state
235 // else {
236 // If track state doesn't exist, no track returned
237 const EVENT::TrackState* ts = lc_track->getTrackState(loc);
238 if (ts == nullptr){
239 return nullptr;
240 }
241
242 // If the track state is AtTarget, replace the d0 & z0
243 // with their reference positions in global x & y.
244 // We do this because the reference for ts@target
245 // is defined as where the track intersects with the target
246 // plane; so d0 & z0 == 0. This is a bit of a kludge to make
247 // it simpler for analysts.
248 // NOTE that these will not be strictly correct perigee parameters
249 double tsD0 = ts->getD0();
250 double tsZ0 = ts->getZ0();
251 if(loc==EVENT::TrackState::AtTarget){
252 tsD0=ts->getReferencePoint()[1];
253 tsZ0=ts->getReferencePoint()[2];
254 }
255
256 // Set the track parameters using trackstate
257 track->setTrackParameters(tsD0,
258 ts->getPhi(),
259 ts->getOmega(),
260 ts->getTanLambda(),
261 tsZ0);
262
263 double position[3] = {
264 ts->getReferencePoint()[1],
265 ts->getReferencePoint()[2],
266 ts->getReferencePoint()[0]
267 };
268
269 track->setCov(static_cast<std::vector<float> > (ts->getCovMatrix()));
270 track->setPosition(position);
271
272 double bLocal = lc_track->getTrackState(loc)->getBLocal();
273 if(abs(bLocal)<10.0) // check if it has non-default value (which should be 666)...this fails for pre-v3 lcio. see below
274 track->setMomentum(bLocal);
275
276 // Set the track id
277 track->setID(lc_track->id());
278
279 // Set the track type
280 track->setType(lc_track->getType());
281
282 // Set the track fit chi^2
283 track->setChi2(lc_track->getChi2());
284
285 // Set the track ndf
286 track->setNdf(lc_track->getNdf());
287
288 // Set the position of the extrapolated track at the ECal face. The
289 // extrapolation uses the full 3D field map.
290 const EVENT::TrackState* track_state
291 = lc_track->getTrackState(trackstateLocationMap_["AtCalorimeter"]);
292
293 if (track_state) {
294 double position_at_ecal[3] = {
295 track_state->getReferencePoint()[1],
296 track_state->getReferencePoint()[2],
297 track_state->getReferencePoint()[0]
298 };
299 track->setPositionAtEcal(position_at_ecal);
300 }
301
302 if (gbl_kink_data) {
303 // Instantiate an LCRelation navigator which will allow faster access
304 // to GBLKinkData object
305 std::shared_ptr<UTIL::LCRelationNavigator> gbl_kink_data_nav = std::make_shared<UTIL::LCRelationNavigator>(gbl_kink_data);
306
307 // Get the list of GBLKinkData associated with the LCIO Track
308 EVENT::LCObjectVec gbl_kink_data_list
309 = gbl_kink_data_nav->getRelatedFromObjects(lc_track);
310
311 // The container of GBLKinkData objects should only contain a
312 // single object. If not, throw an exception
313 if (gbl_kink_data_list.size() == 1) {
314
315 /*
316 std::cout<<"[ Utilities ]: The collection "
317 + std::string(Collections::KINK_DATA)
318 + " has the wrong data structure for this track"<<std::endl;
319 */
320
321 // Get the list GBLKinkData GenericObject associated with the LCIO Track
322 IMPL::LCGenericObjectImpl* gbl_kink_datum
323 = static_cast<IMPL::LCGenericObjectImpl*>(gbl_kink_data_list.at(0));
324
325 // Set the lambda and phi kink values
326 for (int ikink = 0; ikink < gbl_kink_datum->getNDouble(); ++ikink) {
327 track->setLambdaKink(ikink, gbl_kink_datum->getFloatVal(ikink));
328 track->setPhiKink(ikink, gbl_kink_datum->getDoubleVal(ikink));
329 }
330
331 }//gbl_kink_data has right structure
332
333 } // add gbl kink data
334
335 if (track_data) {
336
337 // Instantiate an LCRelation navigator which will allow faster access
338 // to TrackData objects
339 std::shared_ptr<UTIL::LCRelationNavigator> track_data_nav = std::make_shared<UTIL::LCRelationNavigator>(track_data);
340
341 // Get the list of TrackData associated with the LCIO Track
342 EVENT::LCObjectVec track_data_list = track_data_nav->getRelatedFromObjects(lc_track);
343
344 // The container of TrackData objects should only contain a single
345 // object. If not, throw an exception.
346 if (track_data_list.size() == 1) {
347
348 // Get the TrackData GenericObject associated with the LCIO Track
349 IMPL::LCGenericObjectImpl* track_datum = static_cast<IMPL::LCGenericObjectImpl*>(track_data_list.at(0));
350
351 // Check that the TrackData data structure is correct. If it's
352 // not, throw a runtime exception.
353 if (track_datum->getNDouble() > 14 || track_datum->getNFloat() > 8 || track_datum->getNInt() != 1) {
354 throw std::runtime_error("[ TrackingProcessor ]: The collection "
355 + std::string(Collections::TRACK_DATA)
356 + " has the wrong structure.");
357 }
358
359 // Set the SvtTrack isolation values
360 for (int iso_index = 0; iso_index < track_datum->getNDouble(); ++iso_index) {
361 track->setIsolation(iso_index, track_datum->getDoubleVal(iso_index));
362 }
363
364 // Set the SvtTrack time
365 track->setTrackTime(track_datum->getFloatVal(0));
366
367 // Set the Track momentum
368 // mg comment this out
369 // if(abs(bLocal)<10.0) // check if it has non-default value (which should be 666)
370
371 if (track_datum->getNFloat()>3 && abs(bLocal)>10.0) //bfield is not set in track state so get from track data...
372 track->setMomentum(track_datum->getFloatVal(1),track_datum->getFloatVal(2),track_datum->getFloatVal(3));
373
374 // Set the volume (top/bottom) in which the SvtTrack resides
375 track->setTrackVolume(track_datum->getIntVal(0));
376
377 // Set the BfieldY for track state
378 // mg comment this out
379 if( abs(bLocal)>10.0){ //bfield is not set in track state so get from track data...pre-v3 lcio
380 double bfieldY = -999.9;
381 if(track_datum->getNFloat() > 4){
382 if (loc == trackstateLocationMap_[""])
383 bfieldY = track_datum->getFloatVal(4);
384 if (loc == trackstateLocationMap_["AtTarget"]){
385 bfieldY = track_datum->getFloatVal(5);
386 }
387 if (loc == trackstateLocationMap_["AtCalorimeter"])
388 bfieldY = track_datum->getFloatVal(6);
389 track->setMomentum(-bfieldY);
390 }
391 }
392 }
393
394 } //add track data
395
396 return track;
397}
398
399RawSvtHit* utils::buildRawHit(EVENT::TrackerRawData* rawTracker_hit,
400 EVENT::LCCollection* raw_svt_hit_fits) {
401
402 EVENT::long64 value =
403 EVENT::long64(rawTracker_hit->getCellID0() & 0xffffffff) |
404 ( EVENT::long64(rawTracker_hit->getCellID1() ) << 32 );
405 decoder.setValue(value);
406
407 RawSvtHit* rawHit = new RawSvtHit();
408 rawHit->setSystem(decoder["system"]);
409 rawHit->setBarrel(decoder["barrel"]);
410 rawHit->setLayer(decoder["layer"]);
411 rawHit->setModule(decoder["module"]);
412 rawHit->setSensor(decoder["sensor"]);
413 rawHit->setSide(decoder["side"]);
414 rawHit->setStrip(decoder["strip"]);
415
416 // Extract ADC values for this hit
417 int hit_adcs[6] = {
418 (int)rawTracker_hit->getADCValues().at(0),
419 (int)rawTracker_hit->getADCValues().at(1),
420 (int)rawTracker_hit->getADCValues().at(2),
421 (int)rawTracker_hit->getADCValues().at(3),
422 (int)rawTracker_hit->getADCValues().at(4),
423 (int)rawTracker_hit->getADCValues().at(5)};
424
425 rawHit->setADCs(hit_adcs);
426 if (raw_svt_hit_fits) {
427 std::shared_ptr<UTIL::LCRelationNavigator> rawTracker_hit_fits_nav = std::make_shared<UTIL::LCRelationNavigator>(raw_svt_hit_fits);
428
429
430 // Get the list of fit params associated with the raw tracker hit
431 EVENT::LCObjectVec rawTracker_hit_fits_list
432 = rawTracker_hit_fits_nav->getRelatedToObjects(rawTracker_hit);
433
434 // Get the list SVTFittedRawTrackerHit GenericObject associated with the SVTRawTrackerHit
435 IMPL::LCGenericObjectImpl* hit_fit_param
436 = static_cast<IMPL::LCGenericObjectImpl*>(rawTracker_hit_fits_list.at(0));
437
438 double fit_params[5] = {
439 (double)hit_fit_param->getDoubleVal(0),
440 (double)hit_fit_param->getDoubleVal(1),
441 (double)hit_fit_param->getDoubleVal(2),
442 (double)hit_fit_param->getDoubleVal(3),
443 (double)hit_fit_param->getDoubleVal(4)
444 };
445 rawHit->setFit(fit_params, 0);
446 if(rawTracker_hit_fits_list.size()>1)
447 {
448 hit_fit_param = static_cast<IMPL::LCGenericObjectImpl*>(rawTracker_hit_fits_list.at(1));
449 fit_params[0] = (double)hit_fit_param->getDoubleVal(0);
450 fit_params[1] = (double)hit_fit_param->getDoubleVal(1);
451 fit_params[2] = (double)hit_fit_param->getDoubleVal(2);
452 fit_params[3] = (double)hit_fit_param->getDoubleVal(3);
453 fit_params[4] = (double)hit_fit_param->getDoubleVal(4);
454
455 rawHit->setFit(fit_params, 1);
456 }
457 rawHit->setFitN(rawTracker_hit_fits_list.size());
458 }//raw svt hit fits
459
460 return rawHit;
461
462}//build raw hit
463
464//type = 0 RotatedHelicalTrackHit type = 1 SiCluster
465TrackerHit* utils::buildTrackerHit(IMPL::TrackerHitImpl* lc_tracker_hit, bool rotate, int type) {
466
467 if (!lc_tracker_hit)
468 return nullptr;
469
470 TrackerHit* tracker_hit = new TrackerHit();
471
472 // Get the position of the LCIO TrackerHit and set the position of
473 // the TrackerHit
474 double hit_position[3] = {
475 lc_tracker_hit->getPosition()[0], //lcio x
476 lc_tracker_hit->getPosition()[1], //lcio y
477 lc_tracker_hit->getPosition()[2] //lcio z
478 };
479 tracker_hit->setPosition(hit_position, rotate, type);
480
481 // Set the covariance matrix of the SvtHit
482 tracker_hit->setCovarianceMatrix(lc_tracker_hit->getCovMatrix());
483
484 // Set the time of the SvtHit
485 tracker_hit->setTime(lc_tracker_hit->getTime());
486
487 // Set the charge of the SvtHit
488 tracker_hit->setCharge(lc_tracker_hit->getEDep());
489
490 // Set the LCIO id
491 tracker_hit->setID(lc_tracker_hit->id());
492
493 return tracker_hit;
494
495
496}
497
498//type 0 rotatedHelicalHit type 1 SiClusterHit
500 IMPL::TrackerHitImpl* lc_tracker_hit,
501 EVENT::LCCollection* raw_svt_fits, std::vector<RawSvtHit*>* rawHits,int type, bool storeRawHit) {
502
503 if (!tracker_hit || !lc_tracker_hit)
504 return false;
505
506 float rawcharge = 0;
507 //0 top 1 bottom
508 int volume = -1;
509 //1-6(7) for rotated 0-13 for SiCluster
510 int layer = -1;
511
512 // Get decoders to read cellids
513 UTIL::BitField64 decoder("system:6,barrel:3,layer:4,module:12,sensor:1,side:32:-2,strip:12");
514
515 //Get the Raw content of the tracker hits
516 EVENT::LCObjectVec lc_rawHits = lc_tracker_hit->getRawHits();
517
518 std::vector<int> rawhit_strips;
519 for (unsigned int irh = 0 ; irh < lc_rawHits.size(); ++irh) {
520 // Get a raw hit from the list of hits
521 EVENT::TrackerRawData* rawTracker_hit
522 = static_cast<EVENT::TrackerRawData*>(lc_rawHits.at(irh));
523
524 //Decode the cellid
525 EVENT::long64 value = EVENT::long64( rawTracker_hit->getCellID0() & 0xffffffff ) |
526 ( EVENT::long64( rawTracker_hit->getCellID1() ) << 32 ) ;
527 decoder.setValue(value);
528
529 //Get rawhit strip number
530 int stripnumber = decoder["strip"];
531 rawhit_strips.push_back(stripnumber);
532
533 //TODO useless to build all of it?
534 RawSvtHit* rawHit = buildRawHit(rawTracker_hit,raw_svt_fits);
535 rawcharge += rawHit->getAmp(0);
536 int currentHitVolume = rawHit->getModule() % 2 ? 1 : 0;
537 int currentHitLayer = (rawHit->getLayer() - 1 ) / 2;
538 if (type == 1)
539 currentHitLayer = rawHit->getLayer() - 1;
540 if (volume == -1 )
541 volume = currentHitVolume;
542 else {
543 if ( currentHitVolume != volume)
544 std::cout<<"[ ERROR ] : utils::addRawInfoTo3dHit raw hits with inconsistent volume found" <<std::endl;
545 }
546
547 if (layer == -1 )
548 layer = currentHitLayer;
549 else {
550 if (currentHitLayer != layer)
551 std::cout<<"[ ERROR ] : utils::addRawInfoTo3dHit raw hits with inconsistent layer found" <<std::endl;
552 }
553
554 if(storeRawHit){
555 tracker_hit->addRawHit(rawHit);
556 if (rawHits)
557 rawHits->push_back(rawHit);
558 }
559 else
560 delete rawHit;
561
562 }
563
564 tracker_hit->setRawCharge(rawcharge);
565 tracker_hit->setVolume(volume);
566 tracker_hit->setLayer(layer);
567 tracker_hit->setRawHitStripNumbers(rawhit_strips);
568
569 return true;
570}
571
572//TODO-improve shared finding algorithm
573
574bool utils::isUsedByTrack(IMPL::TrackerHitImpl* lc_tracker_hit,
575 EVENT::Track* lc_track) {
576
577 EVENT::TrackerHitVec trk_lc_tracker_hits = lc_track->getTrackerHits();
578
579 for (auto trk_lc_tracker_hit : trk_lc_tracker_hits) {
580 //std::cout<<lc_tracker_hit->id()<<" " <<trk_lc_tracker_hit->id()<<std::endl;
581 if (lc_tracker_hit -> id() == trk_lc_tracker_hit -> id())
582 return true;
583 }
584 return false;
585}
586
588 EVENT::Track* lc_track) {
589
590 EVENT::TrackerHitVec trk_lc_tracker_hits = lc_track->getTrackerHits();
591
592 for (auto trk_lc_tracker_hit : trk_lc_tracker_hits) {
593 if (tracker_hit->getID() == trk_lc_tracker_hit->id())
594 return true;
595 }
596 return false;
597}
598
599
601
602 for (int ipart = 0; ipart < vtx->getParticles().GetEntries(); ++ipart) {
603 int pdg_id = ((Particle*)vtx->getParticles().At(ipart))->getPDG();
604 if (pdg_id == 11) {
605 ele = (Particle*)vtx->getParticles().At(ipart);
606 }
607 else if (pdg_id == -11) {
608 pos = (Particle*)vtx->getParticles().At(ipart);
609 }
610
611 else {
612 std::cout<<"Utilities::Wrong particle ID "<< pdg_id <<"associated to vertex. Skip."<<std::endl;
613 return false;
614 }
615 }
616
617 if (!ele || !pos) {
618 std::cout<<"Utilities::Vertex formed without ele/pos. Skip."<<std::endl;
619 return false;
620 }
621
622 return true;
623}
624
625double utils::getKalmanTrackL1Isolations(Track* track, std::vector<TrackerHit*>* siClusters){
626 double L1_axial_iso = 999999.9;
627 double L1_stereo_iso = 999999.9;
628 //Loop over hits on track
629 for(int i = 0; i < track->getSvtHits().GetEntries(); i++){
630 TrackerHit* track_hit = (TrackerHit*)track->getSvtHits().At(i);
631 //Track hit info
632 int trackhit_id = track_hit->getID();
633 int trackhit_layer = track_hit->getLayer();
634 int trackhit_volume = track_hit->getVolume();
635 double trackhit_y = track_hit->getGlobalY();
636 double trackhit_charge = track_hit->getRawCharge();
637 double trackhit_time = track_hit->getTime();
638
639 //Only look at L1
640 if(trackhit_layer > 1)
641 continue;
642
643 //Get rawhit strip information
644 std::vector<int> trackhit_rawhits = track_hit->getRawHitStripNumbers();
645 if(trackhit_rawhits.size() < 1)
646 continue;
647 int trackhit_maxstrip = *max_element(trackhit_rawhits.begin(), trackhit_rawhits.end());
648 int trackhit_minstrip = *min_element(trackhit_rawhits.begin(), trackhit_rawhits.end());
649
650
651 //Isolation only calculated for axial sensors (sensitive to global y)
652 bool isAxial = false;
653 //Axial/Stereo Top/Bot mapping
654 if(trackhit_volume == 1){
655 if(trackhit_layer%2 == 1)
656 isAxial = true;
657 }
658 if(trackhit_volume == 0){
659 if(trackhit_layer%2 == 0)
660 isAxial = true;
661 }
662
663 //Loop over all SiClusters in event
664 //Find closest/best alternative SiCluster to track hit
665 TrackerHit* closest_althit = nullptr;
666 double isohit_dy = 999999.9;
667 double closest_dcharge = 99999.9;
668 double closest_dt = 999999.9;
669 double isohit_y = 999999.9;
670
671 if ( siClusters == nullptr )
672 return isohit_dy;
673 for(int j = 0; j < siClusters->size(); j++){
674 TrackerHit* althit = siClusters->at(j);
675 int althit_id = althit->getID();
676 int althit_volume = althit->getVolume();
677 int althit_layer = althit->getLayer();
678 double althit_y = althit->getGlobalY();
679 double althit_charge = althit->getRawCharge();
680 double althit_time = althit->getTime();
681
682 //Skip if SiCluster not on same layer as track hit
683 if (althit_layer != trackhit_layer)
684 continue;
685
686 //Skip if volume doesn't match
687 if(althit_volume != trackhit_volume)
688 continue;
689
690 //Skip same hit
691 if (althit_id == trackhit_id)
692 continue;
693
694 //Only look at hits that are further from beam-axis in Global Y
695 if ( (trackhit_volume == 0 && althit_y < trackhit_y) ||
696 (trackhit_volume == 1 && althit_y > trackhit_y))
697 continue;
698
699 //Require alternative hits to be within +-30ns (based on SiClustersOnTrack t distr)
700 if(std::abs(althit_time) > 30.0)
701 continue;
702
703 //Skip adjacent rawhits
704 std::vector<int> althit_rawhits = althit->getRawHitStripNumbers();
705 int althit_maxstrip = *max_element(althit_rawhits.begin(), althit_rawhits.end());
706 int althit_minstrip = *min_element(althit_rawhits.begin(), althit_rawhits.end());
707 if(trackhit_minstrip - althit_maxstrip <= 1 && althit_minstrip - trackhit_maxstrip <= 1)
708 continue;
709
710 //Pick closest alternative hit
711 if (std::abs(trackhit_y - althit_y) < isohit_dy){
712 isohit_dy = std::abs(trackhit_y-althit_y);
713 closest_althit = althit;
714 closest_dcharge = trackhit_charge - althit_charge;
715 closest_dt = trackhit_time - althit_time;
716 isohit_y = althit_y;
717 }
718 }
719
720 if(isAxial)
721 L1_axial_iso = isohit_dy;
722 else
723 L1_stereo_iso = isohit_dy;
724
725 }
726
727 if(L1_axial_iso < L1_stereo_iso){
728 return L1_axial_iso;
729 }
730 else
731 return L1_stereo_iso;
732}
733
734void utils::get2016KFMCTruthHitCodes(Track* ele_trk, Track* pos_trk, int& L1L2hitCode, int& L1hitCode, int& L2hitCode){
735 //Count the number of hits per part on the ele track
736 std::map<int, int> nHits4part_ele;
737 for(int i =0; i < ele_trk->getMcpHits().size(); i++)
738 {
739 int partID = ele_trk->getMcpHits().at(i).second;
740 if ( nHits4part_ele.find(partID) == nHits4part_ele.end() )
741 {
742 // not found
743 nHits4part_ele[partID] = 1;
744 }
745 else
746 {
747 // found
748 nHits4part_ele[partID]++;
749 }
750 }
751
752 //Determine the MC part with the most hits on the track
753 int maxNHits_ele = 0;
754 int maxID_ele = 0;
755 for (std::map<int,int>::iterator it=nHits4part_ele.begin(); it!=nHits4part_ele.end(); ++it)
756 {
757 if(it->second > maxNHits_ele)
758 {
759 maxNHits_ele = it->second;
760 maxID_ele = it->first;
761 }
762 }
763
764 //Count the number of hits per part on the pos track
765 std::map<int, int> nHits4part_pos;
766 for(int i =0; i < pos_trk->getMcpHits().size(); i++)
767 {
768 int partID = pos_trk->getMcpHits().at(i).second;
769 if ( nHits4part_pos.find(partID) == nHits4part_pos.end() )
770 {
771 // not found
772 nHits4part_pos[partID] = 1;
773 }
774 else
775 {
776 // found
777 nHits4part_pos[partID]++;
778 }
779 }
780
781 //Determine the MC part with the most hits on the track
782 int maxNHits_pos = 0;
783 int maxID_pos = 0;
784 for (std::map<int,int>::iterator it=nHits4part_pos.begin(); it!=nHits4part_pos.end(); ++it)
785 {
786 if(it->second > maxNHits_pos)
787 {
788 maxNHits_pos = it->second;
789 maxID_pos = it->first;
790 }
791 }
792
793 //Determine Ele L1 and L2 truth information
794 bool ele_trueAxialL1 = false;
795 bool ele_trueStereoL1 = false;
796 bool ele_trueAxialL2 = false;
797 bool ele_trueStereoL2 = false;
798 bool pos_trueAxialL1 = false;
799 bool pos_trueStereoL1 = false;
800 bool pos_trueAxialL2 = false;
801 bool pos_trueStereoL2 = false;
802
803 if(ele_trk->isKalmanTrack()){
804 for(int i = 0; i < ele_trk->getMcpHits().size(); i++){
805 int mcpid = ele_trk->getMcpHits().at(i).second;
806 int layer = ele_trk->getMcpHits().at(i).first;
807 int volume = -1;
808 if(ele_trk->isTopTrack() == 1)
809 volume = 0;
810 else
811 volume = 1;
812
813 bool isAxial = false;
814 bool isStereo = false;
815 bool isL1 = false;
816 bool isL2 = false;
817 bool isGood = false;
818
819 //L1 and L2 only
820 if(layer < 2)
821 isL1 = true;
822 else if(layer > 1 && layer < 4)
823 isL2 = true;
824 else
825 continue;
826
827 if(volume == 1){
828 if(layer%2 == 1)
829 isAxial = true;
830 else
831 isStereo = true;
832 }
833 if(volume == 0){
834 if(layer%2 == 0)
835 isAxial = true;
836 else
837 isStereo = true;
838 }
839
840 if(mcpid == maxID_ele)
841 isGood = true;
842
843 if(isGood){
844 if(isAxial){
845 if(isL1)
846 ele_trueAxialL1 = true;
847 if(isL2)
848 ele_trueAxialL2 = true;
849 }
850 if(isStereo){
851 if(isL1)
852 ele_trueStereoL1 = true;
853 if(isL2)
854 ele_trueStereoL2 = true;
855 }
856 }
857 }
858 }
859
860 if(pos_trk->isKalmanTrack()){
861 for(int i = 0; i < pos_trk->getMcpHits().size(); i++){
862 int mcpid = pos_trk->getMcpHits().at(i).second;
863 int layer = pos_trk->getMcpHits().at(i).first;
864 int volume = -1;
865 if(pos_trk->isTopTrack() == 1)
866 volume = 0;
867 else
868 volume = 1;
869
870 bool isAxial = false;
871 bool isStereo = false;
872 bool isL1 = false;
873 bool isL2 = false;
874 bool isGood = false;
875
876 //L1 and L2 only
877 if(layer < 2)
878 isL1 = true;
879 else if(layer > 1 && layer < 4)
880 isL2 = true;
881 else
882 continue;
883
884 if(volume == 1){
885 if(layer%2 == 1)
886 isAxial = true;
887 else
888 isStereo = true;
889 }
890 if(volume == 0){
891 if(layer%2 == 0)
892 isAxial = true;
893 else
894 isStereo = true;
895 }
896
897 if(mcpid == maxID_pos)
898 isGood = true;
899
900 if(isGood){
901 if(isAxial){
902 if(isL1)
903 pos_trueAxialL1 = true;
904 if(isL2)
905 pos_trueAxialL2 = true;
906 }
907 if(isStereo){
908 if(isL1)
909 pos_trueStereoL1 = true;
910 if(isL2)
911 pos_trueStereoL2 = true;
912 }
913 }
914 }
915 }
916
917
918 //Require both Axial and Stereo truth hits to be 'Good' hit
919 if(ele_trueAxialL1 && ele_trueStereoL1) L1L2hitCode = L1L2hitCode | (0x1 << 3);
920 if(pos_trueAxialL1 && pos_trueStereoL1) L1L2hitCode = L1L2hitCode | (0x1 << 2);
921 if(ele_trueAxialL2 && ele_trueStereoL2) L1L2hitCode = L1L2hitCode | (0x1 << 1);
922 if(pos_trueAxialL2 && pos_trueStereoL2) L1L2hitCode = L1L2hitCode | (0x1 << 0);
923
924
925 //Set L1 axial/stereo hit code for ele and positron
926 if(ele_trueAxialL1) L1hitCode = L1hitCode | (0x1 << 3);
927 if(ele_trueStereoL1) L1hitCode = L1hitCode | (0x1 << 2);
928 if(pos_trueAxialL1) L1hitCode = L1hitCode | (0x1 << 1);
929 if(pos_trueStereoL1) L1hitCode = L1hitCode | (0x1 << 0);
930
931 //Set L2 axial/stereo hit code for ele and positron
932 if(ele_trueAxialL2) L2hitCode = L2hitCode | (0x1 << 3);
933 if(ele_trueStereoL2) L2hitCode = L2hitCode | (0x1 << 2);
934 if(pos_trueAxialL2) L2hitCode = L2hitCode | (0x1 << 1);
935 if(pos_trueStereoL2) L2hitCode = L2hitCode | (0x1 << 0);
936}
937
938double utils::v0_projection_to_target_significance(json v0proj_fits, int run, double &vtx_proj_x, double &vtx_proj_y,
939 double &vtx_proj_x_signif, double &vtx_proj_y_signif, double vtx_x, double vtx_y, double vtx_z,
940 double vtx_px, double vtx_py, double vtx_pz){
941 //V0 Projection fit parameters are calculated externally by projecting vertices to the target z position,
942 //and then fitting the 2D distribution vtx_x vs vtx_y with a rotated 2D Gaussian.
943 //The fit parameters are defined along the rotated coordinate system.
944 //Therefore, the vertex position must be rotated into this coordinate system before calculating significance.
945 //The rotation angle corresponding to the fit is provided in the json file containing the rotated fit values.
946
947 //Read v0 projection fits from json file
948 int closest_run;
949 for(auto entry : v0proj_fits.items()){
950 int check_run = std::stoi(entry.key());
951 if(check_run > run)
952 break;
953 else{
954 closest_run = check_run;
955 }
956 }
957 double target_pos = v0proj_fits[std::to_string(closest_run)]["target_position"];
958 double rot_mean_x = v0proj_fits[std::to_string(closest_run)]["rotated_mean_x"];
959 double rot_mean_y = v0proj_fits[std::to_string(closest_run)]["rotated_mean_y"];
960 double rot_sigma_x = v0proj_fits[std::to_string(closest_run)]["rotated_sigma_x"];
961 double rot_sigma_y = v0proj_fits[std::to_string(closest_run)]["rotated_sigma_y"];
962 double rotation_angle = (double)v0proj_fits[std::to_string(closest_run)]["rotation_angle_mrad"]/1000.0;
963
964 //project vertex to target position
965 vtx_proj_x = vtx_x - ((vtx_z - target_pos)*(vtx_px/vtx_pz));
966 vtx_proj_y = vtx_y - ((vtx_z - target_pos)*(vtx_py/vtx_pz));
967
968 //Rotate projected vertex by angle corresponding to run number
969 double rot_vtx_proj_x = vtx_proj_x*std::cos(rotation_angle) - vtx_proj_y*std::sin(rotation_angle);
970 double rot_vtx_proj_y = vtx_proj_x*std::sin(rotation_angle) + vtx_proj_y*std::cos(rotation_angle);
971
972 //Calculate significance
973 vtx_proj_x_signif = (rot_vtx_proj_x - rot_mean_x)/rot_sigma_x;
974 vtx_proj_y_signif = (rot_vtx_proj_y - rot_mean_y)/rot_sigma_y;
975
976 //
977 double significance = std::sqrt( vtx_proj_x_signif*vtx_proj_x_signif + vtx_proj_y_signif*vtx_proj_y_signif );
978
979 return significance;
980}
nlohmann::json json
void setPosition(const float *position)
void setEnergy(const double energy)
Definition CalCluster.h:70
void setTime(const double time)
Definition CalCluster.h:80
void setGoodnessOfPID(const double goodness_pid)
Definition Particle.h:84
void setPDG(const int pdg)
Definition Particle.h:98
void setMass(const double mass)
Definition Particle.h:112
void setCharge(const int charge)
Definition Particle.h:77
void setType(const int type)
Definition Particle.h:91
void setMomentum(const double *momentum)
Definition Particle.cxx:23
void setTrack(Track *track)
Definition Particle.h:42
void setEnergy(const double energy)
Definition Particle.h:105
void setCluster(CalCluster *cluster)
Definition Particle.h:56
void setBarrel(int barrel)
Definition RawSvtHit.cxx:48
void setSystem(int system)
Definition RawSvtHit.cxx:44
void setFit(double fit[5], int fitI)
Definition RawSvtHit.cxx:27
int getLayer()
Definition RawSvtHit.cxx:88
void setStrip(int strip)
Definition RawSvtHit.cxx:68
void setSensor(int sensor)
Definition RawSvtHit.cxx:60
void setSide(int side)
Definition RawSvtHit.cxx:64
double getAmp(int fitI)
Definition RawSvtHit.h:101
void setADCs(int adcs[6])
Definition RawSvtHit.cxx:35
int getModule()
Definition RawSvtHit.cxx:92
void setFitN(int fitN)
Definition RawSvtHit.cxx:23
void setLayer(int layer)
Definition RawSvtHit.cxx:52
void setModule(int module)
Definition RawSvtHit.cxx:56
Definition Track.h:32
bool isKalmanTrack() const
Definition Track.h:231
bool isTopTrack() const
Definition Track.h:330
double getPhi() const
Definition Track.h:88
double getChi2Ndf() const
Definition Track.h:126
double getOmega() const
Definition Track.h:90
double getD0() const
Definition Track.h:87
double getTanLambda() const
Definition Track.h:91
std::vector< std::pair< int, int > > getMcpHits()
Definition Track.h:103
double getZ0() const
Definition Track.h:92
double getGlobalY() const
Definition TrackerHit.h:53
void setLayer(const int layer)
Definition TrackerHit.h:106
int getLayer() const
Definition TrackerHit.h:109
void setVolume(const int volume)
Definition TrackerHit.h:100
void addRawHit(TObject *rawhit)
Definition TrackerHit.h:115
void setCovarianceMatrix(std::vector< float > cov)
void setID(const int id)
Definition TrackerHit.h:122
std::vector< int > getRawHitStripNumbers()
Definition TrackerHit.h:130
void setRawHitStripNumbers(std::vector< int > rawhit_strips)
Definition TrackerHit.h:133
void setRawCharge(const double rawcharge)
Definition TrackerHit.h:95
int getID() const
Definition TrackerHit.h:124
void setCharge(const double charge)
Definition TrackerHit.h:90
int getVolume()
Definition TrackerHit.h:103
double getRawCharge() const
Definition TrackerHit.h:98
void setTime(const double time)
Definition TrackerHit.h:73
void setPosition(const double *position, bool rotate=false, int type=0)
double getTime() const
Definition TrackerHit.h:83
void setPos(const float *pos, bool rotate=false)
Definition Vertex.cxx:39
void setVtxParameters(const std::vector< float > &parameters)
Definition Vertex.cxx:81
void setID(const int id)
Definition Vertex.h:83
void setType(const std::string &type)
Definition Vertex.h:80
void setProbability(const float probability)
Definition Vertex.h:92
void setCovariance(const std::vector< float > &vec)
Definition Vertex.cxx:35
void setChi2(const double chi2)
Definition Vertex.h:45
constexpr const char * TRACK_DATA
Definition Collections.h:41
bool addRawInfoTo3dHit(TrackerHit *tracker_hit, IMPL::TrackerHitImpl *lc_tracker_hit, EVENT::LCCollection *raw_svt_fits, std::vector< RawSvtHit * > *rawHits=nullptr, int type=0, bool storeRawHit=true)
description
CalCluster * buildCalCluster(EVENT::Cluster *lc_cluster)
description
Track * buildTrack(EVENT::Track *lc_track, std::string trackstate_location, EVENT::LCCollection *gbl_kink_data, EVENT::LCCollection *track_data)
description
Vertex * buildVertex(EVENT::Vertex *lc_vertex)
description
Definition utilities.cxx:31
bool hasCollection(EVENT::LCEvent *lc_event, const std::string &collection)
description
Definition utilities.cxx:18
bool isUsedByTrack(IMPL::TrackerHitImpl *lc_tracker_hit, EVENT::Track *lc_track)
description
TrackerHit * buildTrackerHit(IMPL::TrackerHitImpl *lc_trackerHit, bool rotate=true, int type=0)
description
double getKalmanTrackL1Isolations(Track *track, std::vector< TrackerHit * > *siClusters)
description
bool getParticlesFromVertex(Vertex *vtx, Particle *ele, Particle *pos)
description
Particle * buildParticle(EVENT::ReconstructedParticle *lc_particle, std::string trackstate_location, EVENT::LCCollection *gbl_kink_data, EVENT::LCCollection *track_data)
description
Definition utilities.cxx:54
double v0_projection_to_target_significance(json v0proj_fits, int run, double &vtx_proj_x, double &vtx_proj_y, double &vtx_proj_x_signif, double &vtx_proj_y_signif, double vtx_x, double vtx_y, double vtx_z, double vtx_px, double vtx_py, double vtx_pz)
description
void get2016KFMCTruthHitCodes(Track *ele_trk, Track *pos_trk, int &L1L2hitCode, int &L1hitCode, int &L2hitCode)
description
bool IsSameTrack(Track *trk1, Track *trk2)
description
RawSvtHit * buildRawHit(EVENT::TrackerRawData *rawTracker_hit, EVENT::LCCollection *raw_svt_hit_fits)