15 #include "art_root_io/TFileService.h" 19 #include "cetlib/cpu_timer.h" 42 #include <unordered_map> 152 m_tupleTree = tfs->make<TTree>(
"Hit3DBuilderTree",
"Tree by StandardHit3DBuilder");
178 collector.
produces<std::vector<recob::Hit>>();
212 cet::cpu_timer theClockMakeHits;
220 if (!hitSpacePointAssnsHandle.
isValid())
return;
228 using SpacePointToWireIDMap = std::unordered_map<const recob::SpacePoint*, geo::WireID>;
230 SpacePointToWireIDMap spacePointToWireIDMap;
232 for (
const auto& assnPair : *hitSpacePointAssnsHandle) {
234 spacePointToWireIDMap[assnPair.second.get()] = assnPair.first->WireID();
239 using OldHitToNewHitMap = std::map<const recob::Hit*, const recob::Hit*>;
240 using SpacePointHitVecMap = std::map<const recob::SpacePoint*, std::vector<const recob::Hit*>>;
242 OldHitToNewHitMap oldHitToNewHitMap;
243 SpacePointHitVecMap spacePointHitVecMap;
246 std::unique_ptr<std::vector<recob::Hit>> newHitVecPtr(
new std::vector<recob::Hit>);
249 newHitVecPtr->reserve(3 * hitSpacePointAssnsHandle->size());
254 for (
auto& assnPair : *hitSpacePointAssnsHandle) {
259 if (oldHitToNewHitMap.find(recobHit.
get()) == oldHitToNewHitMap.end()) {
265 const std::vector<geo::WireID>& wireIDs =
269 for (
const auto& wireID : wireIDs) {
270 if (wireID.TPC != refWireID.
TPC || wireID.Cryostat != refWireID.
Cryostat)
continue;
281 spacePointHitVecMap[spacePoint.
get()].push_back(newHit);
283 recobHitToArtPtrMap[newHit] = ptrMaker(newHitVecPtr->size() - 1);
284 oldHitToNewHitMap[recobHit.
get()] = newHit;
287 spacePointHitVecMap[spacePoint.
get()].push_back(oldHitToNewHitMap[recobHit.
get()]);
292 std::map<geo::PlaneID, double> planeOffsetMap;
294 auto const clock_data =
296 auto const det_prop =
301 for (
size_t tpcIdx = 0; tpcIdx <
fGeometry->
NTPC(); tpcIdx++) {
306 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1)) -
307 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
309 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2)) -
310 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
312 std::cout <<
"***> plane 0 offset: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 0)]
313 <<
", plane 1: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 1)]
314 <<
", plane 2: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 2)] << std::endl;
315 std::cout <<
" Det prop plane 0: " 316 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0))
317 <<
", plane 1: " << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1))
318 <<
", plane 2: " << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2))
324 using RecobHitTo2DHitMap = std::map<const recob::Hit*, const reco::ClusterHit2D*>;
326 RecobHitTo2DHitMap recobHitTo2DHitMap;
333 for (
auto& hitPair : oldHitToNewHitMap) {
339 planeOffsetMap.at(hitWireID.planeID()));
340 double xPosition(det_prop.ConvertTicksToX(
341 recobHit->
PeakTime(), hitWireID.Plane, hitWireID.TPC, hitWireID.Cryostat));
349 for (
auto& pointPair : spacePointHitVecMap) {
351 const std::vector<const recob::Hit*>& recobHitVec = pointPair.second;
353 if (recobHitVec.size() != 3) {
354 std::cout <<
"************>>>>>> do not have 3 hits associated to space point! " 355 << recobHitVec.size() <<
" ***************" << std::endl;
361 for (
const auto& recobHit : recobHitVec) {
368 unsigned int statusBits(0x7);
369 float avePeakTime(0.);
376 for (
size_t planeIdx = 0; planeIdx < 3; planeIdx++) {
379 wireIDVec[planeIdx] = hit2D->
WireID();
387 float weight = 1. / (hitRMS * hitRMS);
390 avePeakTime += peakTime *
weight;
394 avePeakTime /= weightSum;
397 float hitChiSquare(0.);
398 float sigmaPeakTime(std::sqrt(1. / weightSum));
399 std::vector<float> hitDelTSigVec;
401 for (
const auto& hit2D : hitVector) {
402 float hitRMS = hit2D->getHit()->RMS();
403 float combRMS = std::sqrt(hitRMS * hitRMS - sigmaPeakTime * sigmaPeakTime);
404 float peakTime = hit2D->getTimeTicks();
405 float deltaTime = peakTime - avePeakTime;
406 float hitSig = deltaTime / combRMS;
408 hitChiSquare += hitSig * hitSig;
410 hitDelTSigVec.emplace_back(std::fabs(hitSig));
416 int lowMinIndex(std::numeric_limits<int>::max());
417 int lowMaxIndex(std::numeric_limits<int>::min());
418 int hiMinIndex(std::numeric_limits<int>::max());
419 int hiMaxIndex(std::numeric_limits<int>::min());
422 for (
const auto& hit2D : hitVector) {
423 int hitStart = hit2D->getHit()->PeakTime() - 2. * hit2D->getHit()->RMS() - 0.5;
424 int hitStop = hit2D->getHit()->PeakTime() + 2. * hit2D->getHit()->RMS() + 0.5;
426 lowMinIndex = std::min(hitStart, lowMinIndex);
427 lowMaxIndex = std::max(hitStart, lowMaxIndex);
428 hiMinIndex = std::min(hitStop + 1, hiMinIndex);
429 hiMaxIndex = std::max(hitStop + 1, hiMaxIndex);
433 if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex) {
435 std::vector<float> chargeVec;
437 for (
const auto& hit2D : hitVector)
439 hit2D->getHit()->PeakAmplitude(),
440 hit2D->getHit()->RMS(),
445 std::accumulate(chargeVec.begin(), chargeVec.end(), 0.) / float(chargeVec.size());
446 float overlapRange = float(hiMinIndex - lowMaxIndex);
447 float overlapFraction = overlapRange / float(hiMaxIndex - lowMinIndex);
450 std::vector<float> smallestChargeDiffVec;
451 std::vector<float> chargeAveVec;
452 float smallestDiff(std::numeric_limits<float>::max());
453 size_t chargeIndex(0);
455 for (
size_t idx = 0; idx < 3; idx++) {
456 size_t leftIdx = (idx + 2) % 3;
457 size_t rightIdx = (idx + 1) % 3;
459 smallestChargeDiffVec.push_back(
std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
460 chargeAveVec.push_back(
float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
462 if (smallestChargeDiffVec.back() < smallestDiff) {
463 smallestDiff = smallestChargeDiffVec.back();
469 float deltaPeakTime =
470 hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
476 float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) /
477 (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
480 if (chargeAsymmetry < -1. || chargeAsymmetry > 1.) {
483 std::cout <<
"============> Charge asymmetry out of range: " << chargeAsymmetry
484 <<
" <============" << std::endl;
485 std::cout <<
" hit C: " << hitWireID.
Cryostat <<
", TPC: " << hitWireID.
TPC 486 <<
", Plane: " << hitWireID.
Plane <<
", Wire: " << hitWireID.
Wire << std::endl;
487 std::cout <<
" charge: " << chargeVec[0] <<
", " << chargeVec[1] <<
", " 488 << chargeVec[2] << std::endl;
489 std::cout <<
" index: " << chargeIndex <<
", smallest diff: " << smallestDiff
495 float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(), hitDelTSigVec.end());
508 Eigen::Vector3f position(
509 float(spacePoint->
XYZ()[0]),
float(spacePoint->
XYZ()[1]),
float(spacePoint->
XYZ()[2]));
512 hitPairList.emplace_back(0,
533 hitRefiner.
use_hits(std::move(newHitVecPtr));
544 theClockMakeHits.stop();
549 mf::LogDebug(
"Cluster3D") <<
">>>>> 3D hit building done, found " << hitPairList.size()
550 <<
" 3D Hits" << std::endl;
561 for (
int sigPos = low; sigPos < hi; sigPos++) {
562 float arg = (float(sigPos) - peakMean + 0.5) / peakSigma;
563 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 RMS() const
RMS of the hit shape, in tick units.
unsigned int NTPC(CryostatID const &cryoid=details::cryostat_zero) const
Returns the total number of TPCs in the specified cryostat.
float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
If monitoring, recover the time to execute a particular function.
Declaration of signal hit object.
std::vector< float > m_chiSquare3DVec
std::vector< float > m_overlapRangeVec
The data type to uniquely identify a Plane.
float chargeIntegral(float, float, float, int, int) const
Perform charge integration between limits.
const geo::WireID & WireID() const
std::vector< reco::ClusterHit2D > Hit2DVector
constexpr auto abs(T v)
Returns the absolute value of the argument.
CryostatID_t Cryostat
Index of cryostat.
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
WireID_t Wire
Index of the wire within its plane.
geo::WireID const & WireID() const
Initial tdc tick for hit.
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.
const recob::Hit * getHit() const
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
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
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.
Interface for a class providing readout channel mapping to geometry.
Hit2DVector m_clusterHit2DMasterVec
T get(std::string const &key) const
A class handling a collection of hits and its associations.
SpacePointHit3DBuilder class definiton.
const Double32_t * XYZ() const
std::vector< int > m_smallIndexVec
std::vector< float > m_maxPullVec
TimeValues
enumerate the possible values for time checking if monitoring timing
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
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.
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
virtual std::vector< WireID > ChannelToWire(raw::ChannelID_t channel) const =0
SpacePointHit3DBuilder(fhicl::ParameterSet const &pset)
Constructor.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
const geo::WireReadoutGeom * fWireReadoutGeom
std::vector< float > m_hitAsymmetryVec
std::vector< float > m_pairWireDistVec
int trigger_offset(DetectorClocksData const &data)
std::vector< float > m_overlapFractionVec
constexpr WireID()=default
Default constructor: an invalid TPC ID.
2D representation of charge deposited in the TDC/wire plane
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.
art framework interface to geometry description
std::vector< float > fTimeVector
std::vector< float > m_spacePointChargeVec
Signal from collection planes.
unsigned getStatusBits() const
void setStatusBit(unsigned bits) const