CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
BSCTrigger.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: BSCTrigger
4 // Class: BSCTrigger
5 //
13 //
14 // Original Author: Muriel VANDER DONCKT *:0
15 // Created: Wed Jul 16 16:11:05 CEST 2008
16 //
17 //
18 
19 // system include files
20 #include <memory>
21 
22 // user include files
25 
28 
36 
39 
40 //
41 // class declaration
42 //
43 
45 public:
46  explicit BSCTrigger(const edm::ParameterSet&);
47  ~BSCTrigger() override;
48 
49 private:
50  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
51  int getBSCNum(int id, float z) const;
52  bool isInner(int id) const;
53  bool isZplus(int id) const;
54  // ----------member data ---------------------------
55  const std::vector<unsigned> ttBits_;
56  const std::vector<std::string> names_;
57  const double theCoincidence_;
58  const double theResolution_;
61 };
62 
63 //
64 // constants, enums and typedefs
65 //
66 
67 //
68 // static data member definitions
69 //
70 
71 //
72 // constructors and destructor
73 //
75  : ttBits_{iConfig.getParameter<std::vector<unsigned>>("bitNumbers")},
76  names_{iConfig.getParameter<std::vector<std::string>>("bitNames")},
77  theCoincidence_{iConfig.getParameter<double>("coincidence")},
78  theResolution_{iConfig.getParameter<double>("resolution")},
79  theHitsToken_{consumes<CrossingFrame<PSimHit>>(iConfig.getParameter<edm::InputTag>("theHits"))},
80  thePutToken_{produces<L1GtTechnicalTriggerRecord>()} {}
81 
83  // do anything here that needs to be done at desctruction time
84  // (e.g. close files, deallocate resources etc.)
85 }
86 
87 //
88 // member functions
89 //
90 
91 // ------------ method called to produce the data ------------
93  std::vector<L1GtTechnicalTrigger> ttVec(ttBits_.size());
94 
96  iEvent.getByToken(theHitsToken_, cf);
97 
98  if (!cf.failedToGet()) {
99  std::vector<float> EnergyBX(32);
100  std::vector<float> EnergyBXMinusDt(32);
101 
102  for (int c = 0; c < 32; ++c) {
103  EnergyBX[c] = 0;
104  EnergyBXMinusDt[c] = 0;
105  }
106  MixCollection<PSimHit> theBSCHitContainer(cf.product());
107  const float dt1 = theCoincidence_ / 2 + theResolution_;
108  const float dt2 = theCoincidence_ / 2 - theResolution_;
109  if (edm::isDebugEnabled())
110  LogDebug("BSCTrig") << " ----------------new event ---with " << theBSCHitContainer.size() << " hits in the BSC";
111 
112  // collect total deposited energy in BSC segments -> EnergyBX[segment id], in GeV units ---------------------------------------------------------------
113  for (auto itHit = theBSCHitContainer.begin(); itHit != theBSCHitContainer.end(); ++itHit) {
114  float zh = itHit->entryPoint().z() / 10;
115  int id = getBSCNum(itHit->detUnitId(), zh);
116  if (id > 31)
117  continue; // the small 2 paddles further from the IP
118  float t = itHit->timeOfFlight();
119 
120  if (edm::isDebugEnabled()) {
121  float rh = sqrt(itHit->entryPoint().x() * itHit->entryPoint().x() +
122  itHit->entryPoint().y() * itHit->entryPoint().y()) /
123  10;
124  LogTrace("BSCTrig") << " BSC Num " << id << " z=" << zh << " isZplus=" << isZplus(id)
125  << " Hit DetId=" << getBSCNum(id, zh) << " r=" << rh << " isInner=" << isInner(id);
126  LogTrace("BSCTrig") << " Hit time=" << t << " accepted range=[" << dt2 << "," << dt1 << "] from a "
127  << abs(itHit->particleType()) << " with energy " << itHit->energyLoss();
128  }
129  if (fabs(t) > dt1 || fabs(t) < dt2)
130  continue;
131  if (t > 0)
132  EnergyBX[id] += itHit->energyLoss();
133  else
134  EnergyBXMinusDt[id] += itHit->energyLoss();
135  }
136 
137  // count number of segments hit in inner/outer and +z, -z ---------------------------------------------------------------------------------------------
138  int ZMinnerBX = 0, ZMouterBX = 0;
139  int ZPinnerBX = 0, ZPouterBX = 0;
140  int ZMinnerBXMinusDt = 0, ZMouterBXMinusDt = 0;
141  int ZPinnerBXMinusDt = 0, ZPouterBXMinusDt = 0;
142 
143  constexpr float MipFraction = 0.5;
144  constexpr float MipEnergy = 0.0027;
145  constexpr float theThreshold = MipFraction * MipEnergy;
146  for (unsigned int ipad = 0; ipad < 32; ipad++) {
147  if (edm::isDebugEnabled())
148  LogTrace("BSCTrig") << " EnergyBX[" << ipad << "]=" << EnergyBX[ipad];
149  // hits after the bunch crossing
150  if (EnergyBX[ipad] > theThreshold) {
151  if (isZplus(ipad)) {
152  if (isInner(ipad))
153  ZPinnerBX++;
154  else
155  ZPouterBX++;
156  } else {
157  if (isInner(ipad))
158  ZMinnerBX++;
159  else
160  ZMouterBX++;
161  }
162  }
163  // hits before the bunch crossing
164  if (EnergyBXMinusDt[ipad] > theThreshold) {
165  if (isZplus(ipad)) {
166  if (isInner(ipad))
167  ZPinnerBXMinusDt++;
168  else
169  ZPouterBXMinusDt++;
170  } else {
171  if (isInner(ipad))
172  ZMinnerBXMinusDt++;
173  else
174  ZMouterBXMinusDt++;
175  }
176  }
177  }
178 
179  if (edm::isDebugEnabled())
180  LogTrace("BSCTrig") << " Zplus I=" << ZPinnerBX << " Zminus I=" << ZMinnerBX << " Zplus O=" << ZPouterBX
181  << " Zminus O=" << ZMouterBX;
182 
183  // minimum bias technical triggers that are also connected to 'external condition' triggers -----------------
184  bool bit32 = false; // min bias inner >=1
185  if (ZPinnerBX >= 1 && ZMinnerBX >= 1)
186  bit32 = true;
187 
188  bool bit33 = false; // min bias inner >=2
189  if (ZPinnerBX >= 2 && ZMinnerBX >= 2)
190  bit33 = true;
191 
192  bool bit34 = false; // min bias OR
193  if (ZPinnerBX + ZMinnerBX + ZPouterBX + ZMouterBX >= 1)
194  bit34 = true;
195 
196  bool bit35 = false; // high multiplicity
197  if (ZPinnerBX == 8 && ZMinnerBX == 8)
198  bit35 = true;
199 
200  // beam halo technical triggers ----------------------------------------------------------------
201  bool bit36 = false; // beam 2 halo inner
202  if (ZPinnerBX >= 1 && ZMinnerBXMinusDt >= 1)
203  bit36 = true;
204 
205  bool bit37 = false; // beam 2 halo outer
206  if (ZPouterBX >= 1 && ZMouterBXMinusDt >= 1)
207  bit37 = true;
208 
209  bool bit38 = false; // beam 1 halo inner
210  if (ZMinnerBX >= 1 && ZPinnerBXMinusDt >= 1)
211  bit38 = true;
212 
213  bool bit39 = false; // beam 1 halo outer
214  if (ZMouterBX >= 1 && ZPouterBXMinusDt >= 1)
215  bit39 = true;
216 
217  // minimum bias technical triggers ---------------------------------------------------------
218  bool bit40 = false; // min bias all >=1
219  if (ZPinnerBX + ZPouterBX >= 1 && ZMinnerBX + ZMouterBX >= 1)
220  bit40 = true;
221 
222  bool bit41 = false; // min bias all >=2
223  if (ZPinnerBX + ZPouterBX >= 2 && ZMinnerBX + ZMouterBX >= 2)
224  bit41 = true;
225 
226  bool bit42 = false; // beam 1 splash (-z)
227  if (ZMinnerBX >= 2)
228  bit42 = true;
229 
230  bool bit43 = false; // beam 2 splash (+z)
231  if (ZPinnerBX >= 2)
232  bit43 = true;
233 
234  for (unsigned i = 0; i < ttBits_.size(); ++i) {
235  bool bit = false;
236  if (names_.at(i) == names_[0])
237  bit = bit32;
238  if (names_.at(i) == names_[1])
239  bit = bit33;
240  if (names_.at(i) == names_[2])
241  bit = bit34;
242  if (names_.at(i) == names_[3])
243  bit = bit35;
244  if (names_.at(i) == names_[4])
245  bit = bit36;
246  if (names_.at(i) == names_[5])
247  bit = bit37;
248  if (names_.at(i) == names_[6])
249  bit = bit38;
250  if (names_.at(i) == names_[7])
251  bit = bit39;
252  if (names_.at(i) == names_[8])
253  bit = bit40;
254  if (names_.at(i) == names_[9])
255  bit = bit41;
256  if (names_.at(i) == names_[10])
257  bit = bit42;
258  if (names_.at(i) == names_[11])
259  bit = bit43;
260  ttVec.at(i) = L1GtTechnicalTrigger(names_.at(i), ttBits_.at(i), 0, bit);
261  if (edm::isDebugEnabled())
262  LogTrace("AnaBsc") << "bit: " << ttBits_[i] << " VALUE:" << bit;
263  }
264  } else
265  ttVec.clear();
267  output.setGtTechnicalTrigger(ttVec);
268  iEvent.emplace(thePutToken_, std::move(output));
269 }
270 int BSCTrigger::getBSCNum(int id, float z) const {
271  int zside = 0;
272  if (z > 0)
273  zside = 1;
274  if (edm::isDebugEnabled()) {
275  int det = (id & 24) >> 3;
276  int station = id & 7;
277  LogTrace("BSCTrig") << "id=" << id << " zside=" << zside << " det=" << det << " station=" << station;
278  }
279  int BSCNum;
280  if (id & 16)
281  BSCNum = 32 + (id & 1) + (zside << 1); // small paddles further from IP
282  else
283  BSCNum = (id & 15) + (zside << 4); // the BSC on the HF
284  return BSCNum;
285 }
286 
287 bool BSCTrigger::isInner(int id) const { return ((id & 8) >> 3); }
288 
289 bool BSCTrigger::isZplus(int id) const { return ((id & 16) >> 4); }
290 
291 //define this as a plug-in
BSCTrigger(const edm::ParameterSet &)
Definition: BSCTrigger.cc:74
bool isDebugEnabled()
const edm::EventSetup & c
uint16_t *__restrict__ id
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
const edm::EDPutTokenT< L1GtTechnicalTriggerRecord > thePutToken_
Definition: BSCTrigger.cc:60
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const edm::EDGetTokenT< CrossingFrame< PSimHit > > theHitsToken_
Definition: BSCTrigger.cc:59
int zside(DetId const &)
const double theCoincidence_
Definition: BSCTrigger.cc:57
const double theResolution_
Definition: BSCTrigger.cc:58
const std::vector< unsigned > ttBits_
Definition: BSCTrigger.cc:55
#define LogTrace(id)
int getBSCNum(int id, float z) const
Definition: BSCTrigger.cc:270
int iEvent
Definition: GenABIO.cc:224
bool isZplus(int id) const
Definition: BSCTrigger.cc:289
T sqrt(T t)
Definition: SSEVec.h:19
def move
Definition: eostools.py:511
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isInner(int id) const
Definition: BSCTrigger.cc:287
const std::vector< std::string > names_
Definition: BSCTrigger.cc:56
OrphanHandle< PROD > emplace(EDPutTokenT< PROD > token, Args &&...args)
puts a new product
Definition: Event.h:433
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
~BSCTrigger() override
Definition: BSCTrigger.cc:82
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
Definition: BSCTrigger.cc:92
void setGtTechnicalTrigger(const std::vector< L1GtTechnicalTrigger > &gtTechnicalTriggerValue)
#define LogDebug(id)