9 #include "art/Framework/Core/EDProducer.h"
10 #include "art/Framework/Principal/Event.h"
12 #include "WireCellIface/IAnodePlane.h"
13 #include "WireCellIface/IFrame.h"
14 #include "WireCellIface/ITrace.h"
15 #include "WireCellUtil/NamedFactory.h"
29 using namespace WireCell;
33 FrameSaver::~FrameSaver() {}
35 WireCell::Configuration
39 cfg[
"anode"] =
"AnodePlane";
43 cfg[
"digitize"] =
false;
63 cfg[
"pedestal_mean"] = 0.0;
66 cfg[
"pedestal_sigma"] = 0.0;
69 cfg[
"frame_tags"] = Json::arrayValue;
70 cfg[
"frame_scale"] = 1.0;
79 cfg[
"summary_tags"] = Json::arrayValue;
80 cfg[
"summary_scale"] = 1.0;
89 cfg[
"summary_operator"] = Json::objectValue;
92 cfg[
"chanmaskmaps"] = Json::arrayValue;
100 return std::accumulate(tsvals.begin(), tsvals.end(), 0);
105 if (tsvals.empty()) {
return 0.0; }
106 return tsvals.back();
112 const std::string anode_tn = cfg[
"anode"].asString();
113 if (anode_tn.empty()) { THROW(ValueError() << errmsg{
"FrameSaver requires an anode plane"}); }
115 WireCell::IAnodePlane::pointer anode = Factory::find_tn<IAnodePlane>(anode_tn);
116 for (
auto chid : anode->channels()) {
118 auto wpid = anode->resolve(chid);
128 view = (
geo::View_t) (cfg[
"plane_map"][wct_layer].asInt());
134 m_sparse =
get(cfg,
"sparse",
true);
136 m_cmms = cfg[
"chanmaskmaps"];
141 if (!cfg[
"frame_scale"].isNull()) {
143 auto jscale = cfg[
"frame_scale"];
145 auto jtags = cfg[
"frame_tags"];
146 for (
auto jtag : jtags) {
147 std::string tag = jtag.asString();
153 if (!jscale.isNull()) {
154 if (jscale.isArray()) { scale = jscale[ind].asDouble(); }
156 scale = jscale.asDouble();
166 auto jso = cfg[
"summary_operator"];
168 if (!cfg[
"summary_tags"].isNull()) {
170 auto jscale = cfg[
"summary_scale"];
172 auto jtags = cfg[
"summary_tags"];
173 for (
auto jtag : jtags) {
174 std::string tag = jtag.asString();
178 if (!jscale.isNull()) {
179 if (jscale.isArray()) { scale = jscale[ind].asDouble(); }
181 scale = jscale.asDouble();
187 auto so = get<std::string>(jso, tag,
"sum");
201 std::cerr <<
"wclsFrameSaver: promising to produce recob::Wires named \"" << tag <<
"\"\n";
202 collector.produces<std::vector<recob::Wire>>(tag);
205 std::cerr <<
"wclsFrameSaver: promising to produce raw::RawDigits named \"" << tag <<
"\"\n";
206 collector.produces<std::vector<raw::RawDigit>>(tag);
210 std::cerr <<
"wclsFrameSaver: promising to produce channel summary named \"" << tag <<
"\"\n";
211 collector.produces<std::vector<double>>(tag);
214 const std::string cmm_name = cmm.asString();
215 std::cerr <<
"wclsFrameSaver: promising to produce channel masks named \"" << cmm_name
217 collector.produces<
channel_list>(cmm_name +
"channels");
225 auto const& all_traces = frame->traces();
226 const auto& ttinds = frame->tagged_traces(tag);
228 for (
size_t index : ttinds) {
229 ret.push_back(all_traces->at(index));
233 auto ftags = frame->frame_tags();
234 if (std::find(ftags.begin(), ftags.end(), tag) == ftags.end()) {
return; }
235 ret.insert(ret.begin(), all_traces->begin(), all_traces->end());
242 for (
auto trace : traces) {
243 int chid =
trace->channel();
244 ret[chid].push_back(
trace);
253 PU(Json::Value pu) : pu(pu) {}
258 if (pu.isNumeric()) {
return pu.asFloat(); }
259 if (pu.asString() ==
"fiction") {
260 art::ServiceHandle<lariov::DetPedestalService const> dps;
261 const auto&
pv = dps->GetPedestalProvider();
262 return pv.PedMean(chid);
272 if (nticks_want < 0) {
274 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event);
275 nticks_want =
detProp.NumberTimeSamples();
279 for (
size_t iftag = 0; iftag < nftags; ++iftag) {
281 std::cerr <<
"wclsFrameSaver: saving raw::RawDigits tagged \"" << ftag <<
"\"\n";
290 std::unique_ptr<std::vector<raw::RawDigit>> out(
new std::vector<raw::RawDigit>);
293 const int chid = chv.first;
294 const auto& traces = bychan[chid];
295 const size_t ntraces = traces.size();
298 std::vector<float> charge;
300 auto trace = traces[0];
301 tbin =
trace->tbin();
302 charge =
trace->charge();
307 size_t ncharge = charge.size();
308 int nticks = tbin + ncharge;
310 if (nticks_want < nticks) { ncharge = nticks_want - tbin; }
311 nticks = nticks_want;
314 for (
size_t ind = 0; ind < ncharge; ++ind) {
315 adcv[tbin + ind] = scale * charge[ind];
319 short baseline = Waveform::most_frequent(adcv);
327 event.put(std::move(out), ftag);
335 if (nticks_want < 0) {
337 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event);
338 nticks_want =
detProp.NumberTimeSamples();
339 std::cerr <<
"wclsFrameSaver saving cooked to " << nticks_want <<
" ticks\n";
343 for (
size_t iftag = 0; iftag < nftags; ++iftag) {
350 if (traces.empty()) {
351 std::cerr <<
"wclsFrameSaver: no traces tagged \"" << ftag <<
"\"\n";
355 std::cerr <<
"wclsFrameSaver: saving " << traces.size() <<
" traces tagged \"" << ftag
362 std::unique_ptr<std::vector<recob::Wire>> outwires(
new std::vector<recob::Wire>);
364 double total_charge = 0.0;
365 int total_samples = 0;
368 const int chid = chv.first;
369 const auto& traces = bychan[chid];
373 for (
const auto&
trace : traces) {
374 const int tbin =
trace->tbin();
375 const auto& charge =
trace->charge();
377 auto beg = charge.begin();
378 const auto first = beg;
379 auto end = charge.end();
381 if (tbin >= nticks_want) { beg =
end; }
383 int backup = tbin + charge.size() - nticks_want;
384 if (backup > 0) {
end -= backup; }
388 std::cerr <<
"wclsFrameSaver: no samples within desired window for channel " << chid
393 std::vector<float> scaled(beg,
end);
394 for (
size_t i = 0; i < scaled.size(); ++i)
397 rois.
add_range(tbin, scaled.begin(), scaled.end());
403 beg = std::find_if(beg,
end, [](
float v) {
return v != 0.0; });
404 if (beg ==
end) {
break; }
405 auto mid = std::find_if(beg,
end, [](
float v) {
return v == 0.0; });
406 std::vector<float> scaled(beg, mid);
407 for (
int ind = 0; ind < mid - beg; ++ind) {
408 scaled[ind] *= scale;
409 total_charge += scaled[ind];
418 outwires->emplace_back(
recob::Wire(rois, chid, view));
420 std::cerr <<
"FrameSaver: q=" << total_charge <<
" n=" << total_samples <<
" tag=" << ftag
422 event.put(std::move(outwires), ftag);
434 const size_t nchans =
m_chview.size();
437 for (
int tag_ind = 0; tag_ind < ntags; ++tag_ind) {
441 std::unique_ptr<std::vector<double>> outsum(
new std::vector<double>(nchans, 0.0));
449 const auto& summary =
m_frame->trace_summary(tag);
452 const size_t ntraces = traces.size();
454 std::unordered_map<int, std::vector<float>> bychan;
455 for (
size_t itrace = 0; itrace < ntraces; ++itrace) {
456 const int chid = traces[itrace]->channel();
457 const double summary_value = summary[itrace];
458 bychan[chid].push_back(summary_value);
464 const int chid = chv.first;
465 const float val = oper(bychan[chid]);
466 outsum->at(chanind) = val * scale;
469 event.put(std::move(outsum), tag);
476 if (
m_cmms.isNull()) {
return; }
479 <<
"wclsFrameSaver: wrong type for configuration array of channel mask maps to save\n";
482 for (
auto jcmm :
m_cmms) {
483 std::string
name = jcmm.asString();
484 std::unique_ptr<channel_list> out_list(
new channel_list);
488 auto it = cmm.find(name);
489 if (it == cmm.end()) {
490 std::cerr <<
"wclsFrameSaver: failed to find requested channel masks \"" << name <<
"\"\n";
493 for (
auto cmit : it->second) {
494 out_list->push_back(cmit.first);
495 for (
auto be : cmit.second) {
496 out_masks->push_back(cmit.first);
497 out_masks->push_back(be.first);
498 out_masks->push_back(be.second);
502 if (out_list->empty()) {
503 std::cerr <<
"wclsFrameSaver: found empty channel masks for \"" << name <<
"\"\n";
505 event.put(std::move(out_list), name +
"channels");
506 event.put(std::move(out_masks), name +
"masks");
514 std::cerr <<
"wclsFrameSaver: saving empty frame to art::Event\n";
518 std::unique_ptr<std::vector<raw::RawDigit>> out(
new std::vector<raw::RawDigit>);
519 event.put(std::move(out), ftag);
522 std::unique_ptr<std::vector<recob::Wire>> outwires(
new std::vector<recob::Wire>);
523 event.put(std::move(outwires), ftag);
528 std::unique_ptr<std::vector<double>> outsum(
new std::vector<double>);
529 event.put(std::move(outsum), stag);
532 for (
auto jcmm :
m_cmms) {
533 std::string
name = jcmm.asString();
534 std::unique_ptr<channel_list> out_list(
new channel_list);
536 event.put(std::move(out_list), name +
"channels");
537 event.put(std::move(out_masks), name +
"masks");
563 WireCell::IFrame::pointer& outframe)
570 <<
"wclsFrameSaver: warning: dropping prior frame. Fixme to handle queue of frames.\n";
std::map< int, geo::View_t > m_chview
std::vector< int > channel_masks
Collection of charge vs time digitized from a single readout channel.
BEGIN_PROLOG could also be cerr
float operator()(int chid)
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
virtual WireCell::Configuration default_configuration() const
IConfigurable.
void save_cmms(art::Event &event)
virtual bool operator()(const WireCell::IFrame::pointer &inframe, WireCell::IFrame::pointer &outframe)
IFrameFilter.
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
void save_empty(art::Event &event)
Definition of basic raw digits.
virtual void visit(art::Event &event)
Implement to visit an Art event.
static void tagged_traces(IFrame::pointer frame, std::string tag, ITrace::vector &ret)
std::vector< std::string > m_summary_tags
static float summary_set(const std::vector< float > &tsvals)
M::value_type trace(const M &m)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void save_as_cooked(art::Event &event)
static float summary_sum(const std::vector< float > &tsvals)
virtual void configure(const WireCell::Configuration &config)
std::vector< std::string > m_frame_tags
process_name WireCellLarsoft wclsFrameSaver
auto end(FixedBins< T, C > const &) noexcept
Json::Value m_pedestal_mean
std::unordered_map< int, ITrace::vector > traces_bychan_t
WIRECELL_FACTORY(wclsChannelNoiseDB, wcls::ChannelNoiseDB, wcls::IArtEventVisitor, WireCell::IChannelNoiseDatabase) using namespace WireCell
void save_as_raw(art::Event &event)
std::vector< double > m_summary_scale
WireCell::IFrame::pointer m_frame
static void traces_bychan(ITrace::vector &traces, traces_bychan_t &ret)
std::unordered_map< std::string, summarizer_function > m_summary_operators
std::vector< double > m_frame_scale
std::string to_string(WindowPattern const &pattern)
std::vector< int > channel_list
Class holding the regions of interest of signal from a channel.
Declaration of basic channel signal object.
virtual void produces(art::ProducesCollector &collector)
IArtEventVisitor.
Planes which measure W (third view for Bo, MicroBooNE, etc).
void save_summaries(art::Event &event)