HGCal Test Beam  03a93d6239a951948e06fb3ef8dae4cbdebfad30
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
HGCSimDigiSource.cc
Go to the documentation of this file.
1 // -------------------------------------------------------------------------
2 // Description: convert output of standalone simulator to TB 2016 test beam
3 // data format: SKIROC2DataFrames
4 // Created April 2016 Harrison B. Prosper
5 // Updated: 04-23-2016 HBP use HGCCellMap to get mapping from (u, v) to
6 // (skiroc, channel id)
7 // 05-03-2016 HBP add noise code
8 // -------------------------------------------------------------------------
9 #include <iostream>
10 #include <algorithm>
11 #include "FWCore/Framework/interface/InputSourceMacros.h"
12 #include "HGCal/TBStandaloneSimulator/plugins/HGCSimDigiSource.h"
13 #include "HGCal/DataFormats/interface/HGCalTBDetId.h"
14 // -------------------------------------------------------------------------
15 using namespace std;
16 
17 namespace
18 {
19 const size_t debugCount = 1;
20 };
21 
23 (const edm::ParameterSet& pset, edm::InputSourceDescription const& desc)
24  : edm::ProducerSourceFromFiles(pset, desc, true),
25  _run(pset.getUntrackedParameter<int>("runNumber", 101)),
26  _maxevents(pset.getUntrackedParameter<int>("maxEvents", -1)),
27  _minadccount(pset.getUntrackedParameter<int>("minADCCount", 1)),
28  _adcpermev(pset.getUntrackedParameter<double>("ADCperMeV", 200)),
29  _filenames(pset.getUntrackedParameter<vector<string> >
30  ("fileNames")),
31  _noisefilenames(pset.getUntrackedParameter<vector<string> >
32  ("noiseFileNames")),
33  _chain(0), // chain of files
34  _tree(0), // sim tree
35  _entries(0), // number of simulated events
36  _entry(0), // entry number,
37  _cellmap(HGCCellMap()), // cell id to (u, v) map and (x, y) to (u, v)
38  _simhits(0),
39 
40  _noisechain(0), // chain of files
41  _noisetree(0), // sim tree
42  _noiseentries(0), // number of simulated events
43  _noiseentry(0), // entry number
44  _random(TRandom3()),
45  _noise(vector<map<uint32_t, uint16_t> >())
46 {
47  // collections to be saved
48  produces<SKIROC2DigiCollection>();
49  produces<HGCSSSimHitVec>();
50 
51  // ------------------------------------------------------
52  // create a chain of files
53  // ------------------------------------------------------
54  _chain = new TChain("HGCSSTree");
55  if ( !_chain )
56  throw cms::Exception("ChainCreationFailed", "chain: HGCSSTree");
57 
58  for(size_t c = 0; c < _filenames.size(); c++)
59  _chain->Add(_filenames[c].c_str());
60 
61  // determine number of events to read
62  _entries = _chain->GetEntries();
63  _entries = _maxevents < 0
64  ? _entries
65  : (_entries < (size_t)_maxevents ? _entries : _maxevents);
66  cout << endl
67  << "==> Number of simulated events to read: "
68  << _entries
69  << endl;
70 
71  // map input tree to sim object pointers
72  _tree = (TTree*)_chain;
73  _tree->SetBranchAddress("HGCSSSimHitVec", &_simhits);
74 
75  // ------------------------------------------------------
76  // read in noise mode
77  // ------------------------------------------------------
78  if ( _noisefilenames.size() > (size_t)0 ) {
79  _noisechain = new TChain("Pedestals");
80  if ( !_noisechain )
81  throw cms::Exception("ChainCreationFailed",
82  "chain: Pedestals");
83 
84  for(size_t c = 0; c < _noisefilenames.size(); c++)
85  _noisechain->Add(_noisefilenames[c].c_str());
86 
87  // determine number of noise events to read
88  _noiseentries = _noisechain->GetEntries();
89 
90  // map input tree to object pointers
91  vector<uint32_t>* vkey = 0;
92  vector<uint16_t>* vadc = 0;
93  _noisetree = (TTree*)_noisechain;
94  _noisetree->SetBranchAddress("vkey", &vkey);
95  _noisetree->SetBranchAddress("vadc", &vadc);
96 
97  cout << "==> Creating noise model from file with "
98  << _noiseentries
99  << " pedestal events"
100  << endl;
101 
102  int N = 0;
103  double a1 = 0.0;
104  double a2 = 0.0;
105  for(size_t entry = 0; entry < _noiseentries; entry++) {
106  long localentry = _noisechain->LoadTree(entry);
107  _noisetree->GetEntry(localentry);
108  _noise.push_back(map<uint32_t, uint16_t>());
109  if ( entry % 500 == 0 )
110  cout << entry << "\t" << vkey->size() << endl;
111 
112  for(size_t c = 0; c < vkey->size(); c++) {
113  long key = (*vkey)[c];
114  uint16_t adc = (*vadc)[c];
115  _noise[entry][key] = adc;
116  a1 += adc;
117  a2 += adc * adc;
118  N++;
119  }
120  }
121  a1 /= N;
122  a2 /= N;
123  a2 = sqrt(a2 - a1 * a1);
124  char rec[256];
125  sprintf(rec, "==> pedestal = %8.1f +/-%-8.1f", a1, a2);
126  cout << rec << endl;
127  cout << "==> Done loading noise model"
128  << endl;
129  } else {
130  cout << "==> No noise will be added"
131  << _noiseentries
132  << endl;
133  }
134 }
135 
137 {
138  if ( _chain ) delete _chain;
139  if ( _noisechain ) delete _noisechain;
140 }
141 
142 bool HGCSimDigiSource::
143 setRunAndEventInfo(edm::EventID& id,
144  edm::TimeValue_t& time,
145  edm::EventAuxiliary::ExperimentType&)
146 {
147  if ( !_chain )
148  throw cms::Exception("ChainNotFound")
149  << "sim file chain not open";
150 
151  if ( _entry >= _entries ) return false;
152 
153  // load sim objects into memory
154  long localentry = _chain->LoadTree(_entry);
155  _tree->GetEntry(localentry);
156  _entry++;
157 
158  // construct event info
159  id = edm::EventID(_run, 1, _entry);
160 
161  // FIXME: time hack
162  edm::TimeValue_t present_time = presentTime();
163  unsigned long time_between_events = timeBetweenEvents();
164  time = present_time + time_between_events;
165 
166  return true;
167 }
168 
169 void HGCSimDigiSource::produce(edm::Event& event)
170 {
171  if ( _entry < debugCount ) {
172  cout << endl
173  << "==> entry number: " << _entry
174  << endl;
175  }
176 
177  // auto_ptr own objects they point to and are
178  // automatically deleted when out of scope
179 
180  // add sim hits to event
181  std::auto_ptr<HGCSSSimHitVec> simhits(new HGCSSSimHitVec());
182  for(size_t c = 0; c < _simhits->size(); c++)
183  simhits->push_back((*_simhits)[c]);
184  event.put(simhits);
185 
186  // create skiroc digi objects and put in event
187  std::auto_ptr<SKIROC2DigiCollection>
188  digis(new SKIROC2DigiCollection(SKIROC::MAXSAMPLES));
189 
190  // sum energies of sim hits in each cell
191  // and convert cell energies from MeV to ADC count
192  vector<HGCSimDigiSource::Cell> channels;
193  digitize(channels);
194 
195  // store digitized data
196  if ( _entry < debugCount ) {
197  cout << " number of digi hits: " << channels.size() << endl;
198  }
199 
200  for(size_t c = 0; c < channels.size(); c++) {
201  HGCSimDigiSource::Cell& cell = channels[c];
202  digis->addDataFrame(cell.detid);
203  digis->backDataFrame().setSample(0,
204  cell.ADClow,
205  cell.ADChigh,
206  cell.TDC);
207  if ( _entry < debugCount ) {
208  char record[80];
209  sprintf(record,
210  "%6d (ski,chan)=(%2d,%2d)"
211  " (u,v)=(%2d,%2d), (x,y)=(%6.2f,%6.2f), ADC=(%d)",
212  (int)(c + 1),
213  cell.skiroc, cell.channel,
214  cell.u, cell.v, cell.x, cell.y, cell.ADChigh);
215  cout << record << endl;
216  assert(cell.channel > -1);
217  }
218  }
219  event.put(digis);
220 }
221 
222 void HGCSimDigiSource::digitize(std::vector<HGCSimDigiSource::Cell>& channels)
223 {
224  // Steps:
225  // 1. for each cell, sum sim hit energies
226  // 2. convert energies to adc counts
227  // 3. randomly select a pedestal event and add to current event
228  // 4. apply zero suppression
229  // 5. sort cells
230 
231  if ( _entry < debugCount ) {
232  cout << endl
233  << " number of sim hits: "
234  << _simhits->size() << endl;
235  }
236 
237  // 1. for each cell, sum sim hit energies
238  map<uint32_t, HGCSimDigiSource::Cell> hits;
239 
240  for(size_t c = 0; c < _simhits->size(); c++) {
241  HGCSSSimHit& simhit = (*_simhits)[c];
242  int cellid = simhit.cellid();
243  int layer = simhit.silayer() + 1;
244  // FIXME: hard code for now
245  int sensor_u = 0;
246  int sensor_v = 0;
247  pair<int, int> uv = _cellmap(cellid);
248  int u = uv.first;
249  int v = uv.second;
250  assert(u > -1000);
251 
252  int celltype = _cellmap.celltype(layer,
253  sensor_u, sensor_v,
254  u, v);
255 
256  HGCalTBDetId detid(layer, sensor_u, sensor_v, u, v, celltype);
257  uint32_t key = detid.rawId();
258 
259  if ( hits.find(key) == hits.end() ) {
260  // this is a new cell, so initialize its data structure
262  cell.ADClow = 0;
263  cell.ADChigh = 0;
264  cell.TDC = 0;
265  cell.energy = 0.0;
266  cell.layer = layer;
267  cell.sensor_u = sensor_u;
268  cell.sensor_v = sensor_v;
269  cell.u = u;
270  cell.v = v;
271 
272  pair<double, double> xy = _cellmap.uv2xy(cell.u,
273  cell.v);
274  cell.x = xy.first;
275  cell.y = xy.second;
276 
277  pair<int, int> eid = _cellmap.uv2eid(layer,
278  sensor_u,
279  sensor_v,
280  u, v);
281  cell.skiroc = eid.first;
282  cell.channel = eid.second;
283  cell.celltype = celltype;
284  cell.detid = detid;
285 
286  hits[key] = cell;
287  }
288 
289  // sum energy per cell
290  hits[key].energy += simhit.energy();
291  }
292 
293  // 2. convert cell energy to ADC counts
294  for(map<uint32_t, HGCSimDigiSource::Cell>::iterator it = hits.begin();
295  it != hits.end(); it++) {
296  uint32_t key = it->first;
297  double energy = hits[key].energy;
298  uint16_t adc = static_cast<uint16_t>(_adcpermev * energy);
299  hits[key].ADChigh = adc;
300  }
301 
302  // 3. add noise
303  // randomly select a pedestal event and add to current
304  // event, cell by cell
305  if ( _noisechain ) {
306  int index = _random.Integer(_noiseentries - 1);
307  map<uint32_t, uint16_t>& noise = _noise[index];
308  for(map<uint32_t, uint16_t>::iterator it = noise.begin();
309  it != noise.end(); it++) {
310  uint32_t key = it->first; // this is the rawId
311  uint16_t adc = it->second;
312  if ( hits.find(key) != hits.end() )
313  hits[key].ADChigh += adc;
314  else {
315  // this is a new cell with no signal count, only noise
316  HGCalTBDetId detid(key);
318  cell.ADClow = 0;
319  cell.ADChigh = adc;
320  cell.TDC = 0;
321  cell.energy = 0.0;
322  cell.layer = detid.layer();
323  cell.sensor_u = detid.sensorIU();
324  cell.sensor_v = detid.sensorIV();
325  cell.u = detid.iu();
326  cell.v = detid.iv();
327  cell.celltype = detid.cellType();
328  cell.detid = detid;
329 
330  pair<int, int> eid = _cellmap.uv2eid(cell.layer,
331  cell.sensor_u,
332  cell.sensor_v,
333  cell.u,
334  cell.v);
335  cell.skiroc = eid.first;
336  cell.channel = eid.second;
337 
338  pair<double, double> xy = _cellmap.uv2xy(cell.u, cell.v);
339  cell.x = xy.first;
340  cell.y = xy.second;
341 
342  hits[key] = cell;
343  }
344  }
345  }
346 
347  // 4. apply zero suppression
348  for(map<uint32_t, HGCSimDigiSource::Cell>::iterator it = hits.begin();
349  it != hits.end(); it++) {
350  long key = it->first;
351  HGCSimDigiSource::Cell& cell = hits[key];
352  // apply "zero" suppression
353  if ( cell.ADChigh < _minadccount ) continue;
354  channels.push_back(cell);
355  }
356 
357  // 5. sort so that SKIROC 2 comes before SKIROC 1
358  // and channels increase monotonically
359  sort(channels.begin(), channels.end());
360 }
361 
363 (edm::ConfigurationDescriptions& descriptions)
364 {
365  edm::ParameterSetDescription desc;
366  desc.setComment("Test Beam 2016");
367  desc.addUntracked<int>("runNumber", 101);
368  desc.addUntracked<int>("maxEvents", -1);
369  desc.addUntracked<int>("minADCCount", 1);
370  desc.addUntracked<double>("ADCperMeV", 200);
371  desc.addUntracked<std::vector<std::string> >("fileNames");
372  desc.addUntracked<std::vector<std::string> >("noiseFileNames");
373  descriptions.add("source", desc);
374 }
375 
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
HGCSimDigiSource(const edm::ParameterSet &pset, edm::InputSourceDescription const &desc)
virtual ~HGCSimDigiSource()
DEFINE_FWK_INPUT_SOURCE(HGCalTBTextSource)
HGCalDataFrameContainer< SKIROC2DataFrame > SKIROC2DigiCollection