Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HFTrigger.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file HFTrigger.cc
1 #include "HFTrigger.h"
2 
3 /*
4  * Basic heavy flavor software trigger
5  * Used in study of hardware trigger
6  * Cameron Dean
7  * 01/02/2021
8  */
9 std::map<std::string, bool> triggerDecisions =
10 {
11  {"oneTrack", false}
12 , {"twoTrack", false}
13 , {"lowMultiplicity", false}
14 , {"highMultiplicity", false}
15 };
16 
17 namespace HFTriggerRequirement
18 {
19  float meanHighMult = 100; //Set min num. INTT hits
20  float asymmHighMult = 0.1; //Set highMult asymm between INTT layers (fraction)
21  float meanLowMult = 20; //Set max num. INTT hits
22  float asymmLowMult = 0.1; //Set lowMult asymm between INTT layers (fraction)
23  float trackPT = 0.5; //Min track pT in GeV
24  float trackVertexDCA = 0.01; //Min. DCA of a track with any vertex in cm
25  float trackTrackDCA = 0.03; //Max. DCA of a track with other tracks in cm
26 }
27 
29  : SubsysReco("HFTRIGGER")
30  , m_useOneTrackTrigger(false)
31  , m_useTwoTrackTrigger(false)
32  , m_useLowMultiplicityTrigger(false)
33  , m_useHighMultiplicityTrigger(false)
34 {
35 }
36 
38  : SubsysReco(name)
39  , m_useOneTrackTrigger(false)
40  , m_useTwoTrackTrigger(false)
41  , m_useLowMultiplicityTrigger(false)
42  , m_useHighMultiplicityTrigger(false)
43 {
44 }
45 
47 {
48  return 0;
49 }
50 
52 {
53  bool successfulTrigger = runTrigger(topNode);
54 
55  if (Verbosity() >= VERBOSITY_MORE)
56  {
57  if (successfulTrigger) std::cout << "One of the heavy flavor triggers fired" << std::endl;
58  else std::cout << "No heavy flavor triggers fired" << std::endl;
59  }
60 
61  int failedTriggerDecisions = 0;
62  if (m_useOneTrackTrigger && !triggerDecisions.find("oneTrack")->second)
63  {
64  if (Verbosity() >= VERBOSITY_SOME) std::cout << "The oneTrackTrigger did not fire for this event, skipping." << std::endl;
65  failedTriggerDecisions += 1;
66  }
67  if (m_useTwoTrackTrigger && !triggerDecisions.find("twoTrack")->second)
68  {
69  if (Verbosity() >= VERBOSITY_SOME) std::cout << "The twoTrackTrigger did not fire for this event, skipping." << std::endl;
70  failedTriggerDecisions += 1;
71  }
72  if (m_useLowMultiplicityTrigger && !triggerDecisions.find("lowMultiplicity")->second)
73  {
74  if (Verbosity() >= VERBOSITY_SOME) std::cout << "The lowMultiplicityTrigger did not fire for this event, skipping." << std::endl;
75  failedTriggerDecisions += 1;
76  }
77  if (m_useHighMultiplicityTrigger && !triggerDecisions.find("highMultiplicity")->second)
78  {
79  if (Verbosity() >= VERBOSITY_SOME) std::cout << "The highMultiplicityTrigger did not fire for this event, skipping." << std::endl;
80  failedTriggerDecisions += 1;
81  }
82 
83  if (failedTriggerDecisions > 0) return Fun4AllReturnCodes::ABORTEVENT;
84  else return Fun4AllReturnCodes::EVENT_OK;
85 }
86 
88 {
89  return 0;
90 }
91 
93 {
94  bool anyTriggerFired = false;
95 
96  std::vector<Track> allTracks = makeAllTracks(topNode);
97  std::vector<Vertex> allVertices = makeAllPrimaryVertices(topNode);
98 
99  float meanMult = 0;
100  float asymmMult = 0;
101  calculateMultiplicity(topNode, meanMult, asymmMult);
102 
103  if (m_useOneTrackTrigger) triggerDecisions.find("oneTrack")->second = runOneTrackTrigger(allTracks, allVertices);
104  if (m_useTwoTrackTrigger) triggerDecisions.find("twoTrack")->second = runTwoTrackTrigger(allTracks, allVertices);
105  if (m_useLowMultiplicityTrigger) triggerDecisions.find("lowMultiplicity")->second = runLowMultiplicityTrigger(meanMult, asymmMult);
106  if (m_useHighMultiplicityTrigger) triggerDecisions.find("highMultiplicity")->second = runHighMultiplicityTrigger(meanMult, asymmMult);
107 
109 
110  const int numberOfFiredTriggers = std::accumulate( begin(triggerDecisions), end(triggerDecisions), 0,
111  [](const int previous, const std::pair<const std::string, bool>& element)
112  { return previous + element.second; });
113 
114  if (numberOfFiredTriggers != 0) anyTriggerFired = true;
115 
116  return anyTriggerFired;
117 }
118 
119 bool HFTrigger::runOneTrackTrigger(std::vector<Track> Tracks, std::vector<Vertex> Vertices)
120 { //Can maybe use return when we get a positive trigger decision to break the loops
121  bool oneTrackTriggerDecision = false;
122 
123  for (Track track : Tracks)
124  {
125  float pT = sqrt(pow(track(3,0), 2) + pow(track(4,0), 2));
126  float minIP = FLT_MAX;
127  for (Vertex vertex : Vertices)
128  {
129  float thisIP = calcualteTrackVertexDCA(track, vertex);
130  minIP = std::min(minIP, thisIP);
131  }
132  if (pT > HFTriggerRequirement::trackPT && minIP > HFTriggerRequirement::trackVertexDCA) oneTrackTriggerDecision = true;
133  }
134 
135  return oneTrackTriggerDecision;
136 }
137 
138 bool HFTrigger::runTwoTrackTrigger(std::vector<Track> Tracks, std::vector<Vertex> Vertices)
139 {
140  bool twoTrackTriggerDecision = false;
141  std::vector<Track> goodTracks;
142 
143  for (Track track : Tracks)
144  {
145  std::vector<Track> singleTrack = {track};
146  bool oneTrackTriggerDecision = runOneTrackTrigger(singleTrack, Vertices);
147  if (oneTrackTriggerDecision) goodTracks.push_back(track);
148  }
149 
150  if (goodTracks.size() > 1) //We need at least two good track to start a two track trigger
151  {
152  for (unsigned int i = 0; i < goodTracks.size(); i++)
153  {
154  for (unsigned int j = i + 1; j < goodTracks.size(); j++)
155  {
156  float trackDCA = calcualteTrackTrackDCA(goodTracks[i], goodTracks[j]);
157  if (trackDCA < HFTriggerRequirement::trackTrackDCA) twoTrackTriggerDecision = true;
158  }
159  }
160  }
161 
162  return twoTrackTriggerDecision;
163 }
164 
165 void HFTrigger::calculateMultiplicity(PHCompositeNode *topNode, float& meanMultiplicity, float& asymmetryMultiplicity)
166 {
167  TrkrHitSetContainer* hitContainer = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
168 
169  TrkrHitSetContainer::ConstRange inttHitSetRange[2];
170  for (int i = 0; i < 2; i++) inttHitSetRange[i] = hitContainer->getHitSets(TrkrDefs::TrkrId::inttId, i + 4);
171 
172  int inttHits[2] = {0};
173 
174  for (int i = 0; i < 2; i++)
175  {
176  for (TrkrHitSetContainer::ConstIterator hitsetitr = inttHitSetRange[i].first;
177  hitsetitr != inttHitSetRange[i].second;
178  ++hitsetitr)
179  {
180  TrkrHitSet *hitset = hitsetitr->second;
181  inttHits[i] += hitset->size();
182  }
183  }
184 
185  meanMultiplicity = (inttHits[0] + inttHits[1])/2;
186  asymmetryMultiplicity = (inttHits[0] - inttHits[1])/(inttHits[0] + inttHits[1]);
187 }
188 
189 bool HFTrigger::runHighMultiplicityTrigger(float meanMultiplicity, float asymmetryMultiplicity)
190 {
191  bool multiplicityTriggerDecision = false;
192  float meanRequirement = HFTriggerRequirement::meanHighMult;
193  float asymmRequirement = HFTriggerRequirement::asymmHighMult;
194 
195  if ( meanMultiplicity > meanRequirement && asymmetryMultiplicity < asymmRequirement)
196  multiplicityTriggerDecision = true;
197 
198  return multiplicityTriggerDecision;
199 }
200 
201 bool HFTrigger::runLowMultiplicityTrigger(float meanMultiplicity, float asymmetryMultiplicity)
202 {
203  bool multiplicityTriggerDecision = false;
204  float meanRequirement = HFTriggerRequirement::meanLowMult;
205  float asymmRequirement = HFTriggerRequirement::asymmLowMult;
206 
207  if ( meanMultiplicity < meanRequirement && asymmetryMultiplicity < asymmRequirement)
208  multiplicityTriggerDecision = true;
209 
210  return multiplicityTriggerDecision;
211 }
212 
214 {
215  Vertex vertex;
216 
217  vertex(0,0) = m_dst_vertex->get_x();
218  vertex(1,0) = m_dst_vertex->get_y();
219  vertex(2,0) = m_dst_vertex->get_z();
220 
221  return vertex;
222 }
223 
225 {
226  std::vector<Vertex> primaryVertices;
227  m_dst_vertexmap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
228 
229  for (SvtxVertexMap::ConstIter iter = m_dst_vertexmap->begin(); iter != m_dst_vertexmap->end(); ++iter)
230  {
231  m_dst_vertex = iter->second;
232  primaryVertices.push_back(makeVertex(topNode));
233  }
234 
235  return primaryVertices;
236 }
237 
239 {
240  Track track;
241 
242  track(0,0) = m_dst_track->get_x();
243  track(1,0) = m_dst_track->get_y();
244  track(2,0) = m_dst_track->get_z();
245  track(3,0) = m_dst_track->get_px();
246  track(4,0) = m_dst_track->get_py();
247  track(5,0) = m_dst_track->get_pz();
248 
249  return track;
250 }
251 
252 std::vector<Track> HFTrigger::makeAllTracks(PHCompositeNode *topNode)
253 {
254  std::vector<Track> tracks;
255  m_dst_trackmap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
256 
257  for (SvtxTrackMap::Iter iter = m_dst_trackmap->begin(); iter != m_dst_trackmap->end(); ++iter)
258  {
259  m_dst_track = iter->second;
260  tracks.push_back(makeTrack(topNode));
261  }
262 
263  return tracks;
264 }
265 
266 int HFTrigger::decomposeTrack(Track track, TrackX& trackPosition, TrackP& trackMomentum)
267 {
268  for (unsigned int i = 0; i < 3; i++)
269  {
270  trackPosition(i,0) = track(i,0);
271  trackMomentum(i,0) = track(i+3,0);
272  }
273 
274  return 0;
275 }
276 
278 {
279  TrackX pos;
280  TrackP mom;
281  DCA dcaVertex;
282 
283  decomposeTrack(track, pos, mom);
284 
285  dcaVertex = pos - vertex - mom.dot(pos - vertex)*mom/(mom.dot(mom));
286 
287  float twoD_DCA = std::sqrt(std::pow(dcaVertex(0,0), 2) + std::pow(dcaVertex(1,0), 2));
288 
289  return twoD_DCA;
290 }
291 
293 {
294  TrackX pos;
295  TrackP mom;
296  DCA dcaVertex;
297 
298  decomposeTrack(track, pos, mom);
299 
300  dcaVertex = pos - vertex - mom.dot(pos - vertex)*mom/(mom.dot(mom));
301 
302  return std::abs(dcaVertex.norm());
303 }
304 
306 {
307  TrackX posOne;
308  TrackP momOne;
309  TrackX posTwo;
310  TrackP momTwo;
311  float dcaTrackSize;
312 
313  decomposeTrack(trackOne, posOne, momOne);
314  decomposeTrack(trackTwo, posTwo, momTwo);
315 
316  Eigen::Vector3f momOneCrossmomTwo = momOne.cross(momTwo);
317  Eigen::Vector3f posOneMinusposTwo = posOne - posTwo;
318  dcaTrackSize = std::abs(momOneCrossmomTwo.dot(posOneMinusposTwo)/(momOneCrossmomTwo.norm()));
319 
320  return dcaTrackSize;
321 }
322 
324 {
325  std::cout << "\n---------------HFTrigger information---------------" << std::endl;
326  if (m_useOneTrackTrigger) std::cout << "The oneTrack trigger decision is " << triggerDecisions.find("oneTrack")->second << std::endl;
327  if (m_useTwoTrackTrigger) std::cout << "The twoTrack trigger decision is " << triggerDecisions.find("twoTrack")->second << std::endl;
328  if (m_useLowMultiplicityTrigger) std::cout << "The lowMultiplicity trigger decision is " << triggerDecisions.find("lowMultiplicity")->second << std::endl;
329  if (m_useHighMultiplicityTrigger) std::cout << "The highMultiplicity trigger decision is " << triggerDecisions.find("highMultiplicity")->second << std::endl;
330  std::cout << "---------------------------------------------------\n" << std::endl;
331 }
332