/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*
*/
#include "Utils/CppErrorHandler.hh"
#include "Utils/JsonWrapper.hh"
#include "Interface/dataCards.hh"
#include "DataStructure/MCEvent.hh"
#include "DataStructure/Spill.hh"
#include "API/PyWrapMapBase.hh"
#include "Converter/DataConverters/CppJsonSpillConverter.hh"
#include "Converter/DataConverters/JsonCppSpillConverter.hh"
#include "src/map/MapCppEMRMCDigitization/MapCppEMRMCDigitization.hh"
namespace MAUS {
PyMODINIT_FUNC init_MapCppEMRMCDigitization(void) {
PyWrapMapBase::PyWrapMapBaseModInit
("MapCppEMRMCDigitization", "", "", "", "");
}
MapCppEMRMCDigitization::MapCppEMRMCDigitization()
: MapBase("MapCppEMRMCDigitization") {
}
void MapCppEMRMCDigitization::_birth(const std::string& argJsonConfigDocument) {
_classname = "MapCppEMRMCDigitization";
char* pMAUS_ROOT_DIR = getenv("MAUS_ROOT_DIR");
if (!pMAUS_ROOT_DIR) {
throw MAUS::Exception(Exception::recoverable,
"Could not resolve ${MAUS_ROOT_DIR} environment variable",
"MapCppEMRMCDigitization::birth");
}
// JsonCpp setup
Json::Value configJSON;
configJSON = JsonWrapper::StringToJson(argJsonConfigDocument);
// Fetch variables
_number_of_planes = configJSON["EMRnumberOfPlanes"].asInt();
_number_of_bars = configJSON["EMRnumberOfBars"].asInt();
_tot_noise_up = configJSON["EMRtotNoiseUp"].asInt();
_tot_noise_low = configJSON["EMRtotNoiseLow"].asInt();
_do_sampling = configJSON["EMRdoSampling"].asInt();
_nph_per_MeV = configJSON["EMRnphPerMeV"].asInt();
_seed = configJSON["EMRseed"].asInt();
_trap_eff = configJSON["EMRtrapEff"].asDouble();
_QE_MAPMT = configJSON["EMRqeMAPMT"].asDouble();
_QE_SAPMT = configJSON["EMRqeSAPMT"].asDouble();
_nADC_per_pe_MAPMT = configJSON["EMRnadcPerPeMAPMT"].asDouble();
_nADC_per_pe_SAPMT = configJSON["EMRnadcPerPeSAPMT"].asDouble();
_electronics_response_spread_MAPMT = configJSON["EMRelectronicsResponseSpreadMAPMT"].asDouble();
_electronics_response_spread_SAPMT = configJSON["EMRelectronicsResponseSpreadSAPMT"].asDouble();
_dbb_count = configJSON["EMRdbbCount"].asDouble();
_fadc_count = configJSON["EMRfadcCount"].asDouble();
_time_response_spread = configJSON["EMRtimeResponseSpread"].asInt();
_tot_func_p1 = configJSON["EMRtotFuncP1"].asDouble();
_tot_func_p2 = configJSON["EMRtotFuncP2"].asDouble();
_tot_func_p3 = configJSON["EMRtotFuncP3"].asDouble();
_tot_func_p4 = configJSON["EMRtotFuncP4"].asDouble();
_acquisition_window = configJSON["EMRacquisitionWindow"].asInt();
_signal_integration_window = configJSON["EMRsignalIntegrationWindow"].asInt();
_arrival_time_shift = configJSON["EMRarrivalTimeShift"].asInt();
_arrival_time_gaus_width = configJSON["EMRarrivalTimeGausWidth"].asDouble();
_arrival_time_uniform_width = configJSON["EMRarrivalTimeUniformWidth"].asDouble();
_pulse_shape_landau_width = configJSON["EMRpulseShapeLandauWidth"].asDouble();
_fom = configJSON["EMRfom"].asString();
_birks_constant = configJSON["EMRbirksConstant"].asDouble();
_average_path_length = configJSON["EMRaveragePathLength"].asDouble();
_signal_energy_threshold = configJSON["EMRsignalEnergyThreshold"].asDouble();
_baseline_spread = configJSON["EMRbaselineSpread"].asInt();
_maximum_noise_level = configJSON["EMRmaximumNoiseLevel"].asInt();
_deltat_shift = configJSON["EMRdeltatShift"].asDouble();
_baseline_position = configJSON["EMRbaselinePosition"].asDouble();
_arrival_time_spread = configJSON["EMRarrivalTimeSpread"].asDouble();
// Generate random noise in each SAPMT
_rand = new TRandom3(_seed);
for (int iPlane = 0; iPlane < _number_of_planes; iPlane++) {
_baseline[iPlane] = _baseline_position
+ static_cast(_rand->Uniform(-_baseline_spread, _baseline_spread));
_noise_level[iPlane] = static_cast(_rand->Uniform(0, _maximum_noise_level));
_noise_position[iPlane] = static_cast(_rand->Uniform(0, 1.9999999));
}
// Load the EMR calibration map
bool loaded = _calibMap.InitializeFromCards(configJSON);
if (!loaded)
throw(Exception(Exception::recoverable,
"Could not find EMR calibration map",
"MapCppEMRMCDigitizer::birth"));
// Load the EMR attenuation map
loaded = _attenMap.InitializeFromCards(configJSON);
if (!loaded)
throw(Exception(Exception::recoverable,
"Could not find EMR attenuation map",
"MapCppEMRMCDigitizer::birth"));
}
void MapCppEMRMCDigitization::_death() {
}
void MapCppEMRMCDigitization::_process(Data *data) const {
// Get spill, break if there's no DAQ data
Spill *spill = data->GetSpill();
if (spill->GetMCEvents() == NULL)
return;
int nPartEvents = spill->GetMCEventSize();
// Check the Recon event array is initialised, and if not make it so
if (!spill->GetReconEvents()) {
ReconEventPArray* revts = new ReconEventPArray();
spill->SetReconEvents(revts);
}
// Set primary hits/noise time windows
std::vector delta_t_array;
delta_t_array.resize(0);
for (int iPe = 0; iPe < nPartEvents; iPe++) {
EMRHitArray *hits = spill->GetAnMCEvent(iPe).GetEMRHits();
if (hits) {
int nHits = hits->size();
Primary *primary = spill->GetAnMCEvent(iPe).GetPrimary();
double pTime = primary->GetTime(); // ns
for (int iHit = 0; iHit < nHits; iHit++) {
EMRHit hit = hits->at(iHit);
int time = static_cast(hit.GetTime()); // ns
double delta_t = time - pTime;
delta_t_array.push_back(delta_t);
}
}
}
// Break if there's no EMR data
if (!delta_t_array.size())
return;
int lt = static_cast(*std::min_element(delta_t_array.begin(), delta_t_array.end())
/_dbb_count);
int deltat_limits[4] = {lt, lt+20, lt+20, lt+40};
// Create the DBB and fADC arrays with n events (1 per trigger)
EMRDBBEventVector emr_dbb_events_tmp = get_dbb_data_tmp(nPartEvents);
EMRfADCEventVector emr_fadc_events_tmp = get_fadc_data_tmp(nPartEvents);
// Fill the Recon event array with G4 Spill information
for (int iPe = 0; iPe < nPartEvents; iPe++) {
EMRHitArray *EMRhits = spill->GetAnMCEvent(iPe).GetEMRHits();
if (EMRhits) {
Primary *primary = spill->GetAnMCEvent(iPe).GetPrimary();
double pTime = primary->GetTime(); // ns
processDBB(EMRhits, iPe, pTime, emr_dbb_events_tmp, emr_fadc_events_tmp);
processFADC(EMRhits, iPe, emr_fadc_events_tmp);
}
}
fill(spill, nPartEvents, emr_dbb_events_tmp, emr_fadc_events_tmp);
// Reset/Resize DBB and fADC arrays with n+2 events (1 per trigger + noise + decays)
emr_dbb_events_tmp = get_dbb_data_tmp(nPartEvents+2);
emr_fadc_events_tmp = get_fadc_data_tmp(nPartEvents+2);
// Digitize the Recon event array
for (int iPe = 0; iPe < nPartEvents; iPe++) {
EMREvent *EMRevt = spill->GetReconEvents()->at(iPe)->GetEMREvent();
if (EMRevt) {
digitize(EMRevt, iPe, nPartEvents, deltat_limits, emr_dbb_events_tmp, emr_fadc_events_tmp);
}
}
fill(spill, nPartEvents+2, emr_dbb_events_tmp, emr_fadc_events_tmp);
}
void MapCppEMRMCDigitization::processDBB(MAUS::EMRHitArray *EMRhits,
int xPe,
double pTime,
EMRDBBEventVector& emr_dbb_events_tmp,
EMRfADCEventVector& emr_fadc_events_tmp) const {
int nHits = EMRhits->size();
for (int iHit = 0; iHit < nHits; iHit++) {
EMRHit hit = EMRhits->at(iHit);
// Channel ID
EMRChannelId *id = hit.GetChannelId();
int g4barid = id->GetBar();
int planeid = g4barid / 59;
int barid = g4barid % 59 + 1;
// Energy Deposition
double edep = hit.GetEnergyDeposited(); /*MeV*/
// Position
ThreeVector pos = hit.GetPosition();
double pozx = pos.x(); /*mm*/
double pozy = pos.y(); /*mm*/
double pozz = pos.z(); /*mm*/
// Time
double time = hit.GetTime(); /*ns*/
int lt = static_cast(time);/*ns*/
int tot = static_cast(edep*1000000);/*eV*/
int xPlane = planeid;
int xBar = barid;
int delta_t = lt-pTime;
// Fill EMRDBBEvent
EMRBarHit bHit;
bHit.SetX(pozx);
bHit.SetY(pozy);
bHit.SetZ(pozz);
bHit.SetTot(tot);
bHit.SetHitTime(lt);
bHit.SetDeltaT(delta_t);
emr_dbb_events_tmp[xPe][xPlane][xBar].push_back(bHit);
}
}
void MapCppEMRMCDigitization::processFADC(MAUS::EMRHitArray *EMRhits,
int xPe,
EMRfADCEventVector& emr_fadc_events_tmp) const {
int nHits = EMRhits->size();
for (int iHit = 0; iHit < nHits; iHit++) {
EMRHit hit = EMRhits->at(iHit);
// Plane ID
EMRChannelId *id = hit.GetChannelId();
int g4barid = id->GetBar();
int planeid = g4barid / 59;
// Energy Deposition
double edep = hit.GetEnergyDeposited(); /*MeV*/
double xCharge = edep*1000000;/*eV*/
int xPlane = planeid;
xCharge += emr_fadc_events_tmp[xPe][xPlane]._charge;
fADCdata data;
data._orientation = planeid % 2;
data._charge = xCharge;
data._time = 0;
emr_fadc_events_tmp[xPe][xPlane] = data;
}
}
void MapCppEMRMCDigitization::digitize(MAUS::EMREvent *EMRevt,
int xPe,
int nPartEvents,
int *deltat_limits,
EMRDBBEventVector& emr_dbb_events_tmp,
EMRfADCEventVector& emr_fadc_events_tmp) const {
int nPlHits = EMRevt->GetEMRPlaneHitArray().size();
for (int iPlane = 0; iPlane < nPlHits; iPlane++) {
EMRPlaneHit *plHit = EMRevt->GetEMRPlaneHitArray().at(iPlane);
int xPlane = plHit->GetPlane();
// Find PMT gain correction coefficient
EMRChannelKey xAverageKey(xPlane, xPlane%2, -1, "emr");
double epsilon_MA = _calibMap.Eps(xAverageKey, "MA");
double epsilon_SA = _calibMap.Eps(xAverageKey, "SA");
int nBars = plHit->GetEMRBarArray().size();
int naph_SAPMT = 0;
for (int iBar = 0; iBar < nBars; iBar++) {
EMRBar *bar = plHit->GetEMRBarArray().at(iBar);
int xBar = bar->GetBar();
int nBarHits = bar->GetEMRBarHitArray().size();
bool matched = false;
for (int iBarHit = 0; iBarHit < nBarHits; iBarHit++) {
EMRBarHit barHit = bar->GetEMRBarHitArray().at(iBarHit);
EMRChannelKey xKey(xPlane, xPlane%2, xBar, "emr");
double x = barHit.GetX();/*mm*/
double y = barHit.GetY();/*mm*/
int xTot = barHit.GetTot();/*eV*/
int xDeltaT = barHit.GetDeltaT();/*ns*/
int xHitTime = barHit.GetHitTime();/*ns*/
/*--------- MAPMT signal simulation -------*/
// simulate electronics noise and PMT dark current
// !!! TO DO !!!
// set g4 information
double energy = xTot/1000000.0;/*MeV*/
int time = xDeltaT;/*ns*/
if (energy < _signal_energy_threshold) continue;
// convert energy to the number of scintillation photons (nsph) according to Birks's law
// !!! TO DO !!! calculate path length
int nsph = static_cast(static_cast(_nph_per_MeV*energy) // MeV
/(1.0+_birks_constant // mm/MeV
/_average_path_length*energy)); // MeV
// sample nsph with Poisson
if (_do_sampling) nsph = _rand->Poisson(nsph);
// covert nsph to the number of trapped photons (ntph)
int ntph = static_cast(static_cast(nsph*_trap_eff));
// sample ntph with Poisson
if (_do_sampling) ntph = _rand->Poisson(ntph);
// reduce ntph according to fibre length (naph)
// for MAPMT
int naph_MAPMT = static_cast(static_cast(ntph)
/2.0*_attenMap.fibreAtten(xKey, x, y, "MA"));
// for SAPMT
int naph_SAPMT_hit = static_cast(static_cast(ntph)
/2.0*_attenMap.fibreAtten(xKey, x, y, "SA"));
// apply channel attenuation map
// for MAPMT
naph_MAPMT = static_cast(static_cast(naph_MAPMT)
*_attenMap.connectorAtten(xKey, "MA"));
// for SAPMT
naph_SAPMT_hit = static_cast(static_cast(naph_SAPMT_hit)
*_attenMap.connectorAtten(xKey, "SA"));
if (time > deltat_limits[0] && time < deltat_limits[1]) naph_SAPMT += naph_SAPMT_hit;
// sample naph with Poisson
if (_do_sampling) naph_MAPMT = _rand->Poisson(naph_MAPMT);
// simulate cross-talk and misalignment
// !!! TO DO !!!
// convert naph to the number of photoelectrons (npe)
int npe = static_cast(static_cast(naph_MAPMT)*_QE_MAPMT);
// sample npe with Poisson
if (_do_sampling) npe = _rand->Poisson(npe);
// correct npe for the photocathode non-uniformity
// !!! TO DO !!!
// correct npe for pmt gain difference
npe = static_cast(static_cast(npe)*epsilon_MA);
if (npe == 0) continue;
// convert npe to the number of ADC counts
int nADC = static_cast(static_cast(npe)*_nADC_per_pe_MAPMT);
if (nADC == 0) continue;
// simulate electronics response
if (_do_sampling) nADC = static_cast(_rand->Gaus(nADC, _electronics_response_spread_MAPMT));
// convert nADC to Tot
int xTotDigi = static_cast(_tot_func_p1+_tot_func_p2
*log(static_cast(nADC)
/_tot_func_p4+_tot_func_p3));
if (xTotDigi <= 0) continue;
// convert g4 time to deltaT time in ADC counts
int xDeltaTDigi = static_cast(static_cast(time)/_dbb_count);
// sample deltaT
if (_do_sampling) xDeltaTDigi = static_cast(_rand->Gaus(xDeltaTDigi,
_time_response_spread));
if (xDeltaTDigi < 0) xDeltaTDigi = 0;
// correct deltaT with fibre length
xDeltaTDigi += static_cast(static_cast(_attenMap.fibreDelay(xKey, x, y, "MA"))
/_dbb_count);
// set hit time
int xHitTimeDigi = static_cast(static_cast(xHitTime)/_dbb_count);
// set bar hit
EMRBarHit bHit;
bHit.SetTot(xTotDigi);
bHit.SetDeltaT(xDeltaTDigi);
bHit.SetHitTime(xHitTimeDigi);
// discriminate noise and decays from signal events
if (xDeltaTDigi >= deltat_limits[0] && xDeltaTDigi < deltat_limits[1]) {
emr_dbb_events_tmp[xPe][xPlane][xBar].push_back(bHit);
matched = true;
} else if (xDeltaTDigi >= deltat_limits[2] && xDeltaTDigi < deltat_limits[3] &&
xTotDigi > _tot_noise_low && xTotDigi < _tot_noise_up ) {
emr_dbb_events_tmp[nPartEvents][xPlane][xBar].push_back(bHit);
matched = true;
} else if (iBarHit == nBarHits-1 && !matched) {
bHit.SetDeltaT(0);
emr_dbb_events_tmp[nPartEvents+1][xPlane][xBar].push_back(bHit);
}
}
}
int xOri = plHit->GetOrientation();
/*------------ SAPMT signal simulation -------*/
// simulate PMT dark current
// !!! TO DO !!!
// sample naph with Poisson
if (_do_sampling) naph_SAPMT = _rand->Poisson(naph_SAPMT);
// convert naph to the number of photoelectrons (npe)
int npe = static_cast(static_cast(naph_SAPMT)*_QE_SAPMT);
// sample npe with Poisson
if (_do_sampling) npe = _rand->Poisson(npe);
// correct npe for pmt gain difference
npe = static_cast(static_cast(npe)*epsilon_SA);
// convert npe to the number of ADC counts
int nADC = static_cast(static_cast(npe)*_nADC_per_pe_SAPMT);
// simulate electronics response
if (_do_sampling) nADC = static_cast(_rand->Gaus(nADC,
_electronics_response_spread_SAPMT));
// correct non physical values
if (nADC < 0) nADC = 0;
// set signal baseline (8bit ADC)
int baseline = _baseline[xPlane];
// set electronics noise level - number of fluctuations within acquisition window
int noise_level = _noise_level[xPlane];
// set electronics noise position (upwards/downwards fluctuations)
int noise_position = _noise_position[xPlane];
// simulate negative voltage pulse with random electronics noise
TH1F *pulse_shape = new TH1F("pulse_shape", "pulse_shape",
_acquisition_window, 0, _acquisition_window);
double arrival_time = _signal_integration_window*2 + _arrival_time_shift;
if (static_cast(_rand->Uniform(0, 1.9999999))) arrival_time += _arrival_time_spread;
arrival_time += _rand->Gaus(0, _arrival_time_gaus_width)
+_rand->Uniform(-_arrival_time_uniform_width, _arrival_time_uniform_width);
for (int i = 0; i < noise_level; i++) {
double noise = _rand->Uniform(0, _acquisition_window);
int bin = static_cast(noise+1);
if (pulse_shape->GetBinContent(bin) != 1) pulse_shape->Fill(noise);
}
if (noise_position) for (Int_t i = 1; i <= _acquisition_window; i++) {
pulse_shape->SetBinContent(i, -pulse_shape->GetBinContent(i));}
for (int i = 0; i < nADC; i++) {
pulse_shape->Fill(_rand->Landau(arrival_time, _pulse_shape_landau_width));}
for (int i = 1; i <= _acquisition_window; i++) {
pulse_shape->SetBinContent(i, baseline-pulse_shape->GetBinContent(i));}
double pedestal_baseline = pulse_shape->Integral(1, _signal_integration_window)
/static_cast(_signal_integration_window);
double pedestal_area = pedestal_baseline*static_cast(_signal_integration_window)
- pulse_shape->Integral(_signal_integration_window+1,
_signal_integration_window*2);
double signal_area = pedestal_baseline*static_cast(_signal_integration_window)
- pulse_shape->Integral(arrival_time-10+1,
arrival_time+_signal_integration_window-10);
// set pulse area
double xAreaDigi = signal_area;
// correct non physical values
if (nADC == 0) xAreaDigi = 0;
if (xAreaDigi < 0) xAreaDigi = 0;
// set pedestal area
double xPedestalAreaDigi = pedestal_area;
// set hit arrival time
int xArrivalTimeDigi = arrival_time;
// simulate time delay in cables
// !!! TO DO !!!
// set pulse shape
std::vector xSamplesDigi;
for (Int_t i = 1; i <= _acquisition_window; i++) {
xSamplesDigi.push_back(pulse_shape->GetBinContent(i));}
fADCdata data;
data._orientation = xOri;
data._charge = xAreaDigi;/*ADC*/
data._pedestal_area = xPedestalAreaDigi;/*ADC*/
data._time = xArrivalTimeDigi;/*ADC*/
data._samples = xSamplesDigi;/*#*/
emr_fadc_events_tmp[xPe][xPlane] = data;
delete pulse_shape;
}
}
void MapCppEMRMCDigitization::fill(MAUS::Spill *spill,
int nPartEvents,
EMRDBBEventVector emr_dbb_events_tmp,
EMRfADCEventVector emr_fadc_events_tmp) const {
int recPartEvents = spill->GetReconEventSize();
ReconEventPArray *recEvts = spill->GetReconEvents();
int xSpill = spill->GetSpillNumber();
// Resize the recon event to harbour all the EMR noise+decays
while (recPartEvents < nPartEvents) {
recEvts->push_back(new ReconEvent);
recPartEvents++;
}
// Fill it with DBB and fADC arrays
for (int iPe = 0; iPe < nPartEvents; iPe++) {
EMREvent *evt = new EMREvent;
EMRPlaneHitArray plArray;
for (int iPlane = 0; iPlane < _number_of_planes; iPlane++) {
int xOri = emr_fadc_events_tmp[iPe][iPlane]._orientation;
double xCharge = emr_fadc_events_tmp[iPe][iPlane]._charge;
int xPos = emr_fadc_events_tmp[iPe][iPlane]._time;
double xPedestalArea = emr_fadc_events_tmp[iPe][iPlane]._pedestal_area;
std::vector xSamples = emr_fadc_events_tmp[iPe][iPlane]._samples;
EMRPlaneHit *plHit = new EMRPlaneHit;
plHit->SetPlane(iPlane);
plHit->SetTrigger(iPe);
plHit->SetRun(0);
plHit->SetOrientation(xOri);
plHit->SetCharge(xCharge);
plHit->SetDeltaT(xPos);
plHit->SetSpill(xSpill);
plHit->SetPedestalArea(xPedestalArea);
plHit->SetSamples(xSamples);
EMRBarArray barArray;
for (int iBar = 0; iBar < _number_of_bars; iBar++) {
int nHits = emr_dbb_events_tmp[iPe][iPlane][iBar].size();
if (nHits) {
EMRBar *bar = new EMRBar;
bar->SetBar(iBar);
bar->SetEMRBarHitArray(emr_dbb_events_tmp[iPe][iPlane][iBar]);
barArray.push_back(bar);
}
}
plHit->SetEMRBarArray(barArray);
if (barArray.size() || xCharge) {
plArray.push_back(plHit);
}
}
if (iPe < 1) {evt->SetInitialTrigger(true);
} else {evt->SetInitialTrigger(false);}
evt->SetEMRPlaneHitArray(plArray);
recEvts->at(iPe)->SetEMREvent(evt);
recEvts->at(iPe)->SetPartEventNumber(iPe);
}
spill->SetReconEvents(recEvts);
}
EMRDBBEventVector MapCppEMRMCDigitization::get_dbb_data_tmp(int nPartEvts) const {
EMRDBBEventVector emr_dbb_events_tmp;
emr_dbb_events_tmp.resize(nPartEvts);
for (int iPe = 0; iPe < nPartEvts; iPe++) {
emr_dbb_events_tmp[iPe].resize(_number_of_planes); // number of planes
for (int iPlane = 0; iPlane < _number_of_planes; iPlane++) {
emr_dbb_events_tmp[iPe][iPlane].resize(_number_of_bars); // number of bars in a plane
}
}
return emr_dbb_events_tmp;
}
EMRfADCEventVector MapCppEMRMCDigitization::get_fadc_data_tmp(int nPartEvts) const {
EMRfADCEventVector emr_fadc_events_tmp;
emr_fadc_events_tmp.resize(nPartEvts);
for (int iPe = 0; iPe < nPartEvts ;iPe++) {
emr_fadc_events_tmp[iPe].resize(_number_of_planes);
for (int iPlane = 0; iPlane < _number_of_planes; iPlane++) {
fADCdata data;
data._orientation = iPlane%2;
data._charge = 0.0;
data._pedestal_area = 0.0;
data._time = 0;
std::vector xSamples;
data._samples = xSamples;
emr_fadc_events_tmp[iPe][iPlane] = data;
}
}
return emr_fadc_events_tmp;
}
} // Namespace MAUS