Jpp 20.0.0-27-g39925593c-D
the software that should make you happy
Loading...
Searching...
No Matches
Functions
JTriggerEfficiency.cc File Reference

Auxiliary program to trigger Monte Carlo events. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include "TH1D.h"
#include "TRandom3.h"
#include "km3net-dataformat/offline/Head.hh"
#include "km3net-dataformat/offline/MultiHead.hh"
#include "km3net-dataformat/offline/Evt.hh"
#include "km3net-dataformat/offline/Hit.hh"
#include "km3net-dataformat/definitions/pmt_status.hh"
#include "JDAQ/JDAQTimesliceIO.hh"
#include "JDAQ/JDAQEventIO.hh"
#include "JDAQ/JDAQSummarysliceIO.hh"
#include "JDAQ/JDAQToolkit.hh"
#include "JTimeslice/JEventTimeslice.hh"
#include "JSummaryslice/JSummaryslice.hh"
#include "JAAnet/JHead.hh"
#include "JAAnet/JHeadToolkit.hh"
#include "JAAnet/JAAnetToolkit.hh"
#include "JPhysics/JK40Rates.hh"
#include "JDetector/JDetector.hh"
#include "JDetector/JDetectorToolkit.hh"
#include "JDetector/JDetectorSimulator.hh"
#include "JDetector/JModuleMapper.hh"
#include "JDetector/JPMTRouter.hh"
#include "JDetector/JTimeRange.hh"
#include "JDetector/JPMTParametersMap.hh"
#include "JDetector/JK40DefaultSimulator.hh"
#include "JDetector/JPMTDefaultSimulator.hh"
#include "JDetector/JCLBDefaultSimulator.hh"
#include "JTrigger/JHit.hh"
#include "JTrigger/JHitToolkit.hh"
#include "JTrigger/JTimeslice.hh"
#include "JTrigger/JSuperFrame1D.hh"
#include "JTrigger/JSuperFrame2D.hh"
#include "JTrigger/JHitL0.hh"
#include "JTrigger/JHitL1.hh"
#include "JTrigger/JBuildL1.hh"
#include "JTrigger/JBuildL2.hh"
#include "JTrigger/JTrigger3DShower.hh"
#include "JTrigger/JTriggerMXShower.hh"
#include "JTrigger/JTrigger3DMuon.hh"
#include "JTrigger/JTriggerBits.hh"
#include "JTrigger/JEventOverlap.hh"
#include "JTrigger/JTimesliceRouter.hh"
#include "JTrigger/JTriggeredEvent.hh"
#include "JTrigger/JTimesliceL1.hh"
#include "JTrigger/JTriggerParameters.hh"
#include "JTrigger/JEventToolkit.hh"
#include "JTrigger/JSummaryRouter.hh"
#include "JTrigger/JTriggerToolkit.hh"
#include "JTrigger/JK40RunByRunSimulator.hh"
#include "JTrigger/JPMTRunByRunSimulator.hh"
#include "JTrigger/JCLBRunByRunSimulator.hh"
#include "JSupport/JMultipleFileScanner.hh"
#include "JSupport/JTreeScanner.hh"
#include "JSupport/JFileRecorder.hh"
#include "JSupport/JMonteCarloFileSupportkit.hh"
#include "JSupport/JTriggerParametersSupportkit.hh"
#include "JSupport/JSupportToolkit.hh"
#include "JSupport/JSupport.hh"
#include "JSupport/JMeta.hh"
#include "JROOT/JRandom.hh"
#include "Jeep/JPrint.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Auxiliary program to trigger Monte Carlo events.

The options

The event counter of the triggered events, as returned by KM3NETDAQ::JDAQEvent::getCounter(), is set to the corresponding index of the Monte Carlo event in the output.
This allows for correlating the DAQ event to the Monte Carlo event.
The time of the DAQ hits can be correlated to the time of the Monte Carlo hits using the frame index and the time of the Monte Carlo event (Evt::mc_t), respectively (see also time_converter).
The universal time of the DAQ event is set to the universal time of the Monte Carlo event with a correction for the time of the event (read hits) within the time slice.
In run-by-run mode, the trigger parameters as well as the singles rates and status of the PMTs are read from the given raw data file.
The two-fold (and higher) coincidence rates should still be provided on the command line.

Author
mdejong

Definition in file JTriggerEfficiency.cc.

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 134 of file JTriggerEfficiency.cc.

135{
136 using namespace std;
137 using namespace JPP;
138 using namespace KM3NETDAQ;
139
141
144 JLimit_t& numberOfEvents = inputFile.getLimit();
145 string detectorFileA;
146 string detectorFileB;
147 int run;
148 JTriggerParameters parameters;
150 JPMTParametersMap pmtParameters;
151 JK40Rates rates_Hz;
152 string runbyrun;
153 double sigma_ns;
155 int debug;
156
157 try {
158
159 JParser<> zap("Auxiliary program to trigger Monte Carlo events.");
160
161 zap['f'] = make_field(inputFile, "input file (output of detector simulation)");
162 zap['o'] = make_field(outputFile, "output file") = "trigger_efficieny.root";
163 zap['n'] = make_field(numberOfEvents) = JLimit::max();
164 zap['a'] = make_field(detectorFileA, "detector used for conversion from Monte Carlo truth to raw data.");
165 zap['b'] = make_field(detectorFileB, "detector used for conversion of raw data to calibrated data.") = "";
166 zap['R'] = make_field(run, "run number") = -1;
167 zap['r'] = make_field(runbyrun, "DAQ file for run-by-run mode") = JPARSER::initialised();
168 zap['@'] = make_field(parameters, "Trigger parameters (or corresponding file name)") = JPARSER::initialised();
169 zap['O'] = make_field(triggeredEventsOnly, "optionally write only triggered events.");
170 zap['P'] = make_field(pmtParameters, "PMT simulation data (or corresponding file name)") = JPARSER::initialised();
171 zap['B'] = make_field(rates_Hz, "background rates [Hz]") = JPARSER::initialised();
172 zap['s'] = make_field(sigma_ns, "intrinsic time smearing of K40 coincidences [ns]") = JK40DefaultSimulatorInterface::getSigma();
173 zap['S'] = make_field(seed, "seed") = 0;
174 zap['d'] = make_field(debug, "debug") = 0;
175
176 zap(argc, argv);
177 }
178 catch(const exception &error) {
179 FATAL(error.what() << endl);
180 }
181
182 seed.set(gRandom);
183
185
187
188 if (detectorFileB == "") {
190 }
191
192
195
196 try {
199 }
200 catch(const JException& error) {
201 FATAL(error);
202 }
203
204 const double TA_ns = getT0(detectorA);
205 const double TB_ns = getT0(detectorB);
206
208
209 if (!pmtParameters.is_valid()) {
210 FATAL("Invalid PMT parameters " << pmtParameters << endl);
211 }
212
213 if (pmtParameters.getQE() != 1.0) {
214
215 WARNING("Correct background rates with global efficiency " << pmtParameters.getQE() << endl);
216
217 rates_Hz.correct(pmtParameters.getQE());
218 }
219
220 Head header;
221
222 try {
223 header = getHeader(inputFile);
224 }
225 catch(const JException& error) {
226 FATAL(error);
227 }
228
229 const JModuleRouter moduleRouter(detectorB);
232
234
235 set<int> fs; // frame indices of summary data already written
236
238
239 if (runbyrun != "") {
240
241 NOTICE("Using run-by-run: " << runbyrun << endl);
242
243 scanner.configure(runbyrun);
244
245 if (!scanner.empty()) {
246 UTC = scanner.begin()->getTimesliceStart();
247 } else {
248 FATAL("Run-by-run simulation misses summary data." << endl);
249 }
250
251 try {
252 simbad.reset(new JK40RunByRunSimulator(summaryRouter, rates_Hz));
253 simbad.reset(new JPMTRunByRunSimulator(summaryRouter, pmtParameters, detectorA));
255 }
256 catch(const JException& error) {
257 FATAL(error.what() << endl);
258 }
259
260 try {
261
262 parameters = getTriggerParameters(runbyrun);
263
264 NOTICE("Set trigger parameters from run-by-run input." << endl);
265 }
266 catch(const JException& error) {
267 WARNING("No trigger parameters from run-by-run input;\nrun with default/user input." << endl);
268 }
269
270 // set live time
271
272 JHead buffer(header);
273
274 buffer.DAQ.livetime_s = getTimeDuration(getUTCTimeRange(scanner));
275 buffer.push(&JHead::DAQ);
276
277 copy(buffer, header);
278
279 } else {
280
281 NOTICE("Using fixed rates [Hz]: " << rates_Hz << endl);
282
283 try {
284 simbad.reset(new JK40DefaultSimulator(rates_Hz));
285 simbad.reset(new JPMTDefaultSimulator(pmtParameters, detectorA));
286 simbad.reset(new JCLBDefaultSimulator());
287 }
288 catch(const JException& error) {
289 FATAL(error.what() << endl);
290 }
291 }
292
293 // detector
294
295 if (parameters.disableHighRateVeto) {
296
297 NOTICE("Disabling high-rate veto of all PMTs." << endl);
298
299 detectorB.setPMTStatus(HIGH_RATE_VETO_DISABLE);
300 }
301
302 parameters.set(getMaximalDistance(detectorB));
303
304 DEBUG("Trigger:" << endl << parameters << endl);
305 DEBUG("PMT parameters:" << endl << pmtParameters << endl);
306
307 const double Tmax = max(getMaximalTime(detectorA),
309
310 const JTimeRange period(-(Tmax + parameters.TMaxLocal_ns),
311 +(Tmax + parameters.TMaxLocal_ns));
312
313 const JTimeRange frame_time(0.0, getFrameTime());
314
315 typedef double hit_type;
316
317 typedef JSuperFrame1D<hit_type> JSuperFrame1D_t;
318 typedef JSuperFrame2D<hit_type> JSuperFrame2D_t;
319 typedef JTimeslice <hit_type> JTimeslice_t;
320 typedef JBuildL1 <hit_type> JBuildL1_t;
321 typedef JBuildL2 <hit_type> JBuildL2_t;
322
323 const JBuildL1_t buildL1(parameters);
324 const JBuildL2_t buildL2(parameters.L2);
325 const JBuildL2_t buildSN(parameters.SN);
326
327 JTimesliceRouter timesliceRouter(parameters.numberOfBins);
328
329 const JTrigger3DMuon trigger3DMuon (parameters);
330 const JTrigger3DShower trigger3DShower(parameters);
331 const JTriggerMXShower triggerMXShower(parameters, detectorB);
332
333
334 TH1D h1("Trigger bits", NULL, NUMBER_OF_TRIGGER_BITS, -0.5, NUMBER_OF_TRIGGER_BITS - 0.5);
335
336
337 outputFile.open();
338
339 if (!outputFile.is_open()) {
340 FATAL("Error opening file " << outputFile << endl);
341 }
342
343 outputFile.put(*gRandom);
344 outputFile.put(JMeta(argc, argv));
345 outputFile.put(header);
346 outputFile.put(parameters);
347
348 JHead head;
349 int trigger_counter = 0;
350
351 for (string file_name; inputFile.hasNext(); ) {
352
353 STATUS("event: " << setw(10) << inputFile.getCounter() << '\r'); DEBUG(endl);
354
355 Evt* event = inputFile.next();
356
357 DEBUG(*event << endl);
358
359 if (file_name != inputFile.getFilename()) {
360
361 file_name = inputFile.getFilename();
362 head = getHeader(file_name);
363 }
364
365 event->mc_run_id = head.start_run.run_id;
366
367 if (run == -1) {
368 run = event->mc_run_id;
369 }
370
371 bool trigger = false;
372 int frame_index = inputFile.getCounter() + 1; // event / slice
373 double t1 = gRandom->Rndm() * getFrameTime(); // time of event within time slice
374
375 JDAQUTCExtended utc(UTC.getTimeNanoSecond() + getTimeOfFrame(frame_index));
376
377 if (runbyrun != "") {
378
379 if (event->mc_event_time == TTimeStamp(0)) {
380 FATAL("Monte Carlo event time undefined." << endl);
381 }
382
383 utc = getDAQUTCExtended(event->mc_event_time);
384 t1 = getTimeDifference(summaryRouter.getTimesliceStart(), utc) * 1.0e9;
385
386 if (!frame_time(t1)) {
387
388 const Long64_t index = scanner.find(utc);
389 JDAQSummaryslice* p = scanner.getEntry(index);
390
391 if (getTimeDifference(p->getTimesliceStart(), utc) < 0.0 && index != 0) {
392 p = scanner.getEntry(index - 1);
393 }
394
395 summaryRouter.update(p);
396 summaryRouter.correct(dynamic_cast<const JPMTDefaultSimulatorInterface&>(simbad.getPMTSimulator()));
397 }
398
399 t1 = getTimeDifference(summaryRouter.getTimesliceStart(), utc) * 1.0e9;
400
401 run = summaryRouter.getRunNumber();
402 frame_index = summaryRouter.getFrameIndex();
403 utc = summaryRouter.getTimesliceStart();
404
405 DEBUG("event: "
406 << FIXED(15,3) << event->mc_event_time.AsDouble() << " [s] "
407 << utc << ' '
408 << FIXED(12,0) << t1 << " [ns] "
409 << frame_time(t1) << endl);
410 }
411
412 if (!event->mc_hits.empty() && frame_time(t1)) {
413
414 JTimeRange timeRange = getTimeRange(*event, period);
415
416 double t0 = 0.5 * (timeRange.getLowerLimit() + timeRange.getUpperLimit());
417
418 DEBUG("Start time: " << FIXED(12,2) << t0 << ' ' << FIXED(12,2) << t1 << ' ' << FIXED(9,2) << TA_ns << endl);
419
420 t1 += TA_ns; // add time offset of detector
421
422 event->mc_t = getTimeOfFrame(frame_index) + t1 - t0; // set to time since start of data taking run
423
424 timeRange.add(event->mc_t);
425 timeRange.add(period);
426
427 const JDAQChronometer chronometer(detectorB.getID(), run, frame_index, utc);
428
429 const JEventTimeslice timeslice(chronometer, simbad, *event, period);
430
431 DEBUG(timeslice << endl);
432
433
434 timesliceRouter.configure(timeslice);
435
436 JTimeslice_t timesliceL0(timeslice.getDAQChronometer());
437 JTimeslice_t timesliceL1(timeslice.getDAQChronometer());
438 JTimeslice_t timesliceL2(timeslice.getDAQChronometer());
439 JTimeslice_t timesliceSN(timeslice.getDAQChronometer());
440
441 for (JDAQTimeslice::const_iterator super_frame = timeslice.begin(); super_frame != timeslice.end(); ++super_frame) {
442
443 if (moduleRouter.hasModule(super_frame->getModuleID())) {
444
445 // calibration
446
447 const JModule& module = moduleRouter.getModule(super_frame->getModuleID());
448 const JSuperFrame2D_t& buffer = JSuperFrame2D_t::demultiplex(*super_frame, module);
449
450 // L0
451
452 timesliceL0.push_back(JSuperFrame1D_t(buffer));
453
454 DEBUG("L0 " << setw(8) << timesliceL0.rbegin()->getModuleID() << ' ' << setw(8) << timesliceL0.rbegin()->size() << endl);
455
456 // L1
457
458 timesliceL1.push_back(JSuperFrame1D_t(super_frame->getDAQChronometer(),
459 super_frame->getModuleIdentifier(),
460 module.getPosition()));
461
462 buildL1(*timesliceL0.rbegin(), back_inserter(*timesliceL1.rbegin()));
463
464 DEBUG("L1 " << setw(8) << timesliceL1.rbegin()->getModuleID() << ' ' << setw(8) << timesliceL1.rbegin()->size() << endl);
465
466 // L2
467
468 timesliceL2.push_back(JSuperFrame1D_t(super_frame->getDAQChronometer(),
469 super_frame->getModuleIdentifier(),
470 module.getPosition()));
471
472 buildL2(buffer, *timesliceL1.rbegin(), back_inserter(*timesliceL2.rbegin()));
473
474 DEBUG("L2 " << setw(8) << timesliceL2.rbegin()->getModuleID() << ' ' << setw(8) << timesliceL2.rbegin()->size() << endl);
475
476 // SN
477 {
478 JTimeslice_t::value_type tv(super_frame->getDAQChronometer(),
479 super_frame->getModuleIdentifier(),
480 module.getPosition());
481
482 buildSN(buffer, *timesliceL1.rbegin(), back_inserter(tv));
483
484 if (!tv.empty()) {
485
486 timesliceSN.push_back(tv);
487
488 DEBUG("SN " << setw(8) << timesliceSN.rbegin()->getModuleID() << ' ' << setw(8) << timesliceSN.rbegin()->size() << endl);
489 }
490 }
491 }
492 }
493
494
495 // Trigger
496
499
501 trigger3DShower(trigger_input, back_inserter(trigger_output));
503
504 trigger_output.merge(JEventOverlap(parameters.TMaxEvent_ns));
505
506 for (JTriggerOutput::const_iterator to = trigger_output.begin(); to != trigger_output.end(); ++to) {
507
508 for (int i = 0; i != h1.GetNbinsX(); ++i) {
509 if (to->hasTriggerBit(i)) {
510 h1.Fill((double) i);
511 }
512 }
513
514 JTimeRange eventTime = getTimeRange(*to).add(getTimeOfRTS(*to));
515
516 eventTime.add(TA_ns);
517 eventTime.sub(TB_ns);
518
519 if (debug >= status_t) {
520 cout << "Event time: "
521 << to->getFrameIndex() << ' '
522 << eventTime << ' '
523 << timeRange << ' '
524 << (timeRange.overlap(eventTime) ? "Y" : "N") << endl;
525 }
526
527 if (timeRange.overlap(eventTime)) {
528
530 timesliceRouter,
531 moduleRouter,
532 parameters.TMaxLocal_ns,
533 getTimeRange(parameters));
534
535 tev.setCounter(trigger_counter); // set the event counter to the index of the Monte Carlo event in the output.
536
537 outputFile.put(tev);
538
539 trigger = true;
540 }
541 }
542
543
545
546 if (parameters.writeL0()) {
547 outputFile.put(timeslice);
548 }
549
550 if (parameters.writeL1()) {
551 outputFile.put(JTimesliceL1<JDAQTimesliceL1>(timesliceL1, timesliceRouter, moduleRouter, parameters.TMaxLocal_ns));
552 }
553
554 if (parameters.writeL2()) {
555 outputFile.put(JTimesliceL1<JDAQTimesliceL2>(timesliceL2, timesliceRouter, moduleRouter, parameters.L2.TMaxLocal_ns));
556 }
557
558 if (parameters.writeSN()) {
559 outputFile.put(JTimesliceL1<JDAQTimesliceSN>(timesliceSN, timesliceRouter, moduleRouter, parameters.SN.TMaxLocal_ns));
560 }
561
562 if (parameters.writeSummary()) {
563
564 if (fs.count(chronometer.getFrameIndex()) == 0) {
565
567
568 fs.insert(chronometer.getFrameIndex());
569 }
570 }
571 }
572 }
573
575
576 outputFile.put(*event);
577
578 ++trigger_counter;
579 }
580 }
581 STATUS(endl);
582
583 {
585
586 io >> outputFile;
587 }
588
589 outputFile.put(h1);
590 outputFile.put(*gRandom);
591 outputFile.close();
592}
string outputFile
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define STATUS(A)
Definition JMessage.hh:63
#define NOTICE(A)
Definition JMessage.hh:64
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:72
#define WARNING(A)
Definition JMessage.hh:65
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
Monte Carlo run header.
Definition JHead.hh:1236
JAANET::DAQ DAQ
Definition JHead.hh:1625
Detector data structure.
Definition JDetector.hh:96
static double getSigma()
Get intrinsic time smearing of K40 coincidences.
static void setSigma(const double sigma)
Set intrinsic time smearing of K40 coincidences.
Default implementation of the simulation of K40 background.
Router for direct addressing of module data in detector data structure.
Data structure for a composite optical module.
Definition JModule.hh:76
Auxiliary class for map of PMT parameters.
double getQE(const JPMTIdentifier &id) const
Get QE of given PMT.
bool is_valid() const
Check validity of PMT parameters.
General exception.
Definition JException.hh:24
virtual const char * what() const override
Get error message.
Definition JException.hh:64
static void Throw(const bool option)
Enable/disable throw option.
Definition JThrow.hh:37
Template definition of a multi-dimensional oscillation probability interpolation table.
Router for fast addressing of summary data in KM3NETDAQ::JDAQSummaryslice data structure as a functio...
void insert(const JMultiFunction< __JFunction_t, __JMaplist_t, __JDistance_t > &input)
Insert multidimensional input.
bool overlap(const range_type &range) const
Test overlap with given range.
Definition JRange.hh:382
T getLowerLimit() const
Get lower limit.
Definition JRange.hh:202
range_type & add(argument_type x)
Add offset.
Definition JRange.hh:446
T getUpperLimit() const
Get upper limit.
Definition JRange.hh:213
CLB simulation based on run-by-run information.
K40 simulation based on run-by-run information.
PMT simulation based on run-by-run information.
Data structure for input to trigger algorithm.
Auxiliary class to build KM3NETDAQ::JDAQEvent for a triggered event.
JDAQUTCExtended getTimesliceStart() const
Get start of timeslice.
Data structure for UTC time.
static const JDAQUTCExtended & getInstance()
Get arbitrary offset (e.g.
JTimeRange getTimeRange(const Evt &event)
Get time range (i.e. time between earliest and latest hit) of Monte Carlo event.
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition JHead.cc:163
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
double getMaximalDistance(const JDetector &detector, const bool option=false)
Get maximal distance between modules in detector.
@ status_t
status
Definition JMessage.hh:30
@ debug_t
debug
Definition JMessage.hh:29
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
double getTimeDuration(const JDAQUTCTimeRange &utc)
Get time duration of given UTC time range.
JDAQUTCTimeRange getUTCTimeRange()
Get UTC time range.
JTriggerParameters getTriggerParameters(const JMultipleFileScanner_t &file_list)
Get trigger parameters.
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
KM3NeT DAQ data structures and auxiliaries.
Definition DataQueue.cc:39
double getFrameTime()
Get frame time duration.
Definition JDAQClock.hh:162
void setDAQLongprint(const bool option)
Set DAQ print option.
Definition JDAQPrint.hh:28
double getTimeOfFrame(const int frame_index)
Get start time of frame in ns since start of run for a given frame index.
Definition JDAQClock.hh:185
double getMaximalTime(const double R_Hz)
Get maximal time for given rate.
double getTimeDifference(const JDAQChronometer &first, const JDAQChronometer &second)
Get time difference between two chronometers.
JDAQUTCExtended getDAQUTCExtended(const TTimeStamp &t0, const double t1=0.0)
Get DAQ UTC time.
static const int HIGH_RATE_VETO_DISABLE
Enable (disable) use of high-rate veto test if this status bit is 0 (1);.
Definition pmt_status.hh:14
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition Evt.hh:21
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Definition Head.hh:65
Match of two events considering overlap in time and position.
Transmission with position.
Template definition of random value generator.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:68
Auxiliary class for K40 rates.
Definition JK40Rates.hh:41
void correct(const double QE)
Correct rates for global efficiency,.
Definition JK40Rates.hh:130
Auxiliary class for defining the range of iterations of objects.
Definition JLimit.hh:45
static counter_type max()
Get maximum counter value.
Definition JLimit.hh:128
Auxiliary class for ROOT I/O of application specific meta data.
Definition JMeta.hh:72
Router for fast addressing of hits in KM3NETDAQ::JDAQTimeslice data structure as a function of the op...
Timeslice with Monte Carlo event.
Auxiliary class to create summary data.