15 #include "art_root_io/TFileService.h" 40 #include <unordered_map> 155 collector.
produces<std::vector<recob::Hit>>();
179 m_tupleTree = tfs->make<TTree>(
"Hit3DBuilderTree",
"Tree by StandardHit3DBuilder");
238 if (!hitSpacePointAssnsHandle.
isValid())
return;
246 using SpacePointToWireIDMap = std::unordered_map<const recob::SpacePoint*, geo::WireID>;
248 SpacePointToWireIDMap spacePointToWireIDMap;
250 for (
const auto& assnPair : *hitSpacePointAssnsHandle) {
252 spacePointToWireIDMap[assnPair.second.get()] = assnPair.first->WireID();
257 using OldHitToNewHitMap = std::map<const recob::Hit*, const recob::Hit*>;
258 using SpacePointHitVecMap = std::map<const recob::SpacePoint*, std::vector<const recob::Hit*>>;
260 OldHitToNewHitMap oldHitToNewHitMap;
261 SpacePointHitVecMap spacePointHitVecMap;
264 std::unique_ptr<std::vector<recob::Hit>> newHitVecPtr(
new std::vector<recob::Hit>);
267 newHitVecPtr->reserve(3 * hitSpacePointAssnsHandle->size());
272 for (
auto& assnPair : *hitSpacePointAssnsHandle) {
277 if (oldHitToNewHitMap.find(recobHit.
get()) == oldHitToNewHitMap.end()) {
283 const std::vector<geo::WireID>& wireIDs =
287 for (
const auto& wireID : wireIDs) {
288 if (wireID.TPC != refWireID.
TPC || wireID.Cryostat != refWireID.
Cryostat)
continue;
299 spacePointHitVecMap[spacePoint.
get()].push_back(newHit);
301 recobHitToArtPtrMap[newHit] = ptrMaker(newHitVecPtr->size() - 1);
302 oldHitToNewHitMap[recobHit.
get()] = newHit;
305 spacePointHitVecMap[spacePoint.
get()].push_back(oldHitToNewHitMap[recobHit.
get()]);
310 std::map<geo::PlaneID, double> planeOffsetMap;
312 auto const clock_data =
314 auto const det_prop =
319 for (
size_t tpcIdx = 0; tpcIdx <
fGeometry->
NTPC(); tpcIdx++) {
324 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1)) -
325 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
327 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2)) -
328 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
330 std::cout <<
"***> plane 0 offset: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 0)]
331 <<
", plane 1: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 1)]
333 std::cout <<
" Det prop plane 0: " 334 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0))
335 <<
", plane 1: " << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1))
336 <<
", plane 2: " << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2))
342 using RecobHitTo2DHitMap = std::map<const recob::Hit*, const reco::ClusterHit2D*>;
344 RecobHitTo2DHitMap recobHitTo2DHitMap;
351 for (
auto& hitPair : oldHitToNewHitMap) {
357 planeOffsetMap.at(hitWireID.planeID()));
358 double xPosition(det_prop.ConvertTicksToX(
359 recobHit->
PeakTime(), hitWireID.Plane, hitWireID.TPC, hitWireID.Cryostat));
367 for (
auto& pointPair : spacePointHitVecMap) {
369 const std::vector<const recob::Hit*>& recobHitVec = pointPair.second;
371 if (recobHitVec.size() != 3) {
372 std::cout <<
"************>>>>>> do not have 3 hits associated to space point! " 373 << recobHitVec.size() <<
" ***************" <<
std::endl;
379 for (
const auto& recobHit : recobHitVec) {
386 unsigned int statusBits(0x7);
387 float avePeakTime(0.);
394 for (
size_t planeIdx = 0; planeIdx < 3; planeIdx++) {
397 wireIDVec[planeIdx] = hit2D->
WireID();
405 float weight = 1. / (hitRMS * hitRMS);
408 avePeakTime += peakTime *
weight;
412 avePeakTime /= weightSum;
415 float hitChiSquare(0.);
416 float sigmaPeakTime(std::sqrt(1. / weightSum));
417 std::vector<float> hitDelTSigVec;
419 for (
const auto& hit2D : hitVector) {
420 float hitRMS = hit2D->getHit()->RMS();
421 float combRMS = std::sqrt(hitRMS * hitRMS - sigmaPeakTime * sigmaPeakTime);
422 float peakTime = hit2D->getTimeTicks();
423 float deltaTime = peakTime - avePeakTime;
424 float hitSig = deltaTime / combRMS;
426 hitChiSquare += hitSig * hitSig;
428 hitDelTSigVec.emplace_back(std::fabs(hitSig));
440 for (
const auto& hit2D : hitVector) {
441 int hitStart = hit2D->getHit()->PeakTime() - 2. * hit2D->getHit()->RMS() - 0.5;
442 int hitStop = hit2D->getHit()->PeakTime() + 2. * hit2D->getHit()->RMS() + 0.5;
444 lowMinIndex =
std::min(hitStart, lowMinIndex);
445 lowMaxIndex =
std::max(hitStart, lowMaxIndex);
446 hiMinIndex =
std::min(hitStop + 1, hiMinIndex);
447 hiMaxIndex =
std::max(hitStop + 1, hiMaxIndex);
451 if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex) {
453 std::vector<float> chargeVec;
455 for (
const auto& hit2D : hitVector)
457 hit2D->getHit()->PeakAmplitude(),
458 hit2D->getHit()->RMS(),
464 std::accumulate(chargeVec.begin(), chargeVec.end(), 0.) /
float(chargeVec.size());
465 float overlapRange =
float(hiMinIndex - lowMaxIndex);
466 float overlapFraction = overlapRange /
float(hiMaxIndex - lowMinIndex);
469 std::vector<float> smallestChargeDiffVec;
470 std::vector<float> chargeAveVec;
472 size_t chargeIndex(0);
474 for (
size_t idx = 0; idx < 3; idx++) {
475 size_t leftIdx = (idx + 2) % 3;
476 size_t rightIdx = (idx + 1) % 3;
478 smallestChargeDiffVec.push_back(
std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
479 chargeAveVec.push_back(
float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
481 if (smallestChargeDiffVec.back() < smallestDiff) {
482 smallestDiff = smallestChargeDiffVec.back();
488 float deltaPeakTime =
489 hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
495 float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) /
496 (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
499 if (chargeAsymmetry < -1. || chargeAsymmetry > 1.) {
502 std::cout <<
"============> Charge asymmetry out of range: " << chargeAsymmetry
504 std::cout <<
" hit C: " << hitWireID.
Cryostat <<
", TPC: " << hitWireID.
TPC 506 std::cout <<
" charge: " << chargeVec[0] <<
", " << chargeVec[1] <<
", " 508 std::cout <<
" index: " << chargeIndex <<
", smallest diff: " << smallestDiff
514 float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(), hitDelTSigVec.end());
528 float(spacePoint->
XYZ()[0]),
float(spacePoint->
XYZ()[1]),
float(spacePoint->
XYZ()[2]));
531 hitPairList.emplace_back(0,
563 theClockMakeHits.
stop();
568 mf::LogDebug(
"Cluster3D") <<
">>>>> 3D hit building done, found " << hitPairList.size()
584 for (
int sigPos = low; sigPos < hi; sigPos++) {
585 float arg = (
float(sigPos) - peakMean + 0.5) / peakSigma;
586 integral += peakAmp * std::exp(-0.5 * arg * arg);
bool m_outputHistograms
Take the time to create and fill some histograms for diagnostics.
std::list< reco::ClusterHit3D > HitPairList
art::InputTag fSpacePointProducerLabel
Data members to follow.
float getTimeTicks() const
float chargeIntegral(float, float, float, float, int, int) const
Perform charge integration between limits.
geo::WireID WireID() const
float RMS() const
RMS of the hit shape, in tick units.
float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
If monitoring, recover the time to execute a particular function.
std::vector< float > m_chiSquare3DVec
std::vector< float > m_overlapRangeVec
The data type to uniquely identify a Plane.
const geo::WireID & WireID() const
std::vector< reco::ClusterHit2D > Hit2DVector
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
CryostatID_t Cryostat
Index of cryostat.
~SpacePointHit3DBuilder()
Destructor.
WireID_t Wire
Index of the wire within its plane.
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::vector< float > m_qualityMetricVec
void Hit3DBuilder(art::Event &evt, reco::HitPairList &hitPairList, RecobHitToPtrMap &) override
Given a set of recob hits, run DBscan to form 3D clusters.
art framework interface to geometry description
const recob::Hit * getHit() const
bool isValid() const noexcept
void clear()
clear the tuple vectors before processing next event
Class managing the creation of a new recob::Hit object.
Helper functions to create a hit.
std::vector< float > m_deltaTimeVec
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
void use_hits(std::unique_ptr< std::vector< recob::Hit >> &&srchits)
Uses the specified collection as data product.
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
const geo::Geometry * fGeometry
void put_into(art::Event &)
Moves the data into the event.
Hit2DVector m_clusterHit2DMasterVec
T get(std::string const &key) const
A class handling a collection of hits and its associations.
SpacePointHit3DBuilder class definiton.
std::vector< int > m_smallIndexVec
std::vector< float > m_maxPullVec
TimeValues
enumerate the possible values for time checking if monitoring timing
static int max(int a, int b)
The geometry of one entire detector, as served by art.
PlaneID_t Plane
Index of the plane within its TPC.
std::vector< float > m_smallChargeDiffVec
art::InputTag fHitProducerLabel
Definition of data types for geometry description.
IHit3DBuilder interface class definiton.
std::vector< float > m_maxSideVecVec
This provides an art tool interface definition for tools which construct 3D hits used in 3D clusterin...
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
virtual void produces(art::ProducesCollector &) override
Each algorithm may have different objects it wants "produced" so use this to let the top level produc...
float PeakTime() const
Time of the signal peak, in tick units.
Declaration of signal hit object.
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
SpacePointHit3DBuilder(fhicl::ParameterSet const &pset)
Constructor.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
std::vector< float > m_hitAsymmetryVec
std::vector< float > m_pairWireDistVec
int trigger_offset(DetectorClocksData const &data)
std::vector< float > m_overlapFractionVec
const Double32_t * XYZ() const
constexpr WireID()=default
Default constructor: an invalid TPC ID.
detail::Node< FrameID, bool > PlaneID
2D representation of charge deposited in the TDC/wire plane
double accumulated_real_time() const
TPCID_t TPC
Index of the TPC within its cryostat.
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
TTree * m_tupleTree
output analysis tree
std::unordered_map< const recob::Hit *, art::Ptr< recob::Hit >> RecobHitToPtrMap
Defines a structure mapping art representation to internal.
std::vector< float > fTimeVector
std::vector< float > m_spacePointChargeVec
QTextStream & endl(QTextStream &s)
void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
Signal from collection planes.
unsigned getStatusBits() const
void setStatusBit(unsigned bits) const