344 log->debug(
"MagnifySink: EOS");
347 if (frame->traces()->empty()) {
348 log->debug(
"MagnifySink: passing through empty frame ID {}", frame->ident());
354 log->debug(
"MagnifySink: opening for output: {} with mode {}", ofname, mode);
355 TFile* output_tf = TFile::Open(ofname.c_str(), mode.c_str());
359 auto trace_tag =
tag;
360 auto trace_has_tag =
m_cfg[
"trace_has_tag"].asBool();
363 log->debug(
"MagnifySink: set desired trace tag to \"\" as cfg::trace_has_tag=false");
367 if (traces.empty()) {
368 log->warn(
"MagnifySink: no tagged traces for \"{}\"",
tag);
372 log->debug(
"MagnifySink: tag: \"{}\" with {} traces",
tag, traces.size());
376 Binning tbin = binnings[3];
377 for (
int iplane=0; iplane < 3; ++iplane) {
378 if (traces_byplane[iplane].
empty())
continue;
380 Binning cbin = binnings[iplane];
381 std::stringstream ss;
383 <<
" cbin:"<<cbin.nbins()<<
"["<<cbin.min() <<
"," << cbin.max() <<
"]" 384 <<
" tbin:"<<tbin.nbins()<<
"["<<tbin.min() <<
"," << tbin.max() <<
"]";
385 log->debug(ss.str());
390 TH2F*
hist =
new TH2F(name.c_str(), name.c_str(),
391 cbin.nbins(), cbin.min(), cbin.max(),
392 nbins, tbin.min(), tbin.max());
394 hist->SetDirectory(output_tf);
396 for (
auto trace : traces_byplane[iplane]) {
397 const int tbin1 =
trace->tbin();
398 const int ch =
trace->channel();
399 auto const& charges =
trace->charge();
400 for (
size_t itick=0; itick < charges.size(); ++itick) {
409 int ibin = (tbin1-tbin.min()+itick)/
m_nrebin;
411 hist->SetBinContent(cbin.bin(ch)+1, ibin+1,
412 charges[itick]+hist->GetBinContent(cbin.bin(ch)+1, ibin+1));
424 if (traces.empty()) {
425 log->warn(
"MagnifySink: no traces tagged with \"{}\", skipping summary",
tag);
428 auto const&
summary = frame->trace_summary(
tag);
430 log->warn(
"MagnifySink: warning: empty summary tagged with \"{}\", skipping summary",
tag);
436 log->debug(
"MagnifySink: saving summaries tagged with \"{}\" into per-plane hists", tag);
441 const int ntot = traces.size();
442 std::vector<int> perplane_channels[3];
443 std::vector<double> perplane_values[3];
444 for (
int ind=0; ind<
ntot; ++ind) {
445 const int chid = traces[ind]->channel();
446 const int iplane =
m_anode->resolve(chid).index();
447 perplane_channels[iplane].push_back(chid);
448 perplane_values[iplane].push_back(
summary[ind]);
450 for (
int iplane=0; iplane<3; ++iplane) {
451 std::vector<int>& chans = perplane_channels[iplane];
452 std::vector<double>& vals = perplane_values[iplane];
453 if (!chans.empty()) {
454 auto mme = std::minmax_element(chans.begin(), chans.end());
455 const int ch0 = *mme.first;
456 const int chf = *mme.second;
457 const std::string hname = Form(
"h%c_%s",
'u'+iplane, tag.c_str());
458 TH1F* hist =
new TH1F(hname.c_str(), hname.c_str(),
459 chf-ch0+1, ch0, chf);
460 for (
size_t ind=0; ind<chans.size(); ++ind) {
461 const int x = chans[ind]+0.5;
462 const double val = vals[ind];
464 int bin = hist->FindBin(x);
465 hist->SetBinContent(bin, val);
471 hist->SetDirectory(output_tf);
478 std::unordered_map<std::string, std::string> cmmkey2treename;
479 for (
auto jcmmtree : m_cfg[
"cmmtree"]) {
480 cmmkey2treename[jcmmtree[0].asString()] = jcmmtree[1].asString();
484 for (
auto const& it: input_cmm) {
485 auto cmmkey = it.first;
486 auto ct = cmmkey2treename.find(cmmkey);
487 if (ct == cmmkey2treename.end()) {
488 log->warn(
"MagnifySink: warning: found channel mask \"{}\", but no tree configured to accept it",
493 auto treename = ct->second;
495 log->debug(
"MagnifySink: saving channel mask \"{}\" to tree \"{}\"",
498 TTree *tree =
new TTree(treename.c_str(), treename.c_str());
499 int chid=0, plane=0, start_time=0, end_time=0;
500 tree->Branch(
"chid",&chid,
"chid/I");
501 tree->Branch(
"plane",&plane,
"plane/I");
502 tree->Branch(
"start_time",&start_time,
"start_time/I");
503 tree->Branch(
"end_time",&end_time,
"end_time/I");
504 tree->SetDirectory(output_tf);
506 for (
auto const &chmask : it.second){
508 plane =
m_anode->resolve(chid).index();
509 auto mask = chmask.second;
510 for (
size_t ind = 0; ind <
mask.size(); ++ind){
511 start_time =
mask[ind].first;
512 end_time =
mask[ind].second;
522 auto count = output_tf->Write();
523 log->debug(
"MagnifySink: closing output file {}, wrote {} bytes", ofname, count);
std::vector< WireCell::Binning > collate_byplane(const ITrace::vector &traces, const IAnodePlane::pointer anode, ITrace::vector byplane[])
IAnodePlane::pointer m_anode
std::vector< pointer > vector
QTextStream & bin(QTextStream &s)
string_set_t getset(const WireCell::Configuration &cfg)
void do_shunt(TFile *output_tf)
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.