20 #include "canvas/Utilities/Exception.h"
21 #include "canvas/Persistency/Common/FindOneP.h"
22 #include "art/Framework/Principal/Event.h"
23 #include "art/Framework/Services/Registry/ServiceHandle.h"
35 template <
typename Left,
typename Right,
typename Metadata>
36 void ClearAssociations(art::Assns<Left, Right, Metadata>& assns) {
37 art::Assns<Left, Right, Metadata>
empty;
57 float sigma_peak_time,
59 float sigma_peak_amplitude,
61 float hit_sigma_integral,
63 short int multiplicity,
64 short int local_index,
65 float goodness_of_fit,
84 art::ServiceHandle<geo::Geometry
const>()->View(digits.Channel()),
85 art::ServiceHandle<geo::Geometry
const>()->SignalType(digits.Channel()),
99 float sigma_peak_time,
100 float peak_amplitude,
101 float sigma_peak_amplitude,
103 float hit_sigma_integral,
105 short int multiplicity,
106 short int local_index,
107 float goodness_of_fit,
118 sigma_peak_amplitude,
127 art::ServiceHandle<geo::Geometry
const>()->SignalType(wire.Channel()),
141 float sigma_peak_time,
142 float peak_amplitude,
143 float sigma_peak_amplitude,
145 float hit_sigma_integral,
146 short int multiplicity,
147 short int local_index,
148 float goodness_of_fit,
152 wire, wireID, start_tick, end_tick,
153 rms, peak_time, sigma_peak_time, peak_amplitude, sigma_peak_amplitude,
154 hit_integral, hit_sigma_integral,
156 wire.SignalROI().
begin() + start_tick,
157 wire.SignalROI().
begin() + end_tick,
160 multiplicity, local_index,
172 float sigma_peak_time,
173 float peak_amplitude,
174 float sigma_peak_amplitude,
176 float hit_sigma_integral,
178 short int multiplicity,
179 short int local_index,
180 float goodness_of_fit,
185 wire, wireID, signal.begin_index(), signal.end_index(),
186 rms, peak_time, sigma_peak_time, peak_amplitude, sigma_peak_amplitude,
187 hit_integral, hit_sigma_integral, summedADC, multiplicity, local_index,
199 float sigma_peak_time,
200 float peak_amplitude,
201 float sigma_peak_amplitude,
203 float hit_sigma_integral,
205 short int multiplicity,
206 short int local_index,
207 float goodness_of_fit,
212 wire, wireID, rms, peak_time, sigma_peak_time, peak_amplitude, sigma_peak_amplitude,
213 hit_integral, hit_sigma_integral, summedADC, multiplicity, local_index,
214 goodness_of_fit, dof, wire.SignalROI().range(iSignalRoI)
235 std::string instance_name,
bool doWireAssns,
bool doRawDigitAssns
237 : prod_instance(instance_name)
240 (doWireAssns? new art::Assns<recob::
Wire, recob::
Hit>: nullptr)
242 (doRawDigitAssns? new art::Assns<raw::RawDigit, recob::
Hit>: nullptr)
244 , hitPtrMaker(*(
this->event), prod_instance)
249 art::ProducesCollector& collector,
250 std::string instance_name ,
251 bool doWireAssns ,
bool doRawDigitAssns
253 collector.produces<std::vector<recob::Hit>>(instance_name);
257 collector.produces<art::Assns<recob::Wire, recob::Hit>>
260 if (doRawDigitAssns) {
261 collector.produces<art::Assns<raw::RawDigit, recob::Hit>>
280 std::string instance_name ,
281 bool doWireAssns ,
bool doRawDigitAssns
284 (event, instance_name, doWireAssns, doRawDigitAssns)
286 hits.reset(
new std::vector<recob::Hit>);
292 art::Ptr<recob::Wire>
const& wire, art::Ptr<raw::RawDigit>
const& digits
296 hits->emplace_back(std::move(
hit));
305 art::Ptr<recob::Wire>
const& wire, art::Ptr<raw::RawDigit>
const& digits
309 hits->push_back(hit);
318 throw art::Exception(art::errors::LogicError)
319 <<
"HitCollectionCreator is trying to put into the event"
320 " a hit collection that was never created!\n";
328 art::Ptr<recob::Wire>
const& wire, art::Ptr<raw::RawDigit>
const& digits
352 std::string instance_name,
354 art::InputTag
const& RawDigitModuleLabel
357 event, instance_name,
358 WireModuleLabel !=
"", RawDigitModuleLabel !=
""
360 , wires_label(WireModuleLabel)
361 , digits_label(RawDigitModuleLabel)
363 hits.reset(
new std::vector<recob::Hit>);
369 std::string instance_name,
374 event, instance_name,
375 WireModuleLabel !=
"", doRawDigitAssns
377 , wires_label(WireModuleLabel)
381 throw art::Exception(art::errors::LogicError)
382 <<
"HitCollectionAssociator can't create hit <--> raw digit"
383 " associations through wires, without wires!\n";
385 hits.reset(
new std::vector<recob::Hit>);
390 (std::unique_ptr<std::vector<recob::Hit>>&& srchits)
392 hits = std::move(srchits);
405 (std::vector<recob::Hit>
const& srchits)
407 if (!RawDigitAssns && !WireAssns)
return;
411 if (RawDigitAssns) ClearAssociations(*RawDigitAssns);
412 if (WireAssns) ClearAssociations(*WireAssns);
416 const bool bUseWiresForDigits = RawDigitAssns && (digits_label ==
"");
418 if (WireAssns || bUseWiresForDigits) {
422 art::ValidHandle<std::vector<recob::Wire>> hWires
423 =
event->getValidHandle<std::vector<recob::Wire>>(wires_label);
426 std::vector<size_t> WireMap
434 std::unique_ptr<art::FindOneP<raw::RawDigit>> WireToDigit;
435 if (bUseWiresForDigits) {
437 (
new art::FindOneP<raw::RawDigit>(hWires, *event, wires_label));
441 for (
size_t iHit = 0; iHit < srchits.size(); ++iHit) {
444 size_t iChannel = size_t(srchits[iHit].Channel());
447 size_t iWire = std::numeric_limits<size_t>::max();
448 if (iChannel < WireMap.size()) iWire = WireMap[iChannel];
449 if (iWire == std::numeric_limits<size_t>::max()) {
450 throw art::Exception(art::errors::LogicError)
451 <<
"No wire associated to channel #" << iChannel <<
" whence hit #"
452 << iHit <<
" comes!\n";
457 art::Ptr<recob::Wire> wire(hWires, iWire);
458 WireAssns->addSingle(wire, CreatePtr(iHit));
461 if (bUseWiresForDigits) {
463 art::Ptr<raw::RawDigit>
const& digit = WireToDigit->at(iWire);
464 if (digit.isNull()) {
465 throw art::Exception(art::errors::LogicError)
466 <<
"No raw digit associated to channel #" << iChannel
467 <<
" whence hit #" << iHit <<
" comes!\n";
471 RawDigitAssns->addSingle(digit, CreatePtr(iHit));
477 if (RawDigitAssns && !bUseWiresForDigits) {
479 art::ValidHandle<std::vector<raw::RawDigit>> hDigits
480 =
event->getValidHandle<std::vector<raw::RawDigit>>(digits_label);
483 std::vector<size_t> DigitMap
487 for (
size_t iHit = 0; iHit < srchits.size(); ++iHit) {
490 size_t iChannel = size_t(srchits[iHit].Channel());
493 size_t iDigit = std::numeric_limits<size_t>::max();
494 if (iChannel < DigitMap.size()) iDigit = DigitMap[iChannel];
495 if (iDigit == std::numeric_limits<size_t>::max()) {
496 throw art::Exception(art::errors::LogicError)
497 <<
"No raw digit associated to channel #" << iChannel
498 <<
" whence hit #" << iHit <<
" comes!\n";
502 art::Ptr<raw::RawDigit> digit(hDigits, iDigit);
503 RawDigitAssns->addSingle(digit, CreatePtr(iHit));
515 art::InputTag
const& HitModuleLabel,
516 std::string instance_name ,
517 bool doWireAssns ,
bool doRawDigitAssns
520 (event, instance_name, doWireAssns, doRawDigitAssns)
521 , hits_label(HitModuleLabel)
523 hits.reset(
new std::vector<recob::Hit>);
528 (std::unique_ptr<std::vector<recob::Hit>>&& srchits)
530 hits = std::move(srchits);
543 (std::vector<recob::Hit>
const& srchits)
545 if (!RawDigitAssns && !WireAssns)
return;
549 if (RawDigitAssns) ClearAssociations(*RawDigitAssns);
553 art::ValidHandle<std::vector<recob::Hit>> hHits
554 =
event->getValidHandle<std::vector<recob::Hit>>(hits_label);
559 ClearAssociations(*WireAssns);
562 art::FindOneP<recob::Wire>
HitToWire(hHits, *event, hits_label);
563 if (!HitToWire.isValid()) {
564 throw art::Exception(art::errors::ProductNotFound)
565 <<
"Can't find the associations between hits and wires produced by '"
566 << hits_label <<
"'!\n";
570 std::vector<art::Ptr<recob::Wire>> WireMap;
571 for (
size_t iAssn = 0; iAssn < HitToWire.size(); ++iAssn) {
572 art::Ptr<recob::Wire> wire = HitToWire.at(iAssn);
573 if (wire.isNull())
continue;
574 size_t channelID = (size_t) wire->Channel();
575 if (WireMap.size() <= channelID)
576 WireMap.resize(std::max(channelID + 1, 2 * WireMap.size()), {});
577 WireMap[channelID] = std::move(wire);
581 for (
size_t iHit = 0; iHit < srchits.size(); ++iHit) {
583 size_t channelID = (size_t) hit.
Channel();
586 if ((channelID >= WireMap.size()) || !WireMap[channelID])
continue;
589 WireAssns->addSingle(WireMap[channelID], CreatePtr(iHit));
596 ClearAssociations(*RawDigitAssns);
599 art::FindOneP<raw::RawDigit> HitToDigits(hHits, *event, hits_label);
600 if (!HitToDigits.isValid()) {
601 throw art::Exception(art::errors::ProductNotFound)
602 <<
"Can't find the associations between hits and raw digits"
603 <<
" produced by '" << hits_label <<
"'!\n";
607 std::vector<art::Ptr<raw::RawDigit>> DigitMap;
608 for (
size_t iAssn = 0; iAssn < HitToDigits.size(); ++iAssn) {
609 art::Ptr<raw::RawDigit> digits = HitToDigits.at(iAssn);
610 if (digits.isNull())
continue;
611 size_t channelID = (size_t) digits->Channel();
612 if (DigitMap.size() <= channelID)
613 DigitMap.resize(std::max(channelID + 1, 2 * DigitMap.size()), {});
614 DigitMap[channelID] = std::move(digits);
618 for (
size_t iHit = 0; iHit < srchits.size(); ++iHit) {
620 size_t channelID = (size_t) hit.
Channel();
623 if ((channelID >= DigitMap.size()) || !DigitMap[channelID])
continue;
626 RawDigitAssns->addSingle(DigitMap[channelID], CreatePtr(iHit));
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
HitPtr_t CreatePtrToLastHit() const
Creates an art pointer to the hit with the last index.
Collection of charge vs time digitized from a single readout channel.
void prepare_associations()
Finds out the associations for the current hits.
HitAndAssociationsWriterBase(art::Event &event, std::string instance_name, bool doWireAssns, bool doRawDigitAssns)
Constructor: sets instance name and whether to build associations.
std::string prod_instance
Tame of the instance for data products.
Declaration of signal hit object.
Procedures to create maps of object locations.
ChannelID_t Channel() const
DAQ channel this raw data was read from.
std::unique_ptr< art::Assns< recob::Wire, recob::Hit > > WireAssns
Associations with wires.
void use_hits(std::unique_ptr< std::vector< recob::Hit >> &&srchits)
Uses the specified collection as data product.
std::vector< size_t > MakeIndex(Coll const &data, KeyOf key_of=KeyOf())
Creates a map of indices from an existing collection.
static void declare_products(art::ProducesCollector &collector, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
art::Event * event
Pointer to the event we are using.
recob::Hit hit
Local instance of the hit being constructed.
process_name ccluster WireModuleLabel
int TDCtick_t
Type representing a TDC tick.
Class managing the creation of a new recob::Hit object.
Helper functions to create a hit.
void use_hits(std::unique_ptr< std::vector< recob::Hit >> &&srchits)
Uses the specified collection as data product.
void prepare_associations()
Finds out the associations for the current hits.
void put_into()
Moves the data into the event.
art::Ptr< recob::Hit > HitPtr_t
Type of art pointer to Hit.
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
void put_into()
Moves the data into the event.
details::FindAllP< recob::Hit, recob::Wire > HitToWire
Query object connecting a hit to a wire.
void CreateAssociationsToLastHit(art::Ptr< recob::Wire > const &wire, art::Ptr< raw::RawDigit > const &digits)
Creates associations between the last hit and the specified pointers.
void emplace_back(recob::Hit &&hit, art::Ptr< recob::Wire > const &wire=art::Ptr< recob::Wire >(), art::Ptr< raw::RawDigit > const &digits=art::Ptr< raw::RawDigit >())
Adds the specified hit to the data collection.
HitRefinerAssociator(art::Event &event, art::InputTag const &HitModuleLabel, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Constructor: sets instance name and whether to build associations.
auto begin(FixedBins< T, C > const &) noexcept
HitCollectionAssociator(art::Event &event, std::string instance_name, art::InputTag const &WireModuleLabel, art::InputTag const &RawDigitModuleLabel)
Constructor: sets instance name and whether to build associations.
void put_into()
Moves the data into the event.
geo::WireID fWireID
WireID for the hit (Cryostat, TPC, Plane, Wire)
HitCollectionCreator(art::Event &event, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Constructor: sets instance name and whether to build associations.
Class holding the regions of interest of signal from a channel.
HitCreator(raw::RawDigit const &digits, geo::WireID const &wireID, raw::TDCtick_t start_tick, raw::TDCtick_t end_tick, float rms, float peak_time, float sigma_peak_time, float peak_amplitude, float sigma_peak_amplitude, float hit_integral, float hit_sigma_integral, float summedADC, short int multiplicity, short int local_index, float goodness_of_fit, int dof)
Constructor: extracts some information from raw digit.
Declaration of basic channel signal object.
std::unique_ptr< art::Assns< raw::RawDigit, recob::Hit > > RawDigitAssns
Associations with raw digits.
void put_into()
Moves the data into the event.
2D representation of charge deposited in the TDC/wire plane
recob::Wire::RegionsOfInterest_t::datarange_t RegionOfInterest_t
Type of one region of interest.
std::unique_ptr< std::vector< recob::Hit > > hits
Collection of hits.
bool empty(FixedBins< T, C > const &) noexcept
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Base class handling a collection of hits and its associations.
art framework interface to geometry description