CMS 3D CMS Logo

EcalSelectiveReadoutProducer.cc
Go to the documentation of this file.
5 
8 
9 //#include "DataFormats/EcalDigi/interface/EcalMGPASample.h"
10 
12 
13 #include <memory>
14 #include <fstream>
15 #include <atomic>
16 
17 using namespace std;
18 
20  : suppressor_(params, consumesCollector()), firstCallEB_(true), firstCallEE_(true), iEvent_(1) {
21  //settings:
22  // settings which are only in python config files:
23  digiProducer_ = params.getParameter<string>("digiProducer");
24  ebdigiCollection_ = params.getParameter<std::string>("EBdigiCollection");
25  eedigiCollection_ = params.getParameter<std::string>("EEdigiCollection");
26  ebSRPdigiCollection_ = params.getParameter<std::string>("EBSRPdigiCollection");
27  eeSRPdigiCollection_ = params.getParameter<std::string>("EESRPdigiCollection");
28  ebSrFlagCollection_ = params.getParameter<std::string>("EBSrFlagCollection");
29  eeSrFlagCollection_ = params.getParameter<std::string>("EESrFlagCollection");
30  trigPrimProducer_ = params.getParameter<string>("trigPrimProducer");
31  trigPrimCollection_ = params.getParameter<string>("trigPrimCollection");
32  trigPrimBypass_ = params.getParameter<bool>("trigPrimBypass");
33  trigPrimBypassMode_ = params.getParameter<int>("trigPrimBypassMode");
34  dumpFlags_ = params.getUntrackedParameter<int>("dumpFlags", 0);
35  writeSrFlags_ = params.getUntrackedParameter<bool>("writeSrFlags", false);
36  produceDigis_ = params.getUntrackedParameter<bool>("produceDigis", true);
37  // settings which can come from either condition database or python configuration file:
38  useCondDb_ = false;
39  try {
40  if (params.getParameter<bool>("configFromCondDB")) {
41  useCondDb_ = true;
42  }
43  } catch (cms::Exception const&) {
44  /* pameter not found */
45  edm::LogWarning("EcalSelectiveReadout") << "Parameter configFromCondDB of EcalSelectiveReadout module not found. "
46  "Selective readout configuration will be read from python file.";
47  }
48  if (!useCondDb_) {
49  settingsFromFile_ = std::make_unique<EcalSRSettings>();
52  }
53 
54  //declares the products made by this producer:
55  if (produceDigis_) {
56  produces<EBDigiCollection>(ebSRPdigiCollection_);
57  produces<EEDigiCollection>(eeSRPdigiCollection_);
58  }
59 
60  if (writeSrFlags_) {
61  produces<EBSrFlagCollection>(ebSrFlagCollection_);
62  produces<EESrFlagCollection>(eeSrFlagCollection_);
63  }
64 
65  useFullReadout_ = false;
66  useFullReadout_ = params.getParameter<bool>("UseFullReadout");
67 
68  theGeometry = nullptr;
69  theTriggerTowerMap = nullptr;
70  theElecMap = nullptr;
71 
72  EB_token = consumes<EBDigiCollection>(edm::InputTag(digiProducer_, ebdigiCollection_));
73  EE_token = consumes<EEDigiCollection>(edm::InputTag(digiProducer_, eedigiCollection_));
74  ;
75  EcTP_token = consumes<EcalTrigPrimDigiCollection>(edm::InputTag(trigPrimProducer_, trigPrimCollection_));
76  if (useFullReadout_) {
77  hSr_token_ = esConsumes<EcalSRSettings, EcalSRSettingsRcd>(edm::ESInputTag("", "fullReadout"));
78  } else {
79  hSr_token_ = esConsumes<EcalSRSettings, EcalSRSettingsRcd>();
80  }
81  geom_token_ = esConsumes<CaloGeometry, CaloGeometryRecord>();
82  eTTmap_token_ = esConsumes<EcalTrigTowerConstituentsMap, IdealGeometryRecord>();
83  eElecmap_token_ = esConsumes<EcalElectronicsMapping, EcalMappingRcd>();
84  ;
85 }
86 
88 
90  if (useCondDb_) {
91  //getting selective readout configuration:
93 
94  settings_ = hSr.product();
95  }
96 
97  //gets the trigger primitives:
98  EcalTrigPrimDigiCollection emptyTPColl;
99  const EcalTrigPrimDigiCollection* trigPrims =
100  (trigPrimBypass_ && trigPrimBypassMode_ == 0) ? &emptyTPColl : getTrigPrims(event);
101 
102  //gets the digis from the events:
103  EBDigiCollection dummyEbDigiColl;
104  EEDigiCollection dummyEeDigiColl;
105 
106  const EBDigiCollection* ebDigis = produceDigis_ ? getEBDigis(event) : &dummyEbDigiColl;
107  const EEDigiCollection* eeDigis = produceDigis_ ? getEEDigis(event) : &dummyEeDigiColl;
108 
109  //runs the selective readout algorithm:
110  unique_ptr<EBDigiCollection> selectedEBDigis;
111  unique_ptr<EEDigiCollection> selectedEEDigis;
112  unique_ptr<EBSrFlagCollection> ebSrFlags;
113  unique_ptr<EESrFlagCollection> eeSrFlags;
114 
115  if (produceDigis_) {
116  selectedEBDigis = std::make_unique<EBDigiCollection>();
117  selectedEEDigis = std::make_unique<EEDigiCollection>();
118  }
119 
120  if (writeSrFlags_) {
121  ebSrFlags = std::make_unique<EBSrFlagCollection>();
122  eeSrFlags = std::make_unique<EESrFlagCollection>();
123  }
124 
125  if (not suppressorSettingsSet_) {
126  //Check the validity of EcalSRSettings
128 
130  suppressorSettingsSet_ = true;
131 
132  // check that everything is up-to-date
136  }
137 
139  *trigPrims,
140  *ebDigis,
141  *eeDigis,
142  selectedEBDigis.get(),
143  selectedEEDigis.get(),
144  ebSrFlags.get(),
145  eeSrFlags.get());
146 
147  if (dumpFlags_ >= iEvent_) {
148  ofstream ttfFile("TTF.txt", (iEvent_ == 1 ? ios::trunc : ios::app));
149  suppressor_.printTTFlags(ttfFile, iEvent_, iEvent_ == 1 ? true : false);
150 
151  ofstream srfFile("SRF.txt", (iEvent_ == 1 ? ios::trunc : ios::app));
152  if (iEvent_ == 1) {
154  }
155  srfFile << "# Event " << iEvent_ << "\n";
157  srfFile << "\n";
158 
159  ofstream afFile("AF.txt", (iEvent_ == 1 ? ios::trunc : ios::app));
160  printSrFlags(afFile, *ebSrFlags, *eeSrFlags, iEvent_, iEvent_ == 1 ? true : false);
161  }
162 
163  ++iEvent_; //event counter
164 
165  if (produceDigis_) {
166  //puts the selected digis into the event:
167  event.put(std::move(selectedEBDigis), ebSRPdigiCollection_);
168  event.put(std::move(selectedEEDigis), eeSRPdigiCollection_);
169  }
170 
171  //puts the SR flags into the event:
172  if (writeSrFlags_) {
173  event.put(std::move(ebSrFlags), ebSrFlagCollection_);
174  event.put(std::move(eeSrFlags), eeSrFlagCollection_);
175  }
176 }
177 
180  event.getByToken(EB_token, hEBDigis);
181  //product() method is called before id() in order to get an exception
182  //if the handle is not available (check not done by id() method).
183  const EBDigiCollection* result = hEBDigis.product();
184  if (firstCallEB_) {
185  checkWeights(event, hEBDigis.id());
186  firstCallEB_ = false;
187  }
188  return result;
189 }
190 
193  event.getByToken(EE_token, hEEDigis);
194  //product() method is called before id() in order to get an exception
195  //if the handle is not available (check not done by id() method).
196  const EEDigiCollection* result = hEEDigis.product();
197  if (firstCallEE_) {
198  checkWeights(event, hEEDigis.id());
199  firstCallEE_ = false;
200  }
201  return result;
202 }
203 
206  event.getByToken(EcTP_token, hTPDigis);
207  return hTPDigis.product();
208 }
209 
211  edm::ESHandle<CaloGeometry> hGeometry = eventSetup.getHandle(geom_token_);
212 
213  const CaloGeometry* pGeometry = &*hGeometry;
214 
215  // see if we need to update
216  if (pGeometry != theGeometry) {
217  theGeometry = pGeometry;
219  }
220 }
221 
224 
225  const EcalTrigTowerConstituentsMap* pMap = &*eTTmap;
226 
227  // see if we need to update
228  if (pMap != theTriggerTowerMap) {
229  theTriggerTowerMap = pMap;
231  }
232 }
233 
236 
237  const EcalElectronicsMapping* pMap = &*eElecmap;
238 
239  // see if we need to update
240  if (pMap != theElecMap) {
241  theElecMap = pMap;
243  }
244 }
245 
247  const char tccFlagMarker[] = {'x', '.', 'S', '?', 'C', 'E', 'E', 'E', 'E'};
250 
251  //static bool firstCall=true;
252  // if(firstCall){
253  // firstCall=false;
254  os << "# TCC flag map\n#\n"
255  "# +-->Phi "
256  << tccFlagMarker[0 + 1]
257  << ": 000 (low interest)\n"
258  "# | "
259  << tccFlagMarker[1 + 1]
260  << ": 001 (mid interest)\n"
261  "# | "
262  << tccFlagMarker[2 + 1]
263  << ": 010 (not valid)\n"
264  "# V Eta "
265  << tccFlagMarker[3 + 1]
266  << ": 011 (high interest)\n"
267  "# "
268  << tccFlagMarker[4 + 1]
269  << ": 1xx forced readout (Hw error)\n"
270  "#\n";
271  //}
272 
273  vector<vector<int> > ttf(nEta, vector<int>(nPhi, -1));
274  for (EcalTrigPrimDigiCollection::const_iterator it = tp.begin(); it != tp.end(); ++it) {
275  const EcalTriggerPrimitiveDigi& trigPrim = *it;
276  if (trigPrim.size() > 0) {
277  int iEta = trigPrim.id().ieta();
278  int iEta0 = iEta < 0 ? iEta + nEta / 2 : iEta + nEta / 2 - 1;
279  int iPhi0 = trigPrim.id().iphi() - 1;
280  ttf[iEta0][iPhi0] = trigPrim.ttFlag();
281  }
282  }
283  for (int iEta = 0; iEta < nEta; ++iEta) {
284  for (int iPhi = 0; iPhi < nPhi; ++iPhi) {
285  os << tccFlagMarker[ttf[iEta][iPhi] + 1];
286  }
287  os << "\n";
288  }
289 }
290 
291 void EcalSelectiveReadoutProducer::checkWeights(const edm::Event& evt, const edm::ProductID& noZsDigiId) const {
292  const vector<float>& weights =
293  settings_->dccNormalizedWeights_[0]; //params_.getParameter<vector<double> >("dccNormalizedWeights");
295  static std::atomic<bool> warnWeightCnt{true};
296  bool expected = true;
297  if ((int)weights.size() > nFIRTaps &&
298  warnWeightCnt.compare_exchange_strong(expected, false, std::memory_order_acq_rel)) {
299  edm::LogWarning("Configuration") << "The list of DCC zero suppression FIR "
300  "weights given in parameter dccNormalizedWeights is longer "
301  "than the expected depth of the FIR filter :("
302  << nFIRTaps
303  << "). "
304  "The last weights will be discarded.";
305  }
306 
307  if (!weights.empty()) {
308  int iMaxWeight = 0;
309  double maxWeight = weights[iMaxWeight];
310  //looks for index of maximum weight
311  for (unsigned i = 0; i < weights.size(); ++i) {
312  if (weights[i] > maxWeight) {
313  iMaxWeight = i;
314  maxWeight = weights[iMaxWeight];
315  }
316  }
317 
318  //position of time sample whose maximum weight is applied:
319  int maxWeightBin = settings_->ecalDccZs1stSample_[0] //params_.getParameter<int>("ecalDccZs1stSample")
320  + iMaxWeight;
321 
322  //gets the bin of maximum (in case of raw data it will not exist)
323  int binOfMax = 0;
324  bool rc = getBinOfMax(evt, noZsDigiId, binOfMax);
325 
326  if (rc && maxWeightBin != binOfMax) {
327  edm::LogWarning("Configuration") << "The maximum weight of DCC zero suppression FIR filter is not "
328  "applied to the expected maximum sample("
329  << binOfMax
330  << (binOfMax == 1 ? "st"
331  : (binOfMax == 2 ? "nd" : (binOfMax == 3 ? "rd" : "th")))
332  << " time sample). This may indicate faulty 'dccNormalizedWeights' "
333  "or 'ecalDccZs1sSample' parameters.";
334  }
335  }
336 }
337 
339  const edm::ProductID& noZsDigiId,
340  int& binOfMax) const {
341  bool rc;
342  const edm::StableProvenance& p = evt.getStableProvenance(noZsDigiId);
344  vector<string> ebDigiParamList = result.getParameterNames();
345  string bofm("binOfMaximum");
346  if (find(ebDigiParamList.begin(), ebDigiParamList.end(), bofm) != ebDigiParamList.end()) { //bofm found
347  binOfMax = result.getParameter<int>("binOfMaximum");
348  rc = true;
349  } else {
350  rc = false;
351  }
352  return rc;
353 }
354 
356  const EBSrFlagCollection& ebSrFlags,
357  const EESrFlagCollection& eeSrFlags,
358  int iEvent,
359  bool withHeader) {
360  const char srpFlagMarker[] = {'.', 'z', 'Z', 'F', '4', '5', '6', '7'};
361  if (withHeader) {
362  time_t t;
363  time(&t);
364  const char* date = ctime(&t);
365  os << "#SRP flag map\n#\n"
366  "# Generatied on: "
367  << date
368  << "\n#\n"
369  "# +-->Phi/Y "
370  << srpFlagMarker[0]
371  << ": suppressed\n"
372  "# | "
373  << srpFlagMarker[1]
374  << ": ZS 1\n"
375  "# | "
376  << srpFlagMarker[2]
377  << ": ZS 2\n"
378  "# V Eta/X "
379  << srpFlagMarker[3]
380  << ": full readout\n"
381  "#\n";
382  }
383 
384  //EE-,EB,EE+ map wil be written onto file in following format:
385  //
386  // 72
387  // <-------------->
388  // 20
389  // <--->
390  // EEE A +-----> Y
391  // EEEEE | |
392  // EE EE | 20 EE- |
393  // EEEEE | |
394  // EEE V V X
395  // BBBBBBBBBBBBBBBBB A
396  // BBBBBBBBBBBBBBBBB | +-----> Phi
397  // BBBBBBBBBBBBBBBBB | |
398  // BBBBBBBBBBBBBBBBB | 34 EB |
399  // BBBBBBBBBBBBBBBBB | |
400  // BBBBBBBBBBBBBBBBB | V Eta
401  // BBBBBBBBBBBBBBBBB |
402  // BBBBBBBBBBBBBBBBB |
403  // BBBBBBBBBBBBBBBBB V
404  // EEE A +-----> Y
405  // EEEEE | |
406  // EE EE | 20 EE+ |
407  // EEEEE | |
408  // EEE V V X
409  //
410  //
411  //
412  //
413  //event header:
414  if (iEvent >= 0) {
415  os << "# Event " << iEvent << "\n";
416  }
417 
418  //retrieve flags:
419  const int nEndcaps = 2;
420  const int nScX = 20;
421  const int nScY = 20;
422  int eeSrf[nEndcaps][nScX][nScY];
423  for (size_t i = 0; i < sizeof(eeSrf) / sizeof(int); ((int*)eeSrf)[i++] = -1) {
424  };
425  for (EESrFlagCollection::const_iterator it = eeSrFlags.begin(); it != eeSrFlags.end(); ++it) {
426  const EESrFlag& flag = *it;
427  int iZ0 = flag.id().zside() > 0 ? 1 : 0;
428  int iX0 = flag.id().ix() - 1;
429  int iY0 = flag.id().iy() - 1;
430  assert(iZ0 >= 0 && iZ0 < nEndcaps);
431  assert(iX0 >= 0 && iX0 < nScX);
432  assert(iY0 >= 0 && iY0 < nScY);
433  eeSrf[iZ0][iX0][iY0] = flag.value();
434  }
435  const int nEbTtEta = 34;
436  const int nEeTtEta = 11;
437  const int nTtEta = nEeTtEta * 2 + nEbTtEta;
438  const int nTtPhi = 72;
439  int ebSrf[nEbTtEta][nTtPhi];
440  for (size_t i = 0; i < sizeof(ebSrf) / sizeof(int); ((int*)ebSrf)[i++] = -1) {
441  };
442  for (EBSrFlagCollection::const_iterator it = ebSrFlags.begin(); it != ebSrFlags.end(); ++it) {
443  const EBSrFlag& flag = *it;
444  int iEta = flag.id().ieta();
445  int iEta0 = iEta + nTtEta / 2 - (iEta >= 0 ? 1 : 0); //0->55 from eta=-3 to eta=3
446  int iEbEta0 = iEta0 - nEeTtEta; //0->33 from eta=-1.48 to eta=1.48
447  int iPhi0 = flag.id().iphi() - 1;
448  assert(iEbEta0 >= 0 && iEbEta0 < nEbTtEta);
449  assert(iPhi0 >= 0 && iPhi0 < nTtPhi);
450 
451  // cout << __FILE__ << ":" << __LINE__ << ": "
452  // << iEta << "\t" << flag.id().iphi() << " -> "
453  // << iEbEta0 << "\t" << iPhi0
454  // << "... Flag: " << flag.value() << "\n";
455 
456  ebSrf[iEbEta0][iPhi0] = flag.value();
457  }
458 
459  //print flags:
460 
461  //EE-
462  for (int iX0 = 0; iX0 < nScX; ++iX0) {
463  for (int iY0 = 0; iY0 < nScY; ++iY0) {
464  int srFlag = eeSrf[0][iX0][iY0];
465  assert(srFlag >= -1 && srFlag < (int)(sizeof(srpFlagMarker) / sizeof(srpFlagMarker[0])));
466  os << (srFlag == -1 ? ' ' : srpFlagMarker[srFlag]);
467  }
468  os << "\n"; //one Y supercystal column per line
469  } //next supercrystal X-index
470 
471  //EB
472  for (int iEta0 = 0; iEta0 < nEbTtEta; ++iEta0) {
473  for (int iPhi0 = 0; iPhi0 < nTtPhi; ++iPhi0) {
474  int srFlag = ebSrf[iEta0][iPhi0];
475  assert(srFlag >= -1 && srFlag < (int)(sizeof(srpFlagMarker) / sizeof(srpFlagMarker[0])));
476  os << (srFlag == -1 ? '?' : srpFlagMarker[srFlag]);
477  }
478  os << "\n"; //one phi per line
479  }
480 
481  //EE+
482  for (int iX0 = 0; iX0 < nScX; ++iX0) {
483  for (int iY0 = 0; iY0 < nScY; ++iY0) {
484  int srFlag = eeSrf[1][iX0][iY0];
485  assert(srFlag >= -1 && srFlag < (int)(sizeof(srpFlagMarker) / sizeof(srpFlagMarker[0])));
486  os << (srFlag == -1 ? ' ' : srpFlagMarker[srFlag]);
487  }
488  os << "\n"; //one Y supercystal column per line
489  } //next supercrystal X-index
490 
491  //event trailer:
492  os << "\n";
493 }
494 
496  if (settings.dccNormalizedWeights_.size() != 1) {
497  throw cms::Exception("Configuration")
498  << "Selective readout emulator, EcalSelectiveReadout, supports only single set of ZS weights. "
499  "while the configuration contains "
500  << settings.dccNormalizedWeights_.size() << " set(s)\n";
501  }
502 
503  // if(settings.dccNormalizedWeights_.size() != 1
504  // && settings.dccNormalizedWeights_.size() != 2
505  // && settings.dccNormalizedWeights_.size() != 54
506  // && settings.dccNormalizedWeights_.size() != 75848){
507  // throw cms::Exception("Configuration") << "Invalid number of DCC weight set (" << settings.dccNormalizedWeights_.size()
508  // << ") in condition object EcalSRSetting::dccNormalizedWeights_. "
509  // << "Valid counts are: 1 (single set), 2 (EB and EE), 54 (one per DCC) and 75848 "
510  // "(one per crystal)\n";
511  // }
512 
513  if (settings.dccNormalizedWeights_.size() != settings.ecalDccZs1stSample_.size()) {
514  throw cms::Exception("Configuration")
515  << "Inconsistency between number of weigth sets (" << settings.dccNormalizedWeights_.size() << ") and "
516  << "number of ecalDccZs1Sample values (" << settings.ecalDccZs1stSample_.size() << ").";
517  }
518 }
void setGeometry(const CaloGeometry *caloGeometry)
void setSettings(const EcalSRSettings *settings)
edm::ESGetToken< EcalSRSettings, EcalSRSettingsRcd > hSr_token_
void printHeader(std::ostream &os) const
print out header for the map: see print(std::ostream&)
ProductID id() const
Definition: HandleBase.cc:29
int ieta() const
get the tower ieta
const EBDigiCollection * getEBDigis(edm::Event &event)
void checkTriggerMap(const edm::EventSetup &eventSetup)
EcalSelectiveReadout * getEcalSelectiveReadout()
edm::ESGetToken< EcalTrigTowerConstituentsMap, IdealGeometryRecord > eTTmap_token_
static void importParameterSet(EcalSRSettings &sr, const edm::ParameterSet &ps)
void checkGeometry(const edm::EventSetup &eventSetup)
const EcalTrigTowerDetId & id() const
T const * product() const
Definition: Handle.h:70
void produce(edm::Event &event, const edm::EventSetup &eventSetup) override
std::vector< T >::const_iterator const_iterator
std::vector< std::vector< float > > dccNormalizedWeights_
const char tccFlagMarker[]
Definition: GenABIO.cc:164
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:11
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > geom_token_
edm::EDGetTokenT< EBDigiCollection > EB_token
void setTriggerMap(const EcalTrigTowerConstituentsMap *map)
edm::ESGetToken< EcalElectronicsMapping, EcalMappingRcd > eElecmap_token_
void checkElecMap(const edm::EventSetup &eventSetup)
void run(const edm::EventSetup &eventSetup, const EcalTrigPrimDigiCollection &trigPrims, EBDigiCollection &barrelDigis, EEDigiCollection &endcapDigis)
int iEvent
Definition: GenABIO.cc:224
T const * product() const
Definition: ESHandle.h:86
const EcalTrigTowerConstituentsMap * theTriggerTowerMap
std::vector< int > ecalDccZs1stSample_
const EEDigiCollection * getEEDigis(edm::Event &event)
void checkWeights(const edm::Event &evt, const edm::ProductID &noZSDigiId) const
const EcalElectronicsMapping * theElecMap
const_iterator begin() const
bool getBinOfMax(const edm::Event &evt, const edm::ProductID &noZsDigiId, int &binOfMax) const
const_iterator end() const
static const int nEndcaps
Definition: GenABIO.cc:115
const EcalTrigPrimDigiCollection * getTrigPrims(edm::Event &event) const
std::unique_ptr< EcalSRSettings > settingsFromFile_
void printTTFlags(const EcalTrigPrimDigiCollection &tp, std::ostream &os) const
static const size_t nTriggerTowersInEta
static const size_t nTriggerTowersInPhi
void print(std::ostream &os) const
print out the map
edm::EDGetTokenT< EcalTrigPrimDigiCollection > EcTP_token
edm::EDGetTokenT< EEDigiCollection > EE_token
int ttFlag() const
get the Trigger tower Flag of interesting sample
static void printSrFlags(std::ostream &os, const EBSrFlagCollection &ebSrFlags, const EESrFlagCollection &eeSrFlags, int iEvent=-1, bool withHeader=true)
void setElecMap(const EcalElectronicsMapping *map)
EcalSelectiveReadoutProducer(const edm::ParameterSet &params)
Log< level::Warning, false > LogWarning
int iphi() const
get the tower iphi
void printTTFlags(std::ostream &os, int iEvent=-1, bool withHeader=true) const
static void checkValidity(const EcalSRSettings &settings)
EcalSelectiveReadoutSuppressor suppressor_
ProcessHistory const & processHistory() const override
Definition: Event.cc:250
def move(src, dest)
Definition: eostools.py:511
StableProvenance const & getStableProvenance(BranchID const &theID) const
Definition: Event.cc:124
const char srpFlagMarker[]
Definition: GenABIO.cc:163
Definition: event.py:1