From 296bdbde2bed61e122d627242c6efe2b6d73d6d1 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Mon, 26 Aug 2019 18:05:06 -0500 Subject: [PATCH 01/18] Update StrawGasStep --- MCDataProducts/inc/StrawGasStep.hh | 58 ++++++ TrackerMC/src/CreateStrawGasSteps_module.cc | 209 ++++++++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 MCDataProducts/inc/StrawGasStep.hh create mode 100644 TrackerMC/src/CreateStrawGasSteps_module.cc diff --git a/MCDataProducts/inc/StrawGasStep.hh b/MCDataProducts/inc/StrawGasStep.hh new file mode 100644 index 0000000000..ca1c6f01c9 --- /dev/null +++ b/MCDataProducts/inc/StrawGasStep.hh @@ -0,0 +1,58 @@ +#ifndef MCDataProducts_StrawGasStep_hh +#define MCDataProducts_StrawGasStep_hh +// +// Class to summarize the passage of a single particle through a single straw's gas volume +// This consolidates the G4 steps and insulates the downstream straw response ionization simulation +// from details of the G4 model +// +#include "canvas/Persistency/Common/Ptr.h" +#include "canvas/Persistency/Common/Assns.h" +#include "cetlib/map_vector.h" + +#include "MCDataProducts/inc/ProcessCode.hh" +#include "DataProducts/inc/StrawId.hh" +#include "DataProducts/inc/XYZVec.hh" +#include + +namespace mu2e { + class StrawGasStep { + public: + typedef cet::map_vector_key key_type; + + StrawGasStep() : _eIon(0.0), _pathLen(0.0), _mom(0.0), _time(0.0) {} + StrawGasStep( key_type simParticleKey, StrawId strawId, + Float_t ionizingEdep, Float_t pathLength, Float_t width, Float_t momentum, Double_t time, + XYZVec const& startPosition, XYZVec const& endPosition) : _simpart(simParticleKey), + _strawId(strawId), _eIon(ionizingEdep), _pathLen(pathLength), _width(width), _mom(momentum), _time(time), + _startpos(startPosition), _endpos(endPosition) {} + + key_type simParticleKey() const { return _simpart; } + StrawId strawId() const { return _strawId;} + Float_t ionizingEdep() const { return _eIon; } + Float_t pathLength() const { return _pathLen; } + Float_t radialWidth() const { return _width; } + Float_t momentum() const { return _mom; } + Double_t time() const { return _time; } + XYZVec const& startPosition() const { return _startpos; } + XYZVec const& endPosition() const { return _endpos; } + + private: + + key_type _simpart; // key to the particle generating this edep + StrawId _strawId; // straw + Float_t _eIon; // ionization energy deposited in this volue + Float_t _pathLen; // Length this particle traveled in this straw gas: this is NOT necessarily the end-start distance + Float_t _width; // transverse radial width of the charge cloud + Float_t _mom; // scalar momentum of the particle in the middle of this gas volume + Double_t _time; // time particle passes the middle of this gas volume; must be double to allow for long-lived particles + XYZVec _startpos, _endpos; //entrance and exit to the gas volume + }; + + // this class's collection is a map_vector + typedef cet::map_vector StrawGasStepCollection; + typedef art::Assns StrawGasStepAssns; +} + + +#endif + diff --git a/TrackerMC/src/CreateStrawGasSteps_module.cc b/TrackerMC/src/CreateStrawGasSteps_module.cc new file mode 100644 index 0000000000..ee3a8275ba --- /dev/null +++ b/TrackerMC/src/CreateStrawGasSteps_module.cc @@ -0,0 +1,209 @@ +// +// This module creates the StrawGasStep objects used in downstream digi simulation, using the +// G4 StepPointMCs +// +// Original author: David Brown (LBNL), Krzysztof Genser 19 Aug. 2019 +// +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "cetlib_except/exception.h" +#include "fhiclcpp/types/Atom.h" +#include "canvas/Utilities/InputTag.h" + +#include "TrackerGeom/inc/Tracker.hh" +#include "GeometryService/inc/GeomHandle.hh" +#include "GeometryService/inc/DetectorSystem.hh" + +#include "MCDataProducts/inc/StepPointMCCollection.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" +#include "MCDataProducts/inc/PtrStepPointMCVector.hh" +#include + +using namespace std; +using CLHEP::Hep3Vector; +namespace mu2e { + + class CreateStrawGasSteps : public art::EDProducer { + public: + using Name=fhicl::Name; + using Comment=fhicl::Comment; + struct Config { + fhicl::Atom debug{ Name("debugLevel"), + Comment("Debug Level"), 0}; + fhicl::Atom csize{ Name("OutputCollectionSize"), + Comment("Estimated size of output collection"), 2000}; + fhicl::Atom trackerSteps { Name("trackerStepPoints"), + Comment("Tracker StepPointMC Producer Instance name")}; + }; + using Parameters = art::EDProducer::Table; + explicit CreateStrawGasSteps(const Parameters& conf); + + private: + typedef std::map< std::pair, PtrStepPointMCVector > StrawSimPMap; // steps by straw, SimParticle + void produce(art::Event& e) override; + int _debug; + unsigned _csize; + bool _firstEvent; + string _trackerStepPoints; + + }; + + CreateStrawGasSteps::CreateStrawGasSteps(const Parameters& config ) : + art::EDProducer{config}, + _debug(config().debug()), + _csize(config().csize()), + _firstEvent(false), + _trackerStepPoints(config().trackerSteps()) + { + consumesMany(); + produces (); + produces (); + } + + void CreateStrawGasSteps::produce(art::Event& event) { + // create output + std::unique_ptr sgsc(new StrawGasStepCollection); + std::unique_ptr sgsa(new StrawGasStepAssns); + // needed for making Ptrs + auto StrawGasStepCollectionPID = event.getProductID(); + auto StrawGasStepCollectionGetter = event.productGetter(StrawGasStepCollectionPID); + // extend the collection + sgsc->reserve(_csize); + // Get all of the tracker StepPointMC collections from the event: + typedef vector< art::Handle > HandleVector; + // This selector will select only data products with the given instance name. + art::ProductInstanceNameSelector selector(_trackerStepPoints); + HandleVector stepsHandles; + event.getMany( selector, stepsHandles); + const Tracker& tracker = *GeomHandle(); + // Informational message on the first event. + if ( _firstEvent && _debug>0 ) { + mf::LogInfo log("StrawDigiSim"); + log << "mu2e::CreateStrawGasSteps will use StepPointMCs from: \n"; + for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); + i != e; ++i ){ + art::Provenance const& prov(*(i->provenance())); + log << " " << prov.branchName() << "\n"; + } + _firstEvent = false; + } + if(stepsHandles.empty()){ + throw cet::exception("SIM")<<"mu2e::CreateStrawGasSteps: No StepPointMC collections found for tracker" << endl; + } + unsigned istep(0); + unsigned nsps(0); + // Loop over StepPointMC collections + for ( HandleVector::const_iterator ispmcc=stepsHandles.begin(), espmcc=stepsHandles.end();ispmcc != espmcc; ++ispmcc ){ + + StrawSimPMap stmap; + + art::Handle const& handle(*ispmcc); + StepPointMCCollection const& steps(*handle); + nsps += steps.size(); + // Loop over the StepPointMCs in this collection and sort them + // by straw and SimParticle + for (size_t ispmc =0; ispmcid(); + // create pair + std::pair stpair(sid,tid); + // try to find it in the map + auto const pos = stmap.find(stpair); + // create ptr + art::Ptr spmcptr(handle,ispmc); + // since stmap is a Map, we loop over all steps just once and fill the map + // however since the map elements are pairs of paris(strawid,trackid) and a vector + // we need to check if a straw/track element was created already + if ( pos!=stmap.end() ) { + // the straw/track has been seen already + // add the ptr to the vector corresponding to this strawid and the track + // typedef std::vector > PtrStepPointMCVector; + pos->second.push_back(spmcptr); + } else { + // StepPointMC seen for the first time for this straw/track + // create a new vector with one element; + // may want to reserve some based on the step limit size + std::vector> spmcptrv(1,spmcptr); + stmap.emplace(stpair,spmcptrv); + } + } + } + // now that the StepPoints are sorted by particle and straw, create the StrawGas objects and fill the collection. Loop over the SimParticle/straw pairs + for(auto istmap = stmap.begin(); istmap != stmap.end(); istmap++){ + auto const& spmcptrs = istmap->second; + + // variables we accumulate for all the StepPoints in this pair + double eion(0.0), pathlen(0.0); + double time(0.0), mom(0.0); + // keep track of the first and last step + art::Ptr first(spmcptrs.front()); + art::Ptr last(spmcptrs.front()); + // loop over all the StepPoints for this SimParticle + for(auto const& spmcptr : spmcptrs){ + eion += spmcptr->ionizingEdep(); + pathlen += spmcptr->stepLength(); + if(spmcptr->time() < first->time()) first = spmcptr; + if(spmcptr->time() > last->time()) last = spmcptr; + } + // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last + XYZVec start = Geom::toXYZVec(first->position()); + XYZVec end = Geom::toXYZVec(last->position() + last->stepLength()*last->momentum().unit()); + // average first and last time, momentum + time = 0.5*(first->time() + last->time()); + mom = 0.5*(first->momentum().mag() + last->momentum().mag()); + // 2nd pass through steps to get width + Hep3Vector axis; + if(last != first) + axis = (last->position() - first->position()).unit(); + else + axis = first->momentum().unit(); + + double width(0.0); + for(auto const& spmcptr : spmcptrs) + width = std::max(width,(spmcptr->position()-first->position()).perp2(axis)); + + // create the gas step + StrawGasStep sgs(istmap->first.second, istmap->first.first, + (float)eion, (float)pathlen, (float)width, (float)mom, time, + start, end); + cet::map_vector_key key(istep++); + sgsc->insert(make_pair(key,sgs)); + + auto sgsp = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); + for(auto const& spmcptr : spmcptrs) + sgsa->addSingle(sgsp,spmcptr); + + if(_debug > 1){ + // checks and printout + cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << sgs.simParticleKey() + << " edep = " << eion << " pathlen = " << pathlen << " width = " << width << " mom = " << mom + << " time = " << sgs.time() << endl; +// << " start = " << start << endl +// << " end = " << end << endl; + + // check if end is inside physical straw + const Straw& straw = tracker.getStraw(sgs.strawId()); + double r2 = straw.innerRadius()*straw.innerRadius(); + Hep3Vector hend = Geom::Hep3Vec(end); + double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); + if(rd2 - r2 > 1e-5 ) cout << "End outside straw " << rd2 << endl; + + + } + } // end of pair loop + } // end of collection loop + if(_debug > 0){ + cout << "Total number of StrawGasSteps " << sgsc->size() << " , StepPointMCs = " << nsps << endl; + } + event.put(std::move(sgsc)); + event.put(std::move(sgsa)); + } // end of produce + +} + +DEFINE_ART_MODULE(mu2e::CreateStrawGasSteps) From 9f12b5fc66de428030962cd9fdaae24e4cf81407 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Thu, 29 Aug 2019 00:56:41 -0500 Subject: [PATCH 02/18] Add infrastructure for delta-ray step compression --- MCDataProducts/inc/StrawGasStep.hh | 2 +- TrackerMC/src/CreateStrawGasSteps_module.cc | 135 ++++++++++++++------ 2 files changed, 94 insertions(+), 43 deletions(-) diff --git a/MCDataProducts/inc/StrawGasStep.hh b/MCDataProducts/inc/StrawGasStep.hh index ca1c6f01c9..db6e011a00 100644 --- a/MCDataProducts/inc/StrawGasStep.hh +++ b/MCDataProducts/inc/StrawGasStep.hh @@ -44,7 +44,7 @@ namespace mu2e { Float_t _pathLen; // Length this particle traveled in this straw gas: this is NOT necessarily the end-start distance Float_t _width; // transverse radial width of the charge cloud Float_t _mom; // scalar momentum of the particle in the middle of this gas volume - Double_t _time; // time particle passes the middle of this gas volume; must be double to allow for long-lived particles + Double_t _time; // time particle enters this gas volume; must be double to allow for long-lived particles XYZVec _startpos, _endpos; //entrance and exit to the gas volume }; diff --git a/TrackerMC/src/CreateStrawGasSteps_module.cc b/TrackerMC/src/CreateStrawGasSteps_module.cc index ee3a8275ba..f53ee88d6d 100644 --- a/TrackerMC/src/CreateStrawGasSteps_module.cc +++ b/TrackerMC/src/CreateStrawGasSteps_module.cc @@ -32,19 +32,31 @@ namespace mu2e { struct Config { fhicl::Atom debug{ Name("debugLevel"), Comment("Debug Level"), 0}; + fhicl::Atom compDeltas{ Name("CompressDeltas"), + Comment("Compress short delta-rays into the primary step")}; + fhicl::Atom maxDeltaLength{ Name("MaxDeltaLength"), + Comment("Maximum step length for a delta ray to be compressed"),0.5}; fhicl::Atom csize{ Name("OutputCollectionSize"), Comment("Estimated size of output collection"), 2000}; - fhicl::Atom trackerSteps { Name("trackerStepPoints"), + fhicl::Atom trackerSteps { Name("trackerStepPoints"), Comment("Tracker StepPointMC Producer Instance name")}; + fhicl::Atom startSize { Name("StartSize"), + Comment("Starting size for straw-particle vector"),1}; }; using Parameters = art::EDProducer::Table; explicit CreateStrawGasSteps(const Parameters& conf); private: - typedef std::map< std::pair, PtrStepPointMCVector > StrawSimPMap; // steps by straw, SimParticle + typedef map< pair, PtrStepPointMCVector > StrawSimPMap; // steps by straw, SimParticle + typedef map< cet::map_vector_key, StrawId> SimPStrawMap; // map from SimParticle to Straw void produce(art::Event& e) override; + void extractDeltas(SimPStrawMap const& spmap,StrawSimPMap& sspmap, StrawSimPMap& deltas); + void addDeltas(StrawGasStep& step,StrawSimPMap& deltas); + void endPosition(art::Ptrconst& last, Straw const& straw, XYZVec& lastpos); int _debug; - unsigned _csize; + bool _compressDeltas; + float _maxDeltaLen; + unsigned _csize, _ssize; bool _firstEvent; string _trackerStepPoints; @@ -53,7 +65,10 @@ namespace mu2e { CreateStrawGasSteps::CreateStrawGasSteps(const Parameters& config ) : art::EDProducer{config}, _debug(config().debug()), + _compressDeltas(config().compDeltas()), + _maxDeltaLen(config().maxDeltaLength()), _csize(config().csize()), + _ssize(config().startSize()), _firstEvent(false), _trackerStepPoints(config().trackerSteps()) { @@ -64,8 +79,8 @@ namespace mu2e { void CreateStrawGasSteps::produce(art::Event& event) { // create output - std::unique_ptr sgsc(new StrawGasStepCollection); - std::unique_ptr sgsa(new StrawGasStepAssns); + unique_ptr sgsc(new StrawGasStepCollection); + unique_ptr sgsa(new StrawGasStepAssns); // needed for making Ptrs auto StrawGasStepCollectionPID = event.getProductID(); auto StrawGasStepCollectionGetter = event.productGetter(StrawGasStepCollectionPID); @@ -96,46 +111,40 @@ namespace mu2e { unsigned nsps(0); // Loop over StepPointMC collections for ( HandleVector::const_iterator ispmcc=stepsHandles.begin(), espmcc=stepsHandles.end();ispmcc != espmcc; ++ispmcc ){ - - StrawSimPMap stmap; - + StrawSimPMap sspmap, deltas; + SimPStrawMap spmap; art::Handle const& handle(*ispmcc); StepPointMCCollection const& steps(*handle); nsps += steps.size(); - // Loop over the StepPointMCs in this collection and sort them - // by straw and SimParticle + // Loop over the StepPointMCs in this collection and sort them by straw and SimParticle for (size_t ispmc =0; ispmcid(); - // create pair - std::pair stpair(sid,tid); - // try to find it in the map - auto const pos = stmap.find(stpair); - // create ptr + // check if this particle has already been seen in a different straw + auto sp = spmap.emplace(tid,sid); + if(!sp.second && sp.first->second != sid) + if(sp.first->second.valid())sp.first->second = StrawId(); // Already seen in another straw: make invalid to avoid compressing it + // create key + pair stpair(sid,tid); + // create ptr to this step art::Ptr spmcptr(handle,ispmc); - // since stmap is a Map, we loop over all steps just once and fill the map - // however since the map elements are pairs of paris(strawid,trackid) and a vector - // we need to check if a straw/track element was created already - if ( pos!=stmap.end() ) { - // the straw/track has been seen already - // add the ptr to the vector corresponding to this strawid and the track - // typedef std::vector > PtrStepPointMCVector; - pos->second.push_back(spmcptr); - } else { - // StepPointMC seen for the first time for this straw/track - // create a new vector with one element; - // may want to reserve some based on the step limit size - std::vector> spmcptrv(1,spmcptr); - stmap.emplace(stpair,spmcptrv); - } + vector> spmcptrv(_ssize,spmcptr); + // check if this key exists and add it if not + auto ssp = sspmap.emplace(stpair,spmcptrv); + // if the key already exists, just add this Ptr to the vector + if(!ssp.second)ssp.first->second.push_back(spmcptr); } } - // now that the StepPoints are sorted by particle and straw, create the StrawGas objects and fill the collection. Loop over the SimParticle/straw pairs - for(auto istmap = stmap.begin(); istmap != stmap.end(); istmap++){ - auto const& spmcptrs = istmap->second; + // optionally compress out delta-rays that never leave the straw + + if(_compressDeltas)extractDeltas(spmap,sspmap,deltas); + // create the StrawGas objects and fill the collection. Loop over the SimParticle/straw pairs + for(auto isspmap = sspmap.begin(); isspmap != sspmap.end(); isspmap++){ + auto const& spmcptrs = isspmap->second; + const Straw& straw = tracker.getStraw(isspmap->first.first); // variables we accumulate for all the StepPoints in this pair double eion(0.0), pathlen(0.0); @@ -152,10 +161,10 @@ namespace mu2e { } // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last XYZVec start = Geom::toXYZVec(first->position()); - XYZVec end = Geom::toXYZVec(last->position() + last->stepLength()*last->momentum().unit()); - // average first and last time, momentum - time = 0.5*(first->time() + last->time()); - mom = 0.5*(first->momentum().mag() + last->momentum().mag()); + XYZVec end; + endPosition(last,straw,end); + time = first->time(); // use first time as time of this step (cluster times will be added) + mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum // 2nd pass through steps to get width Hep3Vector axis; if(last != first) @@ -165,18 +174,22 @@ namespace mu2e { double width(0.0); for(auto const& spmcptr : spmcptrs) - width = std::max(width,(spmcptr->position()-first->position()).perp2(axis)); + width = max(width,(spmcptr->position()-first->position()).perp2(axis)); // create the gas step - StrawGasStep sgs(istmap->first.second, istmap->first.first, + StrawGasStep sgs(isspmap->first.second, isspmap->first.first, (float)eion, (float)pathlen, (float)width, (float)mom, time, start, end); cet::map_vector_key key(istep++); + // Add in the energy from the delta-rays + if(_compressDeltas) addDeltas(sgs,deltas); sgsc->insert(make_pair(key,sgs)); + // create the Assns auto sgsp = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); for(auto const& spmcptr : spmcptrs) sgsa->addSingle(sgsp,spmcptr); + // add delta-rays FIXME! if(_debug > 1){ // checks and printout @@ -199,11 +212,49 @@ namespace mu2e { } // end of collection loop if(_debug > 0){ cout << "Total number of StrawGasSteps " << sgsc->size() << " , StepPointMCs = " << nsps << endl; +// << " SimParticles before " << nsimold << endl; } - event.put(std::move(sgsc)); - event.put(std::move(sgsa)); + event.put(move(sgsc)); + event.put(move(sgsa)); } // end of produce + void CreateStrawGasSteps::extractDeltas(SimPStrawMap const& spmap,StrawSimPMap& sspmap, StrawSimPMap& deltas) { + auto issp = sspmap.begin(); + while(issp != sspmap.end()){ + bool isdelta(false); + // see if this particle is a delta-ray and if it's step is short + auto pcode = issp->second.front()->simParticle()->creationCode(); + if(pcode == ProcessCode::eIoni || pcode == ProcessCode::hIoni){ + float len(0.0); + for(auto const& istep : issp->second) + len += istep->stepLength(); + if(len < _maxDeltaLen){ +// make sure this particle didn't create hits in any other straw + isdelta = spmap.find(issp->first.second)->second == issp->first.first; + } + } +// if this is a delta, move the object to the delta-ray list, and erase it from the primary map + if(isdelta){ + deltas.emplace(*issp); + sspmap.erase(issp++); + } else + ++issp; + } + } + + void CreateStrawGasSteps::addDeltas(StrawGasStep& step,StrawSimPMap& deltas) { + //FIXME! + + } + + void CreateStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw, XYZVec& lastpos) { + lastpos = Geom::toXYZVec(last->position() + last->stepLength()*last->momentum().unit()); + // check straw boundary +// double r2 = straw.innerRadius()*straw.innerRadius(); +// Hep3Vector hend = Geom::Hep3Vec(end); +// double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); + // FIXME! + } } -DEFINE_ART_MODULE(mu2e::CreateStrawGasSteps) + DEFINE_ART_MODULE(mu2e::CreateStrawGasSteps) From 3998c0749aba8e0c4b39f0d267ee1d3c1743507a Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Wed, 2 Oct 2019 19:14:33 -0500 Subject: [PATCH 03/18] Implement delta compression. Create 2 assns, one for diags, one for MC matching. Simplify code and structs --- MCDataProducts/inc/StrawGasStep.hh | 16 +- TrackerMC/src/CreateStrawGasSteps_module.cc | 260 ---------------- TrackerMC/src/MakeStrawGasSteps_module.cc | 312 ++++++++++++++++++++ 3 files changed, 319 insertions(+), 269 deletions(-) delete mode 100644 TrackerMC/src/CreateStrawGasSteps_module.cc create mode 100644 TrackerMC/src/MakeStrawGasSteps_module.cc diff --git a/MCDataProducts/inc/StrawGasStep.hh b/MCDataProducts/inc/StrawGasStep.hh index db6e011a00..9ddd686245 100644 --- a/MCDataProducts/inc/StrawGasStep.hh +++ b/MCDataProducts/inc/StrawGasStep.hh @@ -21,9 +21,10 @@ namespace mu2e { StrawGasStep() : _eIon(0.0), _pathLen(0.0), _mom(0.0), _time(0.0) {} StrawGasStep( key_type simParticleKey, StrawId strawId, - Float_t ionizingEdep, Float_t pathLength, Float_t width, Float_t momentum, Double_t time, + Float_t Edep, Float_t pathLength, Float_t width, Float_t momentum, Double_t time, XYZVec const& startPosition, XYZVec const& endPosition) : _simpart(simParticleKey), - _strawId(strawId), _eIon(ionizingEdep), _pathLen(pathLength), _width(width), _mom(momentum), _time(time), + _strawId(strawId), _eIon(Edep), + _pathLen(pathLength), _width(width), _mom(momentum), _time(time), _startpos(startPosition), _endpos(endPosition) {} key_type simParticleKey() const { return _simpart; } @@ -35,24 +36,21 @@ namespace mu2e { Double_t time() const { return _time; } XYZVec const& startPosition() const { return _startpos; } XYZVec const& endPosition() const { return _endpos; } - private: - key_type _simpart; // key to the particle generating this edep + key_type _simpart; // key to the primary particle generating this edep StrawId _strawId; // straw - Float_t _eIon; // ionization energy deposited in this volue - Float_t _pathLen; // Length this particle traveled in this straw gas: this is NOT necessarily the end-start distance + Float_t _eIon; // ionization energy deposited in this straw by this particle + Float_t _pathLen; // Length the primary particle traveled in this straw gas: this is NOT necessarily the end-start distance Float_t _width; // transverse radial width of the charge cloud Float_t _mom; // scalar momentum of the particle in the middle of this gas volume Double_t _time; // time particle enters this gas volume; must be double to allow for long-lived particles XYZVec _startpos, _endpos; //entrance and exit to the gas volume }; - // this class's collection is a map_vector - typedef cet::map_vector StrawGasStepCollection; + typedef std::vector StrawGasStepCollection; typedef art::Assns StrawGasStepAssns; } - #endif diff --git a/TrackerMC/src/CreateStrawGasSteps_module.cc b/TrackerMC/src/CreateStrawGasSteps_module.cc deleted file mode 100644 index f53ee88d6d..0000000000 --- a/TrackerMC/src/CreateStrawGasSteps_module.cc +++ /dev/null @@ -1,260 +0,0 @@ -// -// This module creates the StrawGasStep objects used in downstream digi simulation, using the -// G4 StepPointMCs -// -// Original author: David Brown (LBNL), Krzysztof Genser 19 Aug. 2019 -// -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "cetlib_except/exception.h" -#include "fhiclcpp/types/Atom.h" -#include "canvas/Utilities/InputTag.h" - -#include "TrackerGeom/inc/Tracker.hh" -#include "GeometryService/inc/GeomHandle.hh" -#include "GeometryService/inc/DetectorSystem.hh" - -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/StrawGasStep.hh" -#include "MCDataProducts/inc/PtrStepPointMCVector.hh" -#include - -using namespace std; -using CLHEP::Hep3Vector; -namespace mu2e { - - class CreateStrawGasSteps : public art::EDProducer { - public: - using Name=fhicl::Name; - using Comment=fhicl::Comment; - struct Config { - fhicl::Atom debug{ Name("debugLevel"), - Comment("Debug Level"), 0}; - fhicl::Atom compDeltas{ Name("CompressDeltas"), - Comment("Compress short delta-rays into the primary step")}; - fhicl::Atom maxDeltaLength{ Name("MaxDeltaLength"), - Comment("Maximum step length for a delta ray to be compressed"),0.5}; - fhicl::Atom csize{ Name("OutputCollectionSize"), - Comment("Estimated size of output collection"), 2000}; - fhicl::Atom trackerSteps { Name("trackerStepPoints"), - Comment("Tracker StepPointMC Producer Instance name")}; - fhicl::Atom startSize { Name("StartSize"), - Comment("Starting size for straw-particle vector"),1}; - }; - using Parameters = art::EDProducer::Table; - explicit CreateStrawGasSteps(const Parameters& conf); - - private: - typedef map< pair, PtrStepPointMCVector > StrawSimPMap; // steps by straw, SimParticle - typedef map< cet::map_vector_key, StrawId> SimPStrawMap; // map from SimParticle to Straw - void produce(art::Event& e) override; - void extractDeltas(SimPStrawMap const& spmap,StrawSimPMap& sspmap, StrawSimPMap& deltas); - void addDeltas(StrawGasStep& step,StrawSimPMap& deltas); - void endPosition(art::Ptrconst& last, Straw const& straw, XYZVec& lastpos); - int _debug; - bool _compressDeltas; - float _maxDeltaLen; - unsigned _csize, _ssize; - bool _firstEvent; - string _trackerStepPoints; - - }; - - CreateStrawGasSteps::CreateStrawGasSteps(const Parameters& config ) : - art::EDProducer{config}, - _debug(config().debug()), - _compressDeltas(config().compDeltas()), - _maxDeltaLen(config().maxDeltaLength()), - _csize(config().csize()), - _ssize(config().startSize()), - _firstEvent(false), - _trackerStepPoints(config().trackerSteps()) - { - consumesMany(); - produces (); - produces (); - } - - void CreateStrawGasSteps::produce(art::Event& event) { - // create output - unique_ptr sgsc(new StrawGasStepCollection); - unique_ptr sgsa(new StrawGasStepAssns); - // needed for making Ptrs - auto StrawGasStepCollectionPID = event.getProductID(); - auto StrawGasStepCollectionGetter = event.productGetter(StrawGasStepCollectionPID); - // extend the collection - sgsc->reserve(_csize); - // Get all of the tracker StepPointMC collections from the event: - typedef vector< art::Handle > HandleVector; - // This selector will select only data products with the given instance name. - art::ProductInstanceNameSelector selector(_trackerStepPoints); - HandleVector stepsHandles; - event.getMany( selector, stepsHandles); - const Tracker& tracker = *GeomHandle(); - // Informational message on the first event. - if ( _firstEvent && _debug>0 ) { - mf::LogInfo log("StrawDigiSim"); - log << "mu2e::CreateStrawGasSteps will use StepPointMCs from: \n"; - for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); - i != e; ++i ){ - art::Provenance const& prov(*(i->provenance())); - log << " " << prov.branchName() << "\n"; - } - _firstEvent = false; - } - if(stepsHandles.empty()){ - throw cet::exception("SIM")<<"mu2e::CreateStrawGasSteps: No StepPointMC collections found for tracker" << endl; - } - unsigned istep(0); - unsigned nsps(0); - // Loop over StepPointMC collections - for ( HandleVector::const_iterator ispmcc=stepsHandles.begin(), espmcc=stepsHandles.end();ispmcc != espmcc; ++ispmcc ){ - StrawSimPMap sspmap, deltas; - SimPStrawMap spmap; - art::Handle const& handle(*ispmcc); - StepPointMCCollection const& steps(*handle); - nsps += steps.size(); - // Loop over the StepPointMCs in this collection and sort them by straw and SimParticle - for (size_t ispmc =0; ispmcid(); - // check if this particle has already been seen in a different straw - auto sp = spmap.emplace(tid,sid); - if(!sp.second && sp.first->second != sid) - if(sp.first->second.valid())sp.first->second = StrawId(); // Already seen in another straw: make invalid to avoid compressing it - // create key - pair stpair(sid,tid); - // create ptr to this step - art::Ptr spmcptr(handle,ispmc); - vector> spmcptrv(_ssize,spmcptr); - // check if this key exists and add it if not - auto ssp = sspmap.emplace(stpair,spmcptrv); - // if the key already exists, just add this Ptr to the vector - if(!ssp.second)ssp.first->second.push_back(spmcptr); - } - } - // optionally compress out delta-rays that never leave the straw - - if(_compressDeltas)extractDeltas(spmap,sspmap,deltas); - // create the StrawGas objects and fill the collection. Loop over the SimParticle/straw pairs - for(auto isspmap = sspmap.begin(); isspmap != sspmap.end(); isspmap++){ - auto const& spmcptrs = isspmap->second; - const Straw& straw = tracker.getStraw(isspmap->first.first); - - // variables we accumulate for all the StepPoints in this pair - double eion(0.0), pathlen(0.0); - double time(0.0), mom(0.0); - // keep track of the first and last step - art::Ptr first(spmcptrs.front()); - art::Ptr last(spmcptrs.front()); - // loop over all the StepPoints for this SimParticle - for(auto const& spmcptr : spmcptrs){ - eion += spmcptr->ionizingEdep(); - pathlen += spmcptr->stepLength(); - if(spmcptr->time() < first->time()) first = spmcptr; - if(spmcptr->time() > last->time()) last = spmcptr; - } - // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last - XYZVec start = Geom::toXYZVec(first->position()); - XYZVec end; - endPosition(last,straw,end); - time = first->time(); // use first time as time of this step (cluster times will be added) - mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum - // 2nd pass through steps to get width - Hep3Vector axis; - if(last != first) - axis = (last->position() - first->position()).unit(); - else - axis = first->momentum().unit(); - - double width(0.0); - for(auto const& spmcptr : spmcptrs) - width = max(width,(spmcptr->position()-first->position()).perp2(axis)); - - // create the gas step - StrawGasStep sgs(isspmap->first.second, isspmap->first.first, - (float)eion, (float)pathlen, (float)width, (float)mom, time, - start, end); - cet::map_vector_key key(istep++); - // Add in the energy from the delta-rays - if(_compressDeltas) addDeltas(sgs,deltas); - sgsc->insert(make_pair(key,sgs)); - - // create the Assns - auto sgsp = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); - for(auto const& spmcptr : spmcptrs) - sgsa->addSingle(sgsp,spmcptr); - // add delta-rays FIXME! - - if(_debug > 1){ - // checks and printout - cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << sgs.simParticleKey() - << " edep = " << eion << " pathlen = " << pathlen << " width = " << width << " mom = " << mom - << " time = " << sgs.time() << endl; -// << " start = " << start << endl -// << " end = " << end << endl; - - // check if end is inside physical straw - const Straw& straw = tracker.getStraw(sgs.strawId()); - double r2 = straw.innerRadius()*straw.innerRadius(); - Hep3Vector hend = Geom::Hep3Vec(end); - double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); - if(rd2 - r2 > 1e-5 ) cout << "End outside straw " << rd2 << endl; - - - } - } // end of pair loop - } // end of collection loop - if(_debug > 0){ - cout << "Total number of StrawGasSteps " << sgsc->size() << " , StepPointMCs = " << nsps << endl; -// << " SimParticles before " << nsimold << endl; - } - event.put(move(sgsc)); - event.put(move(sgsa)); - } // end of produce - - void CreateStrawGasSteps::extractDeltas(SimPStrawMap const& spmap,StrawSimPMap& sspmap, StrawSimPMap& deltas) { - auto issp = sspmap.begin(); - while(issp != sspmap.end()){ - bool isdelta(false); - // see if this particle is a delta-ray and if it's step is short - auto pcode = issp->second.front()->simParticle()->creationCode(); - if(pcode == ProcessCode::eIoni || pcode == ProcessCode::hIoni){ - float len(0.0); - for(auto const& istep : issp->second) - len += istep->stepLength(); - if(len < _maxDeltaLen){ -// make sure this particle didn't create hits in any other straw - isdelta = spmap.find(issp->first.second)->second == issp->first.first; - } - } -// if this is a delta, move the object to the delta-ray list, and erase it from the primary map - if(isdelta){ - deltas.emplace(*issp); - sspmap.erase(issp++); - } else - ++issp; - } - } - - void CreateStrawGasSteps::addDeltas(StrawGasStep& step,StrawSimPMap& deltas) { - //FIXME! - - } - - void CreateStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw, XYZVec& lastpos) { - lastpos = Geom::toXYZVec(last->position() + last->stepLength()*last->momentum().unit()); - // check straw boundary -// double r2 = straw.innerRadius()*straw.innerRadius(); -// Hep3Vector hend = Geom::Hep3Vec(end); -// double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); - // FIXME! - } -} - - DEFINE_ART_MODULE(mu2e::CreateStrawGasSteps) diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc new file mode 100644 index 0000000000..ed73f4ab33 --- /dev/null +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -0,0 +1,312 @@ +// +// This module creates the StrawGasStep objects used in downstream digi simulation, using the +// G4 StepPointMCs +// +// Original author: David Brown (LBNL), Krzysztof Genser 19 Aug. 2019 +// +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "cetlib_except/exception.h" +#include "fhiclcpp/types/Atom.h" +#include "canvas/Utilities/InputTag.h" + +#include "TrackerGeom/inc/Tracker.hh" +#include "GeometryService/inc/GeomHandle.hh" +#include "GeometryService/inc/DetectorSystem.hh" + +#include "MCDataProducts/inc/StepPointMCCollection.hh" +#include "MCDataProducts/inc/MCRelationship.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" +#include "MCDataProducts/inc/PtrStepPointMCVector.hh" +#include + +using namespace std; +using CLHEP::Hep3Vector; +namespace mu2e { + + class MakeStrawGasSteps : public art::EDProducer { + public: + using Name=fhicl::Name; + using Comment=fhicl::Comment; + struct Config { + fhicl::Atom debug{ Name("debugLevel"), + Comment("Debug Level"), 0}; + fhicl::Atom combineDeltas{ Name("CombineDeltas"), + Comment("Compress short delta-rays into the primary step"),true}; + fhicl::Atom maxDeltaLength{ Name("MaxDeltaLength"), + Comment("Maximum step length for a delta ray to be compressed"),0.5}; //mm + fhicl::Atom csize{ Name("OutputCollectionSize"), + Comment("Estimated size of output collection"), 2000}; + fhicl::Atom trackerSteps { Name("trackerStepPoints"), + Comment("Tracker StepPointMC Producer Instance name"),"tracker"}; + fhicl::Atom keepDeltas { Name("KeepDeltasModule"), + Comment("Dont combine Deltas from this module's collection")}; + fhicl::Atom startSize { Name("StartSize"), + Comment("Starting size for straw-particle vector"),4}; + fhicl::Atom allStepsAssns{ Name("AllStepsAssns"), + Comment("Build the association to all the contributing StepPointMCs"),false}; + }; + using Parameters = art::EDProducer::Table; + explicit MakeStrawGasSteps(const Parameters& conf); + + private: + typedef pair SSPair; // key for pair of straw, SimParticle + typedef map< SSPair , PtrStepPointMCVector > SPSMap; // steps by straw, SimParticle + void produce(art::Event& e) override; + void compressDeltas(SPSMap& spsmap); + void endPosition(art::Ptrconst& last, Straw const& straw, XYZVec& lastpos); + int _debug; + bool _combineDeltas, _allAssns; + float _maxDeltaLen; + unsigned _csize, _ssize; + bool _firstEvent; + string _trackerSteps, _keepDeltas; + + }; + + MakeStrawGasSteps::MakeStrawGasSteps(const Parameters& config ) : + art::EDProducer{config}, + _debug(config().debug()), + _combineDeltas(config().combineDeltas()), + _allAssns(config().allStepsAssns()), + _maxDeltaLen(config().maxDeltaLength()), + _csize(config().csize()), + _ssize(config().startSize()), + _firstEvent(false), + _trackerSteps(config().trackerSteps()), + _keepDeltas(config().keepDeltas()) + { + consumesMany(); + produces (); + // 2 associations: one to all the constituent StepPointMCs, the other to the first (in time) primary + produces ("Primary"); + if(_allAssns)produces ("All"); + } + + void MakeStrawGasSteps::produce(art::Event& event) { + // create output + unique_ptr sgsc(new StrawGasStepCollection); + sgsc->reserve(_csize); + unique_ptr sgsa_primary(new StrawGasStepAssns); + unique_ptr sgsa_all(new StrawGasStepAssns); + // needed for making Ptrs + auto StrawGasStepCollectionPID = event.getProductID(); + auto StrawGasStepCollectionGetter = event.productGetter(StrawGasStepCollectionPID); + // Get all of the tracker StepPointMC collections from the event: + typedef vector< art::Handle > HandleVector; + // This selector will select only data products with the given instance name. + art::ProductInstanceNameSelector selector(_trackerSteps); + HandleVector stepsHandles; + event.getMany( selector, stepsHandles); + const Tracker& tracker = *GeomHandle(); + // Informational message on the first event. + if ( _firstEvent && _debug>0 ) { + mf::LogInfo log("StrawDigiSim"); + log << "mu2e::MakeStrawGasSteps will use StepPointMCs from: \n"; + for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); + i != e; ++i ){ + art::Provenance const& prov(*(i->provenance())); + log << " " << prov.branchName() << "\n"; + } + _firstEvent = false; + } + if(stepsHandles.empty()){ + throw cet::exception("SIM")<<"mu2e::MakeStrawGasSteps: No StepPointMC collections found for tracker" << endl; + } + // diagnostic counters + unsigned nspmcs(0), nspss(0); + // Loop over StepPointMC collections + for( auto const& handle : stepsHandles) { + SPSMap spsmap; // map of step points by straw,sim particle + StepPointMCCollection const& steps(*handle); + nspmcs += steps.size(); + // see if we should compress deltas from this collection + bool dcomp = _combineDeltas && handle.provenance()->moduleLabel() != _keepDeltas; + // Loop over the StepPointMCs in this collection and sort them by straw and SimParticle + for (size_t ispmc =0; ispmcid(); + // create key + pair stpair(sid,tid); + // create ptr to this step + art::Ptr spmcptr(handle,ispmc); + vector> spmcptrv(_ssize,spmcptr); + // check if this key exists and add it if not + auto ssp = spsmap.emplace(stpair,spmcptrv); + // if the key already exists, just add this Ptr to the vector + if(!ssp.second)ssp.first->second.push_back(spmcptr); + } + } + // optionally combine delta-rays that never leave the straw with their parent particle + if(dcomp)compressDeltas(spsmap); + nspss += spsmap.size(); + // convert the SimParticle/straw pair steps into StrawGas objects and fill the collection. + for(auto ispsmap = spsmap.begin(); ispsmap != spsmap.end(); ispsmap++){ + auto const& spmcptrs = ispsmap->second; + const Straw& straw = tracker.getStraw(ispsmap->first.first); + // variables we accumulate for all the StepPoints in this pair + double eion(0.0), pathlen(0.0); + double time(0.0), mom(0.0); + // keep track of the first and last PRIMARY step + art::Ptr first(spmcptrs.front()); + art::Ptr last(spmcptrs.front()); + // loop over all the StepPoints for this SimParticle + auto pid = first->trackId(); + for(auto const& spmcptr : spmcptrs){ + // treat primary and secondary (delta-ray) energy differently + if(spmcptr->simParticle()->id() == pid) { + // primary: update energy, path length, and entry/exit + eion += spmcptr->ionizingEdep(); + pathlen += spmcptr->stepLength(); + if(spmcptr->time() < first->time()) first = spmcptr; + if(spmcptr->time() > last->time()) last = spmcptr; + } else { +// secondary: only update energy + eion += spmcptr->ionizingEdep(); + } + } + // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last + XYZVec start = Geom::toXYZVec(first->position()); + XYZVec end; + endPosition(last,straw,end); + time = first->time(); // use first time as time of this step (cluster times will be added) + mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum + Hep3Vector axis; + if(last != first) + axis = (last->position() - first->position()).unit(); + else + axis = first->momentum().unit(); + // 2nd pass through steps to get width + double width(0.0); + for(auto const& spmcptr : spmcptrs) + width = max(width,(spmcptr->position()-first->position()).perp2(axis)); + + // create the gas step + StrawGasStep sgs(ispsmap->first.second, ispsmap->first.first, + (float)eion,(float)pathlen, (float)width, (float)mom, time, + start, end); + sgsc->push_back(sgs); + // create the Assns + auto sgsp = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); + sgsa_primary->addSingle(sgsp,first); + // add Assns for all StepPoints, including delta-rays, for diagnostics + if(_allAssns){ + for(auto const& spmcptr : spmcptrs) + sgsa_all->addSingle(sgsp,spmcptr); + } + + if(_debug > 1){ + // checks and printout + cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << sgs.simParticleKey() + << " edep = " << eion << " pathlen = " << pathlen << " width = " << width << " mom = " << mom + << " time = " << sgs.time() << endl; + + // check if end is inside physical straw + const Straw& straw = tracker.getStraw(sgs.strawId()); + double r2 = straw.innerRadius()*straw.innerRadius(); + Hep3Vector hend = Geom::Hep3Vec(end); + double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); + if(rd2 - r2 > 1e-5 ) cout << "End outside straw " << rd2 << endl; + + } + } // end of pair loop + } // end of collection loop + if(_debug > 0){ + cout << "Total number of StrawGasSteps " << sgsc->size() << " , StepPointMCs = " << nspmcs << endl; + } + event.put(move(sgsc)); + event.put(move(sgsa_primary),"Primary"); + if(_allAssns) event.put(move(sgsa_all),"All"); + } // end of produce + + void MakeStrawGasSteps::compressDeltas(SPSMap& spsmap) { + // first, make some helper maps + typedef map< cet::map_vector_key, StrawId > SMap; // map from key to Straw, to test for uniqueness + typedef map< cet::map_vector_key, cet::map_vector_key> DMap; // map from delta ray to parent + SMap smap; + DMap dmap; + for(auto isps = spsmap.begin(); isps != spsmap.end(); isps++ ) { + auto sid = isps->first.first; + auto tid = isps->first.second; + // map key to straw + auto sp = smap.emplace(tid,sid); + if(!sp.second && sp.first->second != sid && sp.first->second.valid())sp.first->second = StrawId(); // Particle already seen in another straw: make invalid to avoid compressing it + } + + // loop over particle-straw pairs looking for delta rays + auto isps =spsmap.begin(); + while(isps != spsmap.end()){ + bool isdelta(false); + auto& dsteps = isps->second; + auto dkey =isps->first.second; + // see if this particle is a delta-ray and if it's step is short + auto pcode = dsteps.front()->simParticle()->creationCode(); + if(pcode == ProcessCode::eIoni || pcode == ProcessCode::hIoni){ + // make sure this particle doesnt have a step in any other straw + auto ifnd = smap.find(dkey); + if(ifnd == smap.end()) + throw cet::exception("SIM")<<"mu2e::MakeStrawGasSteps: No SimParticle found for delta key " << dkey << endl; + else if(ifnd->second.valid()){ // only compress delta rays without hits in any other straw + // add the lengths of all the steps in this straw + float len(0.0); + for(auto const& istep : dsteps) + len += istep->stepLength(); + if(len < _maxDeltaLen){ +// short delta ray. flag for combination + isdelta = true; + } + } + } +// if this is a delta, map it back to the primary + if(isdelta){ + auto strawid = isps->first.first; + // find its parent + auto pkey = dsteps.front()->simParticle()->parentId(); + // map it so that potential daughters can map back through this particle even after compression + dmap[dkey] = pkey; + // find the parent. This must be recursive, as delta rays can come from delta rays (from delta rays...) + auto jfnd = dmap.find(pkey); + while(jfnd != dmap.end()){ + pkey = jfnd->second; + jfnd = dmap.find(pkey); + } + // now, find the parent back in the original map + auto ifnd = spsmap.find(make_pair(strawid,pkey)); + if(ifnd != spsmap.end()){ + if(_debug > 1)cout << "mu2e::MakeStrawGasSteps: SimParticle found for delta parent key " << pkey << " straw " << strawid << endl; + // move the contents to the primary + auto& psteps = ifnd->second; + psteps.insert(psteps.end(),dsteps.begin(),dsteps.end()); + // erase the delta ray and advance the iterator + isps = spsmap.erase(isps); + } else { + // there are a very few delta rays whose parents die in the straw walls that cause StepPoints, so this is not an error. These stay + // as uncompressed particles. + if(_debug > 1)cout << "mu2e::MakeStrawGasSteps: No SimParticle found for delta parent key " << pkey << " straw " << strawid << endl; + isps++; + } + } else + // move to the next straw/particle pair + isps++; + } + } + + void MakeStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw, XYZVec& lastpos) { + // divide into linear, curved, and curlers + + + lastpos = Geom::toXYZVec(last->position() + last->stepLength()*last->momentum().unit()); + // check straw boundary +// double r2 = straw.innerRadius()*straw.innerRadius(); +// Hep3Vector hend = Geom::Hep3Vec(end); +// double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); + // FIXME! + } +} + + DEFINE_ART_MODULE(mu2e::MakeStrawGasSteps) From 2f6c39935dba95dbdd7d559fb8dcf9a569f01de0 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Fri, 4 Oct 2019 18:49:16 -0500 Subject: [PATCH 04/18] Fix bookkeeping bug. Add code to force end inside the straw. Update width calculation, but it's still not physical --- TrackerMC/src/MakeStrawGasSteps_module.cc | 107 +++++++++++++++------- 1 file changed, 72 insertions(+), 35 deletions(-) diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index ed73f4ab33..d40ccfcd1e 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -15,6 +15,8 @@ #include "TrackerGeom/inc/Tracker.hh" #include "GeometryService/inc/GeomHandle.hh" #include "GeometryService/inc/DetectorSystem.hh" +#include "BFieldGeom/inc/BFieldManager.hh" +#include "BTrk/BField/BField.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "MCDataProducts/inc/MCRelationship.hh" @@ -37,6 +39,8 @@ namespace mu2e { Comment("Compress short delta-rays into the primary step"),true}; fhicl::Atom maxDeltaLength{ Name("MaxDeltaLength"), Comment("Maximum step length for a delta ray to be compressed"),0.5}; //mm + fhicl::Atom radiusTolerance{ Name("RadiusTolerance"), + Comment("Tolerance to accept a point outside the straw radius"),0.5}; //mm fhicl::Atom csize{ Name("OutputCollectionSize"), Comment("Estimated size of output collection"), 2000}; fhicl::Atom trackerSteps { Name("trackerStepPoints"), @@ -52,18 +56,20 @@ namespace mu2e { explicit MakeStrawGasSteps(const Parameters& conf); private: + void beginRun(art::Run& run) override; + void produce(art::Event& e) override; typedef pair SSPair; // key for pair of straw, SimParticle typedef map< SSPair , PtrStepPointMCVector > SPSMap; // steps by straw, SimParticle - void produce(art::Event& e) override; void compressDeltas(SPSMap& spsmap); - void endPosition(art::Ptrconst& last, Straw const& straw, XYZVec& lastpos); + XYZVec endPosition(art::Ptrconst& last, Straw const& straw); int _debug; bool _combineDeltas, _allAssns; - float _maxDeltaLen; + float _maxDeltaLen, _radtol; unsigned _csize, _ssize; bool _firstEvent; string _trackerSteps, _keepDeltas; - + // cache the BField direction at the tracker center + Hep3Vector _bdir, _bnom; }; MakeStrawGasSteps::MakeStrawGasSteps(const Parameters& config ) : @@ -72,6 +78,7 @@ namespace mu2e { _combineDeltas(config().combineDeltas()), _allAssns(config().allStepsAssns()), _maxDeltaLen(config().maxDeltaLength()), + _radtol(config().radiusTolerance()), _csize(config().csize()), _ssize(config().startSize()), _firstEvent(false), @@ -85,8 +92,22 @@ namespace mu2e { if(_allAssns)produces ("All"); } + void MakeStrawGasSteps::beginRun( art::Run& run ){ + // get field at the center of the tracker + GeomHandle bfmgr; + GeomHandle det; + Hep3Vector vpoint_mu2e = det->toMu2e(Hep3Vector(0.0,0.0,0.0)); + _bnom = bfmgr->getBField(vpoint_mu2e); + if ( _bnom.mag() < 1.0e-4 ){ + _bdir = Hep3Vector(0.0,0.0,1.0); + } else { + _bdir = _bnom.unit(); + } + } + void MakeStrawGasSteps::produce(art::Event& event) { - // create output + const Tracker& tracker = *GeomHandle(); + // create output unique_ptr sgsc(new StrawGasStepCollection); sgsc->reserve(_csize); unique_ptr sgsa_primary(new StrawGasStepAssns); @@ -100,7 +121,7 @@ namespace mu2e { art::ProductInstanceNameSelector selector(_trackerSteps); HandleVector stepsHandles; event.getMany( selector, stepsHandles); - const Tracker& tracker = *GeomHandle(); + // const Tracker& tracker = *GeomHandle(); // Informational message on the first event. if ( _firstEvent && _debug>0 ) { mf::LogInfo log("StrawDigiSim"); @@ -124,6 +145,7 @@ namespace mu2e { nspmcs += steps.size(); // see if we should compress deltas from this collection bool dcomp = _combineDeltas && handle.provenance()->moduleLabel() != _keepDeltas; + if(_debug > 1 && !dcomp)cout << "No compression for collection " << handle.provenance()->moduleLabel() << endl; // Loop over the StepPointMCs in this collection and sort them by straw and SimParticle for (size_t ispmc =0; ispmc stpair(sid,tid); // create ptr to this step art::Ptr spmcptr(handle,ispmc); - vector> spmcptrv(_ssize,spmcptr); + vector> spmcptrv; + spmcptrv.reserve(_ssize); + spmcptrv.push_back(spmcptr); // check if this key exists and add it if not auto ssp = spsmap.emplace(stpair,spmcptrv); // if the key already exists, just add this Ptr to the vector @@ -158,33 +182,24 @@ namespace mu2e { // loop over all the StepPoints for this SimParticle auto pid = first->trackId(); for(auto const& spmcptr : spmcptrs){ + // update eion for all contributions + eion += spmcptr->ionizingEdep(); // treat primary and secondary (delta-ray) energy differently if(spmcptr->simParticle()->id() == pid) { - // primary: update energy, path length, and entry/exit - eion += spmcptr->ionizingEdep(); + // primary: update path length, and entry/exit pathlen += spmcptr->stepLength(); if(spmcptr->time() < first->time()) first = spmcptr; if(spmcptr->time() > last->time()) last = spmcptr; - } else { -// secondary: only update energy - eion += spmcptr->ionizingEdep(); } } // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last XYZVec start = Geom::toXYZVec(first->position()); - XYZVec end; - endPosition(last,straw,end); + XYZVec end = endPosition(last,straw); time = first->time(); // use first time as time of this step (cluster times will be added) mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum - Hep3Vector axis; - if(last != first) - axis = (last->position() - first->position()).unit(); - else - axis = first->momentum().unit(); - // 2nd pass through steps to get width + // determine the width from the triangle calculation double width(0.0); - for(auto const& spmcptr : spmcptrs) - width = max(width,(spmcptr->position()-first->position()).perp2(axis)); + if(spmcptrs.size() > 1)width = sqrt( pathlen*pathlen - (end-start).mag2())/2.0; // create the gas step StrawGasStep sgs(ispsmap->first.second, ispsmap->first.first, @@ -203,15 +218,15 @@ namespace mu2e { if(_debug > 1){ // checks and printout cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << sgs.simParticleKey() - << " edep = " << eion << " pathlen = " << pathlen << " width = " << width << " mom = " << mom + << " edep = " << eion << " pathlen = " << pathlen << " glen = " << sqrt((end-start).mag2()) << " width = " << width << " mom = " << mom << " time = " << sgs.time() << endl; // check if end is inside physical straw const Straw& straw = tracker.getStraw(sgs.strawId()); - double r2 = straw.innerRadius()*straw.innerRadius(); + static double r2 = straw.innerRadius()*straw.innerRadius(); Hep3Vector hend = Geom::Hep3Vec(end); double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); - if(rd2 - r2 > 1e-5 ) cout << "End outside straw " << rd2 << endl; + if(rd2 - r2 > 1e-5 ) cout << "End outside straw, radius " << sqrt(rd2) << endl; } } // end of pair loop @@ -296,17 +311,39 @@ namespace mu2e { } } - void MakeStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw, XYZVec& lastpos) { - // divide into linear, curved, and curlers - + XYZVec MakeStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw) { +// test linear extrapolation first + auto momhat = last->momentum().unit(); + auto end = last->position() + last->stepLength()*momhat; + // check position against straw boundary + static const double r2 = straw.innerRadius()*straw.innerRadius(); + double rd2 = (end-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); + if(rd2 > r2) { + // outside the straw: adjust the end position + Hep3Vector mperp; + if(rd2 - r2 < _radtol){ + // close enogh; interpolate linearly along the momentum direction; + mperp = momhat.perpPart(straw.getDirection()); + } else { + // curler; assume the net motion is along the BField axis. Sign by the projection of the momentum + mperp = _bdir; + if(momhat.dot(_bdir)<0.0) mperp *= -1.0; + momhat = mperp; + } + auto pperp = (last->position()-straw.getMidPoint()).perpPart(straw.getDirection()); + double pmdot = pperp.dot(mperp); + double ppmag2 = pperp.mag2(); + double mpmag2 = mperp.mag2(); + double len = (sqrt(pmdot*pmdot + mpmag2*(r2 - ppmag2))-pmdot)/mpmag2; + end = last->position() + len*momhat; + if(_debug > 1){ + double newr2 =(end-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); + cout <<"Forced in straw, old length = " << last->stepLength() << " new length " << len << " new r2 " << newr2 << endl; + } - lastpos = Geom::toXYZVec(last->position() + last->stepLength()*last->momentum().unit()); - // check straw boundary -// double r2 = straw.innerRadius()*straw.innerRadius(); -// Hep3Vector hend = Geom::Hep3Vec(end); -// double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); - // FIXME! + } + return Geom::toXYZVec(end); } } - DEFINE_ART_MODULE(mu2e::MakeStrawGasSteps) +DEFINE_ART_MODULE(mu2e::MakeStrawGasSteps) From 3eb9a2e10bddc3b1194ad0fdd0b4ba8f42cd640f Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Wed, 9 Oct 2019 21:50:37 -0500 Subject: [PATCH 05/18] Fixes --- TrackerMC/src/MakeStrawGasSteps_module.cc | 169 +++++++++++++----- .../src/StrawDigisFromStepPointMCs_module.cc | 6 +- 2 files changed, 126 insertions(+), 49 deletions(-) diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index d40ccfcd1e..ed085c7260 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -15,6 +15,9 @@ #include "TrackerGeom/inc/Tracker.hh" #include "GeometryService/inc/GeomHandle.hh" #include "GeometryService/inc/DetectorSystem.hh" +#include "art_root_io/TFileService.h" +#include "GlobalConstantsService/inc/GlobalConstantsHandle.hh" +#include "GlobalConstantsService/inc/ParticleDataTable.hh" #include "BFieldGeom/inc/BFieldManager.hh" #include "BTrk/BField/BField.hh" @@ -23,6 +26,9 @@ #include "MCDataProducts/inc/StrawGasStep.hh" #include "MCDataProducts/inc/PtrStepPointMCVector.hh" #include +// root +#include "TH1F.h" +#include "TTree.h" using namespace std; using CLHEP::Hep3Vector; @@ -35,12 +41,18 @@ namespace mu2e { struct Config { fhicl::Atom debug{ Name("debugLevel"), Comment("Debug Level"), 0}; + fhicl::Atom diag{ Name("diagLevel"), + Comment("Diag Level"), 0}; fhicl::Atom combineDeltas{ Name("CombineDeltas"), Comment("Compress short delta-rays into the primary step"),true}; fhicl::Atom maxDeltaLength{ Name("MaxDeltaLength"), Comment("Maximum step length for a delta ray to be compressed"),0.5}; //mm fhicl::Atom radiusTolerance{ Name("RadiusTolerance"), Comment("Tolerance to accept a point outside the straw radius"),0.5}; //mm + fhicl::Atom parabolicRotation{ Name("parabolicRotation"), + Comment("Maximum bending rotation to use parabolic end estimation"),0.15}; //radians + fhicl::Atom curlRotation{ Name("curlRotation"), + Comment("Minimum bending rotation to use curl end estimation"),1.0}; //radians fhicl::Atom csize{ Name("OutputCollectionSize"), Comment("Estimated size of output collection"), 2000}; fhicl::Atom trackerSteps { Name("trackerStepPoints"), @@ -56,29 +68,39 @@ namespace mu2e { explicit MakeStrawGasSteps(const Parameters& conf); private: + void beginJob() override; void beginRun(art::Run& run) override; void produce(art::Event& e) override; typedef pair SSPair; // key for pair of straw, SimParticle typedef map< SSPair , PtrStepPointMCVector > SPSMap; // steps by straw, SimParticle void compressDeltas(SPSMap& spsmap); - XYZVec endPosition(art::Ptrconst& last, Straw const& straw); - int _debug; + XYZVec endPosition(art::Ptrconst& last, Straw const& straw,float charge); + int _debug, _diag; bool _combineDeltas, _allAssns; - float _maxDeltaLen, _radtol; + float _maxDeltaLen, _radtol, _parrot, _curlrot; unsigned _csize, _ssize; bool _firstEvent; string _trackerSteps, _keepDeltas; // cache the BField direction at the tracker center - Hep3Vector _bdir, _bnom; + Hep3Vector _bdir; + float _bnom; // BField in units of mm/MeV/c + // diagnostic histograms + TH1F *_hendrad, *_hphi; + TTree* _sgsdiag; + Float_t _prilen, _pridist, _elen, _erad, _epri, _esec, _partP, _brot; + Int_t _npri, _nsec, _partPDG; }; MakeStrawGasSteps::MakeStrawGasSteps(const Parameters& config ) : art::EDProducer{config}, _debug(config().debug()), + _diag(config().diag()), _combineDeltas(config().combineDeltas()), _allAssns(config().allStepsAssns()), _maxDeltaLen(config().maxDeltaLength()), _radtol(config().radiusTolerance()), + _parrot(config().parabolicRotation()), + _curlrot(config().curlRotation()), _csize(config().csize()), _ssize(config().startSize()), _firstEvent(false), @@ -92,21 +114,43 @@ namespace mu2e { if(_allAssns)produces ("All"); } + void MakeStrawGasSteps::beginJob(){ + art::ServiceHandle tfs; + if(_diag > 0){ + _hendrad = tfs->make("endrad","EndStep Radius",100,2.0,3.0); + _hphi = tfs->make("phi","Step rotation angle",100,0.0,3.14); + if(_diag > 1) { + _sgsdiag=tfs->make("sgsdiag","StrawGasStep diagnostics"); + _sgsdiag->Branch("prilen",&_prilen,"prilen/F"); + _sgsdiag->Branch("elen",&_elen,"elen/F"); + _sgsdiag->Branch("pridist",&_pridist,"pridist/F"); + _sgsdiag->Branch("brot",&_brot,"brot/F"); + _sgsdiag->Branch("erad",&_erad,"erad/F"); + _sgsdiag->Branch("epri",&_epri,"epri/F"); + _sgsdiag->Branch("esec",&_esec,"esec/F"); + _sgsdiag->Branch("npri",&_npri,"npri/I"); + _sgsdiag->Branch("nsec",&_nsec,"nsec/I"); + _sgsdiag->Branch("partP",&_partP,"partP/F"); + _sgsdiag->Branch("partPDG",&_partPDG,"partPDG/I"); + + } + } + } + void MakeStrawGasSteps::beginRun( art::Run& run ){ // get field at the center of the tracker GeomHandle bfmgr; GeomHandle det; - Hep3Vector vpoint_mu2e = det->toMu2e(Hep3Vector(0.0,0.0,0.0)); - _bnom = bfmgr->getBField(vpoint_mu2e); - if ( _bnom.mag() < 1.0e-4 ){ - _bdir = Hep3Vector(0.0,0.0,1.0); - } else { - _bdir = _bnom.unit(); - } + auto vpoint_mu2e = det->toMu2e(Hep3Vector(0.0,0.0,0.0)); + auto bnom = bfmgr->getBField(vpoint_mu2e); + _bdir = bnom.unit(); + // B in units of mm/MeV/c + _bnom = bnom.mag()*BField::mmTeslaToMeVc; } void MakeStrawGasSteps::produce(art::Event& event) { const Tracker& tracker = *GeomHandle(); + GlobalConstantsHandle pdt; // create output unique_ptr sgsc(new StrawGasStepCollection); sgsc->reserve(_csize); @@ -144,8 +188,13 @@ namespace mu2e { StepPointMCCollection const& steps(*handle); nspmcs += steps.size(); // see if we should compress deltas from this collection - bool dcomp = _combineDeltas && handle.provenance()->moduleLabel() != _keepDeltas; - if(_debug > 1 && !dcomp)cout << "No compression for collection " << handle.provenance()->moduleLabel() << endl; + bool dcomp = _combineDeltas && (handle.provenance()->moduleLabel() != _keepDeltas); + if(_debug > 1){ + if(dcomp) + cout << "Compressing collection " << handle.provenance()->moduleLabel() << endl; + else + cout << "No compression for collection " << handle.provenance()->moduleLabel() << endl; + } // Loop over the StepPointMCs in this collection and sort them by straw and SimParticle for (size_t ispmc =0; ispmcid(); // create key - pair stpair(sid,tid); + SSPair stpair(sid,tid); // create ptr to this step art::Ptr spmcptr(handle,ispmc); vector> spmcptrv; @@ -176,25 +225,44 @@ namespace mu2e { // variables we accumulate for all the StepPoints in this pair double eion(0.0), pathlen(0.0); double time(0.0), mom(0.0); + if(_diag>1){ + _npri=_nsec=0; + _epri=_esec=0.0; + } // keep track of the first and last PRIMARY step art::Ptr first(spmcptrs.front()); art::Ptr last(spmcptrs.front()); // loop over all the StepPoints for this SimParticle - auto pid = first->trackId(); + auto pid = ispsmap->first.second; for(auto const& spmcptr : spmcptrs){ + bool primary=spmcptr->simParticle()->id() == pid; // update eion for all contributions eion += spmcptr->ionizingEdep(); // treat primary and secondary (delta-ray) energy differently - if(spmcptr->simParticle()->id() == pid) { + if(primary) { // primary: update path length, and entry/exit pathlen += spmcptr->stepLength(); if(spmcptr->time() < first->time()) first = spmcptr; if(spmcptr->time() > last->time()) last = spmcptr; } + // diagnostics + if(_diag >1){ + if(primary){ + _npri++; + _epri += spmcptr->ionizingEdep(); + } else { + _nsec++; + _esec += spmcptr->ionizingEdep(); + } + } } // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last XYZVec start = Geom::toXYZVec(first->position()); - XYZVec end = endPosition(last,straw); + float charge(0.0); + if(pdt->particle(first->simParticle()->pdgId()).isValid()) + charge = pdt->particle(first->simParticle()->pdgId()).ref().charge(); + + XYZVec end = endPosition(last,straw,charge); time = first->time(); // use first time as time of this step (cluster times will be added) mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum // determine the width from the triangle calculation @@ -214,6 +282,19 @@ namespace mu2e { for(auto const& spmcptr : spmcptrs) sgsa_all->addSingle(sgsp,spmcptr); } + if(_diag > 0){ + _erad = sqrt((Geom::Hep3Vec(end)-straw.getMidPoint()).perpPart(straw.getDirection()).mag2()); + _hendrad->Fill(_erad); + _hphi->Fill(_brot); + if(_diag > 1){ + _prilen = pathlen; + _pridist = sqrt((end-start).mag2()); + _partP = mom; + _partPDG = first->simParticle()->pdgId(); + _elen = last->stepLength(); + _sgsdiag->Fill(); + } + } if(_debug > 1){ // checks and printout @@ -227,7 +308,7 @@ namespace mu2e { Hep3Vector hend = Geom::Hep3Vec(end); double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); if(rd2 - r2 > 1e-5 ) cout << "End outside straw, radius " << sqrt(rd2) << endl; - + } } // end of pair loop } // end of collection loop @@ -311,38 +392,34 @@ namespace mu2e { } } - XYZVec MakeStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw) { -// test linear extrapolation first - auto momhat = last->momentum().unit(); - auto end = last->position() + last->stepLength()*momhat; - // check position against straw boundary + XYZVec MakeStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw, float charge) { static const double r2 = straw.innerRadius()*straw.innerRadius(); - double rd2 = (end-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); - if(rd2 > r2) { - // outside the straw: adjust the end position - Hep3Vector mperp; - if(rd2 - r2 < _radtol){ - // close enogh; interpolate linearly along the momentum direction; - mperp = momhat.perpPart(straw.getDirection()); - } else { + XYZVec retval; +// test parabolic extrapolation first + auto momhat = last->momentum().unit(); + _brot = last->stepLength()*_bnom/last->momentum().mag(); // magnetic bending rotation angle + if(_debug > 1){ + cout << "Step Length = " << last->stepLength() << " rotation angle " << _brot << endl; + } + auto rho = _bdir.cross(momhat);// points radially outwards for positive charge + if(_brot < _parrot){ + // estimate end position with a parabolic trajectory + retval = last->position() + last->stepLength()*(momhat -(0.5*charge*_brot)*rho); + } else { + Hep3Vector cdir = (momhat-(0.5*charge*_brot)*rho).unit(); // effective propagation direction + if(_brot > _curlrot) { // curler; assume the net motion is along the BField axis. Sign by the projection of the momentum - mperp = _bdir; - if(momhat.dot(_bdir)<0.0) mperp *= -1.0; - momhat = mperp; - } + cdir = _bdir; + if(momhat.dot(_bdir)<0.0)cdir *= -1.0; + } +// propagate to the straw wall auto pperp = (last->position()-straw.getMidPoint()).perpPart(straw.getDirection()); - double pmdot = pperp.dot(mperp); + double pdot = pperp.dot(cdir); double ppmag2 = pperp.mag2(); - double mpmag2 = mperp.mag2(); - double len = (sqrt(pmdot*pmdot + mpmag2*(r2 - ppmag2))-pmdot)/mpmag2; - end = last->position() + len*momhat; - if(_debug > 1){ - double newr2 =(end-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); - cout <<"Forced in straw, old length = " << last->stepLength() << " new length " << len << " new r2 " << newr2 << endl; - } - - } - return Geom::toXYZVec(end); + double len = sqrt(pdot*pdot + r2 - ppmag2)-pdot; + retval = last->position() + len*cdir; + } + return retval; } } diff --git a/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc b/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc index 78d802572a..e9623d6f8b 100644 --- a/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc +++ b/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc @@ -182,7 +182,7 @@ namespace mu2e { Int_t _tdc[2], _tot[2]; TTree* _sdiag; Float_t _steplen, _stepE, _qsum, _esum, _eesum, _qe, _partP, _steptime; - Int_t _nclusd, _netot, _partPDG; + Int_t _nclust, _netot, _partPDG; vector _clusters; Float_t _ewMarkerOffset; array _ewMarkerROCdt; @@ -298,7 +298,7 @@ namespace mu2e { _sdiag->Branch("eesum",&_eesum,"eesum/F"); _sdiag->Branch("qe",&_qe,"qe/F"); _sdiag->Branch("steptime",&_steptime,"steptime/F"); - _sdiag->Branch("nclust",&_nclusd,"nclust/I"); + _sdiag->Branch("nclust",&_nclust,"nclust/I"); _sdiag->Branch("netot",&_netot,"netot/I"); _sdiag->Branch("partPDG",&_partPDG,"partPDG/I"); _sdiag->Branch("clusters",&_clusters); @@ -690,7 +690,7 @@ namespace mu2e { _steptime = microbunchTime(strawele,_toff.timeWithOffsetsApplied(step)); _partP = step.momentum().mag(); _partPDG = step.simParticle()->pdgId(); - _nclusd = (int)clusters.size(); + _nclust = (int)clusters.size(); _netot = 0; _qsum = _esum = _eesum = 0.0; for(auto iclust=clusters.begin();iclust != clusters.end();++iclust){ From 2f1c00fa946f3c88230edc2e2c44d6a6aaa49982 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Thu, 10 Oct 2019 19:15:40 -0500 Subject: [PATCH 06/18] improve end point and width calculations. Add diagnostics --- TrackerMC/src/MakeStrawGasSteps_module.cc | 47 +++++++++++++++-------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index ed085c7260..2fd140ad5e 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -52,7 +52,7 @@ namespace mu2e { fhicl::Atom parabolicRotation{ Name("parabolicRotation"), Comment("Maximum bending rotation to use parabolic end estimation"),0.15}; //radians fhicl::Atom curlRotation{ Name("curlRotation"), - Comment("Minimum bending rotation to use curl end estimation"),1.0}; //radians + Comment("Minimum bending rotation to use curl end estimation"),2.0}; //radians fhicl::Atom csize{ Name("OutputCollectionSize"), Comment("Estimated size of output collection"), 2000}; fhicl::Atom trackerSteps { Name("trackerStepPoints"), @@ -83,11 +83,12 @@ namespace mu2e { string _trackerSteps, _keepDeltas; // cache the BField direction at the tracker center Hep3Vector _bdir; - float _bnom; // BField in units of mm/MeV/c + float _bnom; // BField in units of (MeV/c)/mm // diagnostic histograms TH1F *_hendrad, *_hphi; TTree* _sgsdiag; - Float_t _prilen, _pridist, _elen, _erad, _epri, _esec, _partP, _brot; + Float_t _prilen, _pridist, _elen, _erad, _epri, _esec, _partP, _brot, _width; + vector _sdist; Int_t _npri, _nsec, _partPDG; }; @@ -128,11 +129,12 @@ namespace mu2e { _sgsdiag->Branch("erad",&_erad,"erad/F"); _sgsdiag->Branch("epri",&_epri,"epri/F"); _sgsdiag->Branch("esec",&_esec,"esec/F"); + _sgsdiag->Branch("width",&_width,"width/F"); _sgsdiag->Branch("npri",&_npri,"npri/I"); _sgsdiag->Branch("nsec",&_nsec,"nsec/I"); _sgsdiag->Branch("partP",&_partP,"partP/F"); _sgsdiag->Branch("partPDG",&_partPDG,"partPDG/I"); - + _sgsdiag->Branch("sdist",&_sdist); } } } @@ -262,13 +264,19 @@ namespace mu2e { if(pdt->particle(first->simParticle()->pdgId()).isValid()) charge = pdt->particle(first->simParticle()->pdgId()).ref().charge(); + XYZVec end = endPosition(last,straw,charge); time = first->time(); // use first time as time of this step (cluster times will be added) mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum - // determine the width from the triangle calculation - double width(0.0); - if(spmcptrs.size() > 1)width = sqrt( pathlen*pathlen - (end-start).mag2())/2.0; - + // determine the width from the sigitta or curl radius + auto pdir = first->momentum().unit(); + auto pperp = pdir.perp(_bdir); + static const float invsqrt12(1.0/sqrt(12.0)); + float rbend = 0.5*mom*pperp/_bnom; // bend radius spread. factor accounts for average over all points + // only sigitta perp to the wire counts + float sint = sqrt((_bdir.cross(pdir).cross(straw.getDirection())).mag2()); + float sag = invsqrt12*sint*pathlen*pathlen*_bnom*pperp/(8.0*mom); + double width = std::min(sag,rbend); // create the gas step StrawGasStep sgs(ispsmap->first.second, ispsmap->first.first, (float)eion,(float)pathlen, (float)width, (float)mom, time, @@ -277,7 +285,7 @@ namespace mu2e { // create the Assns auto sgsp = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); sgsa_primary->addSingle(sgsp,first); - // add Assns for all StepPoints, including delta-rays, for diagnostics + // optionall add Assns for all StepPoints, including delta-rays if(_allAssns){ for(auto const& spmcptr : spmcptrs) sgsa_all->addSingle(sgsp,spmcptr); @@ -292,6 +300,13 @@ namespace mu2e { _partP = mom; _partPDG = first->simParticle()->pdgId(); _elen = last->stepLength(); + _width = width; + _sdist.clear(); + auto sdir = Geom::Hep3Vec(end-start).unit(); + for(auto const& spmcptr : spmcptrs){ + auto dist = ((spmcptr->position()-Geom::Hep3Vec(start)).cross(sdir)).mag(); + _sdist.push_back(dist); + } _sgsdiag->Fill(); } } @@ -393,6 +408,7 @@ namespace mu2e { } XYZVec MakeStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw, float charge) { + // in future we should store the end position in the StepPointMC FIXME! static const double r2 = straw.innerRadius()*straw.innerRadius(); XYZVec retval; // test parabolic extrapolation first @@ -406,17 +422,18 @@ namespace mu2e { // estimate end position with a parabolic trajectory retval = last->position() + last->stepLength()*(momhat -(0.5*charge*_brot)*rho); } else { - Hep3Vector cdir = (momhat-(0.5*charge*_brot)*rho).unit(); // effective propagation direction - if(_brot > _curlrot) { + Hep3Vector cdir; + if(_brot > _curlrot) // curler; assume the net motion is along the BField axis. Sign by the projection of the momentum - cdir = _bdir; - if(momhat.dot(_bdir)<0.0)cdir *= -1.0; - } -// propagate to the straw wall + cdir = _bdir * (momhat.dot(_bdir)>0.0 ? 1.0 : -1.0); + else + cdir = (momhat-(0.5*charge*_brot)*rho).unit(); // effective propagation direction +// propagate to the straw wall auto pperp = (last->position()-straw.getMidPoint()).perpPart(straw.getDirection()); double pdot = pperp.dot(cdir); double ppmag2 = pperp.mag2(); double len = sqrt(pdot*pdot + r2 - ppmag2)-pdot; + len = std::min(last->stepLength(),len); retval = last->position() + len*cdir; } return retval; From f2c0ccca75d5472903be4c154240cda31e61b54a Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Fri, 11 Oct 2019 11:55:07 -0500 Subject: [PATCH 07/18] Small tweaks to width calculation. Add DOCA to diagnostics --- MCDataProducts/inc/StrawGasStep.hh | 4 ++-- TrackerMC/src/MakeStrawGasSteps_module.cc | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/MCDataProducts/inc/StrawGasStep.hh b/MCDataProducts/inc/StrawGasStep.hh index 9ddd686245..ddc606757c 100644 --- a/MCDataProducts/inc/StrawGasStep.hh +++ b/MCDataProducts/inc/StrawGasStep.hh @@ -31,7 +31,7 @@ namespace mu2e { StrawId strawId() const { return _strawId;} Float_t ionizingEdep() const { return _eIon; } Float_t pathLength() const { return _pathLen; } - Float_t radialWidth() const { return _width; } + Float_t radialWidth() const { return _width; } Float_t momentum() const { return _mom; } Double_t time() const { return _time; } XYZVec const& startPosition() const { return _startpos; } @@ -42,7 +42,7 @@ namespace mu2e { StrawId _strawId; // straw Float_t _eIon; // ionization energy deposited in this straw by this particle Float_t _pathLen; // Length the primary particle traveled in this straw gas: this is NOT necessarily the end-start distance - Float_t _width; // transverse radial width of the charge cloud + Float_t _width; // transverse RMS of the charge cloud WRT the wire Float_t _mom; // scalar momentum of the particle in the middle of this gas volume Double_t _time; // time particle enters this gas volume; must be double to allow for long-lived particles XYZVec _startpos, _endpos; //entrance and exit to the gas volume diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index 2fd140ad5e..de3eaf1317 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -20,6 +20,7 @@ #include "GlobalConstantsService/inc/ParticleDataTable.hh" #include "BFieldGeom/inc/BFieldManager.hh" #include "BTrk/BField/BField.hh" +#include "Mu2eUtilities/inc/TwoLinePCA.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "MCDataProducts/inc/MCRelationship.hh" @@ -87,7 +88,7 @@ namespace mu2e { // diagnostic histograms TH1F *_hendrad, *_hphi; TTree* _sgsdiag; - Float_t _prilen, _pridist, _elen, _erad, _epri, _esec, _partP, _brot, _width; + Float_t _prilen, _pridist, _elen, _erad, _epri, _esec, _partP, _brot, _width, _doca; vector _sdist; Int_t _npri, _nsec, _partPDG; }; @@ -130,6 +131,7 @@ namespace mu2e { _sgsdiag->Branch("epri",&_epri,"epri/F"); _sgsdiag->Branch("esec",&_esec,"esec/F"); _sgsdiag->Branch("width",&_width,"width/F"); + _sgsdiag->Branch("doca",&_doca,"doca/F"); _sgsdiag->Branch("npri",&_npri,"npri/I"); _sgsdiag->Branch("nsec",&_nsec,"nsec/I"); _sgsdiag->Branch("partP",&_partP,"partP/F"); @@ -271,12 +273,12 @@ namespace mu2e { // determine the width from the sigitta or curl radius auto pdir = first->momentum().unit(); auto pperp = pdir.perp(_bdir); - static const float invsqrt12(1.0/sqrt(12.0)); - float rbend = 0.5*mom*pperp/_bnom; // bend radius spread. factor accounts for average over all points + float bendrms = 0.5*std::min(straw.innerRadius(),mom*pperp/_bnom); // bend radius spread. 0.5 factor givs RMS of a circle // only sigitta perp to the wire counts - float sint = sqrt((_bdir.cross(pdir).cross(straw.getDirection())).mag2()); - float sag = invsqrt12*sint*pathlen*pathlen*_bnom*pperp/(8.0*mom); - double width = std::min(sag,rbend); + float sint = (_bdir.cross(pdir).cross(straw.getDirection())).mag(); + static const float prms(1.0/(12.0*sqrt(5.0))); // RMS for a parabola. This includes a factor 1/8 for the sagitta calculation too + float sagrms = prms*sint*pathlen*pathlen*_bnom*pperp/mom; + double width = std::min(sagrms,bendrms); // choose the smaller: different approximations work for different momenta/directions // create the gas step StrawGasStep sgs(ispsmap->first.second, ispsmap->first.first, (float)eion,(float)pathlen, (float)width, (float)mom, time, @@ -301,6 +303,10 @@ namespace mu2e { _partPDG = first->simParticle()->pdgId(); _elen = last->stepLength(); _width = width; + // compute DOCA to the wire + TwoLinePCA poca(Geom::Hep3Vec(start),Geom::Hep3Vec(end-start), + straw.getMidPoint(),straw.getDirection()); + _doca = poca.dca(); _sdist.clear(); auto sdir = Geom::Hep3Vec(end-start).unit(); for(auto const& spmcptr : spmcptrs){ From a996316bca44e4fc38909192074528a5d46fe8ea Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Sun, 13 Oct 2019 15:44:18 -0500 Subject: [PATCH 08/18] preliminary version: not yet functional --- .../src/StrawDigisFromStrawGasSteps_module.cc | 1311 +++++++++++++++++ 1 file changed, 1311 insertions(+) create mode 100644 TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc new file mode 100644 index 0000000000..67ad372092 --- /dev/null +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -0,0 +1,1311 @@ +// +// module to convert G4 steps into straw digis. +// It also builds the truth match +// +// Original author David Brown, LBNL +// +// framework +#include "art/Framework/Principal/Event.h" +#include "fhiclcpp/ParameterSet.h" +#include "art/Framework/Principal/Handle.h" +#include "GeometryService/inc/GeomHandle.hh" +#include "art/Framework/Core/EDProducer.h" +#include "GeometryService/inc/DetectorSystem.hh" +#include "art/Framework/Core/ModuleMacros.h" +#include "art_root_io/TFileService.h" +#include "SeedService/inc/SeedService.hh" +#include "cetlib_except/exception.h" +// conditions +#include "ProditionsService/inc/ProditionsHandle.hh" +#include "ConditionsService/inc/ConditionsHandle.hh" +#include "ConditionsService/inc/AcceleratorParams.hh" +#include "TrackerGeom/inc/Tracker.hh" +#include "ConfigTools/inc/ConfigFileLookupPolicy.hh" +#include "TrackerConditions/inc/DeadStraw.hh" +#include "TrackerConditions/inc/StrawElectronics.hh" +#include "TrackerConditions/inc/StrawPhysics.hh" +#include "GeometryService/inc/DetectorSystem.hh" +#include "BFieldGeom/inc/BFieldManager.hh" +#include "BTrk/BField/BField.hh" +#include "GlobalConstantsService/inc/GlobalConstantsHandle.hh" +#include "GlobalConstantsService/inc/ParticleDataTable.hh" +// utiliities +#include "Mu2eUtilities/inc/TwoLinePCA.hh" +#include "Mu2eUtilities/inc/SimParticleTimeOffset.hh" +#include "DataProducts/inc/TrkTypes.hh" +// data +#include "DataProducts/inc/EventWindowMarker.hh" +#include "DataProducts/inc/StrawId.hh" +#include "RecoDataProducts/inc/StrawDigiCollection.hh" +#include "MCDataProducts/inc/StepPointMCCollection.hh" +#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" +#include "MCDataProducts/inc/StrawDigiMCCollection.hh" +// MC structures +#include "TrackerMC/inc/StrawClusterSequencePair.hh" +#include "TrackerMC/inc/StrawWaveform.hh" +#include "TrackerMC/inc/IonCluster.hh" +//CLHEP +#include "CLHEP/Random/RandGaussQ.h" +#include "CLHEP/Random/RandFlat.h" +#include "CLHEP/Random/RandExponential.h" +#include "CLHEP/Random/RandPoisson.h" +#include "CLHEP/Vector/LorentzVector.h" +// root +#include "TMath.h" +#include "TH1F.h" +#include "TH2F.h" +#include "TGraph.h" +#include "TMarker.h" +#include "TTree.h" +// C++ +#include +#include +#include +#include +#include +using namespace std; +using CLHEP::Hep3Vector; +namespace mu2e { + namespace TrackerMC { + using namespace TrkTypes; + + struct WireCharge { // charge at the wire after drift + double _charge; // charge at the wire, in units of pC + double _time; // relative time at the wire, relative to ionzation time (ns) + double _dd; // transverse distance drifted to the wrie + double _phi; //JB: angle between E and B at ionization event + double _wpos; // position long the wire, WRT the wire center, signed by the wire direction + + }; + + struct WireEndCharge { // charge at one end of the wire after propagation + double _charge; // charge at the wire, in units of pC + double _time; // time at the wire end, relative to the time the charge reached the wire (ns) + double _wdist; // propagation distance from the point of collection to the end + }; + + class StrawDigisFromStrawGasSteps : public art::EDProducer { + + public: + typedef map StrawClusterMap; // clusts by straw + typedef vector > StrawSPMCPV; // vector of associated StepPointMCs for a single straw/particle + // work with pairs of waveforms, one for each straw end + typedef std::array SWFP; + typedef std::array WFXP; + typedef list WFXPList; + typedef WFXPList::const_iterator WFXPI; + + explicit StrawDigisFromStrawGasSteps(fhicl::ParameterSet const& pset); + // Accept compiler written d'tor. + + private: + + void beginJob() override; + void beginRun(art::Run& run) override; + void produce(art::Event& e) override; + + // Diagnostics level. + int _debug, _diag, _printLevel; + unsigned _maxhist; + bool _xtalkhist; + unsigned _minnxinghist; + double _tstep, _nfall; + // Limit on number of events for which there will be full printout. + int _maxFullPrint; + // Name of the tracker StepPoint collection + string _trackerStepPoints; + + // Parameters + bool _addXtalk; // should we add cross talk hits? + double _ctMinCharge; // minimum charge to add cross talk (for performance issues) + bool _addNoise; // should we add noise hits? + double _preampxtalk, _postampxtalk; // x-talk parameters; these should come from conditions, FIXME!! + double _bgcut; // cut dividing 'min-ion' particles from highly-ionizing + double _minstepE; // minimum step energy to simulate + art::InputTag _ewMarkerTag; // name of the module that makes eventwindowmarkers + double _mbtime; // period of 1 microbunch + double _mbbuffer; // buffer on that for ghost clusts (for waveform) + double _adcbuffer; // time buffer for ADC + double _steptimebuf; // buffer for MC step point times + double _tdcbuf; // buffer for TDC jitter + uint16_t _allStraw; // minimum straw # to read all hits + std::vector _allPlanes; // planes in which to read all hits + // models of straw response to stimuli + ProditionsHandle _strawphys_h; + ProditionsHandle _strawele_h; + SimParticleTimeOffset _toff; + StrawElectronics::Path _diagpath; // electronics path for waveform diagnostics + // Random number distributions + art::RandomNumberGenerator::base_engine_t& _engine; + CLHEP::RandGaussQ _randgauss; + CLHEP::RandFlat _randflat; + CLHEP::RandExponential _randexp; + CLHEP::RandPoisson _randP; + // A category for the error logger. + const string _messageCategory; + // Give some informationation messages only on the first event. + bool _firstEvent; + // record the BField direction at the tracker center + Hep3Vector _bdir; + // minimum pt (perp to bfield) to assume straight trajectory in a starw + double _ptmin, _ptfac; + // max # clusters for modeling non-minion steps + unsigned _maxnclu; + bool _sort; // sort cluster sizes before filling energy + // List of dead straws as a parameter set; needed at beginRun time. + ProditionsHandle _deadStraw_h; + + // diagnostics + TTree* _swdiag; + Int_t _swplane, _swpanel, _swlayer, _swstraw, _ndigi; + Float_t _hqsum[2], _vmax[2], _tvmax[2], _sesum[2]; + Int_t _wmcpdg[2], _wmcproc[2], _nxing[2], _nclu[2]; + Int_t _nsteppoint[2], _npart[2]; + Float_t _mce[2], _slen[2], _sedep[2]; + Float_t _tmin[2], _tmax[2], _txing[2], _xddist[2], _xwdist[2], _xpdist[2]; + TTree* _sddiag; + Int_t _sdplane, _sdpanel, _sdlayer, _sdstraw; + Int_t _ncludd[2], _iclust[2]; + Int_t _nstep; + Float_t _ectime[2], _ecddist[2], _ecdtime[2], _ecptime[2]; + Float_t _xtime[2], _tctime[2], _charge[2], _ddist[2], _dtime[2], _ptime[2]; + Float_t _wdist[2], _vstart[2], _vcross[2]; + Float_t _phi[2]; //JB + Float_t _mcenergy, _mctrigenergy, _mcthreshenergy; + Double_t _mctime; + Int_t _mcthreshpdg, _mcthreshproc, _mcnstep; + Float_t _mcdca, _mcdcaphi, _mcdcadtime; + Int_t _dmcpdg, _dmcproc, _dmcgen; + Float_t _dmcmom; + Bool_t _xtalk; + vector _adc; + Int_t _tdc[2], _tot[2]; + TTree* _sdiag; + Float_t _steplen, _stepE, _qsum, _esum, _eesum, _qe, _partP, _steptime; + Int_t _nclust, _netot, _partPDG; + vector _clusters; + Float_t _ewMarkerOffset; + array _ewMarkerROCdt; + + // helper functions + void fillClusterMap(art::Event const& event, StrawClusterMap & hmap); + void addStep(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + art::Ptr const& spmcptr, + Straw const& straw, StrawClusterSequencePair& shsp); + void divideStep(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + StepPointMC const& step, vector& clusters); + void driftCluster(StrawPhysics const& strawphys, Straw const& straw, + IonCluster const& cluster, WireCharge& wireq); + void propagateCharge(StrawPhysics const& strawphys, Straw const& straw, + WireCharge const& wireq, StrawEnd end, WireEndCharge& weq); + double microbunchTime(StrawElectronics const& strawele, double globaltime) const; + void addGhosts(StrawElectronics const& strawele, StrawCluster const& clust,StrawClusterSequence& shs); + void addNoise(StrawClusterMap& hmap); + void findThresholdCrossings(StrawElectronics const& strawele, SWFP const& swfp, WFXPList& xings); + void createDigis(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + StrawClusterSequencePair const& hsp, + XTalk const& xtalk, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, + PtrStepPointMCVectorCollection* mcptrs ); + void fillDigis(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + WFXPList const& xings,SWFP const& swfp , StrawId sid, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, + PtrStepPointMCVectorCollection* mcptrs ); + bool createDigi(StrawElectronics const& strawele,WFXP const& xpair, SWFP const& wf, StrawId sid, StrawDigiCollection* digis); + void findCrossTalkStraws(Straw const& straw,vector& xtalk); + void fillClusterNe(StrawPhysics const& strawphys,std::vector& me); + void fillClusterPositions(Straw const& straw, StepPointMC const& step, std::vector& cpos); + void fillClusterMinion(StrawPhysics const& strawphys, StepPointMC const& step, std::vector& me, std::vector& cen); + bool readAll(StrawId const& sid) const; + // diagnostic functions + void waveformHist(StrawElectronics const& strawele, + SWFP const& wf, WFXPList const& xings); + void waveformDiag(StrawElectronics const& strawele, + SWFP const& wf, WFXPList const& xings); + void digiDiag(StrawPhysics const& strawphys, SWFP const& wf, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi); + + struct Config { + + + }; + }; + + StrawDigisFromStrawGasSteps::StrawDigisFromStrawGasSteps(fhicl::ParameterSet const& pset) : + EDProducer{pset}, + // diagnostic parameters + _debug(pset.get("debugLevel",0)), + _diag(pset.get("diagLevel",0)), + _printLevel(pset.get("printLevel",0)), + _maxhist(pset.get("MaxHist",100)), + _xtalkhist(pset.get("CrossTalkHist",false)), + _minnxinghist(pset.get("MinNXingHist",1)), // minimum # of crossings to histogram waveform + _tstep(pset.get("WaveformStep",0.1)), // ns + _nfall(pset.get("WaveformTail",10.0)), // # of decay lambda past last signal to record waveform + // Parameters + _maxFullPrint(pset.get("maxFullPrint",2)), + _trackerStepPoints(pset.get("trackerStepPoints","tracker")), + _addXtalk(pset.get("addCrossTalk",false)), + _ctMinCharge(pset.get("xtalkMinimumCharge",0)), + _addNoise(pset.get("addNoise",false)), + _preampxtalk(pset.get("preAmplificationCrossTalk",0.0)), + _postampxtalk(pset.get("postAmplificationCrossTalk",0.02)), // dimensionless relative coupling + _bgcut(pset.get("BetaGammaCut",0.5)), // treat particles with beta-gamma above this as minimum-ionizing + _minstepE(pset.get("minstepE",2.0e-6)), // minimum step energy depostion to turn into a straw signal (MeV) + _ewMarkerTag(pset.get("EventWindowMarkerLabel","EWMProducer")), + _steptimebuf(pset.get("StepPointMCTimeBuffer",100.0)), // nsec + _tdcbuf(pset.get("TDCTimeBuffer",2.0)), // nsec + _allStraw(pset.get("AllHitsStraw",90)), + _allPlanes(pset.get>("AllHitsPlanes",std::vector{})), // planes to read all hits + _toff(pset.get("TimeOffsets", {})), + _diagpath(static_cast(pset.get("WaveformDiagPath",StrawElectronics::thresh))), + // Random number distributions + _engine(createEngine( art::ServiceHandle()->getSeed())), + _randgauss( _engine ), + _randflat( _engine ), + _randexp( _engine), + _randP( _engine), + _messageCategory("HITS"), + _firstEvent(true), // Control some information messages. + _ptfac(pset.get("PtFactor", 2.0)), // factor for defining curling in a straw + _maxnclu(pset.get("MaxNClusters", 10)), // max # of clusters for low-PT steps + _sort(pset.get("SortClusterEnergy",false)) + { + // Tell the framework what we consume. + consumesMany(); + consumes(_ewMarkerTag); + // Since SimParticleTimeOffset calls getValidHandle, we have to + // declare the consumes statements here. + auto const& toffInputs = pset.get>("TimeOffsets.inputs", {}); + for (auto const& tag : toffInputs) { + consumes(tag); + } + // Tell the framework what we make. + produces(); + produces(); + produces(); + } + + void StrawDigisFromStrawGasSteps::beginJob(){ + + if(_diag > 0){ + + art::ServiceHandle tfs; + _sdiag =tfs->make("sdiag","Step diagnostics"); + _sdiag->Branch("steplen",&_steplen,"steplen/F"); + _sdiag->Branch("stepE",&_stepE,"stepE/F"); + _sdiag->Branch("partP",&_partP,"partP/F"); + _sdiag->Branch("qsum",&_qsum,"qsum/F"); + _sdiag->Branch("esum",&_esum,"esum/F"); + _sdiag->Branch("eesum",&_eesum,"eesum/F"); + _sdiag->Branch("qe",&_qe,"qe/F"); + _sdiag->Branch("steptime",&_steptime,"steptime/F"); + _sdiag->Branch("nclust",&_nclust,"nclust/I"); + _sdiag->Branch("netot",&_netot,"netot/I"); + _sdiag->Branch("partPDG",&_partPDG,"partPDG/I"); + _sdiag->Branch("clusters",&_clusters); + + _swdiag =tfs->make("swdiag","StrawWaveform diagnostics"); + _swdiag->Branch("plane",&_swplane,"plane/I"); + _swdiag->Branch("panel",&_swpanel,"panel/I"); + _swdiag->Branch("layer",&_swlayer,"layer/I"); + _swdiag->Branch("straw",&_swstraw,"straw/I"); + _swdiag->Branch("ndigi",&_ndigi,"ndigi/I"); + _swdiag->Branch("hqsum",&_hqsum,"hqsumcal/F:hqsumhv/F"); + _swdiag->Branch("vmax",&_vmax,"vmaxcal/F:vmaxhv/F"); + _swdiag->Branch("tvmax",&_tvmax,"tvmaxcal/F:tvmaxhv/F"); + _swdiag->Branch("mcpdg",&_wmcpdg,"mcpdgcal/I:mcpdghv/I"); + _swdiag->Branch("mcproc",&_wmcproc,"mcproccal/I:mcprochv/I"); + _swdiag->Branch("mce",&_mce,"mcecal/F:mcehv/F"); + _swdiag->Branch("slen",&_slen,"slencal/F:slenhv/F"); + _swdiag->Branch("sedep",&_sedep,"sedepcal/F:sedephv/F"); + _swdiag->Branch("nxing",&_nxing,"nxingcal/I:nxinghv/I"); + _swdiag->Branch("nclust",&_nclu,"nclucal/I:ncluhv/I"); + _swdiag->Branch("nstep",&_nsteppoint,"nscal/I:nshv/I"); + _swdiag->Branch("sesum",&_sesum,"sesumcal/F:sesumhv/F"); + _swdiag->Branch("npart",&_npart,"npart/I"); + _swdiag->Branch("tmin",&_tmin,"tmincal/F:tminhv/F"); + _swdiag->Branch("tmax",&_tmax,"tmaxcal/F:tmaxhv/F"); + _swdiag->Branch("txing",&_txing,"txcal/F:txhv/F"); + _swdiag->Branch("xddist",&_xddist,"xdcal/F:xdhv/F"); + _swdiag->Branch("xwdist",&_xwdist,"xwdcal/F:xwdhv/F"); + _swdiag->Branch("xpdist",&_xpdist,"xpdcal/F:xpdhv/F"); + + + if(_diag > 1){ + _sddiag =tfs->make("sddiag","StrawDigi diagnostics"); + _sddiag->Branch("plane",&_sdplane,"plane/I"); + _sddiag->Branch("panel",&_sdpanel,"panel/I"); + _sddiag->Branch("layer",&_sdlayer,"layer/I"); + _sddiag->Branch("straw",&_sdstraw,"straw/I"); + _sddiag->Branch("nstep",&_nstep,"nstep/I"); + _sddiag->Branch("xtime",&_xtime,"xtimecal/F:xtimehv/F"); + _sddiag->Branch("tctime",&_tctime,"tctimecal/F:tctimehv/F"); + _sddiag->Branch("ectime",&_ectime,"ectimecal/F:ectimehv/F"); + _sddiag->Branch("ecdtime",&_ecdtime,"ecdtimecal/F:ecdtimehv/F"); + _sddiag->Branch("ecptime",&_ecptime,"ecptimecal/F:ecptimehv/F"); + _sddiag->Branch("charge",&_charge,"chargecal/F:chargehv/F"); + _sddiag->Branch("wdist",&_wdist,"wdistcal/F:wdisthv/F"); + _sddiag->Branch("phi",&_phi,"phical/F:phihv/F");//JB + _sddiag->Branch("ecddist",&_ecddist,"ecddistcal/F:ecddisthv/F"); + _sddiag->Branch("vstart",&_vstart,"vstartcal/F:vstarthv/F"); + _sddiag->Branch("vcross",&_vcross,"vcrosscal/F:vcrosshv/F"); + _sddiag->Branch("ddist",&_ddist,"ddistcal/F:ddisthv/F"); + _sddiag->Branch("dtime",&_dtime,"dtimecal/F:dtimehv/F"); + _sddiag->Branch("ptime",&_ptime,"ptimecal/F:ptimehv/F"); + _sddiag->Branch("nclust",&_ncludd,"nclustcal/I:nclusthv/I"); + _sddiag->Branch("iclust",&_iclust,"iclustcal/I:iclusthv/I"); + _sddiag->Branch("tdc",&_tdc,"tdccal/I:tdchv/I"); + _sddiag->Branch("tot",&_tot,"totcal/I:tothv/I"); + _sddiag->Branch("adc",&_adc); + _sddiag->Branch("mctime",&_mctime,"mctime/D"); + _sddiag->Branch("mcenergy",&_mcenergy,"mcenergy/F"); + _sddiag->Branch("mctrigenergy",&_mctrigenergy,"mctrigenergy/F"); + _sddiag->Branch("mcthreshenergy",&_mcthreshenergy,"mcthreshenergy/F"); + _sddiag->Branch("mcthreshpdg",&_mcthreshpdg,"mcthreshpdg/I"); + _sddiag->Branch("mcthreshproc",&_mcthreshproc,"mcthreshproc/I"); + _sddiag->Branch("mcnstep",&_mcnstep,"mcnstep/I"); + _sddiag->Branch("mcdca",&_mcdca,"mcdca/F"); + _sddiag->Branch("mcdcaphi",&_mcdcaphi,"mcdcaphi/F"); + _sddiag->Branch("mcdcadtime",&_mcdcadtime,"mcdcadtime/F"); + _sddiag->Branch("mcpdg",&_dmcpdg,"mcpdg/I"); + _sddiag->Branch("mcproc",&_dmcproc,"mcproc/I"); + _sddiag->Branch("mcgen",&_dmcgen,"mcgen/I"); + _sddiag->Branch("mcmom",&_dmcmom,"mcmom/F"); + _sddiag->Branch("xtalk",&_xtalk,"xtalk/B"); + + } + } + } + + void StrawDigisFromStrawGasSteps::beginRun( art::Run& run ){ + // get field at the center of the tracker + GeomHandle bfmgr; + GeomHandle det; + Hep3Vector vpoint_mu2e = det->toMu2e(Hep3Vector(0.0,0.0,0.0)); + Hep3Vector b0 = bfmgr->getBField(vpoint_mu2e); + // if the field is too small, don't perform any curvature-based analysis + if ( b0.mag() < 1.0e-4 ){ + _bdir = Hep3Vector(0.0,0.0,1.0); + _ptmin = -1.0; + } else { + _bdir = b0.unit(); + //compute the transverse momentum for which a particle will curl up in a straw + const Tracker& tracker = *GeomHandle(); + const Straw& straw = tracker.getStraw(StrawId(0,0,0)); + double rstraw = straw.getRadius(); + _ptmin = _ptfac*BField::mmTeslaToMeVc*b0.mag()*rstraw; + } + if ( _printLevel > 0 ) { + auto const& strawphys = _strawphys_h.get(run.id()); + strawphys.print(cout); + } + } + + void StrawDigisFromStrawGasSteps::produce(art::Event& event) { + if ( _printLevel > 1 ) cout << "StrawDigisFromStrawGasSteps: produce() begin; event " << event.id().event() << endl; + static int ncalls(0); + ++ncalls; + // update conditions caches. + ConditionsHandle accPar("ignored"); + _mbtime = accPar->deBuncherPeriod; + _toff.updateMap(event); + StrawElectronics const& strawele = _strawele_h.get(event.id()); + StrawPhysics const& strawphys = _strawphys_h.get(event.id()); + art::Handle ewMarkerHandle; + event.getByLabel(_ewMarkerTag, ewMarkerHandle); + const EventWindowMarker& ewMarker(*ewMarkerHandle); + _ewMarkerOffset = ewMarker.timeOffset(); + // calculate event window marker jitter for this microbunch for each panel + for (size_t i=0;i(); + // make the microbunch buffer long enough to get the full waveform + _mbbuffer = (strawele.nADCSamples() - strawele.nADCPreSamples())*strawele.adcPeriod(); + _adcbuffer = 0.01*strawele.adcPeriod(); + // Containers to hold the output information. + unique_ptr digis(new StrawDigiCollection); + unique_ptr mcdigis(new StrawDigiMCCollection); + unique_ptr mcptrs(new PtrStepPointMCVectorCollection); + // create the StrawCluster map + StrawClusterMap hmap; + // fill this from the event + fillClusterMap(event,hmap); + // add noise clusts + if(_addNoise)addNoise(hmap); + // loop over the clust sequences + for(auto ihsp=hmap.begin();ihsp!= hmap.end();++ihsp){ + StrawClusterSequencePair const& hsp = ihsp->second; + // create primary digis from this clust sequence + XTalk self(hsp.strawId()); // this object represents the straws coupling to itself, ie 100% + createDigis(strawphys,strawele,hsp,self,digis.get(),mcdigis.get(),mcptrs.get()); + // if we're applying x-talk, look for nearby coupled straws + if(_addXtalk) { + // only apply if the charge is above a threshold + double totalCharge = 0; + for(auto ih=hsp.clustSequence(StrawEnd::cal).clustList().begin();ih!= hsp.clustSequence(StrawEnd::cal).clustList().end();++ih){ + totalCharge += ih->charge(); + } + if( totalCharge > _ctMinCharge){ + vector xtalk; + Straw const& straw = tracker.getStraw(hsp.strawId()); + findCrossTalkStraws(straw,xtalk); + for(auto ixtalk=xtalk.begin();ixtalk!=xtalk.end();++ixtalk){ + createDigis(strawphys,strawele,hsp,*ixtalk,digis.get(),mcdigis.get(),mcptrs.get()); + } + } + } + } + // store the digis in the event + event.put(move(digis)); + // store MC truth match + event.put(move(mcdigis)); + event.put(move(mcptrs)); + if ( _printLevel > 1 ) cout << "StrawDigisFromStrawGasSteps: produce() end" << endl; + // Done with the first event; disable some messages. + _firstEvent = false; + } // end produce + + void StrawDigisFromStrawGasSteps::createDigis( + StrawPhysics const& strawphys, + StrawElectronics const& strawele, + StrawClusterSequencePair const& hsp, XTalk const& xtalk, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, + PtrStepPointMCVectorCollection* mcptrs ) { + // instantiate waveforms for both ends of this straw + SWFP waveforms ={ StrawWaveform(hsp.clustSequence(StrawEnd::cal),xtalk), + StrawWaveform(hsp.clustSequence(StrawEnd::hv),xtalk) }; + // find the threshold crossing points for these waveforms + WFXPList xings; + // find the threshold crossings + findThresholdCrossings(strawele,waveforms,xings); + // convert the crossing points into digis, and add them to the event data + fillDigis(strawphys,strawele,xings,waveforms,xtalk._dest,digis,mcdigis,mcptrs); + // waveform diagnostics + if (_diag >1 && ( + waveforms[0].clusts().clustList().size() > 0 || + waveforms[1].clusts().clustList().size() > 0 ) ) { + // waveform xing diagnostics + _ndigi = digis->size(); + waveformDiag(strawele,waveforms,xings); + // waveform histograms + if(_diag > 2 )waveformHist(strawele,waveforms,xings); + } + } + + void StrawDigisFromStrawGasSteps::fillClusterMap(art::Event const& event, StrawClusterMap & hmap){ + // get conditions + DeadStraw const& deadStraw = _deadStraw_h.get(event.id()); + StrawPhysics const& strawphys = _strawphys_h.get(event.id()); + StrawElectronics const& strawele = _strawele_h.get(event.id()); + const Tracker& tracker = *GeomHandle(); + // Get all of the tracker StepPointMC collections from the event: + typedef vector< art::Handle > HandleVector; + // This selector will select only data products with the given instance name. + art::ProductInstanceNameSelector selector(_trackerStepPoints); + HandleVector stepsHandles; + event.getMany( selector, stepsHandles); + // Informational message on the first event. + if ( _firstEvent ) { + mf::LogInfo log(_messageCategory); + log << "StrawDigisFromStrawGasSteps::fillHitMap will use StepPointMCs from: \n"; + for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); + i != e; ++i ){ + art::Provenance const& prov(*(i->provenance())); + log << " " << prov.branchName() << "\n"; + } + } + if(stepsHandles.empty()){ + throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StepPointMC collections found for tracker" << endl; + } + // Loop over StepPointMC collections + for ( HandleVector::const_iterator ispmcc=stepsHandles.begin(), espmcc=stepsHandles.end();ispmcc != espmcc; ++ispmcc ){ + art::Handle const& handle(*ispmcc); + StepPointMCCollection const& steps(*handle); + // Loop over the StepPointMCs in this collection + for (size_t ispmc =0; ispmc _minstepE){ + // create ptr to MC truth, used for references + art::Ptr spmcptr(handle,ispmc); + // create a clust from this step, and add it to the clust map + addStep(strawphys,strawele,spmcptr,straw,hmap[sid]); + } + } + } + } + } + + void StrawDigisFromStrawGasSteps::addStep(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + art::Ptr const& spmcptr, + Straw const& straw, StrawClusterSequencePair& shsp) { + StepPointMC const& step = *spmcptr; + StrawId sid = straw.id(); + // get time offset for this step + double tstep = _toff.timeWithOffsetsApplied(step); + // test if this step point is roughly in the digitization window + double mbtime = microbunchTime(strawele,tstep); + if( (mbtime > strawele.flashEnd() - _steptimebuf + && mbtime < strawele.flashStart()) + || readAll(sid)) { + // Subdivide the StepPointMC into ionization clusters + _clusters.clear(); + divideStep(strawphys,strawele,step,_clusters); + // check + if(_debug > 1){ + double ec(0.0); + double ee(0.0); + double eq(0.0); + for (auto const& cluster : _clusters) { + ec += cluster._eion; + ee += strawphys.ionizationEnergy(cluster._ne); + eq += strawphys.ionizationEnergy(cluster._charge); + } + cout << "step with ionization edep = " << step.ionizingEdep() + << " creates " << _clusters.size() + << " clusters with total cluster energy = " << ec + << " electron count energy = " << ee + << " charge energy = " << eq << endl; + } + // drift these clusters to the wire, and record the charge at the wire + for(auto iclu = _clusters.begin(); iclu != _clusters.end(); ++iclu){ + WireCharge wireq; + driftCluster(strawphys,straw,*iclu,wireq); + // propagate this charge to each end of the wire + for(size_t iend=0;iend<2;++iend){ + StrawEnd end(static_cast(iend)); + // compute the longitudinal propagation effects + WireEndCharge weq; + propagateCharge(strawphys,straw,wireq,end,weq); + // compute the total time, modulo the microbunch + double gtime = tstep + wireq._time + weq._time; + // convert from + double ctime = microbunchTime(strawele,gtime); + // create the clust + StrawCluster clust(StrawCluster::primary,sid,end,ctime,weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time, + spmcptr,CLHEP::HepLorentzVector(iclu->_pos,mbtime)); //JB: + wireq._phi + + // add the clusts to the appropriate sequence. + shsp.clustSequence(end).insert(clust); + // if required, add a 'ghost' copy of this clust + addGhosts(strawele,clust,shsp.clustSequence(end)); + } + } + } + } + + void StrawDigisFromStrawGasSteps::divideStep(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + StepPointMC const& step, vector& clusters) { + // get particle charge + double charge(0.0); + GlobalConstantsHandle pdt; + if(pdt->particle(step.simParticle()->pdgId()).isValid()){ + charge = pdt->particle(step.simParticle()->pdgId()).ref().charge(); + } + + // get tracker information + const Tracker& tracker = *GeomHandle(); //JB + const Straw& straw = tracker.getStraw(step.strawId());//JB + // if the step length is small compared to the mean free path, or this is an + // uncharged particle, put all the energy in a single cluster + if (charge == 0.0 || step.stepLength() < strawphys.meanFreePath()){ + double cen = step.ionizingEdep(); + double fne = cen/strawphys.meanElectronEnergy(); + unsigned ne = std::max( static_cast(_randP(fne)),(unsigned)1); + + Hep3Vector cdir = (step.position()-straw.getMidPoint());//JB + cdir -= straw.getDirection()*(cdir.dot(straw.getDirection()));//JB + double phi = cdir.theta(); //JB + for (size_t i=0;iparticle(step.simParticle()->pdgId()).isValid()){ + double mass = pdt->particle(step.simParticle()->pdgId()).ref().mass(); + double mom = step.momentum().mag(); + // approximate pt + double apt = 0.; + if ( _bdir.mag() > 0 ) apt = step.momentum().perpPart(_bdir).mag(); + double bg = mom/mass; // beta x gamma + minion = bg > _bgcut && apt > _ptmin; + } + + + // compute the number of clusters for this step from the mean free path + double fnc = step.stepLength()/strawphys.meanFreePath(); + // use a truncated Poisson distribution; this keeps both the mean and variance physical + unsigned nc = std::max(static_cast(_randP.fire(fnc)),(unsigned)1); + if(!minion)nc = std::min(nc,_maxnclu); + // require clusters not exceed the energy sum required for single-electron clusters + nc = std::min(nc,static_cast(floor(step.ionizingEdep()/strawphys.ionizationEnergy((unsigned)1)))); + // generate random positions for the clusters + std::vector cpos(nc); + fillClusterPositions(straw,step,cpos); + // generate electron counts and energies for these clusters: minion model is more detailed + std::vector ne(nc); + std::vector cen(nc); + if(minion){ + fillClusterMinion(strawphys,step,ne,cen); + } else { + // get Poisson distribution of # of electrons for the average energy + double fne = step.ionizingEdep()/(nc*strawphys.meanElectronEnergy()); // average # of electrons/cluster for non-minion clusters + for(unsigned ic=0;ic(std::max(_randP.fire(fne),(long)1)); + cen[ic] = ne[ic]*strawphys.meanElectronEnergy(); // average energy per electron, works for large numbers of electrons + } + } + // create the cluster objects + for(unsigned ic=0;ic 0){ + _steplen = step.stepLength(); + _stepE = step.ionizingEdep(); + _steptime = microbunchTime(strawele,_toff.timeWithOffsetsApplied(step)); + _partP = step.momentum().mag(); + _partPDG = step.simParticle()->pdgId(); + _nclust = (int)clusters.size(); + _netot = 0; + _qsum = _esum = _eesum = 0.0; + for(auto iclust=clusters.begin();iclust != clusters.end();++iclust){ + _netot += iclust->_ne; + _qsum += iclust->_charge; + _esum += iclust->_eion; + _eesum += strawphys.meanElectronEnergy()*iclust->_ne; + } + _qe = strawphys.ionizationEnergy(_qsum); + _sdiag->Fill(); + } + } + + void StrawDigisFromStrawGasSteps::driftCluster( + StrawPhysics const& strawphys,Straw const& straw, + IonCluster const& cluster, WireCharge& wireq ) { + // Compute the vector from the cluster to the wire + Hep3Vector cpos = cluster._pos-straw.getMidPoint(); + // drift distance perp to wire, and angle WRT magnetic field (for Lorentz effect) + double dd = min(cpos.perp(straw.getDirection()),straw.innerRadius()); + // sample the gain for this cluster + double gain = strawphys.clusterGain(_randgauss, _randflat, cluster._ne); + wireq._charge = cluster._charge*(gain); + // compute drift time for this cluster + double dt = strawphys.driftDistanceToTime(dd,cluster._phi); //JB: this is now from the lorentz corrected r-component of the drift + wireq._phi = cluster._phi; //JB + wireq._time = _randgauss.fire(dt,strawphys.driftTimeSpread(dd)); + wireq._dd = dd; + // position along wire + wireq._wpos = cpos.dot(straw.getDirection()); + + } + + void StrawDigisFromStrawGasSteps::propagateCharge( + StrawPhysics const& strawphys, Straw const& straw, + WireCharge const& wireq, StrawEnd end, WireEndCharge& weq) { + // compute distance to the appropriate end + double wlen = straw.halfLength(); // use the full length, not the active length + // NB: the following assumes the straw direction points in increasing azimuth. FIXME! + if(end == StrawEnd::hv) + weq._wdist = wlen - wireq._wpos; + else + weq._wdist = wlen + wireq._wpos; + // split the charge + weq._charge = 0.5*wireq._charge; + weq._time = strawphys.propagationTime(weq._wdist); + } + + double StrawDigisFromStrawGasSteps::microbunchTime(StrawElectronics const& strawele, double globaltime) const { + // converts time from proton beam time (StepPointMC time) to event window marker time + // fold time relative to MB frequency + double mbtime = fmod(globaltime - _ewMarkerOffset,_mbtime); + // keep the microbunch time contiguous + if(mbtime < strawele.flashStart()-_mbtime ) mbtime += _mbtime; + return mbtime; + } + + void StrawDigisFromStrawGasSteps::addGhosts(StrawElectronics const& strawele,StrawCluster const& clust,StrawClusterSequence& shs) { + // add enough buffer to cover both the flash blanking and the ADC waveform + if(clust.time() < strawele.flashStart() - _mbtime + _mbbuffer) + shs.insert(StrawCluster(clust,_mbtime)); + if(clust.time() > _mbtime - _mbbuffer) shs.insert(StrawCluster(clust,-_mbtime)); + } + + void StrawDigisFromStrawGasSteps::findThresholdCrossings(StrawElectronics const& strawele, SWFP const& swfp, WFXPList& xings){ + //randomize the threshold to account for electronics noise; this includes parts that are coherent + // for both ends (coming from the straw itself) + // Keep track of crossings on each end to keep them in sequence + double strawnoise = _randgauss.fire(0,strawele.strawNoise()); + // add specifics for each end + double thresh[2] = {_randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(0))+strawnoise,strawele.analogNoise(StrawElectronics::thresh)), + _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(1))+strawnoise,strawele.analogNoise(StrawElectronics::thresh))}; + // Initialize search when the electronics becomes enabled: + double tstart =strawele.flashEnd() - 10.0; // this buffer should be a parameter FIXME! + // for reading all hits, make sure we start looking for clusters at the minimum possible cluster time + // this accounts for deadtime effects from previous microbunches + if(readAll(swfp[0].strawId()))tstart = -strawele.deadTimeAnalog(); + WFXP wfx = {WFX(swfp[0],tstart),WFX(swfp[1],tstart)}; + // search for coherent crossings on both ends + bool crosses[2]; + for(size_t iend=0;iend<2;++iend){ + crosses[iend] = swfp[iend].crossesThreshold(strawele,thresh[iend],wfx[iend]); + } + // loop until we hit the end of the waveforms. Require both in time. Buffer to account for eventual TDC jitter + // this is a loose pre-selection, final selection is done at digitization + while( crosses[0] && crosses[1] && std::max(wfx[0]._time,wfx[1]._time) + < strawele.flashStart() + strawele.electronicsTimeDelay() + _tdcbuf){ + // see if the crossings match + if(strawele.combineEnds(wfx[0]._time,wfx[1]._time)){ + // put the pair of crossings in the crosing list + // make sure the time is positive in case this was a hit from the 'previous' microbunch + if(std::min(wfx[0]._time,wfx[1]._time) > 0.0 )xings.push_back(wfx); + // search for next crossing: + // update threshold for straw noise + strawnoise = _randgauss.fire(0,strawele.strawNoise()); + for(unsigned iend=0;iend<2;++iend){ + // insure a minimum time buffer between crossings + wfx[iend]._time += strawele.deadTimeAnalog(); + // skip to the next clust + ++(wfx[iend]._iclust); + // update threshold for incoherent noise + thresh[iend] = _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(iend)),strawele.analogNoise(StrawElectronics::thresh)); + // find next crossing + crosses[iend] = swfp[iend].crossesThreshold(strawele,thresh[iend],wfx[iend]); + } + } else { + // skip to the next crossing on the earlier waveform + unsigned iearly = wfx[0]._time < wfx[1]._time ? 0 : 1; + ++(wfx[iearly]._iclust); + wfx[iearly]._time += strawele.deadTimeAnalog(); + crosses[iearly] = swfp[iearly].crossesThreshold(strawele,thresh[iearly],wfx[iearly]); + } + } + } + + void StrawDigisFromStrawGasSteps::fillDigis(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + WFXPList const& xings, SWFP const& wf, + StrawId sid, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, + PtrStepPointMCVectorCollection* mcptrs ){ + // loop over crossings + for(auto xpair : xings) { + // create a digi from this pair. This also performs a finial test + // on whether the pair should make a digi + if(createDigi(strawele,xpair,wf,sid,digis)){ + // fill associated MC truth matching. Only count the same step once + set > xmcsp; + double wetime[2] = {-100.,-100.}; + CLHEP::HepLorentzVector cpos[2]; + art::Ptr stepMC[2]; + set > spmcs; + for (size_t iend=0;iend<2;++iend){ + StrawCluster const& sc = *(xpair[iend]._iclust); + xmcsp.insert(sc.stepPointMC()); + wetime[iend] = sc.time(); + cpos[iend] = sc.clusterPosition(); + stepMC[iend] = sc.stepPointMC(); + // make sure the trigter StepPoints also go in the StrawDigiMC + spmcs.insert(sc.stepPointMC()); + } + // choose the minimum time from either end, as the ADC sums both + double ptime = 1.0e10; + for (size_t iend=0;iend<2;++iend){ + ptime = std::min(ptime,wetime[iend]); + } + // subtract a small buffer + ptime -= _adcbuffer; + // pickup all StepPointMCs associated with clusts inside the time window of the ADC digitizations (after the threshold) + for (auto ih=wf[0].clusts().clustList().begin();ih!=wf[0].clusts().clustList().end();++ih){ + if (ih->time() >= ptime && ih->time() < ptime + + ( strawele.nADCSamples()-strawele.nADCPreSamples())*strawele.adcPeriod()) + spmcs.insert(ih->stepPointMC()); + } + vector > stepMCs; + stepMCs.reserve(spmcs.size()); + for(auto ispmc=spmcs.begin(); ispmc!= spmcs.end(); ++ispmc){ + stepMCs.push_back(*ispmc); + } + PtrStepPointMCVector mcptr; + for(auto ixmcsp=xmcsp.begin();ixmcsp!=xmcsp.end();++ixmcsp) + mcptr.push_back(*ixmcsp); + mcptrs->push_back(mcptr); + mcdigis->push_back(StrawDigiMC(sid,wetime,cpos,stepMC,stepMCs)); + // diagnostics + if(_diag > 1)digiDiag(strawphys,wf,xpair,digis->back(),mcdigis->back()); + } + } + } + + bool StrawDigisFromStrawGasSteps::createDigi(StrawElectronics const& strawele, WFXP const& xpair, SWFP const& waveform, + StrawId sid, StrawDigiCollection* digis){ + // initialize the float variables that we later digitize + TDCTimes xtimes = {0.0,0.0}; + TrkTypes::TOTValues tot; + // get the ADC sample times from the electroincs. Use the cal side time to randomize + // the phase, this doesn't really matter + TrkTypes::ADCTimes adctimes; + strawele.adcTimes(xpair[0]._time,adctimes); + // sums voltages from both waveforms for ADC + ADCVoltages wf[2]; + // add the jitter in the EventWindowMarker time for this Panel (constant for a whole microbunch, same for both sides) + double dt = _ewMarkerROCdt[sid.getPanel()]; + // loop over the associated crossings + for(size_t iend = 0;iend<2; ++iend){ + WFX const& wfx = xpair[iend]; + // record the crossing time for this end, including clock jitter These already include noise effects + // add noise for TDC on each side + double tdc_jitter = _randgauss.fire(0.0,strawele.TDCResolution()); + xtimes[iend] = wfx._time+dt+tdc_jitter; + // randomize threshold using the incoherent noise + double threshold = _randgauss.fire(wfx._vcross,strawele.analogNoise(StrawElectronics::thresh)); + // find TOT + tot[iend] = waveform[iend].digitizeTOT(strawele,threshold,wfx._time + dt); + // sample ADC + waveform[iend].sampleADCWaveform(strawele,adctimes,wf[iend]); + } + // uncalibrate + strawele.uncalibrateTimes(xtimes,sid); + // add ends and add noise + ADCVoltages wfsum; wfsum.reserve(adctimes.size()); + for(unsigned isamp=0;isamppush_back(StrawDigi(sid,tdcs,tot,adc)); + } + return digitize; + } + + // find straws which couple to the given one, and record them and their couplings in XTalk objects. + // For now, this is just a fixed number for adjacent straws, + // the couplings and straw identities should eventually come from a database, FIXME!!! + void StrawDigisFromStrawGasSteps::findCrossTalkStraws(Straw const& straw, vector& xtalk) { + StrawId selfid = straw.id(); + xtalk.clear(); + // find straws sensitive to straw-to-straw cross talk + vector const& strawNeighbors = straw.nearestNeighboursById(); + // find straws sensitive to electronics cross talk + vector const& preampNeighbors = straw.preampNeighboursById(); + // convert these to cross-talk + for(auto isid=strawNeighbors.begin();isid!=strawNeighbors.end();++isid){ + xtalk.push_back(XTalk(selfid,*isid,_preampxtalk,0)); + } + for(auto isid=preampNeighbors.begin();isid!=preampNeighbors.end();++isid){ + xtalk.push_back(XTalk(selfid,*isid,0,_postampxtalk)); + } + } + + // functions that need implementing:: FIXME!!!!!! + // Could also fold in beam-off random trigger hits from real data + void StrawDigisFromStrawGasSteps::addNoise(StrawClusterMap& hmap){ + // create random noise clusts and add them to the sequences of random straws. + } + // diagnostic functions + void StrawDigisFromStrawGasSteps::waveformHist(StrawElectronics const& strawele, SWFP const& wfs, WFXPList const& xings) { + // histogram individual waveforms + static unsigned nhist(0);// maximum number of histograms per job! + for(size_t iend=0;iend<2;++iend){ + // step to the 1st cluster past the blanking time to avoid double-counting + ClusterList const& clist = wfs[iend].clusts().clustList(); + auto icl = clist.begin(); + while(icl->time() < strawele.flashEnd()) + icl++; + if(icl != clist.end() && nhist < _maxhist && xings.size() >= _minnxinghist && + ( ((!_xtalkhist) && wfs[iend].xtalk().self()) || (_xtalkhist && !wfs[iend].xtalk().self()) ) ) { + double tstart = icl->time()-_tstep; + double tfall = strawele.fallTime(_diagpath); + double tend = clist.rbegin()->time() + _nfall*tfall; + ADCTimes times; + ADCVoltages volts; + times.reserve(size_t(ceil(tend-tstart)/_tstep)); + volts.reserve(size_t(ceil(tend-tstart)/_tstep)); + double t = tstart; + while(t tfs; + char name[60]; + char title[100]; + snprintf(name,60,"SWF%i_%i",wfs[iend].clusts().strawId().asUint16(),nhist); + snprintf(title,100,"Electronic output for straw %i end %i path %i;time (nSec);Waveform (mVolts)",wfs[iend].clusts().strawId().asUint16(),(int)iend,_diagpath); + TH1F* wfh = tfs->make(name,title,volts.size(),times.front(),times.back()); + for(size_t ibin=0;ibinSetBinContent(ibin+1,volts[ibin]); + TList* flist = wfh->GetListOfFunctions(); + for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ + TMarker* smark = new TMarker(ixing->at(iend)._time,ixing->at(iend)._vcross,8); + smark->SetMarkerColor(kGreen); + smark->SetMarkerSize(2); + flist->Add(smark); + } + } + } + } + + void StrawDigisFromStrawGasSteps::waveformDiag( + StrawElectronics const& strawele, + SWFP const& wfs, WFXPList const& xings) { + const Tracker& tracker = *GeomHandle(); + const Straw& straw = tracker.getStraw( wfs[0].clusts().strawId() ); + _swplane = straw.id().getPlane(); + _swpanel = straw.id().getPanel(); + _swlayer = straw.id().getLayer(); + _swstraw = straw.id().getStraw(); + for(size_t iend=0;iend<2; ++iend){ + ClusterList const& clusts = wfs[iend].clusts().clustList(); + size_t nclust = clusts.size(); + set > steps; + set > parts; + _nxing[iend] = 0; + _txing[iend] = strawele.flashStart() + _mbbuffer; + _xddist[iend] = _xwdist[iend] = _xpdist[iend] = -1.0; + for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ + ++_nxing[iend]; + _txing[iend] = min(_txing[iend],static_cast(ixing->at(iend)._time)); + _xddist[iend] = ixing->at(iend)._iclust->driftDistance(); + _xwdist[iend] = ixing->at(iend)._iclust->wireDistance(); + // compute direction perpendicular to wire and momentum + art::Ptr const& spp = ixing->at(iend)._iclust->stepPointMC(); + if(!spp.isNull()){ + Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); + // project the differences in position to get the perp distance + _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); + } + } + if(_nxing[iend] == 0){ + // no xings: just take the 1st clust + if(nclust > 0 ){ + _xddist[iend] = clusts.front().driftDistance(); + _xwdist[iend] = clusts.front().wireDistance(); + art::Ptr const& spp = clusts.front().stepPointMC(); + if(!spp.isNull()){ + Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); + // project the differences in position to get the perp distance + _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); + } + } + } + if(nclust > 0){ + _tmin[iend] = clusts.begin()->time(); + _tmax[iend] = clusts.rbegin()->time(); + } else { + _tmin[iend] = _mbtime+_mbbuffer; + _tmax[iend] = -100.0; + } + + _hqsum[iend] = 0.0; + _vmax[iend] = _tvmax[iend] = 0.0; + _wmcpdg[iend] = _wmcproc[iend] = 0; + for(auto iclu=clusts.begin();iclu!=clusts.end();++iclu){ + if(iclu->stepPointMC().isNonnull()){ + steps.insert(iclu->stepPointMC()); + parts.insert(iclu->stepPointMC()->simParticle()); + _hqsum[iend] += iclu->charge(); + double ctime = iclu->time()+strawele.maxResponseTime(_diagpath,iclu->wireDistance()); + double vout = wfs[iend].sampleWaveform(strawele,_diagpath,ctime); + if(vout > _vmax[iend]){ + _vmax[iend] = vout; + _tvmax[iend] = ctime; + _wmcpdg[iend] = iclu->stepPointMC()->simParticle()->pdgId(); + _wmcproc[iend] = iclu->stepPointMC()->simParticle()->creationCode(); + _mce[iend] = iclu->stepPointMC()->simParticle()->startMomentum().e(); + _slen[iend] = iclu->stepPointMC()->stepLength(); + _sedep[iend] = iclu->stepPointMC()->ionizingEdep(); + } + } + } + _nsteppoint[iend] = steps.size(); + _npart[iend] = parts.size(); + _sesum[iend] = 0.0; + for(auto istep=steps.begin();istep!=steps.end();++istep) + _sesum [iend]+= (*istep)->ionizingEdep(); + } + _swdiag->Fill(); + } + + void StrawDigisFromStrawGasSteps::digiDiag(StrawPhysics const& strawphys, SWFP const& wfs, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi) { + const Tracker& tracker = *GeomHandle(); + const Straw& straw = tracker.getStraw( digi.strawId() ); + _sdplane = straw.id().getPlane(); + _sdpanel = straw.id().getPanel(); + _sdlayer = straw.id().getLayer(); + _sdstraw = straw.id().getStraw(); + + for(size_t iend=0;iend<2;++iend){ + _xtime[iend] = xpair[iend]._time; + _tctime[iend] = xpair[iend]._iclust->time(); + _charge[iend] = xpair[iend]._iclust->charge(); + _ddist[iend] = xpair[iend]._iclust->driftDistance(); + _dtime[iend] = xpair[iend]._iclust->driftTime(); + _ptime[iend] = xpair[iend]._iclust->propTime(); + _phi[iend] = xpair[iend]._iclust->phi(); //JB + _wdist[iend] = xpair[iend]._iclust->wireDistance(); + _vstart[iend] = xpair[iend]._vstart; + _vcross[iend] = xpair[iend]._vcross; + _tdc[iend] = digi.TDC(xpair[iend]._iclust->strawEnd()); + _tot[iend] = digi.TOT(xpair[iend]._iclust->strawEnd()); + ClusterList const& clist = wfs[iend].clusts().clustList(); + auto ctrig = xpair[iend]._iclust; + _ncludd[iend] = clist.size(); + // find the earliest cluster from the same particle that triggered the crossing + auto iclu = clist.begin(); + while( iclu != clist.end() && ctrig->stepPointMC()->simParticle() != iclu->stepPointMC()->simParticle() ){ + ++iclu; + } + if(iclu != clist.end() ){ + _ectime[iend] = iclu->time(); + _ecddist[iend] = iclu->driftDistance(); + _ecdtime[iend] = iclu->driftTime(); + _ecptime[iend] = iclu->propTime(); + // count how many clusters till we get to the trigger cluster + size_t iclust(0); + while( iclu != clist.end() && iclu != ctrig){ + ++iclu; + ++iclust; + } + _iclust[iend] = iclust; + } + } + if(xpair[0]._iclust->stepPointMC() == xpair[1]._iclust->stepPointMC()) + _nstep = 1; + else + _nstep = 2; + _adc.clear(); + for(auto iadc=digi.adcWaveform().begin();iadc!=digi.adcWaveform().end();++iadc){ + _adc.push_back(*iadc); + } + // mc truth information + _dmcpdg = _dmcproc = _dmcgen = 0; + _dmcmom = -1.0; + _mctime = _mcenergy = _mctrigenergy = _mcthreshenergy = _mcdca = -1000.0; + _mcthreshpdg = _mcthreshproc = _mcnstep = 0; + art::Ptr const& spmc = xpair[0]._iclust->stepPointMC(); + if(!spmc.isNull()){ + _mctime = _toff.timeWithOffsetsApplied(*spmc); + // compute the doca for this step + TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), + spmc->position(), spmc->momentum().unit() ); + _mcdca = pca.dca(); + + Hep3Vector mccdir = (pca.point2()-straw.getMidPoint()); + mccdir -= straw.getDirection()*(mccdir.dot(straw.getDirection())); + _mcdcaphi = mccdir.theta(); + _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); //JB: this is now from the lorentz corrected r-component of the drift + + if(!spmc->simParticle().isNull()){ + _dmcpdg = spmc->simParticle()->pdgId(); + _dmcproc = spmc->simParticle()->creationCode(); + if(spmc->simParticle()->genParticle().isNonnull()) + _dmcgen = spmc->simParticle()->genParticle()->generatorId().id(); + _dmcmom = spmc->momentum().mag(); + } + } + _mcenergy = mcdigi.energySum(); + _mctrigenergy = mcdigi.triggerEnergySum(StrawEnd::cal); + // sum the energy from the explicit trigger particle, and find it's releationship + _mcthreshenergy = 0.0; + _mcnstep = mcdigi.stepPointMCs().size(); + art::Ptr threshpart = mcdigi.stepPointMC(StrawEnd::cal); + if(threshpart.isNull()) threshpart = mcdigi.stepPointMC(StrawEnd::hv); + for(auto imcs = mcdigi.stepPointMCs().begin(); imcs!= mcdigi.stepPointMCs().end(); ++ imcs){ + // if the SimParticle for this step is the same as the one which fired the discrim, add the energy + if( (*imcs)->simParticle() == threshpart->simParticle() ) + _mcthreshenergy += (*imcs)->eDep(); + } + _mcthreshpdg = threshpart->simParticle()->pdgId(); + _mcthreshproc = threshpart->simParticle()->creationCode(); + + _xtalk = digi.strawId() != spmc->strawId(); + // fill the tree entry + _sddiag->Fill(); + }//End of digiDiag + + + + + void StrawDigisFromStrawGasSteps::fillClusterPositions(Straw const& straw, StepPointMC const& step, std::vector& cpos) { + // basic info + double charge(0.0); + GlobalConstantsHandle pdt; + if(pdt->particle(step.simParticle()->pdgId()).isValid()){ + charge = pdt->particle(step.simParticle()->pdgId()).ref().charge(); + } + static const double r2 = straw.innerRadius()*straw.innerRadius(); + // decide how we step; straight or helix, depending on the Pt + Hep3Vector const& mom = step.momentum(); + Hep3Vector mdir = mom.unit(); + // approximate pt + double apt = step.momentum().perpPart(_bdir).mag(); + if( apt > _ptmin) { // use linear approximation + double slen = step.stepLength(); + // make sure this linear approximation doesn't extend past the physical straw + Hep3Vector dperp = (step.position() -straw.getMidPoint()).perpPart(straw.getDirection()); + Hep3Vector mperp = mdir.perpPart(straw.getDirection()); + double dm = dperp.dot(mperp); + double m2 = mperp.mag2(); + double dp2 = dperp.mag2(); + double sarg = dm*dm + m2*(r2 - dp2); + // some glancing cases fail the linear math + if(sarg > 0.0 && m2 > 0.0){ + double smax = (-dm + sqrt(sarg))/m2; + slen = std::min(smax,slen); + } + // generate random cluster positions + for(unsigned ic=0;ic < cpos.size();++ic){ + // + cpos[ic] = step.position() +_randflat.fire(slen) *mdir; + } + } else { + // Use a helix to model particles which curl on the scale of the straws + GeomHandle bfmgr; + GeomHandle det; + // find the local field vector at this step + Hep3Vector vpoint_mu2e = det->toMu2e(step.position()); + Hep3Vector bf = bfmgr->getBField(vpoint_mu2e); + // compute transverse radius of particle + double rcurl = fabs(charge*(mom.perpPart(bf).mag())/BField::mmTeslaToMeVc*bf.mag()); + // basis using local Bfield direction + Hep3Vector bfdir = bf.unit(); + Hep3Vector qmdir = (charge*mom).unit(); // charge-signed momentum direction + Hep3Vector rdir = qmdir.cross(bfdir).unit(); // points along magnetic force, ie towards center + Hep3Vector pdir = bfdir.cross(rdir).unit(); // perp to this and field + // find the center of the helix at the start of this step + Hep3Vector hcent = step.position() + rcurl*rdir; + // find helix parameters. By definition, z0 = phi0 = 0 + double omega = qmdir.dot(pdir)/(rcurl*qmdir.dot(bfdir)); + // compute how far this step goes along the field direction. This includes sign information + double zlen = step.stepLength()*mdir.dot(bfdir); + // loop until we've found enough valid samples, or have given up trying + unsigned iclu(0); + unsigned ntries(0); + unsigned nclus = cpos.size(); + while(iclu < nclus && ntries < 10*nclus){ + double zclu = _randflat.fire(zlen); + double phi = zclu*omega; + // build cluster position from these + Hep3Vector cp = hcent + rcurl*(-rdir*cos(phi) + pdir*sin(phi)) + zclu*bfdir; + // test + double rd2 = (cp-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); + if(rd2 - r2 < 1.0e-3){ + cpos[iclu] = cp; + ++iclu; + } else if (_debug > 0) { + cout << "cluster outside straw: helix " << sqrt(rd2) << endl; + } + ++ntries; + } + if(iclu != nclus){ + // failed to find valid steps. put any remining energy at the step + if(_debug > 0)cout << "mu2e::StrawDigisFromStrawGasSteps: Couldn't create enough clusters : "<< iclu << " wanted " << nclus << endl; + while(iclu < nclus){ + cpos[iclu] = step.position(); + ++iclu; + } + } + } + } + + void StrawDigisFromStrawGasSteps::fillClusterMinion(StrawPhysics const& strawphys, StepPointMC const& step, std::vector& ne, std::vector& cen) { + // Loop until we've assigned energy + electrons to every cluster + unsigned mc(0); + double esum(0.0); + double etot = step.ionizingEdep(); + unsigned nc = ne.size(); + while(mc < nc){ + std::vector me(nc); + // fill an array of random# of electrons according to the measured distribution. These are returned sorted lowest-highest. + fillClusterNe(strawphys,me); + for(auto ie : me) { + // maximum energy for this cluster requires at least 1 electron for the rest of the cluster + double emax = etot - esum - (nc -mc -1)*strawphys.ionizationEnergy((unsigned)1); + double eele = strawphys.ionizationEnergy(ie); + if( eele < emax){ + ne[mc] = ie; + cen[mc] = eele; + ++mc; + esum += eele; + } else { + break; + } + } + } + // distribute any residual energy randomly to these clusters. This models delta rays + unsigned ns; + do{ + unsigned me = strawphys.nePerIon(_randflat.fire()); + double emax = etot - esum; + double eele = strawphys.ionizationEnergy(me); + if(eele < emax){ + // choose a random cluster to assign this energy to + unsigned mc = std::min(nc-1,static_cast(floor(_randflat.fire(nc)))); + ne[mc] += me; + cen[mc] += eele; + esum += eele; + } + // maximum energy for this cluster requires at least 1 electron for the rest of the cluster + ns = static_cast(floor((etot-esum)/strawphys.ionizationEnergy((unsigned)1))); + } while(ns > 0); + } + + void StrawDigisFromStrawGasSteps::fillClusterNe(StrawPhysics const& strawphys,std::vector& me) { + for(size_t ie=0;ie < me.size(); ++ie){ + me[ie] = strawphys.nePerIon(_randflat.fire()); + } + if(_sort)std::sort(me.begin(),me.end()); + } + + bool StrawDigisFromStrawGasSteps::readAll(StrawId const& sid) const { + + return sid.straw() >= _allStraw && + (std::find(_allPlanes.begin(),_allPlanes.end(),sid.plane()) != _allPlanes.end()); + } + + } // end namespace trackermc +} // end namespace mu2e + +using mu2e::TrackerMC::StrawDigisFromStrawGasSteps; +DEFINE_ART_MODULE(StrawDigisFromStrawGasSteps); From 1f00c320fd037fa0d2a4d97745dab4971fdf4226 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Wed, 30 Oct 2019 00:05:59 -0500 Subject: [PATCH 09/18] pre-compile commit to create StrawDigis from StrawGasSteps --- MCDataProducts/inc/StepPointMC.hh | 2 + MCDataProducts/inc/StepPointMCCollection.hh | 14 +- MCDataProducts/inc/StrawGasStep.hh | 40 +- TrackerMC/src/MakeStrawGasSteps_module.cc | 364 ++++++++----- .../src/StrawDigisFromStrawGasSteps_module.cc | 513 +++++++++--------- 5 files changed, 499 insertions(+), 434 deletions(-) diff --git a/MCDataProducts/inc/StepPointMC.hh b/MCDataProducts/inc/StepPointMC.hh index b62d730d1f..c9c8328630 100644 --- a/MCDataProducts/inc/StepPointMC.hh +++ b/MCDataProducts/inc/StepPointMC.hh @@ -90,6 +90,7 @@ #include "CLHEP/Vector/ThreeVector.h" #include +#include namespace mu2e { @@ -203,6 +204,7 @@ namespace mu2e { h.print(ost, false); return ost; } + typedef std::vector StepPointMCCollection; } // namespace mu2e diff --git a/MCDataProducts/inc/StepPointMCCollection.hh b/MCDataProducts/inc/StepPointMCCollection.hh index 4ef2b4ae66..f9ebd67497 100644 --- a/MCDataProducts/inc/StepPointMCCollection.hh +++ b/MCDataProducts/inc/StepPointMCCollection.hh @@ -2,21 +2,9 @@ #define MCDataProducts_StepPointMCCollection_hh // -// Define a type for a collection of StepPointMC objects. -// -// $Id: StepPointMCCollection.hh,v 1.1 2011/05/24 17:16:44 kutschke Exp $ -// $Author: kutschke $ -// $Date: 2011/05/24 17:16:44 $ -// -// Original author Rob Kutschke +// Deprecated file, use StepPointMC instead. // -#include - #include "MCDataProducts/inc/StepPointMC.hh" -namespace mu2e { - typedef std::vector StepPointMCCollection; -} - #endif /* MCDataProducts_StepPointMCCollection_hh */ diff --git a/MCDataProducts/inc/StrawGasStep.hh b/MCDataProducts/inc/StrawGasStep.hh index ddc606757c..c5033905f1 100644 --- a/MCDataProducts/inc/StrawGasStep.hh +++ b/MCDataProducts/inc/StrawGasStep.hh @@ -7,8 +7,8 @@ // #include "canvas/Persistency/Common/Ptr.h" #include "canvas/Persistency/Common/Assns.h" -#include "cetlib/map_vector.h" +#include "MCDataProducts/inc/StepPointMC.hh" #include "MCDataProducts/inc/ProcessCode.hh" #include "DataProducts/inc/StrawId.hh" #include "DataProducts/inc/XYZVec.hh" @@ -17,33 +17,45 @@ namespace mu2e { class StrawGasStep { public: - typedef cet::map_vector_key key_type; - - StrawGasStep() : _eIon(0.0), _pathLen(0.0), _mom(0.0), _time(0.0) {} - StrawGasStep( key_type simParticleKey, StrawId strawId, - Float_t Edep, Float_t pathLength, Float_t width, Float_t momentum, Double_t time, - XYZVec const& startPosition, XYZVec const& endPosition) : _simpart(simParticleKey), - _strawId(strawId), _eIon(Edep), - _pathLen(pathLength), _width(width), _mom(momentum), _time(time), + struct StepType { + constexpr static uint8_t _smsk = 0xF; // mask for shape field + constexpr static uint8_t _ssft = 0; // shift for shape field + constexpr static uint8_t _imsk = 0xF0; // mask for ionization field + constexpr static uint8_t _isft = 4; // shift for ionization field + enum shape {line=0,arc,curl,point }; // shape of the trajectory within the straw + enum ionization { minion=0, highion, neutral }; // type of ionization + uint16_t _stype; + + StepType() : _stype(0) {} + StepType(StepType::shape shp, StepType::ionization ion) : + _stype( shp | (ion << _isft)) {} + shape() const { return _stype & _smsk; } + ionization() const { return (_stype & _imsk) >> _isft; } + + }; + + StrawGasStep() : _eIon(0.0), _pathLen(0.), _mom(0.0), _time(0.0) {} + StrawGasStep( StrawId strawId, StepType stype, + Float_t Edep, Float_t pathLength, Float_t width, Double_t time, + XYZVec const& startPosition, XYZVec const& endPosition) : + _strawId(strawId), _stype(stype), _eIon(Edep), + _pathLen(pathLength), _width(width), _time(time), _startpos(startPosition), _endpos(endPosition) {} - key_type simParticleKey() const { return _simpart; } StrawId strawId() const { return _strawId;} + StepType stepType() const { return _stype; } Float_t ionizingEdep() const { return _eIon; } Float_t pathLength() const { return _pathLen; } Float_t radialWidth() const { return _width; } - Float_t momentum() const { return _mom; } Double_t time() const { return _time; } XYZVec const& startPosition() const { return _startpos; } XYZVec const& endPosition() const { return _endpos; } private: - - key_type _simpart; // key to the primary particle generating this edep StrawId _strawId; // straw + StepType _stype; // type of step: used downstream in response simulation Float_t _eIon; // ionization energy deposited in this straw by this particle Float_t _pathLen; // Length the primary particle traveled in this straw gas: this is NOT necessarily the end-start distance Float_t _width; // transverse RMS of the charge cloud WRT the wire - Float_t _mom; // scalar momentum of the particle in the middle of this gas volume Double_t _time; // time particle enters this gas volume; must be double to allow for long-lived particles XYZVec _startpos, _endpos; //entrance and exit to the gas volume }; diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index de3eaf1317..e938eb9773 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -18,6 +18,7 @@ #include "art_root_io/TFileService.h" #include "GlobalConstantsService/inc/GlobalConstantsHandle.hh" #include "GlobalConstantsService/inc/ParticleDataTable.hh" +#include "TrackerConditions/inc/DeadStraw.hh" #include "BFieldGeom/inc/BFieldManager.hh" #include "BTrk/BField/BField.hh" #include "Mu2eUtilities/inc/TwoLinePCA.hh" @@ -47,13 +48,19 @@ namespace mu2e { fhicl::Atom combineDeltas{ Name("CombineDeltas"), Comment("Compress short delta-rays into the primary step"),true}; fhicl::Atom maxDeltaLength{ Name("MaxDeltaLength"), - Comment("Maximum step length for a delta ray to be compressed"),0.5}; //mm + Comment("Maximum step length for a delta ray to be compressed (mm)"),0.5}; fhicl::Atom radiusTolerance{ Name("RadiusTolerance"), - Comment("Tolerance to accept a point outside the straw radius"),0.5}; //mm + Comment("Tolerance to accept a point outside the straw radius (mm) "),0.5}; fhicl::Atom parabolicRotation{ Name("parabolicRotation"), - Comment("Maximum bending rotation to use parabolic end estimation"),0.15}; //radians + Comment("Maximum bending rotation to use parabolic end estimation (radians)"),0.15}; fhicl::Atom curlRotation{ Name("curlRotation"), - Comment("Minimum bending rotation to use curl end estimation"),2.0}; //radians + Comment("Minimum bending rotation to use curl end estimation (radians)"),2.0}; + fhicl::Atom minionBG{ Name("minionBetaGamma"), + Comment("Minimum beta x gamma value to consider a particle minimmum-ionizing"),0.5}; + fhicl::Atom curlRatio{ Name("CurlRatio"), + Comment("Maximum bend radius to straw radius ratio to consider a particle a curler"),1.0}; + fhicl::Atom lineRatio{ Name("LineRatio"), + Comment("Minimum bend radius to straw radius ratio to consider a particle path a line"),10.0}; fhicl::Atom csize{ Name("OutputCollectionSize"), Comment("Estimated size of output collection"), 2000}; fhicl::Atom trackerSteps { Name("trackerStepPoints"), @@ -74,11 +81,20 @@ namespace mu2e { void produce(art::Event& e) override; typedef pair SSPair; // key for pair of straw, SimParticle typedef map< SSPair , PtrStepPointMCVector > SPSMap; // steps by straw, SimParticle + typedef art::Handle SPMCCH; + typedef vector< SPMCCH > SPMCCHV; + void fillMap(Tracker const& tracker,DeadStraw const& deadStraw, + SPMCCH const& spmcch, SPSMap& spsmap); void compressDeltas(SPSMap& spsmap); + void fillStep(PtrStepPointMCVector const& spmcptrs, Straw const& straw, + ParticleData const* pdata, StrawGasStep& sgs, art::Ptr& spmcptr); + void fillStepDiag(Straw const& straw, StrawGasStep const& sgs, art::Ptrconst& spmcptr); XYZVec endPosition(art::Ptrconst& last, Straw const& straw,float charge); int _debug, _diag; bool _combineDeltas, _allAssns; float _maxDeltaLen, _radtol, _parrot, _curlrot; + float _minionBG; + float _curlmom, _linemom; unsigned _csize, _ssize; bool _firstEvent; string _trackerSteps, _keepDeltas; @@ -91,6 +107,7 @@ namespace mu2e { Float_t _prilen, _pridist, _elen, _erad, _epri, _esec, _partP, _brot, _width, _doca; vector _sdist; Int_t _npri, _nsec, _partPDG; + ProditionsHandle _deadStraw_h; }; MakeStrawGasSteps::MakeStrawGasSteps(const Parameters& config ) : @@ -103,6 +120,9 @@ namespace mu2e { _radtol(config().radiusTolerance()), _parrot(config().parabolicRotation()), _curlrot(config().curlRotation()), + _minionBG(config().minionBG()), + _curlRatio(config().curlRatio()), + _lineRatio(config().lineRatio()), _csize(config().csize()), _ssize(config().startSize()), _firstEvent(false), @@ -150,11 +170,18 @@ namespace mu2e { _bdir = bnom.unit(); // B in units of mm/MeV/c _bnom = bnom.mag()*BField::mmTeslaToMeVc; + // pre-compute momentum thresholds for straight, arc, and curler + const Tracker& tracker = *GeomHandle(); + const Straw& straw = tracker.getStraw(StrawId(0,0,0)); + float rstraw = straw.innerRadius(); + _curlmom = _bnom*rstraw; + _linemom = _arcfac*_pcurl; } void MakeStrawGasSteps::produce(art::Event& event) { const Tracker& tracker = *GeomHandle(); GlobalConstantsHandle pdt; + DeadStraw const& deadStraw = _deadStraw_h.get(event.id()); // create output unique_ptr sgsc(new StrawGasStepCollection); sgsc->reserve(_csize); @@ -164,17 +191,16 @@ namespace mu2e { auto StrawGasStepCollectionPID = event.getProductID(); auto StrawGasStepCollectionGetter = event.productGetter(StrawGasStepCollectionPID); // Get all of the tracker StepPointMC collections from the event: - typedef vector< art::Handle > HandleVector; // This selector will select only data products with the given instance name. art::ProductInstanceNameSelector selector(_trackerSteps); - HandleVector stepsHandles; + SPMCCHV stepsHandles; event.getMany( selector, stepsHandles); // const Tracker& tracker = *GeomHandle(); // Informational message on the first event. if ( _firstEvent && _debug>0 ) { mf::LogInfo log("StrawDigiSim"); log << "mu2e::MakeStrawGasSteps will use StepPointMCs from: \n"; - for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); + for ( SPMCCHV::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); i != e; ++i ){ art::Provenance const& prov(*(i->provenance())); log << " " << prov.branchName() << "\n"; @@ -188,7 +214,6 @@ namespace mu2e { unsigned nspmcs(0), nspss(0); // Loop over StepPointMC collections for( auto const& handle : stepsHandles) { - SPSMap spsmap; // map of step points by straw,sim particle StepPointMCCollection const& steps(*handle); nspmcs += steps.size(); // see if we should compress deltas from this collection @@ -200,123 +225,30 @@ namespace mu2e { cout << "No compression for collection " << handle.provenance()->moduleLabel() << endl; } // Loop over the StepPointMCs in this collection and sort them by straw and SimParticle - for (size_t ispmc =0; ispmcid(); - // create key - SSPair stpair(sid,tid); - // create ptr to this step - art::Ptr spmcptr(handle,ispmc); - vector> spmcptrv; - spmcptrv.reserve(_ssize); - spmcptrv.push_back(spmcptr); - // check if this key exists and add it if not - auto ssp = spsmap.emplace(stpair,spmcptrv); - // if the key already exists, just add this Ptr to the vector - if(!ssp.second)ssp.first->second.push_back(spmcptr); - } - } + SPSMap spsmap; // map of step points by straw,sim particle + fillMap(tracker,deadStraw,handle, spsmap); // optionally combine delta-rays that never leave the straw with their parent particle if(dcomp)compressDeltas(spsmap); nspss += spsmap.size(); // convert the SimParticle/straw pair steps into StrawGas objects and fill the collection. for(auto ispsmap = spsmap.begin(); ispsmap != spsmap.end(); ispsmap++){ + auto pid = ispsmap->first.second; // primary SimParticle auto const& spmcptrs = ispsmap->second; const Straw& straw = tracker.getStraw(ispsmap->first.first); - // variables we accumulate for all the StepPoints in this pair - double eion(0.0), pathlen(0.0); - double time(0.0), mom(0.0); - if(_diag>1){ - _npri=_nsec=0; - _epri=_esec=0.0; - } - // keep track of the first and last PRIMARY step - art::Ptr first(spmcptrs.front()); - art::Ptr last(spmcptrs.front()); - // loop over all the StepPoints for this SimParticle - auto pid = ispsmap->first.second; - for(auto const& spmcptr : spmcptrs){ - bool primary=spmcptr->simParticle()->id() == pid; - // update eion for all contributions - eion += spmcptr->ionizingEdep(); - // treat primary and secondary (delta-ray) energy differently - if(primary) { - // primary: update path length, and entry/exit - pathlen += spmcptr->stepLength(); - if(spmcptr->time() < first->time()) first = spmcptr; - if(spmcptr->time() > last->time()) last = spmcptr; - } - // diagnostics - if(_diag >1){ - if(primary){ - _npri++; - _epri += spmcptr->ionizingEdep(); - } else { - _nsec++; - _esec += spmcptr->ionizingEdep(); - } - } - } - // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last - XYZVec start = Geom::toXYZVec(first->position()); - float charge(0.0); - if(pdt->particle(first->simParticle()->pdgId()).isValid()) - charge = pdt->particle(first->simParticle()->pdgId()).ref().charge(); - - - XYZVec end = endPosition(last,straw,charge); - time = first->time(); // use first time as time of this step (cluster times will be added) - mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum - // determine the width from the sigitta or curl radius - auto pdir = first->momentum().unit(); - auto pperp = pdir.perp(_bdir); - float bendrms = 0.5*std::min(straw.innerRadius(),mom*pperp/_bnom); // bend radius spread. 0.5 factor givs RMS of a circle - // only sigitta perp to the wire counts - float sint = (_bdir.cross(pdir).cross(straw.getDirection())).mag(); - static const float prms(1.0/(12.0*sqrt(5.0))); // RMS for a parabola. This includes a factor 1/8 for the sagitta calculation too - float sagrms = prms*sint*pathlen*pathlen*_bnom*pperp/mom; - double width = std::min(sagrms,bendrms); // choose the smaller: different approximations work for different momenta/directions - // create the gas step - StrawGasStep sgs(ispsmap->first.second, ispsmap->first.first, - (float)eion,(float)pathlen, (float)width, (float)mom, time, - start, end); + ParticleData const* pdata = pdt->particle(spcptrs.front()->simParticle()->pdgId()); + StrawGasStep sgs; + art::Ptr spmcptr; + fillStep(spmcptrs,straw,pdata,sgs,spmcptr); sgsc->push_back(sgs); - // create the Assns + // create the Assns to the 'trigger' StepPointMC auto sgsp = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); - sgsa_primary->addSingle(sgsp,first); + sgsa_primary->addSingle(sgsp,spmcptr); // optionall add Assns for all StepPoints, including delta-rays if(_allAssns){ for(auto const& spmcptr : spmcptrs) sgsa_all->addSingle(sgsp,spmcptr); } - if(_diag > 0){ - _erad = sqrt((Geom::Hep3Vec(end)-straw.getMidPoint()).perpPart(straw.getDirection()).mag2()); - _hendrad->Fill(_erad); - _hphi->Fill(_brot); - if(_diag > 1){ - _prilen = pathlen; - _pridist = sqrt((end-start).mag2()); - _partP = mom; - _partPDG = first->simParticle()->pdgId(); - _elen = last->stepLength(); - _width = width; - // compute DOCA to the wire - TwoLinePCA poca(Geom::Hep3Vec(start),Geom::Hep3Vec(end-start), - straw.getMidPoint(),straw.getDirection()); - _doca = poca.dca(); - _sdist.clear(); - auto sdir = Geom::Hep3Vec(end-start).unit(); - for(auto const& spmcptr : spmcptrs){ - auto dist = ((spmcptr->position()-Geom::Hep3Vec(start)).cross(sdir)).mag(); - _sdist.push_back(dist); - } - _sgsdiag->Fill(); - } - } - + if(_diag > 0)fillStepDiag(straw,sgs,spmcptr); if(_debug > 1){ // checks and printout cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << sgs.simParticleKey() @@ -329,7 +261,6 @@ namespace mu2e { Hep3Vector hend = Geom::Hep3Vec(end); double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); if(rd2 - r2 > 1e-5 ) cout << "End outside straw, radius " << sqrt(rd2) << endl; - } } // end of pair loop } // end of collection loop @@ -341,6 +272,105 @@ namespace mu2e { if(_allAssns) event.put(move(sgsa_all),"All"); } // end of produce + void MakeStrawGasSteps::fillStep(PtrStepPointMCVector const& spmcptrs, Straw const& straw, + ParticleData const* pdata, StrawGasStep& sgs, art::Ptr& spmcptr){ + // variables we accumulate for all the StepPoints in this pair + double eion(0.0), pathlen(0.0); + double time(0.0), mom(0.0); + if(_diag>1){ + _npri=_nsec=0; + _epri=_esec=0.0; + } + // keep track of the first and last PRIMARY step + art::Ptr first; + art::Ptr last; + // loop over all the StepPoints for this SimParticle + for(auto const& spmcptr : spmcptrs){ + bool primary=spmcptr->simParticle()->id() == pid; + // update eion for all contributions + eion += spmcptr->ionizingEdep(); + // treat primary and secondary (delta-ray) energy differently + if(primary) { + // primary: update path length, and entry/exit + pathlen += spmcptr->stepLength(); + if(first.isNull() || spmcptr->time() < first->time()) first = spmcptr; + if(last.isNull() || spmcptr->time() > last->time()) last = spmcptr; + } + // diagnostics + if(_diag >1){ + if(primary){ + _npri++; + _epri += spmcptr->ionizingEdep(); + } else { + _nsec++; + _esec += spmcptr->ionizingEdep(); + } + } + } + if(first.isNull() || last.isNull()) + throw cet::exception("SIM")<<"mu2e::MakeStrawGasSteps: No first or last step" << endl; + // for now, define the first StepPoint as the 'trigger' for this step. Eventually + // this might be the one closest to the wire FIXME! + spmcptr = first; + // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last + XYZVec start = Geom::toXYZVec(first->position()); + float charge(0.0); + if(pdata!=0){ + charge = pdt->particle(first->simParticle()->pdgId()).ref().charge(); + } + // determine the type of step + StrawGasStep::StepType stype; + setType(first,stype); + // compute the end position and step type + // in future we should store the end position in the StepPointMC FIXME! + XYZVec end = endPosition(last,straw,charge,stype); + time = first->time(); // use first time as time of this step (cluster times will be added) + mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum + // determine the width from the sigitta or curl radius + auto pdir = first->momentum().unit(); + auto pperp = pdir.perp(_bdir); + float bendrms = 0.5*std::min(straw.innerRadius(),mom*pperp/_bnom); // bend radius spread. 0.5 factor givs RMS of a circle + // only sigitta perp to the wire counts + float sint = (_bdir.cross(pdir).cross(straw.getDirection())).mag(); + static const float prms(1.0/(12.0*sqrt(5.0))); // RMS for a parabola. This includes a factor 1/8 for the sagitta calculation too + float sagrms = prms*sint*pathlen*pathlen*_bnom*pperp/mom; + double width = std::min(sagrms,bendrms); // choose the smaller: different approximations work for different momenta/directions + // create the gas step + sgs = StrawGasStep( first->strawId(), stype, + (float)eion,(float)pathlen, (float)width, (float)mom, time, + start, end); + } + + void MakeStrawGasSteps::fillMap(Tracker const& tracker,DeadStraw const& deadStraw, + SPMCCH const& spmcch, SPSMap& spsmap) { + StepPointMCCollection const& steps(*spmcch); + for (size_t ispmc =0; ispmcid(); + // create key + SSPair stpair(sid,tid); + // create ptr to this step + art::Ptr spmcptr(spmcch,ispmc); + vector> spmcptrv; + spmcptrv.reserve(_ssize); + spmcptrv.push_back(spmcptr); + // check if this key exists and add it if not + auto ssp = spsmap.emplace(stpair,spmcptrv); + // if the key already exists, just add this Ptr to the vector + if(!ssp.second)ssp.first->second.push_back(spmcptr); + } + } + } + void MakeStrawGasSteps::compressDeltas(SPSMap& spsmap) { // first, make some helper maps typedef map< cet::map_vector_key, StrawId > SMap; // map from key to Straw, to test for uniqueness @@ -355,13 +385,13 @@ namespace mu2e { if(!sp.second && sp.first->second != sid && sp.first->second.valid())sp.first->second = StrawId(); // Particle already seen in another straw: make invalid to avoid compressing it } - // loop over particle-straw pairs looking for delta rays + // loop over particle-straw pairs looking for delta rays auto isps =spsmap.begin(); while(isps != spsmap.end()){ bool isdelta(false); auto& dsteps = isps->second; auto dkey =isps->first.second; - // see if this particle is a delta-ray and if it's step is short + // see if this particle is a delta-ray and if it's step is short auto pcode = dsteps.front()->simParticle()->creationCode(); if(pcode == ProcessCode::eIoni || pcode == ProcessCode::hIoni){ // make sure this particle doesnt have a step in any other straw @@ -369,12 +399,12 @@ namespace mu2e { if(ifnd == smap.end()) throw cet::exception("SIM")<<"mu2e::MakeStrawGasSteps: No SimParticle found for delta key " << dkey << endl; else if(ifnd->second.valid()){ // only compress delta rays without hits in any other straw - // add the lengths of all the steps in this straw + // add the lengths of all the steps in this straw float len(0.0); for(auto const& istep : dsteps) len += istep->stepLength(); if(len < _maxDeltaLen){ -// short delta ray. flag for combination + // short delta ray. flag for combination isdelta = true; } } @@ -414,36 +444,92 @@ namespace mu2e { } XYZVec MakeStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw, float charge) { - // in future we should store the end position in the StepPointMC FIXME! static const double r2 = straw.innerRadius()*straw.innerRadius(); XYZVec retval; -// test parabolic extrapolation first - auto momhat = last->momentum().unit(); - _brot = last->stepLength()*_bnom/last->momentum().mag(); // magnetic bending rotation angle - if(_debug > 1){ - cout << "Step Length = " << last->stepLength() << " rotation angle " << _brot << endl; + // null charge has no propagation. + if(charge == 0.0){ + retval = last->position(); + } else { + auto momhat = last->momentum().unit(); + // test parabolic extrapolation first + _brot = last->stepLength()*_bnom/last->momentum().mag(); // magnetic bending rotation angle + if(_debug > 1){ + cout << "Step Length = " << last->stepLength() << " rotation angle " << _brot << endl; + } + auto rho = _bdir.cross(momhat);// points radially outwards for positive charge + if(_brot < _parrot){ + // estimate end position with a parabolic trajectory + retval = last->position() + last->stepLength()*(momhat -(0.5*charge*_brot)*rho); + } else { + Hep3Vector cdir; + if(_brot > _curlrot) + // curler; assume the net motion is along the BField axis. Sign by the projection of the momentum + cdir = _bdir * (momhat.dot(_bdir)>0.0 ? 1.0 : -1.0); + else + cdir = (momhat-(0.5*charge*_brot)*rho).unit(); // effective propagation direction + // propagate to the straw wall + auto pperp = (last->position()-straw.getMidPoint()).perpPart(straw.getDirection()); + double pdot = pperp.dot(cdir); + double ppmag2 = pperp.mag2(); + double len = sqrt(pdot*pdot + r2 - ppmag2)-pdot; + len = std::min(last->stepLength(),len); + retval = last->position() + len*cdir; + } } - auto rho = _bdir.cross(momhat);// points radially outwards for positive charge - if(_brot < _parrot){ - // estimate end position with a parabolic trajectory - retval = last->position() + last->stepLength()*(momhat -(0.5*charge*_brot)*rho); + return retval; + } + + void MakeStrawGasSteps::fillStepDiag(Straw const& straw, StrawGasStep const& sgs, + art::Ptrconst& spmcptr) { + _erad = sqrt((Geom::Hep3Vec(sgs.endPosition())-straw.getMidPoint()).perpPart(straw.getDirection()).mag2()); + _hendrad->Fill(_erad); + _hphi->Fill(_brot); + if(_diag > 1){ + _prilen = pathlen; + _pridist = sqrt((sgs.endPosition()-sgs.startPosition()).mag2()); + _partP = mom; + _partPDG = spmcptr->simParticle()->pdgId(); + _elen = spmcptr->stepLength(); + _width = width; + // compute DOCA to the wire + TwoLinePCA poca(Geom::Hep3Vec(sgs.startPosition()),Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()), + straw.getMidPoint(),straw.getDirection()); + _doca = poca.dca(); + _sdist.clear(); + auto sdir = Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()).unit(); + for(auto const& spmcptr : spmcptrs){ + auto dist = ((spmcptr->position()-Geom::Hep3Vec(sgs.startPosition())).cross(sdir)).mag(); + _sdist.push_back(dist); + } + _sgsdiag->Fill(); + } + } + + void MakeStrawGasSteps::setType(art::Ptrconst& spmcptr, StrawGasStep::StepType& stype) { + // now determine ioniztion and shape + int itype, shape; + if(pdata->charge() == 0.0){ + itype = StrawGasStep::StepType::neutral; + shape = StrawGasStep::StepType::point; } else { - Hep3Vector cdir; - if(_brot > _curlrot) - // curler; assume the net motion is along the BField axis. Sign by the projection of the momentum - cdir = _bdir * (momhat.dot(_bdir)>0.0 ? 1.0 : -1.0); + double mom = spmcptr->momentum().mag(); + if(mom < _curlmom) + shape = StrawGasStep::StepType::curl; + else if(mom < _linemom) + shape = StrawGasStep::StepType::arc; + else + shape = StrawGasStep::StepType::line; + mass = pdata->mass(); + double bg = mom/mass; // beta x gamma + if(bg > _minionBG) + itype =StrawGasStep::StepType::minion; else - cdir = (momhat-(0.5*charge*_brot)*rho).unit(); // effective propagation direction -// propagate to the straw wall - auto pperp = (last->position()-straw.getMidPoint()).perpPart(straw.getDirection()); - double pdot = pperp.dot(cdir); - double ppmag2 = pperp.mag2(); - double len = sqrt(pdot*pdot + r2 - ppmag2)-pdot; - len = std::min(last->stepLength(),len); - retval = last->position() + len*cdir; + itype =StrawGasStep::StepType::highion; } - return retval; + stype = StrawGasStep::StepType( (StrawGasStep::StepType::shape)shape, + (StrawGasStep::StepType::ionization)itype ); } + } DEFINE_ART_MODULE(mu2e::MakeStrawGasSteps) diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc index 67ad372092..c4dfcbaa8b 100644 --- a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -21,7 +21,6 @@ #include "ConditionsService/inc/AcceleratorParams.hh" #include "TrackerGeom/inc/Tracker.hh" #include "ConfigTools/inc/ConfigFileLookupPolicy.hh" -#include "TrackerConditions/inc/DeadStraw.hh" #include "TrackerConditions/inc/StrawElectronics.hh" #include "TrackerConditions/inc/StrawPhysics.hh" #include "GeometryService/inc/DetectorSystem.hh" @@ -33,14 +32,13 @@ #include "Mu2eUtilities/inc/TwoLinePCA.hh" #include "Mu2eUtilities/inc/SimParticleTimeOffset.hh" #include "DataProducts/inc/TrkTypes.hh" -// data +// persistent data #include "DataProducts/inc/EventWindowMarker.hh" #include "DataProducts/inc/StrawId.hh" -#include "RecoDataProducts/inc/StrawDigiCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "MCDataProducts/inc/StrawDigiMCCollection.hh" -// MC structures +#include "RecoDataProducts/inc/StrawDigi.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" +#include "MCDataProducts/inc/StrawDigiMC.hh" +// temporary MC structures #include "TrackerMC/inc/StrawClusterSequencePair.hh" #include "TrackerMC/inc/StrawWaveform.hh" #include "TrackerMC/inc/IonCluster.hh" @@ -85,17 +83,47 @@ namespace mu2e { }; class StrawDigisFromStrawGasSteps : public art::EDProducer { - public: + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + struct Config { + fhicl::Atom debug{ Name("debugLevel"), Comment("Debug Level"), 0}; + fhicl::Atom diag{ Name("diagLevel"), Comment("Diag Level"), 0}; + fhicl::Atom print{ Name("printLevel"), Comment("Print Level"), 0}; + fhicl::Atom maxhist{ Name("MaxHist"), Comment("Maximum number of waveform histograms"), 100}; + fhicl::Atom xtalkhist{ Name("CrossTalkHist"), Comment("Histogram of cross-talk"), false}; + fhicl::Atom minnxinghist{ Name("MinNXingHist"), Comment("Minimum # of crossings to histogram waveform"),1}; + fhicl::Atom tstep { Name("WaveformStep"), Comment("WaveformStep (nsec)"),0.1 }; + fhicl::Atom nfall{ Name("WaveformTail"), Comment("# of decay lambda past last signal to record waveform"),10.0}; + fhicl::Atom maxFullPrint{ Name("maxFullPrint", Comment("Limit on number of events for which there will be full printout") ,2)}; + fhicl::Atom addXtalk{ Name("addCrossTalk"), Comment("Should we add cross talk hits?"),false }; + fhicl::Atom ctMinCharge{ Name("xtalkMinimumCharge"), Comment("minimum charge to add cross talk (for performance issues)") ,0}; + fhicl::Atom addNoise{ Name("addNoise",false), Comment("should we add noise hits? NOT CURRENTLY IMPLEMENTED FIXME!") }; + fhicl::Atom preampxtalk{ Name("preAmplificationCrossTalk",0.0), Comment("Pre-amplification (straw) X-talk coupling") }; + fhicl::Atom postampxtalk{ Name("postAmplificationCrossTalk",0.02), Comment("Post-amplification (board) X-talk coupling") }; + fhicl::Atom bgcut{ Name("BetaGammaCut"), Comment("treat particles with beta-gamma above this as minimum-ionizing"),0.5 }; + fhicl::Atom minstepE{ Name("minstepE"), Comment(" minimum step energy depostion to turn into a straw signal (MeV)"),2.0e-6 }; + fhicl::Atom ewMarkerTag{ Name("EventWindowMarker"), Comment("EventWindowMarker producer"),"EWMProducer" }; + fhicl::Atom steptimebuf{ Name("StrawGasStepTimeBuffer"), Comment("buffer for MC step point times (nsec) ") ,100.0 }; + fhicl::Atom tdcbuf{ Name("TDCTimeBuffer"), Comment("buffer for TDC jitter (nsec) ") ,2.0 }; + fhicl::Atom allStraw{ Name("AllHitsStraw"), Comment("minimum straw # to read all hits") ,90}; + fhicl::Sequence allPlanes{ Name("AllHitsPlanes",std::vector{}), Comment("planes to read all hits") }; + fhicl::Sequence SPTO { Name("TimeOffsets"), Comment("Sim Particle Time Offset Maps")}; + fhicl::Atom diagpath{ Name("DiagPath"), Comment("Digitization Path for waveform diagnostics") ,0 }; + fhicl::Atom sort{ Name("SortClusterEnergy"), Comment("Sort clusters by energy before digitizing") ,false }; + }; + + typedef map StrawClusterMap; // clusts by straw - typedef vector > StrawSPMCPV; // vector of associated StepPointMCs for a single straw/particle + typedef vector > StrawSPMCPV; // vector of associated StrawGasSteps for a single straw/particle // work with pairs of waveforms, one for each straw end typedef std::array SWFP; typedef std::array WFXP; typedef list WFXPList; typedef WFXPList::const_iterator WFXPI; - explicit StrawDigisFromStrawGasSteps(fhicl::ParameterSet const& pset); + explicit StrawDigisFromStrawGasStepsfhicl::ParameterSet const& pset); // Accept compiler written d'tor. private: @@ -112,29 +140,26 @@ namespace mu2e { double _tstep, _nfall; // Limit on number of events for which there will be full printout. int _maxFullPrint; - // Name of the tracker StepPoint collection - string _trackerStepPoints; // Parameters - bool _addXtalk; // should we add cross talk hits? - double _ctMinCharge; // minimum charge to add cross talk (for performance issues) - bool _addNoise; // should we add noise hits? - double _preampxtalk, _postampxtalk; // x-talk parameters; these should come from conditions, FIXME!! - double _bgcut; // cut dividing 'min-ion' particles from highly-ionizing - double _minstepE; // minimum step energy to simulate - art::InputTag _ewMarkerTag; // name of the module that makes eventwindowmarkers - double _mbtime; // period of 1 microbunch - double _mbbuffer; // buffer on that for ghost clusts (for waveform) - double _adcbuffer; // time buffer for ADC - double _steptimebuf; // buffer for MC step point times - double _tdcbuf; // buffer for TDC jitter - uint16_t _allStraw; // minimum straw # to read all hits - std::vector _allPlanes; // planes in which to read all hits - // models of straw response to stimuli - ProditionsHandle _strawphys_h; - ProditionsHandle _strawele_h; + bool _addXtalk; + double _ctMinCharge; + bool _addNoise; + double _preampxtalk, _postampxtalk;// these should come from conditions, FIXME!! + double _bgcut; + double _minstepE; + art::InputTag _ewMarkerTag; + double _mbtime; + double _mbbuffer; + double _adcbuffer; + double _steptimebuf; + double _tdcbuf; + uint16_t _allStraw; + std::vector _allPlanes; SimParticleTimeOffset _toff; - StrawElectronics::Path _diagpath; // electronics path for waveform diagnostics + StrawElectronics::Path _diagpath; + unsigned _maxnclu; + bool _sort; // sort cluster sizes before filling energy // Random number distributions art::RandomNumberGenerator::base_engine_t& _engine; CLHEP::RandGaussQ _randgauss; @@ -145,15 +170,9 @@ namespace mu2e { const string _messageCategory; // Give some informationation messages only on the first event. bool _firstEvent; - // record the BField direction at the tracker center - Hep3Vector _bdir; - // minimum pt (perp to bfield) to assume straight trajectory in a starw - double _ptmin, _ptfac; - // max # clusters for modeling non-minion steps - unsigned _maxnclu; - bool _sort; // sort cluster sizes before filling energy - // List of dead straws as a parameter set; needed at beginRun time. - ProditionsHandle _deadStraw_h; + // Proditions + ProditionsHandle _strawphys_h; + ProditionsHandle _strawele_h; // diagnostics TTree* _swdiag; @@ -188,44 +207,48 @@ namespace mu2e { array _ewMarkerROCdt; // helper functions - void fillClusterMap(art::Event const& event, StrawClusterMap & hmap); + void fillClusterMap(StrawPhysics const& strawphys, + StrawElectronics const& strawele,Tracker const& tracker, + art::Event const& event, StrawClusterMap & hmap); void addStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - art::Ptr const& spmcptr, - Straw const& straw, StrawClusterSequencePair& shsp); + StrawElectronics const& strawele, + Straw const& straw, + StrawGasStep const& step, + art::Ptr const& spmcptr, + StrawClusterSequencePair& shsp); void divideStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StepPointMC const& step, vector& clusters); + StrawElectronics const& strawele, + StrawGasStep const& step, vector& clusters); void driftCluster(StrawPhysics const& strawphys, Straw const& straw, - IonCluster const& cluster, WireCharge& wireq); + IonCluster const& cluster, WireCharge& wireq); void propagateCharge(StrawPhysics const& strawphys, Straw const& straw, - WireCharge const& wireq, StrawEnd end, WireEndCharge& weq); + WireCharge const& wireq, StrawEnd end, WireEndCharge& weq); double microbunchTime(StrawElectronics const& strawele, double globaltime) const; void addGhosts(StrawElectronics const& strawele, StrawCluster const& clust,StrawClusterSequence& shs); void addNoise(StrawClusterMap& hmap); void findThresholdCrossings(StrawElectronics const& strawele, SWFP const& swfp, WFXPList& xings); void createDigis(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StrawClusterSequencePair const& hsp, - XTalk const& xtalk, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStepPointMCVectorCollection* mcptrs ); + StrawElectronics const& strawele, + StrawClusterSequencePair const& hsp, + XTalk const& xtalk, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, + PtrStrawGasStepVectorCollection* mcptrs ); void fillDigis(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - WFXPList const& xings,SWFP const& swfp , StrawId sid, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStepPointMCVectorCollection* mcptrs ); + StrawElectronics const& strawele, + WFXPList const& xings,SWFP const& swfp , StrawId sid, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, + PtrStrawGasStepVectorCollection* mcptrs ); bool createDigi(StrawElectronics const& strawele,WFXP const& xpair, SWFP const& wf, StrawId sid, StrawDigiCollection* digis); void findCrossTalkStraws(Straw const& straw,vector& xtalk); void fillClusterNe(StrawPhysics const& strawphys,std::vector& me); - void fillClusterPositions(Straw const& straw, StepPointMC const& step, std::vector& cpos); - void fillClusterMinion(StrawPhysics const& strawphys, StepPointMC const& step, std::vector& me, std::vector& cen); + void fillClusterPositions(Straw const& straw, StrawGasStep const& step, std::vector& cpos); + void fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& me, std::vector& cen); bool readAll(StrawId const& sid) const; // diagnostic functions void waveformHist(StrawElectronics const& strawele, - SWFP const& wf, WFXPList const& xings); + SWFP const& wf, WFXPList const& xings); void waveformDiag(StrawElectronics const& strawele, - SWFP const& wf, WFXPList const& xings); + SWFP const& wf, WFXPList const& xings); void digiDiag(StrawPhysics const& strawphys, SWFP const& wf, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi); struct Config { @@ -233,59 +256,54 @@ namespace mu2e { }; }; + using Parameters = art::EDProducer::Table; - StrawDigisFromStrawGasSteps::StrawDigisFromStrawGasSteps(fhicl::ParameterSet const& pset) : - EDProducer{pset}, - // diagnostic parameters - _debug(pset.get("debugLevel",0)), - _diag(pset.get("diagLevel",0)), - _printLevel(pset.get("printLevel",0)), - _maxhist(pset.get("MaxHist",100)), - _xtalkhist(pset.get("CrossTalkHist",false)), - _minnxinghist(pset.get("MinNXingHist",1)), // minimum # of crossings to histogram waveform - _tstep(pset.get("WaveformStep",0.1)), // ns - _nfall(pset.get("WaveformTail",10.0)), // # of decay lambda past last signal to record waveform - // Parameters - _maxFullPrint(pset.get("maxFullPrint",2)), - _trackerStepPoints(pset.get("trackerStepPoints","tracker")), - _addXtalk(pset.get("addCrossTalk",false)), - _ctMinCharge(pset.get("xtalkMinimumCharge",0)), - _addNoise(pset.get("addNoise",false)), - _preampxtalk(pset.get("preAmplificationCrossTalk",0.0)), - _postampxtalk(pset.get("postAmplificationCrossTalk",0.02)), // dimensionless relative coupling - _bgcut(pset.get("BetaGammaCut",0.5)), // treat particles with beta-gamma above this as minimum-ionizing - _minstepE(pset.get("minstepE",2.0e-6)), // minimum step energy depostion to turn into a straw signal (MeV) - _ewMarkerTag(pset.get("EventWindowMarkerLabel","EWMProducer")), - _steptimebuf(pset.get("StepPointMCTimeBuffer",100.0)), // nsec - _tdcbuf(pset.get("TDCTimeBuffer",2.0)), // nsec - _allStraw(pset.get("AllHitsStraw",90)), - _allPlanes(pset.get>("AllHitsPlanes",std::vector{})), // planes to read all hits - _toff(pset.get("TimeOffsets", {})), - _diagpath(static_cast(pset.get("WaveformDiagPath",StrawElectronics::thresh))), - // Random number distributions - _engine(createEngine( art::ServiceHandle()->getSeed())), - _randgauss( _engine ), - _randflat( _engine ), - _randexp( _engine), - _randP( _engine), - _messageCategory("HITS"), - _firstEvent(true), // Control some information messages. - _ptfac(pset.get("PtFactor", 2.0)), // factor for defining curling in a straw - _maxnclu(pset.get("MaxNClusters", 10)), // max # of clusters for low-PT steps - _sort(pset.get("SortClusterEnergy",false)) + explicit StrawDigisFromStrawGasSteps::StrawDigisFromStrawGasSteps(const& Parameters pset) : + EDProducer(pset), + _debug(pset().debug()), + _diag(pset().diag()), + _print(pset().print()), + _maxhist(pset().maxhits()), + _xtalkhist(pset().xtalkhist()), + _minnxinghist(pset()("MinNXingHist",1)), + _tstep(pset().tstep()), + _nfall(pset().nfall()), + _maxFullPrint(pset().maxFullPrint()), + _addXtalk(pset().addXtalk()), + _ctMinCharge(pset().ctMinCharge()), + _addNoise(pset().addNoise()), + _preampxtalk(pset().preampxtalk()), + _postampxtalk(pset().postampxtalk()), + _bgcut(pset().bgcut()), + _minstepE(pset().minstepE()), + _ewMarkerTag(pset().(ewMarkerTag)), + _steptimebuf(pset().(steptimebuf)), + _tdcbuf(pset().tdcbuf()), + _allStraw(pset().allStraw()), + _allPlanes(pset().allPlanes()), + _toff(pset().SPTO()), + _diagpath(static_cast(pset().diagpath())), + _sort(pset().sort()), + // Random number distributions + _engine(createEngine( art::ServiceHandle()->getSeed())), + _randgauss( _engine ), + _randflat( _engine ), + _randexp( _engine), + _randP( _engine), + _messageCategory("HITS"), + _firstEvent(true), // Control some information messages. { // Tell the framework what we consume. - consumesMany(); + consumesMany(); + consumesMany(); consumes(_ewMarkerTag); - // Since SimParticleTimeOffset calls getValidHandle, we have to - // declare the consumes statements here. - auto const& toffInputs = pset.get>("TimeOffsets.inputs", {}); - for (auto const& tag : toffInputs) { - consumes(tag); - } + // Since SimParticleTimeOffset calls getValidHandle, we have to declare the consumes statements here. + // auto const& toffInputs = pset.get>("TimeOffsets.inputs", {}); + // for (auto const& tag : toffInputs) { + // consumes(tag); + // } // Tell the framework what we make. produces(); - produces(); produces(); } @@ -293,18 +311,18 @@ namespace mu2e { if(_diag > 0){ - art::ServiceHandle tfs; - _sdiag =tfs->make("sdiag","Step diagnostics"); - _sdiag->Branch("steplen",&_steplen,"steplen/F"); - _sdiag->Branch("stepE",&_stepE,"stepE/F"); - _sdiag->Branch("partP",&_partP,"partP/F"); - _sdiag->Branch("qsum",&_qsum,"qsum/F"); - _sdiag->Branch("esum",&_esum,"esum/F"); - _sdiag->Branch("eesum",&_eesum,"eesum/F"); - _sdiag->Branch("qe",&_qe,"qe/F"); - _sdiag->Branch("steptime",&_steptime,"steptime/F"); - _sdiag->Branch("nclust",&_nclust,"nclust/I"); - _sdiag->Branch("netot",&_netot,"netot/I"); + art::ServiceHandle tfs; + _sdiag =tfs->make("sdiag","StrawGasStep diagnostics"); + _sdiag->Branch("steplen",&_steplen,"steplen/F"); + _sdiag->Branch("stepE",&_stepE,"stepE/F"); + _sdiag->Branch("partP",&_partP,"partP/F"); + _sdiag->Branch("qsum",&_qsum,"qsum/F"); + _sdiag->Branch("esum",&_esum,"esum/F"); + _sdiag->Branch("eesum",&_eesum,"eesum/F"); + _sdiag->Branch("qe",&_qe,"qe/F"); + _sdiag->Branch("steptime",&_steptime,"steptime/F"); + _sdiag->Branch("nclust",&_nclust,"nclust/I"); + _sdiag->Branch("netot",&_netot,"netot/I"); _sdiag->Branch("partPDG",&_partPDG,"partPDG/I"); _sdiag->Branch("clusters",&_clusters); @@ -382,23 +400,6 @@ namespace mu2e { } void StrawDigisFromStrawGasSteps::beginRun( art::Run& run ){ - // get field at the center of the tracker - GeomHandle bfmgr; - GeomHandle det; - Hep3Vector vpoint_mu2e = det->toMu2e(Hep3Vector(0.0,0.0,0.0)); - Hep3Vector b0 = bfmgr->getBField(vpoint_mu2e); - // if the field is too small, don't perform any curvature-based analysis - if ( b0.mag() < 1.0e-4 ){ - _bdir = Hep3Vector(0.0,0.0,1.0); - _ptmin = -1.0; - } else { - _bdir = b0.unit(); - //compute the transverse momentum for which a particle will curl up in a straw - const Tracker& tracker = *GeomHandle(); - const Straw& straw = tracker.getStraw(StrawId(0,0,0)); - double rstraw = straw.getRadius(); - _ptmin = _ptfac*BField::mmTeslaToMeVc*b0.mag()*rstraw; - } if ( _printLevel > 0 ) { auto const& strawphys = _strawphys_h.get(run.id()); strawphys.print(cout); @@ -411,10 +412,12 @@ namespace mu2e { ++ncalls; // update conditions caches. ConditionsHandle accPar("ignored"); + StrawPhysics const& strawphys = _strawphys_h.get(event.id()); + StrawElectronics const& strawele = _strawele_h.get(event.id()); + const Tracker& tracker = *GeomHandle(); + _mbtime = accPar->deBuncherPeriod; _toff.updateMap(event); - StrawElectronics const& strawele = _strawele_h.get(event.id()); - StrawPhysics const& strawphys = _strawphys_h.get(event.id()); art::Handle ewMarkerHandle; event.getByLabel(_ewMarkerTag, ewMarkerHandle); const EventWindowMarker& ewMarker(*ewMarkerHandle); @@ -423,18 +426,16 @@ namespace mu2e { for (size_t i=0;i(); // make the microbunch buffer long enough to get the full waveform _mbbuffer = (strawele.nADCSamples() - strawele.nADCPreSamples())*strawele.adcPeriod(); _adcbuffer = 0.01*strawele.adcPeriod(); // Containers to hold the output information. unique_ptr digis(new StrawDigiCollection); unique_ptr mcdigis(new StrawDigiMCCollection); - unique_ptr mcptrs(new PtrStepPointMCVectorCollection); // create the StrawCluster map StrawClusterMap hmap; // fill this from the event - fillClusterMap(event,hmap); + fillClusterMap(strawphys,strawele,tracker,event,hmap); // add noise clusts if(_addNoise)addNoise(hmap); // loop over the clust sequences @@ -464,7 +465,6 @@ namespace mu2e { event.put(move(digis)); // store MC truth match event.put(move(mcdigis)); - event.put(move(mcptrs)); if ( _printLevel > 1 ) cout << "StrawDigisFromStrawGasSteps: produce() end" << endl; // Done with the first event; disable some messages. _firstEvent = false; @@ -475,7 +475,7 @@ namespace mu2e { StrawElectronics const& strawele, StrawClusterSequencePair const& hsp, XTalk const& xtalk, StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStepPointMCVectorCollection* mcptrs ) { + PtrStrawGasStepVectorCollection* mcptrs ) { // instantiate waveforms for both ends of this straw SWFP waveforms ={ StrawWaveform(hsp.clustSequence(StrawEnd::cal),xtalk), StrawWaveform(hsp.clustSequence(StrawEnd::hv),xtalk) }; @@ -497,22 +497,20 @@ namespace mu2e { } } - void StrawDigisFromStrawGasSteps::fillClusterMap(art::Event const& event, StrawClusterMap & hmap){ - // get conditions - DeadStraw const& deadStraw = _deadStraw_h.get(event.id()); - StrawPhysics const& strawphys = _strawphys_h.get(event.id()); - StrawElectronics const& strawele = _strawele_h.get(event.id()); - const Tracker& tracker = *GeomHandle(); - // Get all of the tracker StepPointMC collections from the event: - typedef vector< art::Handle > HandleVector; + void StrawDigisFromStrawGasSteps::fillClusterMap(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + + art::Event const& event, StrawClusterMap & hmap){ + // Get all of the tracker StrawGasStep collections from the event: + typedef vector< art::Handle > HandleVector; // This selector will select only data products with the given instance name. - art::ProductInstanceNameSelector selector(_trackerStepPoints); + art::ProductInstanceNameSelector selector(""); HandleVector stepsHandles; event.getMany( selector, stepsHandles); // Informational message on the first event. if ( _firstEvent ) { mf::LogInfo log(_messageCategory); - log << "StrawDigisFromStrawGasSteps::fillHitMap will use StepPointMCs from: \n"; + log << "StrawDigisFromStrawGasSteps::fillHitMap will use StrawGasSteps from: \n"; for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); i != e; ++i ){ art::Provenance const& prov(*(i->provenance())); @@ -520,32 +518,35 @@ namespace mu2e { } } if(stepsHandles.empty()){ - throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StepPointMC collections found for tracker" << endl; + throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StrawGasStep collections found for tracker" << endl; } - // Loop over StepPointMC collections - for ( HandleVector::const_iterator ispmcc=stepsHandles.begin(), espmcc=stepsHandles.end();ispmcc != espmcc; ++ispmcc ){ - art::Handle const& handle(*ispmcc); - StepPointMCCollection const& steps(*handle); - // Loop over the StepPointMCs in this collection - for (size_t ispmc =0; ispmc _minstepE){ - // create ptr to MC truth, used for references - art::Ptr spmcptr(handle,ispmc); - // create a clust from this step, and add it to the clust map - addStep(strawphys,strawele,spmcptr,straw,hmap[sid]); - } + // Loop over StrawGasStep collections + for ( auto const& sgsch : stepsHandles) { + StrawGasStepCollection const& steps(*sgsch); + // find the associated Assns for this sgsch + art::Handle sgsah; + if(!event.getByLabel(sgsch->provenance().moduleLabel(),sgsch->provenance().productInstanceName(),sgsah)){ + throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StrawGasStepAssns found for module " + << sgsch->provenance().moduleLabel() << " instance " + << sgsch->provenance().productInstanceName() << endl; + } + StrawGasStepAssns const& sgsa = *sgsah; + // Loop over the StrawGasSteps in this collection + for(size_t isgs = 0; isgs < steps.size(); isgs++){ + auto const& sgs = steps[isgs]; + // lookup straw here, to avoid having to find the tracker for every step + StrawId const & sid = sgs.strawId(); + Straw const& straw = tracker.getStraw(sid); + if(sgs.ionizingEdep() > _minstepE){ + // find assocated pPointMC for MC truth mapping + art::Ptr sgsptr(sgsch,isgs); + auto const& isgsa = sgsa[isgs];// these should be lock-step, but check + if(isgsa.first != sgsptr){ + throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: StrawGasStepAssns doesn't match StrawGasStep!" << endl; + } + auto const& spmcptr = isgsa.second; + // create a clust from this step, and add it to the clust map + addStep(strawphys,strawele,straw,sgs,spmcptr,hmap[sid]); } } } @@ -553,10 +554,11 @@ namespace mu2e { void StrawDigisFromStrawGasSteps::addStep(StrawPhysics const& strawphys, StrawElectronics const& strawele, - art::Ptr const& spmcptr, - Straw const& straw, StrawClusterSequencePair& shsp) { - StepPointMC const& step = *spmcptr; - StrawId sid = straw.id(); + Straw const& straw, + StrawGasStep const& step, + art::Ptr const& stmcptr, + StrawClusterSequencePair& shsp) { + StrawId sid = step.strawId(); // get time offset for this step double tstep = _toff.timeWithOffsetsApplied(step); // test if this step point is roughly in the digitization window @@ -564,9 +566,9 @@ namespace mu2e { if( (mbtime > strawele.flashEnd() - _steptimebuf && mbtime < strawele.flashStart()) || readAll(sid)) { - // Subdivide the StepPointMC into ionization clusters + // Subdivide the StrawGasStep into ionization clusters _clusters.clear(); - divideStep(strawphys,strawele,step,_clusters); + divideStep(strawphys,strawele,straw,step,_clusters); // check if(_debug > 1){ double ec(0.0); @@ -599,7 +601,7 @@ namespace mu2e { double ctime = microbunchTime(strawele,gtime); // create the clust StrawCluster clust(StrawCluster::primary,sid,end,ctime,weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time, - spmcptr,CLHEP::HepLorentzVector(iclu->_pos,mbtime)); //JB: + wireq._phi + stmcptr,CLHEP::HepLorentzVector(iclu->_pos,mbtime)); //JB: + wireq._phi // add the clusts to the appropriate sequence. shsp.clustSequence(end).insert(clust); @@ -611,58 +613,36 @@ namespace mu2e { } void StrawDigisFromStrawGasSteps::divideStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StepPointMC const& step, vector& clusters) { - // get particle charge - double charge(0.0); - GlobalConstantsHandle pdt; - if(pdt->particle(step.simParticle()->pdgId()).isValid()){ - charge = pdt->particle(step.simParticle()->pdgId()).ref().charge(); - } - - // get tracker information - const Tracker& tracker = *GeomHandle(); //JB - const Straw& straw = tracker.getStraw(step.strawId());//JB - // if the step length is small compared to the mean free path, or this is an - // uncharged particle, put all the energy in a single cluster - if (charge == 0.0 || step.stepLength() < strawphys.meanFreePath()){ - double cen = step.ionizingEdep(); - double fne = cen/strawphys.meanElectronEnergy(); - unsigned ne = std::max( static_cast(_randP(fne)),(unsigned)1); + StrawElectronics const& strawele, + Straw const& straw, + StrawGasStep const& step, vector& clusters) { + // single cluster + if (step.stepType().shape() == StrawGasStep::StepType::point || step.pathLength() < strawphys.meanFreePath()){ + double cen = step.ionizingEdep(); + double fne = cen/strawphys.meanElectronEnergy(); + unsigned ne = std::max( static_cast(_randP(fne)),(unsigned)1); - Hep3Vector cdir = (step.position()-straw.getMidPoint());//JB + Hep3Vector cdir = (step.startPosition()-straw.getMidPoint());//JB cdir -= straw.getDirection()*(cdir.dot(straw.getDirection()));//JB double phi = cdir.theta(); //JB for (size_t i=0;iparticle(step.simParticle()->pdgId()).isValid()){ - double mass = pdt->particle(step.simParticle()->pdgId()).ref().mass(); - double mom = step.momentum().mag(); - // approximate pt - double apt = 0.; - if ( _bdir.mag() > 0 ) apt = step.momentum().perpPart(_bdir).mag(); - double bg = mom/mass; // beta x gamma - minion = bg > _bgcut && apt > _ptmin; - } - - - // compute the number of clusters for this step from the mean free path - double fnc = step.stepLength()/strawphys.meanFreePath(); - // use a truncated Poisson distribution; this keeps both the mean and variance physical - unsigned nc = std::max(static_cast(_randP.fire(fnc)),(unsigned)1); - if(!minion)nc = std::min(nc,_maxnclu); - // require clusters not exceed the energy sum required for single-electron clusters - nc = std::min(nc,static_cast(floor(step.ionizingEdep()/strawphys.ionizationEnergy((unsigned)1)))); - // generate random positions for the clusters - std::vector cpos(nc); - fillClusterPositions(straw,step,cpos); - // generate electron counts and energies for these clusters: minion model is more detailed + } else { + // compute the number of clusters for this step from the mean free path + double fnc = step.pathLength()/strawphys.meanFreePath(); + // use a truncated Poisson distribution; this keeps both the mean and variance physical + unsigned nc = std::max(static_cast(_randP.fire(fnc)),(unsigned)1); + // if not minion, limit the number of steps geometrically + bool minion = (step.stepType().ionization()==StrawGasStep::StepType::minion); + if(!minion )nc = std::min(nc,_maxnclu); + // require clusters not exceed the energy sum required for single-electron clusters + nc = std::min(nc,static_cast(floor(step.ionizingEdep()/strawphys.ionizationEnergy((unsigned)1)))); + // generate random positions for the clusters + std::vector cpos(nc); + fillClusterPositions(straw,step,cpos); + // generate electron counts and energies for these clusters: minion model is more detailed std::vector ne(nc); std::vector cen(nc); if(minion){ @@ -690,7 +670,7 @@ namespace mu2e { } // diagnostics if(_diag > 0){ - _steplen = step.stepLength(); + _steplen = step.pathLength(); _stepE = step.ionizingEdep(); _steptime = microbunchTime(strawele,_toff.timeWithOffsetsApplied(step)); _partP = step.momentum().mag(); @@ -745,7 +725,7 @@ namespace mu2e { } double StrawDigisFromStrawGasSteps::microbunchTime(StrawElectronics const& strawele, double globaltime) const { - // converts time from proton beam time (StepPointMC time) to event window marker time + // converts time from proton beam time (StrawGasStep time) to event window marker time // fold time relative to MB frequency double mbtime = fmod(globaltime - _ewMarkerOffset,_mbtime); // keep the microbunch time contiguous @@ -816,18 +796,18 @@ namespace mu2e { WFXPList const& xings, SWFP const& wf, StrawId sid, StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStepPointMCVectorCollection* mcptrs ){ + PtrStrawGasStepVectorCollection* mcptrs ){ // loop over crossings for(auto xpair : xings) { // create a digi from this pair. This also performs a finial test // on whether the pair should make a digi if(createDigi(strawele,xpair,wf,sid,digis)){ // fill associated MC truth matching. Only count the same step once - set > xmcsp; + set > xmcsp; double wetime[2] = {-100.,-100.}; CLHEP::HepLorentzVector cpos[2]; - art::Ptr stepMC[2]; - set > spmcs; + art::Ptr stepMC[2]; + set > sgss; for (size_t iend=0;iend<2;++iend){ StrawCluster const& sc = *(xpair[iend]._iclust); xmcsp.insert(sc.stepPointMC()); @@ -835,7 +815,7 @@ namespace mu2e { cpos[iend] = sc.clusterPosition(); stepMC[iend] = sc.stepPointMC(); // make sure the trigter StepPoints also go in the StrawDigiMC - spmcs.insert(sc.stepPointMC()); + sgss.insert(sc.stepPointMC()); } // choose the minimum time from either end, as the ADC sums both double ptime = 1.0e10; @@ -844,18 +824,18 @@ namespace mu2e { } // subtract a small buffer ptime -= _adcbuffer; - // pickup all StepPointMCs associated with clusts inside the time window of the ADC digitizations (after the threshold) + // pickup all StrawGasSteps associated with clusts inside the time window of the ADC digitizations (after the threshold) for (auto ih=wf[0].clusts().clustList().begin();ih!=wf[0].clusts().clustList().end();++ih){ if (ih->time() >= ptime && ih->time() < ptime + ( strawele.nADCSamples()-strawele.nADCPreSamples())*strawele.adcPeriod()) - spmcs.insert(ih->stepPointMC()); + sgss.insert(ih->stepPointMC()); } - vector > stepMCs; - stepMCs.reserve(spmcs.size()); - for(auto ispmc=spmcs.begin(); ispmc!= spmcs.end(); ++ispmc){ - stepMCs.push_back(*ispmc); + vector > stepMCs; + stepMCs.reserve(sgss.size()); + for(auto isgs=sgss.begin(); isgs!= sgss.end(); ++isgs){ + stepMCs.push_back(*isgs); } - PtrStepPointMCVector mcptr; + PtrStrawGasStepVector mcptr; for(auto ixmcsp=xmcsp.begin();ixmcsp!=xmcsp.end();++ixmcsp) mcptr.push_back(*ixmcsp); mcptrs->push_back(mcptr); @@ -998,7 +978,7 @@ namespace mu2e { for(size_t iend=0;iend<2; ++iend){ ClusterList const& clusts = wfs[iend].clusts().clustList(); size_t nclust = clusts.size(); - set > steps; + set > steps; set > parts; _nxing[iend] = 0; _txing[iend] = strawele.flashStart() + _mbbuffer; @@ -1009,7 +989,7 @@ namespace mu2e { _xddist[iend] = ixing->at(iend)._iclust->driftDistance(); _xwdist[iend] = ixing->at(iend)._iclust->wireDistance(); // compute direction perpendicular to wire and momentum - art::Ptr const& spp = ixing->at(iend)._iclust->stepPointMC(); + art::Ptr const& spp = ixing->at(iend)._iclust->stepPointMC(); if(!spp.isNull()){ Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); // project the differences in position to get the perp distance @@ -1021,7 +1001,7 @@ namespace mu2e { if(nclust > 0 ){ _xddist[iend] = clusts.front().driftDistance(); _xwdist[iend] = clusts.front().wireDistance(); - art::Ptr const& spp = clusts.front().stepPointMC(); + art::Ptr const& spp = clusts.front().stepPointMC(); if(!spp.isNull()){ Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); // project the differences in position to get the perp distance @@ -1053,7 +1033,7 @@ namespace mu2e { _wmcpdg[iend] = iclu->stepPointMC()->simParticle()->pdgId(); _wmcproc[iend] = iclu->stepPointMC()->simParticle()->creationCode(); _mce[iend] = iclu->stepPointMC()->simParticle()->startMomentum().e(); - _slen[iend] = iclu->stepPointMC()->stepLength(); + _slen[iend] = iclu->stepPointMC()->pathLength(); _sedep[iend] = iclu->stepPointMC()->ionizingEdep(); } } @@ -1123,12 +1103,12 @@ namespace mu2e { _dmcmom = -1.0; _mctime = _mcenergy = _mctrigenergy = _mcthreshenergy = _mcdca = -1000.0; _mcthreshpdg = _mcthreshproc = _mcnstep = 0; - art::Ptr const& spmc = xpair[0]._iclust->stepPointMC(); - if(!spmc.isNull()){ - _mctime = _toff.timeWithOffsetsApplied(*spmc); + art::Ptr const& sgs = xpair[0]._iclust->stepPointMC(); + if(!sgs.isNull()){ + _mctime = _toff.timeWithOffsetsApplied(*sgs); // compute the doca for this step TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), - spmc->position(), spmc->momentum().unit() ); + sgs->position(), sgs->momentum().unit() ); _mcdca = pca.dca(); Hep3Vector mccdir = (pca.point2()-straw.getMidPoint()); @@ -1136,12 +1116,12 @@ namespace mu2e { _mcdcaphi = mccdir.theta(); _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); //JB: this is now from the lorentz corrected r-component of the drift - if(!spmc->simParticle().isNull()){ - _dmcpdg = spmc->simParticle()->pdgId(); - _dmcproc = spmc->simParticle()->creationCode(); - if(spmc->simParticle()->genParticle().isNonnull()) - _dmcgen = spmc->simParticle()->genParticle()->generatorId().id(); - _dmcmom = spmc->momentum().mag(); + if(!sgs->simParticle().isNull()){ + _dmcpdg = sgs->simParticle()->pdgId(); + _dmcproc = sgs->simParticle()->creationCode(); + if(sgs->simParticle()->genParticle().isNonnull()) + _dmcgen = sgs->simParticle()->genParticle()->generatorId().id(); + _dmcmom = sgs->momentum().mag(); } } _mcenergy = mcdigi.energySum(); @@ -1149,7 +1129,7 @@ namespace mu2e { // sum the energy from the explicit trigger particle, and find it's releationship _mcthreshenergy = 0.0; _mcnstep = mcdigi.stepPointMCs().size(); - art::Ptr threshpart = mcdigi.stepPointMC(StrawEnd::cal); + art::Ptr threshpart = mcdigi.stepPointMC(StrawEnd::cal); if(threshpart.isNull()) threshpart = mcdigi.stepPointMC(StrawEnd::hv); for(auto imcs = mcdigi.stepPointMCs().begin(); imcs!= mcdigi.stepPointMCs().end(); ++ imcs){ // if the SimParticle for this step is the same as the one which fired the discrim, add the energy @@ -1159,15 +1139,12 @@ namespace mu2e { _mcthreshpdg = threshpart->simParticle()->pdgId(); _mcthreshproc = threshpart->simParticle()->creationCode(); - _xtalk = digi.strawId() != spmc->strawId(); + _xtalk = digi.strawId() != sgs->strawId(); // fill the tree entry _sddiag->Fill(); }//End of digiDiag - - - - void StrawDigisFromStrawGasSteps::fillClusterPositions(Straw const& straw, StepPointMC const& step, std::vector& cpos) { + void StrawDigisFromStrawGasSteps::fillClusterPositions(Straw const& straw, StrawGasStep const& step, std::vector& cpos) { // basic info double charge(0.0); GlobalConstantsHandle pdt; @@ -1181,7 +1158,7 @@ namespace mu2e { // approximate pt double apt = step.momentum().perpPart(_bdir).mag(); if( apt > _ptmin) { // use linear approximation - double slen = step.stepLength(); + double slen = step.pathLength(); // make sure this linear approximation doesn't extend past the physical straw Hep3Vector dperp = (step.position() -straw.getMidPoint()).perpPart(straw.getDirection()); Hep3Vector mperp = mdir.perpPart(straw.getDirection()); @@ -1218,7 +1195,7 @@ namespace mu2e { // find helix parameters. By definition, z0 = phi0 = 0 double omega = qmdir.dot(pdir)/(rcurl*qmdir.dot(bfdir)); // compute how far this step goes along the field direction. This includes sign information - double zlen = step.stepLength()*mdir.dot(bfdir); + double zlen = step.pathLength()*mdir.dot(bfdir); // loop until we've found enough valid samples, or have given up trying unsigned iclu(0); unsigned ntries(0); @@ -1249,7 +1226,7 @@ namespace mu2e { } } - void StrawDigisFromStrawGasSteps::fillClusterMinion(StrawPhysics const& strawphys, StepPointMC const& step, std::vector& ne, std::vector& cen) { + void StrawDigisFromStrawGasSteps::fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& ne, std::vector& cen) { // Loop until we've assigned energy + electrons to every cluster unsigned mc(0); double esum(0.0); From 1543283549049b957e7907935884cedaef16a60b Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Wed, 6 Nov 2019 12:12:40 -0600 Subject: [PATCH 10/18] First complete StrawGasStep-compatible StrawDigi sim that compiles --- Analyses/src/PointerCheck_module.cc | 1 - Analyses/src/TrackSummaryTruthMaker_module.cc | 4 +- Filters/src/CalibCosmicFilter_module.cc | 9 +- Filters/src/CompressDigiMCsCheck_module.cc | 70 +- Filters/src/CompressDigiMCs_module.cc | 33 +- Filters/src/StepPointsInDigis_module.cc | 6 - MCDataProducts/inc/SimParticle.hh | 1 + MCDataProducts/inc/SimParticleCollection.hh | 15 +- MCDataProducts/inc/StrawDigiMC.hh | 28 +- MCDataProducts/inc/StrawGasStep.hh | 22 +- MCDataProducts/src/StrawDigiMC.cc | 41 +- MCDataProducts/src/classes.h | 3 +- MCDataProducts/src/classes_def.xml | 6 + Print/src/StrawDigiMCPrinter.cc | 7 +- TrackerMC/inc/StrawCluster.hh | 66 +- TrackerMC/src/MakeStrawGasSteps_module.cc | 147 ++-- TrackerMC/src/StrawCluster.cc | 51 +- .../src/StrawDigisFromStepPointMCs_module.cc | 4 +- .../src/StrawDigisFromStrawGasSteps_module.cc | 740 ++++++++---------- TrkDiag/src/StrawHitDiag_module.cc | 2 +- TrkDiag/src/TrkMCTools.cc | 29 +- Validation/src/ValStrawDigiMC.cc | 3 - 22 files changed, 582 insertions(+), 706 deletions(-) diff --git a/Analyses/src/PointerCheck_module.cc b/Analyses/src/PointerCheck_module.cc index 01bc531087..f052060272 100644 --- a/Analyses/src/PointerCheck_module.cc +++ b/Analyses/src/PointerCheck_module.cc @@ -454,7 +454,6 @@ namespace mu2e { for(auto const& d: coll) { // loop over the collection n++; // assemble all the pointer in the object - ptrs = d.stepPointMCs(); ptrs.push_back(d.stepPointMC(StrawEnd::cal)); ptrs.push_back(d.stepPointMC(StrawEnd::hv )); // check them diff --git a/Analyses/src/TrackSummaryTruthMaker_module.cc b/Analyses/src/TrackSummaryTruthMaker_module.cc index 7123580cb5..da45738bbd 100644 --- a/Analyses/src/TrackSummaryTruthMaker_module.cc +++ b/Analyses/src/TrackSummaryTruthMaker_module.cc @@ -83,9 +83,7 @@ namespace mu2e { ++nPrincipal[particleEnteringG4Volume(*dmc.stepPointMC(end))]; // Aggregate all the steps, so that each particle is counted no more than once per hit std::set > parts; - for(const auto& pstep: dmc.stepPointMCs()) { - parts.insert(particleEnteringG4Volume(*pstep)); - } + parts.insert(particleEnteringG4Volume(*dmc.stepPointMC(end))); for(const auto& p: parts) { ++nAll[p]; } diff --git a/Filters/src/CalibCosmicFilter_module.cc b/Filters/src/CalibCosmicFilter_module.cc index 0b7fb533f9..185e9edb24 100644 --- a/Filters/src/CalibCosmicFilter_module.cc +++ b/Filters/src/CalibCosmicFilter_module.cc @@ -201,9 +201,6 @@ namespace mu2e { for(auto const& sd : *trkDMC) { // loop over StrawDigiMC SPsave.insert(sd.stepPointMC(StrawEnd::cal)->simParticle().key()); SPsave.insert(sd.stepPointMC(StrawEnd::hv )->simParticle().key()); - for(auto const& s: sd.stepPointMCs()) { - SPsave.insert(s->simParticle().key()); - } } if(_verbose>5) std::cout << "CalibCosmicFilter SimParticles saved after tracker " @@ -357,13 +354,10 @@ namespace mu2e { outDMCp(new mu2e::StrawDigiMCCollection()); auto& outDMC = *outDMCp; art::Ptr stepMC[2]; - std::vector > stepMCs; for(auto d: *trkDMC) { stepMC[StrawEnd::cal] = SPMCmap[d.stepPointMC(StrawEnd::cal)]; stepMC[StrawEnd::hv ] = SPMCmap[d.stepPointMC(StrawEnd::hv )]; - stepMCs.clear(); - for(auto i:d.stepPointMCs()) stepMCs.push_back(SPMCmap[i]); - outDMC.push_back( mu2e::StrawDigiMC(d, stepMC, stepMCs) ); + outDMC.push_back( mu2e::StrawDigiMC(d, stepMC) ); } // loop over digis if(_verbose>5) std::cout @@ -398,6 +392,7 @@ namespace mu2e { auto& outCrvDMC = *outCrvDMCp; auto crvDMC = event.getValidHandle(_crvDMCtag); + std::vector > stepMCs; for(auto d: *crvDMC) { stepMCs.clear(); for(auto i:d.GetStepPoints()) stepMCs.push_back(SPMCmap[i]); diff --git a/Filters/src/CompressDigiMCsCheck_module.cc b/Filters/src/CompressDigiMCsCheck_module.cc index 9c4bd51f6e..a267a3419d 100644 --- a/Filters/src/CompressDigiMCsCheck_module.cc +++ b/Filters/src/CompressDigiMCsCheck_module.cc @@ -144,41 +144,41 @@ namespace mu2e { // If we only access steps through digis then you will get the correct information // You cannot loop over the StepPointMCCollection however // Here we check that the HV and Cal StepPtrs also exist in the WaveformStepPtrs - const auto& i_newStepPointMCCal = i_newStrawDigiMC.stepPointMC(StrawEnd::cal); - bool identical_cal_ptr = false; - bool identical_hv_ptr = false; - for (const auto& i_triggerStepPointPtr : i_newStrawDigiMC.stepPointMCs()) { - if (i_triggerStepPointPtr == i_newStepPointMC) { - identical_hv_ptr = true; - } - if (i_triggerStepPointPtr == i_newStepPointMCCal) { - identical_cal_ptr = true; - } - } - if (! (identical_hv_ptr && identical_cal_ptr) ) { - throw cet::exception("CompressDigiMCsCheck") << "Trigger StepPointMCs in StrawDigiMCs are not identical to any StepPointMC in the waveform. This could indicate a duplication of StepPointMCs" << std::endl; - } - - // Case 2: In this case, we have looped over an StepPointMCCollection with duplicated steps - // (and have not duplicated things further) - // StepPointMCs: A, B, C, D, E, A', A'' - // and the waveform will now include the duplicated steps: - // StrawDigiMC: HVStepPtr-->A', CalStepPtr-->A'', WaveformStepPtrs-->A, B, C, D, E, A', A'' - // This will not trigger the exception in Case 1 - // Here we check that there are no identical waveform steps - for (const auto& i_stepPointPtr : i_newStrawDigiMC.stepPointMCs()) { - for (const auto& j_stepPointPtr : i_newStrawDigiMC.stepPointMCs()) { - if (i_stepPointPtr == j_stepPointPtr) { - continue; // these will obviously match - } - - if ( (i_stepPointPtr->volumeId() == j_stepPointPtr->volumeId()) && - (i_stepPointPtr->totalEDep() == j_stepPointPtr->totalEDep()) - ) { - throw cet::exception("CompressDigiMCsCheck") << "Two StepPointMCs in StrawDigiMC waveform are identical" << std::endl; - } - } - } +// const auto& i_newStepPointMCCal = i_newStrawDigiMC.stepPointMC(StrawEnd::cal); +// bool identical_cal_ptr = false; +// bool identical_hv_ptr = false; +// for (const auto& i_triggerStepPointPtr : i_newStrawDigiMC.stepPointMCs()) { +// if (i_triggerStepPointPtr == i_newStepPointMC) { +// identical_hv_ptr = true; +// } +// if (i_triggerStepPointPtr == i_newStepPointMCCal) { +// identical_cal_ptr = true; +// } +// } +// if (! (identical_hv_ptr && identical_cal_ptr) ) { +// throw cet::exception("CompressDigiMCsCheck") << "Trigger StepPointMCs in StrawDigiMCs are not identical to any StepPointMC in the waveform. This could indicate a duplication of StepPointMCs" << std::endl; +// } +// +// // Case 2: In this case, we have looped over an StepPointMCCollection with duplicated steps +// // (and have not duplicated things further) +// // StepPointMCs: A, B, C, D, E, A', A'' +// // and the waveform will now include the duplicated steps: +// // StrawDigiMC: HVStepPtr-->A', CalStepPtr-->A'', WaveformStepPtrs-->A, B, C, D, E, A', A'' +// // This will not trigger the exception in Case 1 +// // Here we check that there are no identical waveform steps +// for (const auto& i_stepPointPtr : i_newStrawDigiMC.stepPointMCs()) { +// for (const auto& j_stepPointPtr : i_newStrawDigiMC.stepPointMCs()) { +// if (i_stepPointPtr == j_stepPointPtr) { +// continue; // these will obviously match +// } +// +// if ( (i_stepPointPtr->volumeId() == j_stepPointPtr->volumeId()) && +// (i_stepPointPtr->totalEDep() == j_stepPointPtr->totalEDep()) +// ) { +// throw cet::exception("CompressDigiMCsCheck") << "Two StepPointMCs in StrawDigiMC waveform are identical" << std::endl; +// } +// } +// } } } } diff --git a/Filters/src/CompressDigiMCs_module.cc b/Filters/src/CompressDigiMCs_module.cc index 9212a6f4d6..72383cef7a 100644 --- a/Filters/src/CompressDigiMCs_module.cc +++ b/Filters/src/CompressDigiMCs_module.cc @@ -672,22 +672,23 @@ void mu2e::CompressDigiMCs::copyStrawDigiMC(const mu2e::StrawDigiMC& old_straw_d newTriggerStepPtr[i_end] = new_step_point; } - std::vector > newWaveformStepPtrs; - for (const auto& i_step_mc : old_straw_digi_mc.stepPointMCs()) { - const auto& newStepPtrIter = step_remap.find(i_step_mc); - if (newStepPtrIter == step_remap.end()) { - if (i_step_mc.isAvailable()) { - step_remap[i_step_mc] = copyStepPointMC( *i_step_mc, _trackerOutputInstanceLabel ); - } - else { // this is a null Ptr but it should be added anyway to keep consistency (not expected for StrawDigis) - step_remap[i_step_mc] = i_step_mc; - } - } - art::Ptr new_step_point = step_remap.at(i_step_mc); - newWaveformStepPtrs.push_back(new_step_point); - } - - StrawDigiMC new_straw_digi_mc(old_straw_digi_mc, newTriggerStepPtr, newWaveformStepPtrs); // copy everything except the Ptrs from the old StrawDigiMC +// std::vector > newWaveformStepPtrs; +// for (const auto& i_step_mc : old_straw_digi_mc.stepPointMCs()) { +// const auto& newStepPtrIter = step_remap.find(i_step_mc); +// if (newStepPtrIter == step_remap.end()) { +// if (i_step_mc.isAvailable()) { +// step_remap[i_step_mc] = copyStepPointMC( *i_step_mc, _trackerOutputInstanceLabel ); +// } +// else { // this is a null Ptr but it should be added anyway to keep consistency (not expected for StrawDigis) +// step_remap[i_step_mc] = i_step_mc; +// } +// } +// art::Ptr new_step_point = step_remap.at(i_step_mc); +// newWaveformStepPtrs.push_back(new_step_point); +// } + +// StrawDigiMC new_straw_digi_mc(old_straw_digi_mc, newTriggerStepPtr, newWaveformStepPtrs); // copy everything except the Ptrs from the old StrawDigiMC + StrawDigiMC new_straw_digi_mc(old_straw_digi_mc, newTriggerStepPtr); // copy everything except the Ptrs from the old StrawDigiMC _newStrawDigiMCs->push_back(new_straw_digi_mc); } diff --git a/Filters/src/StepPointsInDigis_module.cc b/Filters/src/StepPointsInDigis_module.cc index 93ece19875..ab29e87f0c 100644 --- a/Filters/src/StepPointsInDigis_module.cc +++ b/Filters/src/StepPointsInDigis_module.cc @@ -126,12 +126,6 @@ void mu2e::StepPointsInDigis::analyze(art::Event const& event) } } - for (const auto& i_step_mc : i_strawDigiMC.stepPointMCs()) { - if (i_step_mc.isAvailable()) { - fillTree(*i_step_mc); - } - } - _digiProductId = _stepProductId; _digiTime = i_strawDigiMC.wireEndTime(StrawEnd::cal); _digis->Fill(); diff --git a/MCDataProducts/inc/SimParticle.hh b/MCDataProducts/inc/SimParticle.hh index cbaf2639e2..ec40e62375 100644 --- a/MCDataProducts/inc/SimParticle.hh +++ b/MCDataProducts/inc/SimParticle.hh @@ -279,6 +279,7 @@ namespace mu2e { bool _endDefined; }; + typedef cet::map_vector SimParticleCollection; } diff --git a/MCDataProducts/inc/SimParticleCollection.hh b/MCDataProducts/inc/SimParticleCollection.hh index 0635b21aaf..718cb8510c 100644 --- a/MCDataProducts/inc/SimParticleCollection.hh +++ b/MCDataProducts/inc/SimParticleCollection.hh @@ -1,21 +1,8 @@ #ifndef MCDataProducts_SimParticleCollection_hh #define MCDataProducts_SimParticleCollection_hh -// -// Define a type for a collection of SimParticle objects. -// -// $Id: SimParticleCollection.hh,v 1.2 2011/05/24 20:03:31 wb Exp $ -// $Author: wb $ -// $Date: 2011/05/24 20:03:31 $ -// -// Original author Rob Kutschke -// +// deprecated: use SimParticle.hh instead #include "MCDataProducts/inc/SimParticle.hh" -#include "cetlib/map_vector.h" - -namespace mu2e { - typedef cet::map_vector SimParticleCollection; -} #endif /* MCDataProducts_SimParticleCollection_hh */ diff --git a/MCDataProducts/inc/StrawDigiMC.hh b/MCDataProducts/inc/StrawDigiMC.hh index 8eb01985ff..bf6908cf93 100644 --- a/MCDataProducts/inc/StrawDigiMC.hh +++ b/MCDataProducts/inc/StrawDigiMC.hh @@ -6,8 +6,9 @@ // Original author David Brown, LBNL // // Mu2e includes -#include "RecoDataProducts/inc/StrawDigi.hh" #include "DataProducts/inc/StrawId.hh" +#include "DataProducts/inc/StrawEnd.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" #include "MCDataProducts/inc/StepPointMC.hh" // CLHEP includes #include "CLHEP/Vector/LorentzVector.h" @@ -17,6 +18,7 @@ // C++ includes #include #include +#include // Mu2e includes @@ -29,13 +31,15 @@ namespace mu2e { StrawDigiMC(); // construct from hitlets StrawDigiMC(StrawId sid, double wetime[2], - CLHEP::HepLorentzVector cpos[2], - art::Ptr stepMC[2], std::vector > const& stepMCs); + CLHEP::HepLorentzVector cpos[2], + art::Ptr sgs[2], art::Ptr stepMC[2]); + // temporary legacy construtctor fot testing FIXME! + StrawDigiMC(StrawId sid, double wetime[2], + CLHEP::HepLorentzVector cpos[2], art::Ptr stepMC[2], std::vector > const& stepmcs); // copy construcors StrawDigiMC(const StrawDigiMC& rhs); // default: don't copy art::Ptrs - StrawDigiMC(const StrawDigiMC& rhs, art::Ptr stepMC[2], std::vector > const& stepMCs); - + StrawDigiMC(const StrawDigiMC& rhs, art::Ptr stepMC[2] ); // Accessors StrawId strawId() const { return _strawid; } double wireEndTime(StrawEnd strawend) const { return _wetime[strawend]; } @@ -44,9 +48,11 @@ namespace mu2e { double driftDistance(StrawEnd strawend) const; double distanceToMid(StrawEnd strawend) const; art::Ptr const& stepPointMC(StrawEnd strawend) const { return _stepMC[strawend]; } - std::vector > const& stepPointMCs() const { return _stepMCs; } + std::array,StrawEnd::nends> const& stepPointMCs() const { return _stepMC; } + art::Ptr const& strawGasStep(StrawEnd strawend) const { return _sgs[strawend]; } StrawEnd earlyEnd() const { return (_wetime[StrawEnd::cal] < _wetime[StrawEnd::hv]) ? StrawEnd::cal : StrawEnd::hv; } art::Ptr const& earlyStepPointMC() const { return stepPointMC(earlyEnd()); } + art::Ptr const& earlyStrawGasStep() const { return strawGasStep(earlyEnd()); } double energySum() const;// sum of all MC true energy deposited // energy sum of particle that triggered the discriminator @@ -58,15 +64,13 @@ namespace mu2e { private: StrawId _strawid; // Straw sid - // the following should be an std::array<,2>, but that's not supported by CINT: FIXME!! - CLHEP::HepLorentzVector _cpos[2]; // Positions of the clusters responsible + std::array _cpos; // Positions of the clusters responsible // for the TDC firings on each end (can be the same) - double _wetime[2]; // times at the wire ends of the signals which fired the TDC. This needs double precision as neutrons can take seconds (!) to generate signals + std::array _wetime; // times at the wire ends of the signals which fired the TDC. This needs double precision as neutrons can take seconds (!) to generate signals // in ns from event window marker - art::Ptr _stepMC[2]; // Ptr into StepPointMC collection of step which - // triggered the TDC - std::vector > _stepMCs; // All StepPointMCs which contributed to the waveform + std::array,StrawEnd::nends> _sgs; // Ptr into StrawGasStep collection of step which + std::array,StrawEnd::nends> _stepMC; // Ptr into StepPointMC collection of step which }; inline std::ostream& operator<<( std::ostream& ost, diff --git a/MCDataProducts/inc/StrawGasStep.hh b/MCDataProducts/inc/StrawGasStep.hh index c5033905f1..1dfc840565 100644 --- a/MCDataProducts/inc/StrawGasStep.hh +++ b/MCDataProducts/inc/StrawGasStep.hh @@ -22,19 +22,19 @@ namespace mu2e { constexpr static uint8_t _ssft = 0; // shift for shape field constexpr static uint8_t _imsk = 0xF0; // mask for ionization field constexpr static uint8_t _isft = 4; // shift for ionization field - enum shape {line=0,arc,curl,point }; // shape of the trajectory within the straw - enum ionization { minion=0, highion, neutral }; // type of ionization + enum Shape {line=0,arc,curl,point }; // shape of the trajectory within the straw + enum Ionization { minion=0, highion, neutral }; // type of ionization uint16_t _stype; StepType() : _stype(0) {} - StepType(StepType::shape shp, StepType::ionization ion) : + StepType(StepType::Shape shp, StepType::Ionization ion) : _stype( shp | (ion << _isft)) {} - shape() const { return _stype & _smsk; } - ionization() const { return (_stype & _imsk) >> _isft; } + Shape shape() const { return static_cast(_stype & _smsk); } + Ionization ionization() const { return static_cast((_stype & _imsk) >> _isft); } }; - StrawGasStep() : _eIon(0.0), _pathLen(0.), _mom(0.0), _time(0.0) {} + StrawGasStep() : _eIon(0.0), _pathLen(0.), _width(0.0), _time(0.0) {} StrawGasStep( StrawId strawId, StepType stype, Float_t Edep, Float_t pathLength, Float_t width, Double_t time, XYZVec const& startPosition, XYZVec const& endPosition) : @@ -46,7 +46,7 @@ namespace mu2e { StepType stepType() const { return _stype; } Float_t ionizingEdep() const { return _eIon; } Float_t pathLength() const { return _pathLen; } - Float_t radialWidth() const { return _width; } + Float_t width() const { return _width; } Double_t time() const { return _time; } XYZVec const& startPosition() const { return _startpos; } XYZVec const& endPosition() const { return _endpos; } @@ -62,6 +62,14 @@ namespace mu2e { typedef std::vector StrawGasStepCollection; typedef art::Assns StrawGasStepAssns; + + inline std::ostream& operator<<( std::ostream& ost, StrawGasStep const& sgs){ + ost << "StrawGasStep StrawId " << sgs.strawId() << " Type " << sgs.stepType()._stype + << " Ionization " << sgs.ionizingEdep() << " path length " << sgs.pathLength() + << " Width " << sgs.width(); + return ost; + } + } #endif diff --git a/MCDataProducts/src/StrawDigiMC.cc b/MCDataProducts/src/StrawDigiMC.cc index 7eb8b1d6a6..0acc515958 100644 --- a/MCDataProducts/src/StrawDigiMC.cc +++ b/MCDataProducts/src/StrawDigiMC.cc @@ -25,8 +25,20 @@ namespace mu2e { StrawDigiMC::StrawDigiMC(StrawId sid, double wetime[2], CLHEP::HepLorentzVector cpos[2], - art::Ptr stepMC[2], vector > const& stepMCs) : - _strawid(sid), _stepMCs(stepMCs) + art::Ptr sgs[2], art::Ptr stepmc[2]) : + _strawid(sid) + { + for(size_t strawend=0;strawend<2;++strawend){ + _wetime[strawend] = wetime[strawend]; + _cpos[strawend] = cpos[strawend]; + _sgs[strawend] = sgs[strawend]; + _stepMC[strawend] = stepmc[strawend]; + } + } + +// legacy constructor: StrawGasSteps will be empty! + StrawDigiMC::StrawDigiMC(StrawId sid, double wetime[2], + CLHEP::HepLorentzVector cpos[2], art::Ptr stepMC[2], std::vector > const& stepmcs) :_strawid(sid) { for(size_t strawend=0;strawend<2;++strawend){ _wetime[strawend] = wetime[strawend]; @@ -35,23 +47,24 @@ namespace mu2e { } } - StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs) : _strawid(rhs.strawId()), _stepMCs(rhs.stepPointMCs()) { + StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs) : _strawid(rhs.strawId()) { for(int i_end=0;i_end(i_end); _wetime[end] = rhs.wireEndTime(end); _cpos[end] = rhs.clusterPosition(end); + _sgs[end] = rhs.strawGasStep(end); _stepMC[end] = rhs.stepPointMC(end); } } - StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs, art::Ptr stepMC[2], std::vector > const& stepMCs) : _strawid(rhs.strawId()) { + StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs, art::Ptr stepMC[2] ) : _strawid(rhs.strawId()) { for(int i_end=0;i_end(i_end); _wetime[end] = rhs.wireEndTime(end); _cpos[end] = rhs.clusterPosition(end); + _sgs[end] = rhs.strawGasStep(end); _stepMC[end] = stepMC[i_end]; } - _stepMCs = stepMCs; } double StrawDigiMC::driftDistance(StrawEnd strawend) const { @@ -84,26 +97,12 @@ namespace mu2e { } double StrawDigiMC::energySum() const { - double esum(0.0); - for(auto imcs = _stepMCs.begin(); imcs!= _stepMCs.end(); ++ imcs){ - esum += (*imcs)->eDep(); - } - return esum; + return _sgs[0]->ionizingEdep(); } double StrawDigiMC::triggerEnergySum(StrawEnd strawend) const { - double esum(0.0); - if(!_stepMC[(size_t)strawend].isNull()){ - for(auto imcs = _stepMCs.begin(); imcs!= _stepMCs.end(); ++ imcs){ - // if the simParticle for this step is the same as the one which fired the discrim, add the energy - if( (*imcs)->simParticle() == _stepMC[(size_t)strawend]->simParticle() || - (*imcs)->simParticle()->parent() == _stepMC[(size_t)strawend]->simParticle() || - (*imcs)->simParticle() == _stepMC[(size_t)strawend]->simParticle()->parent() ) - esum += (*imcs)->eDep(); - } - } - return esum; + return _sgs[strawend]->ionizingEdep(); } // Print the information found in this hit. diff --git a/MCDataProducts/src/classes.h b/MCDataProducts/src/classes.h index dd8f9aab3c..257c463c41 100644 --- a/MCDataProducts/src/classes.h +++ b/MCDataProducts/src/classes.h @@ -64,7 +64,8 @@ #include "MCDataProducts/inc/CaloClusterMC.hh" // straws #include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" -#include "MCDataProducts/inc/StrawDigiMCCollection.hh" +#include "MCDataProducts/inc/StrawDigiMC.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" // tracking #include "MCDataProducts/inc/TrackSummaryTruthAssns.hh" diff --git a/MCDataProducts/src/classes_def.xml b/MCDataProducts/src/classes_def.xml index f564cb6556..3958e880a9 100644 --- a/MCDataProducts/src/classes_def.xml +++ b/MCDataProducts/src/classes_def.xml @@ -207,6 +207,12 @@ + + + + + + diff --git a/Print/src/StrawDigiMCPrinter.cc b/Print/src/StrawDigiMCPrinter.cc index bd49b4c5d1..9d2435b92e 100644 --- a/Print/src/StrawDigiMCPrinter.cc +++ b/Print/src/StrawDigiMCPrinter.cc @@ -70,9 +70,10 @@ mu2e::StrawDigiMCPrinter::Print(const mu2e::StrawDigiMC& obj, int ind, std::ostr // energy accessor is not protected against bad Ptr double energy = 0.0, tenergy0 = 0.0, tenergy1 = 0.0; bool eOK = true; - for(auto const& ap: obj.stepPointMCs()) { - if(!ap.isAvailable()) eOK = false; - } + if(!obj.stepPointMC(StrawEnd::cal).isAvailable() || + !obj.stepPointMC(StrawEnd::hv).isAvailable() || + !obj.strawGasStep(StrawEnd::cal).isAvailable() || + !obj.strawGasStep(StrawEnd::hv).isAvailable() ) eOK = false; if(eOK) { energy = obj.energySum(); tenergy0 = obj.triggerEnergySum(StrawEnd::cal); diff --git a/TrackerMC/inc/StrawCluster.hh b/TrackerMC/inc/StrawCluster.hh index 800a05d550..e9ff388fdb 100644 --- a/TrackerMC/inc/StrawCluster.hh +++ b/TrackerMC/inc/StrawCluster.hh @@ -17,6 +17,7 @@ #include "DataProducts/inc/StrawId.hh" #include "DataProducts/inc/StrawEnd.hh" #include "MCDataProducts/inc/StepPointMC.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" // toolkit includes #include "canvas/Persistency/Common/Ptr.h" #include "CLHEP/Vector/LorentzVector.h" @@ -28,38 +29,36 @@ namespace mu2e { enum ClusterType {unknown=-1,primary=0,xtalk=1,noise=2}; // constructors StrawCluster(); - StrawCluster(const StrawCluster&); // x-talk constructor - explicit StrawCluster(const StrawCluster& primary, StrawId const& sid, double xfactor); + explicit StrawCluster(const StrawCluster& primary, StrawId const& sid, float xfactor); // ghost constructor explicit StrawCluster(const StrawCluster& primary, double deltat); - StrawCluster(ClusterType type, - StrawId sid, - StrawEnd end, - double time, - double charge, - double ddist, - double phi, //JB: added - double wiredist, - double drifttime, - double proptime, - art::Ptr const& stepmc, - CLHEP::HepLorentzVector const& cpos); - - StrawCluster& operator = (StrawCluster const& other); - + explicit StrawCluster(ClusterType type,StrawId sid, + StrawEnd end, + double time, + float charge, + float ddist, + float phi, + float wdist, + float drifttime, + float proptime, + art::Ptr const& sgs, + art::Ptr const& stepmc, + CLHEP::HepLorentzVector const& cpos); + // use compiler version of copy, assignment // Accessors ClusterType type() const { return _type; } StrawId strawId() const { return _strawId; } StrawEnd strawEnd() const { return _end; } - double time() const { return _time;} - double charge() const { return _charge; } - double driftDistance() const { return _ddist; } - double phi() const { return _phi; } //JB: added - double wireDistance() const { return _wdist; } - double driftTime() const { return _drifttime; } - double propTime() const { return _proptime; } - art::Ptr const& stepPointMC() const { return _stepMC; } + double time() const { return _time;} + float charge() const { return _charge; } + float driftDistance() const { return _ddist; } + float phi() const { return _phi; } //JB: added + float wireDistance() const { return _wdist; } + float driftTime() const { return _drifttime; } + float propTime() const { return _proptime; } + art::Ptr const& strawGasStep() const { return _sgsptr; } + art::Ptr const& stepPointMC() const { return _spmcptr; } CLHEP::HepLorentzVector const& clusterPosition() const { return _cpos; } // Print contents of the object. void print( std::ostream& ost = std::cout, bool doEndl = true ) const; @@ -67,14 +66,15 @@ namespace mu2e { ClusterType _type; // type of clust StrawId _strawId; // Straw id StrawEnd _end; // which end of the straw - double _time; // microbunch time at the wire end, in ns since EventWindowMarker - double _charge; // charge at the wire end, in units of pC - double _ddist; // drift distance charge traveled to the wire - double _phi; //JB: angle between E and B at ionization event - double _wdist; // distance along the wire the charge has traveled, used to calculate dispersion - double _drifttime; - double _proptime; - art::Ptr _stepMC; // Ptr into StepPointMC collection + double _time; // microbunch time at the wire end, in ns since EventWindowMarker + float _charge; // charge at the wire end, in units of pC + float _ddist; // drift distance charge traveled to the wire + float _phi; //JB: angle between E and B at ionization event + float _wdist; // distance along the wire the charge has traveled, used to calculate dispersion + float _drifttime; + float _proptime; + art::Ptr _sgsptr; // reference to step + art::Ptr _spmcptr; // legacy ref to StepPointMC FIXME! CLHEP::HepLorentzVector _cpos; // position and time of the cluster that created this clust }; } // namespace TrackerMC diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index e938eb9773..83cbf12ce4 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -18,15 +18,18 @@ #include "art_root_io/TFileService.h" #include "GlobalConstantsService/inc/GlobalConstantsHandle.hh" #include "GlobalConstantsService/inc/ParticleDataTable.hh" +#include "HepPDT/ParticleData.hh" +#include "ProditionsService/inc/ProditionsHandle.hh" #include "TrackerConditions/inc/DeadStraw.hh" #include "BFieldGeom/inc/BFieldManager.hh" #include "BTrk/BField/BField.hh" #include "Mu2eUtilities/inc/TwoLinePCA.hh" +#include "Mu2eUtilities/inc/SimParticleTimeOffset.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "MCDataProducts/inc/MCRelationship.hh" #include "MCDataProducts/inc/StrawGasStep.hh" -#include "MCDataProducts/inc/PtrStepPointMCVector.hh" +#include "MCDataProducts/inc/StepPointMC.hh" #include // root #include "TH1F.h" @@ -34,6 +37,7 @@ using namespace std; using CLHEP::Hep3Vector; +using HepPDT::ParticleData; namespace mu2e { class MakeStrawGasSteps : public art::EDProducer { @@ -64,11 +68,14 @@ namespace mu2e { fhicl::Atom csize{ Name("OutputCollectionSize"), Comment("Estimated size of output collection"), 2000}; fhicl::Atom trackerSteps { Name("trackerStepPoints"), - Comment("Tracker StepPointMC Producer Instance name"),"tracker"}; + Comment("Tracker StepPointMC Instance name"),"tracker"}; + fhicl::Atom stepsToSkip { Name("SkipTheseStepPoints"), + Comment("Tracker StepPointMC producers to skip"), ""}; fhicl::Atom keepDeltas { Name("KeepDeltasModule"), Comment("Dont combine Deltas from this module's collection")}; fhicl::Atom startSize { Name("StartSize"), Comment("Starting size for straw-particle vector"),4}; + fhicl::Sequence SPTO { Name("TimeOffsets"), Comment("Sim Particle Time Offset Maps")}; fhicl::Atom allStepsAssns{ Name("AllStepsAssns"), Comment("Build the association to all the contributing StepPointMCs"),false}; }; @@ -80,34 +87,44 @@ namespace mu2e { void beginRun(art::Run& run) override; void produce(art::Event& e) override; typedef pair SSPair; // key for pair of straw, SimParticle - typedef map< SSPair , PtrStepPointMCVector > SPSMap; // steps by straw, SimParticle + typedef art::Ptr SPMCP; + typedef vector SPMCPV; + typedef map< SSPair , SPMCPV > SPSMap; // steps by straw, SimParticle typedef art::Handle SPMCCH; typedef vector< SPMCCH > SPMCCHV; void fillMap(Tracker const& tracker,DeadStraw const& deadStraw, SPMCCH const& spmcch, SPSMap& spsmap); void compressDeltas(SPSMap& spsmap); - void fillStep(PtrStepPointMCVector const& spmcptrs, Straw const& straw, - ParticleData const* pdata, StrawGasStep& sgs, art::Ptr& spmcptr); - void fillStepDiag(Straw const& straw, StrawGasStep const& sgs, art::Ptrconst& spmcptr); - XYZVec endPosition(art::Ptrconst& last, Straw const& straw,float charge); + void setStepType(SPMCP const& spmcptr, ParticleData const* pdata, StrawGasStep::StepType& stype); + void fillStep(SPMCPV const& spmcptrs, Straw const& straw, + ParticleData const* pdata, cet::map_vector_key pid, + StrawGasStep& sgs, SPMCP & spmcptr); + void fillStepDiag(Straw const& straw, StrawGasStep const& sgs, SPMCP const& spmcptr, SPMCPV const& spmcptrs); + XYZVec endPosition(SPMCP const& last, Straw const& straw,float charge,StrawGasStep::StepType& stype); int _debug, _diag; bool _combineDeltas, _allAssns; float _maxDeltaLen, _radtol, _parrot, _curlrot; float _minionBG; + float _curlfac, _linefac; float _curlmom, _linemom; unsigned _csize, _ssize; + SimParticleTimeOffset _toff; // time offsets + string _keepDeltas; + // StepPointMC selector + // This selector will select only data products with the given instance name. + // optionally exclude modules: this is a fix + art::Selector _selector; bool _firstEvent; - string _trackerSteps, _keepDeltas; // cache the BField direction at the tracker center Hep3Vector _bdir; float _bnom; // BField in units of (MeV/c)/mm + ProditionsHandle _deadStraw_h; // dead straw list // diagnostic histograms TH1F *_hendrad, *_hphi; TTree* _sgsdiag; Float_t _prilen, _pridist, _elen, _erad, _epri, _esec, _partP, _brot, _width, _doca; vector _sdist; Int_t _npri, _nsec, _partPDG; - ProditionsHandle _deadStraw_h; }; MakeStrawGasSteps::MakeStrawGasSteps(const Parameters& config ) : @@ -121,20 +138,22 @@ namespace mu2e { _parrot(config().parabolicRotation()), _curlrot(config().curlRotation()), _minionBG(config().minionBG()), - _curlRatio(config().curlRatio()), - _lineRatio(config().lineRatio()), + _curlfac(config().curlRatio()), + _linefac(config().lineRatio()), _csize(config().csize()), _ssize(config().startSize()), - _firstEvent(false), - _trackerSteps(config().trackerSteps()), - _keepDeltas(config().keepDeltas()) - { - consumesMany(); - produces (); - // 2 associations: one to all the constituent StepPointMCs, the other to the first (in time) primary - produces ("Primary"); - if(_allAssns)produces ("All"); - } + _toff(config().SPTO()), + _keepDeltas(config().keepDeltas()), + _selector{art::ProductInstanceNameSelector(config().trackerSteps()) && + !art::ModuleLabelSelector(config().stepsToSkip()) }, + _firstEvent(false) + { + consumesMany(); + produces (); + // 2 associations: one to all the constituent StepPointMCs, the other to the first (in time) primary + produces ("Primary"); + if(_allAssns)produces ("All"); + } void MakeStrawGasSteps::beginJob(){ art::ServiceHandle tfs; @@ -143,9 +162,9 @@ namespace mu2e { _hphi = tfs->make("phi","Step rotation angle",100,0.0,3.14); if(_diag > 1) { _sgsdiag=tfs->make("sgsdiag","StrawGasStep diagnostics"); - _sgsdiag->Branch("prilen",&_prilen,"prilen/F"); - _sgsdiag->Branch("elen",&_elen,"elen/F"); - _sgsdiag->Branch("pridist",&_pridist,"pridist/F"); + _sgsdiag->Branch("prilen",&_prilen,"prilen/F"); + _sgsdiag->Branch("elen",&_elen,"elen/F"); + _sgsdiag->Branch("pridist",&_pridist,"pridist/F"); _sgsdiag->Branch("brot",&_brot,"brot/F"); _sgsdiag->Branch("erad",&_erad,"erad/F"); _sgsdiag->Branch("epri",&_epri,"epri/F"); @@ -172,16 +191,18 @@ namespace mu2e { _bnom = bnom.mag()*BField::mmTeslaToMeVc; // pre-compute momentum thresholds for straight, arc, and curler const Tracker& tracker = *GeomHandle(); - const Straw& straw = tracker.getStraw(StrawId(0,0,0)); - float rstraw = straw.innerRadius(); - _curlmom = _bnom*rstraw; - _linemom = _arcfac*_pcurl; + const Straw& straw = tracker.getStraw(StrawId(0,0,0)); // any straw is good enough + float pstraw = _bnom*straw.innerRadius();// transverse momentum with same radius as straw + _curlmom = _curlfac*pstraw; + _linemom = _linefac*pstraw; } void MakeStrawGasSteps::produce(art::Event& event) { + // setup conditions, etc const Tracker& tracker = *GeomHandle(); GlobalConstantsHandle pdt; DeadStraw const& deadStraw = _deadStraw_h.get(event.id()); + _toff.updateMap(event); // create output unique_ptr sgsc(new StrawGasStepCollection); sgsc->reserve(_csize); @@ -192,9 +213,8 @@ namespace mu2e { auto StrawGasStepCollectionGetter = event.productGetter(StrawGasStepCollectionPID); // Get all of the tracker StepPointMC collections from the event: // This selector will select only data products with the given instance name. - art::ProductInstanceNameSelector selector(_trackerSteps); SPMCCHV stepsHandles; - event.getMany( selector, stepsHandles); + event.getMany( _selector, stepsHandles); // const Tracker& tracker = *GeomHandle(); // Informational message on the first event. if ( _firstEvent && _debug>0 ) { @@ -234,11 +254,14 @@ namespace mu2e { for(auto ispsmap = spsmap.begin(); ispsmap != spsmap.end(); ispsmap++){ auto pid = ispsmap->first.second; // primary SimParticle auto const& spmcptrs = ispsmap->second; - const Straw& straw = tracker.getStraw(ispsmap->first.first); - ParticleData const* pdata = pdt->particle(spcptrs.front()->simParticle()->pdgId()); + auto const& straw = tracker.getStraw(ispsmap->first.first); + auto const& simptr = spmcptrs.front()->simParticle(); + auto pref = pdt->particle(simptr->pdgId()); + ParticleData const* pdata(0); + if(pref.isValid())pdata = &pref.ref(); StrawGasStep sgs; - art::Ptr spmcptr; - fillStep(spmcptrs,straw,pdata,sgs,spmcptr); + SPMCP spmcptr; + fillStep(spmcptrs,straw,pdata,pid,sgs,spmcptr); sgsc->push_back(sgs); // create the Assns to the 'trigger' StepPointMC auto sgsp = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); @@ -248,17 +271,17 @@ namespace mu2e { for(auto const& spmcptr : spmcptrs) sgsa_all->addSingle(sgsp,spmcptr); } - if(_diag > 0)fillStepDiag(straw,sgs,spmcptr); + if(_diag > 0)fillStepDiag(straw,sgs,spmcptr,spmcptrs); if(_debug > 1){ // checks and printout - cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << sgs.simParticleKey() - << " edep = " << eion << " pathlen = " << pathlen << " glen = " << sqrt((end-start).mag2()) << " width = " << width << " mom = " << mom + cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << spmcptr->simParticle().id() + << " edep = " << sgs.ionizingEdep() << " pathlen = " << sgs.pathLength() << " glen = " << sqrt((sgs.endPosition()-sgs.startPosition()).mag2()) << " width = " << sgs.width() << " time = " << sgs.time() << endl; // check if end is inside physical straw const Straw& straw = tracker.getStraw(sgs.strawId()); static double r2 = straw.innerRadius()*straw.innerRadius(); - Hep3Vector hend = Geom::Hep3Vec(end); + Hep3Vector hend = Geom::Hep3Vec(sgs.endPosition()); double rd2 = (hend-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); if(rd2 - r2 > 1e-5 ) cout << "End outside straw, radius " << sqrt(rd2) << endl; } @@ -272,18 +295,17 @@ namespace mu2e { if(_allAssns) event.put(move(sgsa_all),"All"); } // end of produce - void MakeStrawGasSteps::fillStep(PtrStepPointMCVector const& spmcptrs, Straw const& straw, - ParticleData const* pdata, StrawGasStep& sgs, art::Ptr& spmcptr){ + void MakeStrawGasSteps::fillStep(SPMCPV const& spmcptrs, Straw const& straw, + ParticleData const* pdata, cet::map_vector_key pid, StrawGasStep& sgs, SPMCP & spmcptr){ // variables we accumulate for all the StepPoints in this pair double eion(0.0), pathlen(0.0); - double time(0.0), mom(0.0); if(_diag>1){ _npri=_nsec=0; _epri=_esec=0.0; } // keep track of the first and last PRIMARY step - art::Ptr first; - art::Ptr last; + SPMCP first; + SPMCP last; // loop over all the StepPoints for this SimParticle for(auto const& spmcptr : spmcptrs){ bool primary=spmcptr->simParticle()->id() == pid; @@ -315,17 +337,14 @@ namespace mu2e { // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last XYZVec start = Geom::toXYZVec(first->position()); float charge(0.0); - if(pdata!=0){ - charge = pdt->particle(first->simParticle()->pdgId()).ref().charge(); - } + if(pdata!=0) charge = pdata->charge(); // determine the type of step StrawGasStep::StepType stype; - setType(first,stype); + setStepType(first,pdata,stype); // compute the end position and step type // in future we should store the end position in the StepPointMC FIXME! XYZVec end = endPosition(last,straw,charge,stype); - time = first->time(); // use first time as time of this step (cluster times will be added) - mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum + float mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum // determine the width from the sigitta or curl radius auto pdir = first->momentum().unit(); auto pperp = pdir.perp(_bdir); @@ -335,9 +354,11 @@ namespace mu2e { static const float prms(1.0/(12.0*sqrt(5.0))); // RMS for a parabola. This includes a factor 1/8 for the sagitta calculation too float sagrms = prms*sint*pathlen*pathlen*_bnom*pperp/mom; double width = std::min(sagrms,bendrms); // choose the smaller: different approximations work for different momenta/directions - // create the gas step + // apply the time offsets + double stime = _toff.timeWithOffsetsApplied(*first); + // create the gas step sgs = StrawGasStep( first->strawId(), stype, - (float)eion,(float)pathlen, (float)width, (float)mom, time, + (float)eion,(float)pathlen, (float)width, (float)stime, start, end); } @@ -359,8 +380,8 @@ namespace mu2e { // create key SSPair stpair(sid,tid); // create ptr to this step - art::Ptr spmcptr(spmcch,ispmc); - vector> spmcptrv; + SPMCP spmcptr(spmcch,ispmc); + vector spmcptrv; spmcptrv.reserve(_ssize); spmcptrv.push_back(spmcptr); // check if this key exists and add it if not @@ -443,11 +464,11 @@ namespace mu2e { } } - XYZVec MakeStrawGasSteps::endPosition(art::Ptrconst& last, Straw const& straw, float charge) { + XYZVec MakeStrawGasSteps::endPosition(SPMCP const& last, Straw const& straw, float charge,StrawGasStep::StepType& stype) { static const double r2 = straw.innerRadius()*straw.innerRadius(); XYZVec retval; // null charge has no propagation. - if(charge == 0.0){ + if(charge == 0.0 || stype.shape()==StrawGasStep::StepType::point){ retval = last->position(); } else { auto momhat = last->momentum().unit(); @@ -480,17 +501,17 @@ namespace mu2e { } void MakeStrawGasSteps::fillStepDiag(Straw const& straw, StrawGasStep const& sgs, - art::Ptrconst& spmcptr) { + SPMCP const& spmcptr, SPMCPV const& spmcptrs) { _erad = sqrt((Geom::Hep3Vec(sgs.endPosition())-straw.getMidPoint()).perpPart(straw.getDirection()).mag2()); _hendrad->Fill(_erad); _hphi->Fill(_brot); if(_diag > 1){ - _prilen = pathlen; + _prilen = sgs.pathLength(); _pridist = sqrt((sgs.endPosition()-sgs.startPosition()).mag2()); - _partP = mom; + _partP = spmcptr->momentum().mag(); _partPDG = spmcptr->simParticle()->pdgId(); _elen = spmcptr->stepLength(); - _width = width; + _width = sgs.width(); // compute DOCA to the wire TwoLinePCA poca(Geom::Hep3Vec(sgs.startPosition()),Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()), straw.getMidPoint(),straw.getDirection()); @@ -505,7 +526,7 @@ namespace mu2e { } } - void MakeStrawGasSteps::setType(art::Ptrconst& spmcptr, StrawGasStep::StepType& stype) { + void MakeStrawGasSteps::setStepType(SPMCP const& spmcptr, ParticleData const* pdata, StrawGasStep::StepType& stype) { // now determine ioniztion and shape int itype, shape; if(pdata->charge() == 0.0){ @@ -519,15 +540,15 @@ namespace mu2e { shape = StrawGasStep::StepType::arc; else shape = StrawGasStep::StepType::line; - mass = pdata->mass(); + double mass = pdata->mass(); double bg = mom/mass; // beta x gamma if(bg > _minionBG) itype =StrawGasStep::StepType::minion; else itype =StrawGasStep::StepType::highion; } - stype = StrawGasStep::StepType( (StrawGasStep::StepType::shape)shape, - (StrawGasStep::StepType::ionization)itype ); + stype = StrawGasStep::StepType( (StrawGasStep::StepType::Shape)shape, + (StrawGasStep::StepType::Ionization)itype ); } } diff --git a/TrackerMC/src/StrawCluster.cc b/TrackerMC/src/StrawCluster.cc index 9245fb0bdd..6db3648810 100644 --- a/TrackerMC/src/StrawCluster.cc +++ b/TrackerMC/src/StrawCluster.cc @@ -11,28 +11,24 @@ using namespace std; namespace mu2e { namespace TrackerMC { StrawCluster::StrawCluster() : _type(unknown), _strawId(0), _end(StrawEnd::cal), _time(0.0), _charge(0.0), _ddist(0.0),_phi(0.0), _wdist(0.0), _drifttime(0.0), _proptime(0.0) - {}//JB: added phi + {} StrawCluster::StrawCluster(ClusterType type,StrawId sid, StrawEnd end, double time, - double charge, - double ddist, - double phi,//JB: added - double wdist, - double drifttime, - double proptime, - art::Ptr const& stepmc, - CLHEP::HepLorentzVector const& cpos) : _type(type), _strawId(sid), _end(end), _time(time), - _charge(charge), _ddist(ddist), _phi(phi),_wdist(wdist), _drifttime(drifttime), _proptime(proptime), _stepMC(stepmc), _cpos(cpos) - {}//JB: added phi - - StrawCluster::StrawCluster(const StrawCluster& other) : - _type(other._type), _strawId(other._strawId), _end(other._end), - _time(other._time), _charge(other._charge), _ddist(other._ddist), _phi(other._phi), _wdist(other._wdist), _drifttime(other._drifttime), _proptime(other._proptime), _stepMC(other._stepMC), _cpos(other._cpos) + float charge, + float ddist, + float phi, + float wdist, + float drifttime, + float proptime, + art::Ptr const& sgs, + art::Ptr const& stepmc, + CLHEP::HepLorentzVector const& cpos) : _type(type), _strawId(sid), _end(end), _time(time), + _charge(charge), _ddist(ddist), _phi(phi),_wdist(wdist), _drifttime(drifttime), _proptime(proptime), _sgsptr(sgs), _spmcptr(stepmc), _cpos(cpos) {} // delegating constructors in C++11! - StrawCluster::StrawCluster(const StrawCluster& primary, StrawId const& id, double xfactor) : + StrawCluster::StrawCluster(const StrawCluster& primary, StrawId const& id, float xfactor) : StrawCluster(primary) { _type = xtalk; _strawId = id; @@ -43,24 +39,6 @@ namespace mu2e { _time += deltat; } - StrawCluster& StrawCluster::operator=(StrawCluster const& other ) { - if(&other != this){ - _type = other._type; - _strawId = other._strawId; - _end = other._end; - _time = other._time; - _charge = other._charge; - _ddist = other._ddist; - _phi = other._phi; //JB: added phi - _wdist = other._wdist; - _drifttime = other._drifttime; - _proptime = other._proptime; - _stepMC = other._stepMC; - _cpos = other._cpos; - } - return *this; - } - void StrawCluster::print(std::ostream& ost, bool doEndl) const { ost << "StrawCluster of type " << _type << " for straw id " << _strawId @@ -69,9 +47,8 @@ namespace mu2e { << " charge " << _charge << " drift distance " << _ddist << " phi " << _phi - << " wire propagation distance " << _wdist - << " StepPointMC "; - _stepMC->print(ost,doEndl); //JB: added phi + << " wire propagation distance " << _wdist + << *_sgsptr << std::endl; } } } diff --git a/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc b/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc index 71b5e31876..82dbf7846d 100644 --- a/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc +++ b/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc @@ -40,6 +40,7 @@ #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" #include "MCDataProducts/inc/StrawDigiMCCollection.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" // MC structures #include "TrackerMC/inc/StrawClusterSequencePair.hh" #include "TrackerMC/inc/StrawWaveform.hh" @@ -551,6 +552,7 @@ namespace mu2e { art::Ptr const& spmcptr, Straw const& straw, StrawClusterSequencePair& shsp) { StepPointMC const& step = *spmcptr; + art::Ptr sgsptr;// kludge for backwards compatibility StrawId sid = straw.id(); // get time offset for this step double tstep = _toff.timeWithOffsetsApplied(step); @@ -594,7 +596,7 @@ namespace mu2e { double ctime = microbunchTime(strawele,gtime); // create the clust StrawCluster clust(StrawCluster::primary,sid,end,ctime,weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time, - spmcptr,CLHEP::HepLorentzVector(iclu->_pos,mbtime)); //JB: + wireq._phi + sgsptr,spmcptr,CLHEP::HepLorentzVector(iclu->_pos,mbtime)); //JB: + wireq._phi // add the clusts to the appropriate sequence. shsp.clustSequence(end).insert(clust); diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc index c4dfcbaa8b..b49b9d7427 100644 --- a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -96,34 +96,37 @@ namespace mu2e { fhicl::Atom minnxinghist{ Name("MinNXingHist"), Comment("Minimum # of crossings to histogram waveform"),1}; fhicl::Atom tstep { Name("WaveformStep"), Comment("WaveformStep (nsec)"),0.1 }; fhicl::Atom nfall{ Name("WaveformTail"), Comment("# of decay lambda past last signal to record waveform"),10.0}; - fhicl::Atom maxFullPrint{ Name("maxFullPrint", Comment("Limit on number of events for which there will be full printout") ,2)}; + fhicl::Atom maxFullPrint{ Name("maxFullPrint"), Comment("Limit on number of events for which there will be full printout") ,2}; fhicl::Atom addXtalk{ Name("addCrossTalk"), Comment("Should we add cross talk hits?"),false }; fhicl::Atom ctMinCharge{ Name("xtalkMinimumCharge"), Comment("minimum charge to add cross talk (for performance issues)") ,0}; - fhicl::Atom addNoise{ Name("addNoise",false), Comment("should we add noise hits? NOT CURRENTLY IMPLEMENTED FIXME!") }; - fhicl::Atom preampxtalk{ Name("preAmplificationCrossTalk",0.0), Comment("Pre-amplification (straw) X-talk coupling") }; - fhicl::Atom postampxtalk{ Name("postAmplificationCrossTalk",0.02), Comment("Post-amplification (board) X-talk coupling") }; + fhicl::Atom addNoise{ Name("addNoise"), Comment("should we add noise hits? NOT CURRENTLY IMPLEMENTED FIXME!"),false }; + fhicl::Atom preampxtalk{ Name("preAmplificationCrossTalk"), Comment("Pre-amplification (straw) X-talk coupling"), 0.0 }; + fhicl::Atom postampxtalk{ Name("postAmplificationCrossTalk"), Comment("Post-amplification (board) X-talk coupling") ,0.02}; fhicl::Atom bgcut{ Name("BetaGammaCut"), Comment("treat particles with beta-gamma above this as minimum-ionizing"),0.5 }; fhicl::Atom minstepE{ Name("minstepE"), Comment(" minimum step energy depostion to turn into a straw signal (MeV)"),2.0e-6 }; fhicl::Atom ewMarkerTag{ Name("EventWindowMarker"), Comment("EventWindowMarker producer"),"EWMProducer" }; + fhicl::Atom StrawGasStepCollectionTag{ Name("StrawGasStepCollection"), Comment("StrawGasStepCollection producer"),"SGSMaker" }; fhicl::Atom steptimebuf{ Name("StrawGasStepTimeBuffer"), Comment("buffer for MC step point times (nsec) ") ,100.0 }; + fhicl::Atom flashBuffer{ Name("FlashTimeBuffer"), Comment("buffer for flash blanking times (nsec) ") ,10.0 }; fhicl::Atom tdcbuf{ Name("TDCTimeBuffer"), Comment("buffer for TDC jitter (nsec) ") ,2.0 }; - fhicl::Atom allStraw{ Name("AllHitsStraw"), Comment("minimum straw # to read all hits") ,90}; - fhicl::Sequence allPlanes{ Name("AllHitsPlanes",std::vector{}), Comment("planes to read all hits") }; - fhicl::Sequence SPTO { Name("TimeOffsets"), Comment("Sim Particle Time Offset Maps")}; + fhicl::Atom allStraw{ Name("AllHitsStraw"), Comment("minimum straw # to read all hits") ,90}; + fhicl::Sequence allPlanes{ Name("AllHitsPlanes"), Comment("planes to read all hits"), std::vector{} }; fhicl::Atom diagpath{ Name("DiagPath"), Comment("Digitization Path for waveform diagnostics") ,0 }; fhicl::Atom sort{ Name("SortClusterEnergy"), Comment("Sort clusters by energy before digitizing") ,false }; - }; - + fhicl::Atom spinstance { Name("StrawGasStepInstance"), Comment("StrawGasStep Instance name"),""}; + }; + typedef art::Ptr SGSPtr; + typedef art::Ptr SPMCPtr; typedef map StrawClusterMap; // clusts by straw - typedef vector > StrawSPMCPV; // vector of associated StrawGasSteps for a single straw/particle // work with pairs of waveforms, one for each straw end typedef std::array SWFP; typedef std::array WFXP; typedef list WFXPList; typedef WFXPList::const_iterator WFXPI; - explicit StrawDigisFromStrawGasStepsfhicl::ParameterSet const& pset); + using Parameters = art::EDProducer::Table; + explicit StrawDigisFromStrawGasSteps(const Parameters& config); // Accept compiler written d'tor. private: @@ -132,7 +135,7 @@ namespace mu2e { void beginRun(art::Run& run) override; void produce(art::Event& e) override; - // Diagnostics level. + // Diagnostics int _debug, _diag, _printLevel; unsigned _maxhist; bool _xtalkhist; @@ -151,12 +154,12 @@ namespace mu2e { art::InputTag _ewMarkerTag; double _mbtime; double _mbbuffer; + double _flashbuffer; double _adcbuffer; double _steptimebuf; double _tdcbuf; uint16_t _allStraw; std::vector _allPlanes; - SimParticleTimeOffset _toff; StrawElectronics::Path _diagpath; unsigned _maxnclu; bool _sort; // sort cluster sizes before filling energy @@ -173,7 +176,7 @@ namespace mu2e { // Proditions ProditionsHandle _strawphys_h; ProditionsHandle _strawele_h; - + art::Selector _selector; // diagnostics TTree* _swdiag; Int_t _swplane, _swpanel, _swlayer, _swstraw, _ndigi; @@ -201,7 +204,7 @@ namespace mu2e { Int_t _tdc[2], _tot[2]; TTree* _sdiag; Float_t _steplen, _stepE, _qsum, _esum, _eesum, _qe, _partP, _steptime; - Int_t _nclust, _netot, _partPDG; + Int_t _nclust, _netot, _partPDG, _stype; vector _clusters; Float_t _ewMarkerOffset; array _ewMarkerROCdt; @@ -213,12 +216,14 @@ namespace mu2e { void addStep(StrawPhysics const& strawphys, StrawElectronics const& strawele, Straw const& straw, - StrawGasStep const& step, - art::Ptr const& spmcptr, + SGSPtr const& sgsptr, + SPMCPtr const& spmcptr, StrawClusterSequencePair& shsp); void divideStep(StrawPhysics const& strawphys, StrawElectronics const& strawele, - StrawGasStep const& step, vector& clusters); + Straw const& straw, + StrawGasStep const& step, + vector& clusters); void driftCluster(StrawPhysics const& strawphys, Straw const& straw, IonCluster const& cluster, WireCharge& wireq); void propagateCharge(StrawPhysics const& strawphys, Straw const& straw, @@ -231,17 +236,15 @@ namespace mu2e { StrawElectronics const& strawele, StrawClusterSequencePair const& hsp, XTalk const& xtalk, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStrawGasStepVectorCollection* mcptrs ); + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis); void fillDigis(StrawPhysics const& strawphys, StrawElectronics const& strawele, WFXPList const& xings,SWFP const& swfp , StrawId sid, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStrawGasStepVectorCollection* mcptrs ); + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis); bool createDigi(StrawElectronics const& strawele,WFXP const& xpair, SWFP const& wf, StrawId sid, StrawDigiCollection* digis); void findCrossTalkStraws(Straw const& straw,vector& xtalk); void fillClusterNe(StrawPhysics const& strawphys,std::vector& me); - void fillClusterPositions(Straw const& straw, StrawGasStep const& step, std::vector& cpos); + void fillClusterPositions(StrawGasStep const& step, std::vector& cpos); void fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& me, std::vector& cen); bool readAll(StrawId const& sid) const; // diagnostic functions @@ -250,40 +253,36 @@ namespace mu2e { void waveformDiag(StrawElectronics const& strawele, SWFP const& wf, WFXPList const& xings); void digiDiag(StrawPhysics const& strawphys, SWFP const& wf, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi); - - struct Config { - - - }; + void stepDiag(StrawPhysics const& strawphys, StrawElectronics const& strawele, + StrawGasStep const& sgs, StepPointMC const& spmc); }; - using Parameters = art::EDProducer::Table; - explicit StrawDigisFromStrawGasSteps::StrawDigisFromStrawGasSteps(const& Parameters pset) : - EDProducer(pset), - _debug(pset().debug()), - _diag(pset().diag()), - _print(pset().print()), - _maxhist(pset().maxhits()), - _xtalkhist(pset().xtalkhist()), - _minnxinghist(pset()("MinNXingHist",1)), - _tstep(pset().tstep()), - _nfall(pset().nfall()), - _maxFullPrint(pset().maxFullPrint()), - _addXtalk(pset().addXtalk()), - _ctMinCharge(pset().ctMinCharge()), - _addNoise(pset().addNoise()), - _preampxtalk(pset().preampxtalk()), - _postampxtalk(pset().postampxtalk()), - _bgcut(pset().bgcut()), - _minstepE(pset().minstepE()), - _ewMarkerTag(pset().(ewMarkerTag)), - _steptimebuf(pset().(steptimebuf)), - _tdcbuf(pset().tdcbuf()), - _allStraw(pset().allStraw()), - _allPlanes(pset().allPlanes()), - _toff(pset().SPTO()), - _diagpath(static_cast(pset().diagpath())), - _sort(pset().sort()), + StrawDigisFromStrawGasSteps::StrawDigisFromStrawGasSteps(const Parameters& config) : + EDProducer(config), + _debug(config().debug()), + _diag(config().diag()), + _printLevel(config().print()), + _maxhist(config().maxhist()), + _xtalkhist(config().xtalkhist()), + _minnxinghist(config().minnxinghist()), + _tstep(config().tstep()), + _nfall(config().nfall()), + _maxFullPrint(config().maxFullPrint()), + _addXtalk(config().addXtalk()), + _ctMinCharge(config().ctMinCharge()), + _addNoise(config().addNoise()), + _preampxtalk(config().preampxtalk()), + _postampxtalk(config().postampxtalk()), + _bgcut(config().bgcut()), + _minstepE(config().minstepE()), + _ewMarkerTag(config().ewMarkerTag()), + _flashbuffer(config().flashBuffer()), + _steptimebuf(config().steptimebuf()), + _tdcbuf(config().tdcbuf()), + _allStraw(config().allStraw()), + _allPlanes(config().allPlanes()), + _diagpath(static_cast(config().diagpath())), + _sort(config().sort()), // Random number distributions _engine(createEngine( art::ServiceHandle()->getSeed())), _randgauss( _engine ), @@ -292,16 +291,13 @@ namespace mu2e { _randP( _engine), _messageCategory("HITS"), _firstEvent(true), // Control some information messages. + // This selector will select only data products with the given instance name. + _selector{ art::ProductInstanceNameSelector(config().spinstance()) } { // Tell the framework what we consume. consumesMany(); consumesMany(); consumes(_ewMarkerTag); - // Since SimParticleTimeOffset calls getValidHandle, we have to declare the consumes statements here. - // auto const& toffInputs = pset.get>("TimeOffsets.inputs", {}); - // for (auto const& tag : toffInputs) { - // consumes(tag); - // } // Tell the framework what we make. produces(); produces(); @@ -324,6 +320,7 @@ namespace mu2e { _sdiag->Branch("nclust",&_nclust,"nclust/I"); _sdiag->Branch("netot",&_netot,"netot/I"); _sdiag->Branch("partPDG",&_partPDG,"partPDG/I"); + _sdiag->Branch("stepType",&_stype,"stepType/I"); _sdiag->Branch("clusters",&_clusters); _swdiag =tfs->make("swdiag","StrawWaveform diagnostics"); @@ -417,7 +414,6 @@ namespace mu2e { const Tracker& tracker = *GeomHandle(); _mbtime = accPar->deBuncherPeriod; - _toff.updateMap(event); art::Handle ewMarkerHandle; event.getByLabel(_ewMarkerTag, ewMarkerHandle); const EventWindowMarker& ewMarker(*ewMarkerHandle); @@ -432,7 +428,7 @@ namespace mu2e { // Containers to hold the output information. unique_ptr digis(new StrawDigiCollection); unique_ptr mcdigis(new StrawDigiMCCollection); - // create the StrawCluster map + // create the StrawCluster map and StepPointMC map StrawClusterMap hmap; // fill this from the event fillClusterMap(strawphys,strawele,tracker,event,hmap); @@ -443,7 +439,7 @@ namespace mu2e { StrawClusterSequencePair const& hsp = ihsp->second; // create primary digis from this clust sequence XTalk self(hsp.strawId()); // this object represents the straws coupling to itself, ie 100% - createDigis(strawphys,strawele,hsp,self,digis.get(),mcdigis.get(),mcptrs.get()); + createDigis(strawphys,strawele,hsp,self,digis.get(),mcdigis.get()); // if we're applying x-talk, look for nearby coupled straws if(_addXtalk) { // only apply if the charge is above a threshold @@ -456,7 +452,7 @@ namespace mu2e { Straw const& straw = tracker.getStraw(hsp.strawId()); findCrossTalkStraws(straw,xtalk); for(auto ixtalk=xtalk.begin();ixtalk!=xtalk.end();++ixtalk){ - createDigis(strawphys,strawele,hsp,*ixtalk,digis.get(),mcdigis.get(),mcptrs.get()); + createDigis(strawphys,strawele,hsp,*ixtalk,digis.get(),mcdigis.get()); } } } @@ -468,14 +464,15 @@ namespace mu2e { if ( _printLevel > 1 ) cout << "StrawDigisFromStrawGasSteps: produce() end" << endl; // Done with the first event; disable some messages. _firstEvent = false; + } // end produce void StrawDigisFromStrawGasSteps::createDigis( StrawPhysics const& strawphys, StrawElectronics const& strawele, - StrawClusterSequencePair const& hsp, XTalk const& xtalk, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStrawGasStepVectorCollection* mcptrs ) { + StrawClusterSequencePair const& hsp, + XTalk const& xtalk, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis) { // instantiate waveforms for both ends of this straw SWFP waveforms ={ StrawWaveform(hsp.clustSequence(StrawEnd::cal),xtalk), StrawWaveform(hsp.clustSequence(StrawEnd::hv),xtalk) }; @@ -484,29 +481,17 @@ namespace mu2e { // find the threshold crossings findThresholdCrossings(strawele,waveforms,xings); // convert the crossing points into digis, and add them to the event data - fillDigis(strawphys,strawele,xings,waveforms,xtalk._dest,digis,mcdigis,mcptrs); - // waveform diagnostics - if (_diag >1 && ( - waveforms[0].clusts().clustList().size() > 0 || - waveforms[1].clusts().clustList().size() > 0 ) ) { - // waveform xing diagnostics - _ndigi = digis->size(); - waveformDiag(strawele,waveforms,xings); - // waveform histograms - if(_diag > 2 )waveformHist(strawele,waveforms,xings); - } + fillDigis(strawphys,strawele,xings,waveforms,xtalk._dest,digis,mcdigis); } void StrawDigisFromStrawGasSteps::fillClusterMap(StrawPhysics const& strawphys, StrawElectronics const& strawele, - + const Tracker& tracker, art::Event const& event, StrawClusterMap & hmap){ // Get all of the tracker StrawGasStep collections from the event: typedef vector< art::Handle > HandleVector; - // This selector will select only data products with the given instance name. - art::ProductInstanceNameSelector selector(""); HandleVector stepsHandles; - event.getMany( selector, stepsHandles); + event.getMany( _selector, stepsHandles); // Informational message on the first event. if ( _firstEvent ) { mf::LogInfo log(_messageCategory); @@ -525,10 +510,10 @@ namespace mu2e { StrawGasStepCollection const& steps(*sgsch); // find the associated Assns for this sgsch art::Handle sgsah; - if(!event.getByLabel(sgsch->provenance().moduleLabel(),sgsch->provenance().productInstanceName(),sgsah)){ + if(!event.getByLabel(sgsch.provenance()->moduleLabel(),sgsch.provenance()->productInstanceName(),sgsah)){ throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StrawGasStepAssns found for module " - << sgsch->provenance().moduleLabel() << " instance " - << sgsch->provenance().productInstanceName() << endl; + << sgsch.provenance()->moduleLabel() << " instance " + << sgsch.provenance()->productInstanceName() << endl; } StrawGasStepAssns const& sgsa = *sgsah; // Loop over the StrawGasSteps in this collection @@ -539,159 +524,121 @@ namespace mu2e { Straw const& straw = tracker.getStraw(sid); if(sgs.ionizingEdep() > _minstepE){ // find assocated pPointMC for MC truth mapping - art::Ptr sgsptr(sgsch,isgs); + SGSPtr sgsptr(sgsch,isgs); auto const& isgsa = sgsa[isgs];// these should be lock-step, but check if(isgsa.first != sgsptr){ throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: StrawGasStepAssns doesn't match StrawGasStep!" << endl; } auto const& spmcptr = isgsa.second; - // create a clust from this step, and add it to the clust map - addStep(strawphys,strawele,straw,sgs,spmcptr,hmap[sid]); + // create a clust from this step, and add it to the clust map + addStep(strawphys,strawele,straw,sgsptr,spmcptr,hmap[sid]); } - } + } } } void StrawDigisFromStrawGasSteps::addStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - Straw const& straw, - StrawGasStep const& step, - art::Ptr const& stmcptr, - StrawClusterSequencePair& shsp) { - StrawId sid = step.strawId(); - // get time offset for this step - double tstep = _toff.timeWithOffsetsApplied(step); + StrawElectronics const& strawele, + Straw const& straw, + SGSPtr const& sgsptr, SPMCPtr const& spmcptr, + StrawClusterSequencePair& shsp) { + auto const& sgs = *sgsptr; + StrawId sid = sgs.strawId(); // test if this step point is roughly in the digitization window - double mbtime = microbunchTime(strawele,tstep); + double mbtime = microbunchTime(strawele,sgs.time()); if( (mbtime > strawele.flashEnd() - _steptimebuf - && mbtime < strawele.flashStart()) - || readAll(sid)) { - // Subdivide the StrawGasStep into ionization clusters - _clusters.clear(); - divideStep(strawphys,strawele,straw,step,_clusters); - // check - if(_debug > 1){ - double ec(0.0); - double ee(0.0); - double eq(0.0); - for (auto const& cluster : _clusters) { - ec += cluster._eion; - ee += strawphys.ionizationEnergy(cluster._ne); - eq += strawphys.ionizationEnergy(cluster._charge); - } - cout << "step with ionization edep = " << step.ionizingEdep() - << " creates " << _clusters.size() - << " clusters with total cluster energy = " << ec - << " electron count energy = " << ee - << " charge energy = " << eq << endl; - } - // drift these clusters to the wire, and record the charge at the wire - for(auto iclu = _clusters.begin(); iclu != _clusters.end(); ++iclu){ - WireCharge wireq; - driftCluster(strawphys,straw,*iclu,wireq); - // propagate this charge to each end of the wire - for(size_t iend=0;iend<2;++iend){ - StrawEnd end(static_cast(iend)); - // compute the longitudinal propagation effects - WireEndCharge weq; - propagateCharge(strawphys,straw,wireq,end,weq); - // compute the total time, modulo the microbunch - double gtime = tstep + wireq._time + weq._time; - // convert from + && mbtime < strawele.flashStart()) || readAll(sid)) { + // Subdivide the StrawGasStep into ionization clusters + _clusters.clear(); + divideStep(strawphys,strawele,straw,sgs,_clusters); + // check + // drift these clusters to the wire, and record the charge at the wire + for(auto iclu = _clusters.begin(); iclu != _clusters.end(); ++iclu){ + WireCharge wireq; + driftCluster(strawphys,straw,*iclu,wireq); + // propagate this charge to each end of the wire + for(size_t iend=0;iend<2;++iend){ + StrawEnd end(static_cast(iend)); + // compute the longitudinal propagation effects + WireEndCharge weq; + propagateCharge(strawphys,straw,wireq,end,weq); + // compute the total time incuding propagation delays, modulo the microbunch + double gtime = sgs.time() + wireq._time + weq._time; double ctime = microbunchTime(strawele,gtime); + CLHEP::HepLorentzVector cpos(iclu->_pos,mbtime); // create the clust - StrawCluster clust(StrawCluster::primary,sid,end,ctime,weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time, - stmcptr,CLHEP::HepLorentzVector(iclu->_pos,mbtime)); //JB: + wireq._phi - + StrawCluster clust(StrawCluster::primary,sid,end,ctime,weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time,sgsptr,spmcptr,cpos); // add the clusts to the appropriate sequence. shsp.clustSequence(end).insert(clust); // if required, add a 'ghost' copy of this clust addGhosts(strawele,clust,shsp.clustSequence(end)); } } + if(_diag > 0) stepDiag(strawphys, strawele, sgs, *spmcptr); } } void StrawDigisFromStrawGasSteps::divideStep(StrawPhysics const& strawphys, StrawElectronics const& strawele, Straw const& straw, - StrawGasStep const& step, vector& clusters) { - // single cluster - if (step.stepType().shape() == StrawGasStep::StepType::point || step.pathLength() < strawphys.meanFreePath()){ - double cen = step.ionizingEdep(); + StrawGasStep const& sgs, + vector& clusters) { + // single cluster + if (sgs.stepType().shape() == StrawGasStep::StepType::point || sgs.pathLength() < strawphys.meanFreePath()){ + double cen = sgs.ionizingEdep(); double fne = cen/strawphys.meanElectronEnergy(); unsigned ne = std::max( static_cast(_randP(fne)),(unsigned)1); - - Hep3Vector cdir = (step.startPosition()-straw.getMidPoint());//JB - cdir -= straw.getDirection()*(cdir.dot(straw.getDirection()));//JB - double phi = cdir.theta(); //JB - for (size_t i=0;i(_randP.fire(fnc)),(unsigned)1); // if not minion, limit the number of steps geometrically - bool minion = (step.stepType().ionization()==StrawGasStep::StepType::minion); + bool minion = (sgs.stepType().ionization()==StrawGasStep::StepType::minion); if(!minion )nc = std::min(nc,_maxnclu); // require clusters not exceed the energy sum required for single-electron clusters - nc = std::min(nc,static_cast(floor(step.ionizingEdep()/strawphys.ionizationEnergy((unsigned)1)))); + nc = std::min(nc,static_cast(floor(sgs.ionizingEdep()/strawphys.ionizationEnergy((unsigned)1)))); // generate random positions for the clusters - std::vector cpos(nc); - fillClusterPositions(straw,step,cpos); + std::vector cposv(nc); + fillClusterPositions(sgs,cposv); // generate electron counts and energies for these clusters: minion model is more detailed - std::vector ne(nc); - std::vector cen(nc); - if(minion){ - fillClusterMinion(strawphys,step,ne,cen); - } else { - // get Poisson distribution of # of electrons for the average energy - double fne = step.ionizingEdep()/(nc*strawphys.meanElectronEnergy()); // average # of electrons/cluster for non-minion clusters - for(unsigned ic=0;ic(std::max(_randP.fire(fne),(long)1)); - cen[ic] = ne[ic]*strawphys.meanElectronEnergy(); // average energy per electron, works for large numbers of electrons - } - } - // create the cluster objects - for(unsigned ic=0;ic 0){ - _steplen = step.pathLength(); - _stepE = step.ionizingEdep(); - _steptime = microbunchTime(strawele,_toff.timeWithOffsetsApplied(step)); - _partP = step.momentum().mag(); - _partPDG = step.simParticle()->pdgId(); - _nclust = (int)clusters.size(); - _netot = 0; - _qsum = _esum = _eesum = 0.0; - for(auto iclust=clusters.begin();iclust != clusters.end();++iclust){ - _netot += iclust->_ne; - _qsum += iclust->_charge; - _esum += iclust->_eion; - _eesum += strawphys.meanElectronEnergy()*iclust->_ne; - } - _qe = strawphys.ionizationEnergy(_qsum); - _sdiag->Fill(); + std::vector ne(nc); + std::vector cen(nc); + if(minion){ + fillClusterMinion(strawphys,sgs,ne,cen); + } else { + // get Poisson distribution of # of electrons for the average energy + double fne = sgs.ionizingEdep()/(nc*strawphys.meanElectronEnergy()); // average # of electrons/cluster for non-minion clusters + for(unsigned ic=0;ic(std::max(_randP.fire(fne),(long)1)); + cen[ic] = ne[ic]*strawphys.meanElectronEnergy(); // average energy per electron, works for large numbers of electrons + } + } + // create the cluster objects + for(unsigned ic=0;ic(0))+strawnoise,strawele.analogNoise(StrawElectronics::thresh)), _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(1))+strawnoise,strawele.analogNoise(StrawElectronics::thresh))}; // Initialize search when the electronics becomes enabled: - double tstart =strawele.flashEnd() - 10.0; // this buffer should be a parameter FIXME! + double tstart =strawele.flashEnd() - _flashbuffer; // for reading all hits, make sure we start looking for clusters at the minimum possible cluster time // this accounts for deadtime effects from previous microbunches if(readAll(swfp[0].strawId()))tstart = -strawele.deadTimeAnalog(); @@ -792,30 +739,26 @@ namespace mu2e { } void StrawDigisFromStrawGasSteps::fillDigis(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - WFXPList const& xings, SWFP const& wf, - StrawId sid, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStrawGasStepVectorCollection* mcptrs ){ + StrawElectronics const& strawele, + WFXPList const& xings, SWFP const& wf, + StrawId sid, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis ) { // loop over crossings for(auto xpair : xings) { // create a digi from this pair. This also performs a finial test // on whether the pair should make a digi if(createDigi(strawele,xpair,wf,sid,digis)){ // fill associated MC truth matching. Only count the same step once - set > xmcsp; double wetime[2] = {-100.,-100.}; CLHEP::HepLorentzVector cpos[2]; - art::Ptr stepMC[2]; - set > sgss; + art::Ptr sgs[2]; + art::Ptr stepMC[2]; for (size_t iend=0;iend<2;++iend){ StrawCluster const& sc = *(xpair[iend]._iclust); - xmcsp.insert(sc.stepPointMC()); wetime[iend] = sc.time(); cpos[iend] = sc.clusterPosition(); + sgs[iend] = sc.strawGasStep(); stepMC[iend] = sc.stepPointMC(); - // make sure the trigter StepPoints also go in the StrawDigiMC - sgss.insert(sc.stepPointMC()); } // choose the minimum time from either end, as the ADC sums both double ptime = 1.0e10; @@ -824,26 +767,19 @@ namespace mu2e { } // subtract a small buffer ptime -= _adcbuffer; - // pickup all StrawGasSteps associated with clusts inside the time window of the ADC digitizations (after the threshold) - for (auto ih=wf[0].clusts().clustList().begin();ih!=wf[0].clusts().clustList().end();++ih){ - if (ih->time() >= ptime && ih->time() < ptime + - ( strawele.nADCSamples()-strawele.nADCPreSamples())*strawele.adcPeriod()) - sgss.insert(ih->stepPointMC()); - } - vector > stepMCs; - stepMCs.reserve(sgss.size()); - for(auto isgs=sgss.begin(); isgs!= sgss.end(); ++isgs){ - stepMCs.push_back(*isgs); - } - PtrStrawGasStepVector mcptr; - for(auto ixmcsp=xmcsp.begin();ixmcsp!=xmcsp.end();++ixmcsp) - mcptr.push_back(*ixmcsp); - mcptrs->push_back(mcptr); - mcdigis->push_back(StrawDigiMC(sid,wetime,cpos,stepMC,stepMCs)); - // diagnostics - if(_diag > 1)digiDiag(strawphys,wf,xpair,digis->back(),mcdigis->back()); + mcdigis->push_back(StrawDigiMC(sid,wetime,cpos,sgs,stepMC)); + if(_diag > 1){ + digiDiag(strawphys,wf,xpair,digis->back(),mcdigis->back()); + } } } + // waveform diags + if ( _diag > 1 && (wf[0].clusts().clustList().size() > 0 || + wf[1].clusts().clustList().size() > 0 ) ) { + // waveform xing diagnostics + _ndigi = digis->size(); + waveformDiag(strawele,wf,xings); + } } bool StrawDigisFromStrawGasSteps::createDigi(StrawElectronics const& strawele, WFXP const& xpair, SWFP const& waveform, @@ -921,51 +857,71 @@ namespace mu2e { void StrawDigisFromStrawGasSteps::addNoise(StrawClusterMap& hmap){ // create random noise clusts and add them to the sequences of random straws. } - // diagnostic functions - void StrawDigisFromStrawGasSteps::waveformHist(StrawElectronics const& strawele, SWFP const& wfs, WFXPList const& xings) { - // histogram individual waveforms - static unsigned nhist(0);// maximum number of histograms per job! - for(size_t iend=0;iend<2;++iend){ - // step to the 1st cluster past the blanking time to avoid double-counting - ClusterList const& clist = wfs[iend].clusts().clustList(); - auto icl = clist.begin(); - while(icl->time() < strawele.flashEnd()) - icl++; - if(icl != clist.end() && nhist < _maxhist && xings.size() >= _minnxinghist && - ( ((!_xtalkhist) && wfs[iend].xtalk().self()) || (_xtalkhist && !wfs[iend].xtalk().self()) ) ) { - double tstart = icl->time()-_tstep; - double tfall = strawele.fallTime(_diagpath); - double tend = clist.rbegin()->time() + _nfall*tfall; - ADCTimes times; - ADCVoltages volts; - times.reserve(size_t(ceil(tend-tstart)/_tstep)); - volts.reserve(size_t(ceil(tend-tstart)/_tstep)); - double t = tstart; - while(t tfs; - char name[60]; - char title[100]; - snprintf(name,60,"SWF%i_%i",wfs[iend].clusts().strawId().asUint16(),nhist); - snprintf(title,100,"Electronic output for straw %i end %i path %i;time (nSec);Waveform (mVolts)",wfs[iend].clusts().strawId().asUint16(),(int)iend,_diagpath); - TH1F* wfh = tfs->make(name,title,volts.size(),times.front(),times.back()); - for(size_t ibin=0;ibinSetBinContent(ibin+1,volts[ibin]); - TList* flist = wfh->GetListOfFunctions(); - for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ - TMarker* smark = new TMarker(ixing->at(iend)._time,ixing->at(iend)._vcross,8); - smark->SetMarkerColor(kGreen); - smark->SetMarkerSize(2); - flist->Add(smark); + + void StrawDigisFromStrawGasSteps::fillClusterPositions(StrawGasStep const& sgs, std::vector& cposv) { + // generate a random position between the start and end points. Also smear perp to the path by the width + XYZVec path = sgs.endPosition() - sgs.startPosition(); + for(auto& cpos : cposv) { + // add width effects FIXME! + cpos = Geom::Hep3Vec(sgs.startPosition() + _randflat.fire(1.0)*path); + } + } + + void StrawDigisFromStrawGasSteps::fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& ne, std::vector& cen) { + // Loop until we've assigned energy + electrons to every cluster + unsigned mc(0); + double esum(0.0); + double etot = step.ionizingEdep(); + unsigned nc = ne.size(); + while(mc < nc){ + std::vector me(nc); + // fill an array of random# of electrons according to the measured distribution. These are returned sorted lowest-highest. + fillClusterNe(strawphys,me); + for(auto ie : me) { + // maximum energy for this cluster requires at least 1 electron for the rest of the cluster + double emax = etot - esum - (nc -mc -1)*strawphys.ionizationEnergy((unsigned)1); + double eele = strawphys.ionizationEnergy(ie); + if( eele < emax){ + ne[mc] = ie; + cen[mc] = eele; + ++mc; + esum += eele; + } else { + break; } } } + // distribute any residual energy randomly to these clusters. This models delta rays + unsigned ns; + do{ + unsigned me = strawphys.nePerIon(_randflat.fire()); + double emax = etot - esum; + double eele = strawphys.ionizationEnergy(me); + if(eele < emax){ + // choose a random cluster to assign this energy to + unsigned mc = std::min(nc-1,static_cast(floor(_randflat.fire(nc)))); + ne[mc] += me; + cen[mc] += eele; + esum += eele; + } + // maximum energy for this cluster requires at least 1 electron for the rest of the cluster + ns = static_cast(floor((etot-esum)/strawphys.ionizationEnergy((unsigned)1))); + } while(ns > 0); } + void StrawDigisFromStrawGasSteps::fillClusterNe(StrawPhysics const& strawphys,std::vector& me) { + for(size_t ie=0;ie < me.size(); ++ie){ + me[ie] = strawphys.nePerIon(_randflat.fire()); + } + if(_sort)std::sort(me.begin(),me.end()); + } + + bool StrawDigisFromStrawGasSteps::readAll(StrawId const& sid) const { + return sid.straw() >= _allStraw && + (std::find(_allPlanes.begin(),_allPlanes.end(),sid.plane()) != _allPlanes.end()); + } + +// diagnostic functions void StrawDigisFromStrawGasSteps::waveformDiag( StrawElectronics const& strawele, SWFP const& wfs, WFXPList const& xings) { @@ -978,7 +934,7 @@ namespace mu2e { for(size_t iend=0;iend<2; ++iend){ ClusterList const& clusts = wfs[iend].clusts().clustList(); size_t nclust = clusts.size(); - set > steps; + set > steps; set > parts; _nxing[iend] = 0; _txing[iend] = strawele.flashStart() + _mbbuffer; @@ -989,7 +945,7 @@ namespace mu2e { _xddist[iend] = ixing->at(iend)._iclust->driftDistance(); _xwdist[iend] = ixing->at(iend)._iclust->wireDistance(); // compute direction perpendicular to wire and momentum - art::Ptr const& spp = ixing->at(iend)._iclust->stepPointMC(); + auto const& spp = ixing->at(iend)._iclust->stepPointMC(); if(!spp.isNull()){ Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); // project the differences in position to get the perp distance @@ -1001,7 +957,7 @@ namespace mu2e { if(nclust > 0 ){ _xddist[iend] = clusts.front().driftDistance(); _xwdist[iend] = clusts.front().wireDistance(); - art::Ptr const& spp = clusts.front().stepPointMC(); + auto const& spp = clusts.front().stepPointMC(); if(!spp.isNull()){ Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); // project the differences in position to get the perp distance @@ -1033,7 +989,7 @@ namespace mu2e { _wmcpdg[iend] = iclu->stepPointMC()->simParticle()->pdgId(); _wmcproc[iend] = iclu->stepPointMC()->simParticle()->creationCode(); _mce[iend] = iclu->stepPointMC()->simParticle()->startMomentum().e(); - _slen[iend] = iclu->stepPointMC()->pathLength(); + _slen[iend] = iclu->stepPointMC()->stepLength(); _sedep[iend] = iclu->stepPointMC()->ionizingEdep(); } } @@ -1045,6 +1001,52 @@ namespace mu2e { _sesum [iend]+= (*istep)->ionizingEdep(); } _swdiag->Fill(); + // waveform histograms + if(_diag > 2 )waveformHist(strawele,wfs,xings); + } + + void StrawDigisFromStrawGasSteps::waveformHist(StrawElectronics const& strawele, SWFP const& wfs, WFXPList const& xings) { + // histogram individual waveforms + static unsigned nhist(0);// maximum number of histograms per job! + for(size_t iend=0;iend<2;++iend){ + // step to the 1st cluster past the blanking time to avoid double-counting + ClusterList const& clist = wfs[iend].clusts().clustList(); + auto icl = clist.begin(); + while(icl->time() < strawele.flashEnd()) + icl++; + if(icl != clist.end() && nhist < _maxhist && xings.size() >= _minnxinghist && + ( ((!_xtalkhist) && wfs[iend].xtalk().self()) || (_xtalkhist && !wfs[iend].xtalk().self()) ) ) { + double tstart = icl->time()-_tstep; + double tfall = strawele.fallTime(_diagpath); + double tend = clist.rbegin()->time() + _nfall*tfall; + ADCTimes times; + ADCVoltages volts; + times.reserve(size_t(ceil(tend-tstart)/_tstep)); + volts.reserve(size_t(ceil(tend-tstart)/_tstep)); + double t = tstart; + while(t tfs; + char name[60]; + char title[100]; + snprintf(name,60,"SWF%i_%i",wfs[iend].clusts().strawId().asUint16(),nhist); + snprintf(title,100,"Electronic output for straw %i end %i path %i;time (nSec);Waveform (mVolts)",wfs[iend].clusts().strawId().asUint16(),(int)iend,_diagpath); + TH1F* wfh = tfs->make(name,title,volts.size(),times.front(),times.back()); + for(size_t ibin=0;ibinSetBinContent(ibin+1,volts[ibin]); + TList* flist = wfh->GetListOfFunctions(); + for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ + TMarker* smark = new TMarker(ixing->at(iend)._time,ixing->at(iend)._vcross,8); + smark->SetMarkerColor(kGreen); + smark->SetMarkerSize(2); + flist->Add(smark); + } + } + } } void StrawDigisFromStrawGasSteps::digiDiag(StrawPhysics const& strawphys, SWFP const& wfs, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi) { @@ -1103,12 +1105,15 @@ namespace mu2e { _dmcmom = -1.0; _mctime = _mcenergy = _mctrigenergy = _mcthreshenergy = _mcdca = -1000.0; _mcthreshpdg = _mcthreshproc = _mcnstep = 0; - art::Ptr const& sgs = xpair[0]._iclust->stepPointMC(); - if(!sgs.isNull()){ - _mctime = _toff.timeWithOffsetsApplied(*sgs); + auto const& sgsptr = xpair[0]._iclust->strawGasStep(); + auto const& spmcptr = xpair[0]._iclust->stepPointMC(); + if(!sgsptr.isNull() && !spmcptr.isNull()){ + auto const& sgs = *sgsptr; + auto const& spmc = *spmcptr; + _mctime = sgs.time(); // compute the doca for this step TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), - sgs->position(), sgs->momentum().unit() ); + Geom::Hep3Vec(sgs.startPosition()), Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()) ); _mcdca = pca.dca(); Hep3Vector mccdir = (pca.point2()-straw.getMidPoint()); @@ -1116,170 +1121,49 @@ namespace mu2e { _mcdcaphi = mccdir.theta(); _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); //JB: this is now from the lorentz corrected r-component of the drift - if(!sgs->simParticle().isNull()){ - _dmcpdg = sgs->simParticle()->pdgId(); - _dmcproc = sgs->simParticle()->creationCode(); - if(sgs->simParticle()->genParticle().isNonnull()) - _dmcgen = sgs->simParticle()->genParticle()->generatorId().id(); - _dmcmom = sgs->momentum().mag(); - } + if(!spmc.simParticle().isNull()){ + auto const& sp = *spmc.simParticle(); + _dmcpdg = sp.pdgId(); + _dmcproc = sp.creationCode(); + if(sp.genParticle().isNonnull()) + _dmcgen = sp.genParticle()->generatorId().id(); + _dmcmom = spmc.momentum().mag(); + _mcthreshpdg = spmc.simParticle()->pdgId(); + _mcthreshproc = spmc.simParticle()->creationCode(); + } } _mcenergy = mcdigi.energySum(); _mctrigenergy = mcdigi.triggerEnergySum(StrawEnd::cal); // sum the energy from the explicit trigger particle, and find it's releationship - _mcthreshenergy = 0.0; - _mcnstep = mcdigi.stepPointMCs().size(); - art::Ptr threshpart = mcdigi.stepPointMC(StrawEnd::cal); - if(threshpart.isNull()) threshpart = mcdigi.stepPointMC(StrawEnd::hv); - for(auto imcs = mcdigi.stepPointMCs().begin(); imcs!= mcdigi.stepPointMCs().end(); ++ imcs){ - // if the SimParticle for this step is the same as the one which fired the discrim, add the energy - if( (*imcs)->simParticle() == threshpart->simParticle() ) - _mcthreshenergy += (*imcs)->eDep(); - } - _mcthreshpdg = threshpart->simParticle()->pdgId(); - _mcthreshproc = threshpart->simParticle()->creationCode(); - - _xtalk = digi.strawId() != sgs->strawId(); + _mcthreshenergy = 0.0; // FIXME! + _mcnstep = 2;// FIXME! + _xtalk = digi.strawId() != mcdigi.strawId(); // fill the tree entry _sddiag->Fill(); - }//End of digiDiag - void StrawDigisFromStrawGasSteps::fillClusterPositions(Straw const& straw, StrawGasStep const& step, std::vector& cpos) { - // basic info - double charge(0.0); - GlobalConstantsHandle pdt; - if(pdt->particle(step.simParticle()->pdgId()).isValid()){ - charge = pdt->particle(step.simParticle()->pdgId()).ref().charge(); - } - static const double r2 = straw.innerRadius()*straw.innerRadius(); - // decide how we step; straight or helix, depending on the Pt - Hep3Vector const& mom = step.momentum(); - Hep3Vector mdir = mom.unit(); - // approximate pt - double apt = step.momentum().perpPart(_bdir).mag(); - if( apt > _ptmin) { // use linear approximation - double slen = step.pathLength(); - // make sure this linear approximation doesn't extend past the physical straw - Hep3Vector dperp = (step.position() -straw.getMidPoint()).perpPart(straw.getDirection()); - Hep3Vector mperp = mdir.perpPart(straw.getDirection()); - double dm = dperp.dot(mperp); - double m2 = mperp.mag2(); - double dp2 = dperp.mag2(); - double sarg = dm*dm + m2*(r2 - dp2); - // some glancing cases fail the linear math - if(sarg > 0.0 && m2 > 0.0){ - double smax = (-dm + sqrt(sarg))/m2; - slen = std::min(smax,slen); - } - // generate random cluster positions - for(unsigned ic=0;ic < cpos.size();++ic){ - // - cpos[ic] = step.position() +_randflat.fire(slen) *mdir; - } - } else { - // Use a helix to model particles which curl on the scale of the straws - GeomHandle bfmgr; - GeomHandle det; - // find the local field vector at this step - Hep3Vector vpoint_mu2e = det->toMu2e(step.position()); - Hep3Vector bf = bfmgr->getBField(vpoint_mu2e); - // compute transverse radius of particle - double rcurl = fabs(charge*(mom.perpPart(bf).mag())/BField::mmTeslaToMeVc*bf.mag()); - // basis using local Bfield direction - Hep3Vector bfdir = bf.unit(); - Hep3Vector qmdir = (charge*mom).unit(); // charge-signed momentum direction - Hep3Vector rdir = qmdir.cross(bfdir).unit(); // points along magnetic force, ie towards center - Hep3Vector pdir = bfdir.cross(rdir).unit(); // perp to this and field - // find the center of the helix at the start of this step - Hep3Vector hcent = step.position() + rcurl*rdir; - // find helix parameters. By definition, z0 = phi0 = 0 - double omega = qmdir.dot(pdir)/(rcurl*qmdir.dot(bfdir)); - // compute how far this step goes along the field direction. This includes sign information - double zlen = step.pathLength()*mdir.dot(bfdir); - // loop until we've found enough valid samples, or have given up trying - unsigned iclu(0); - unsigned ntries(0); - unsigned nclus = cpos.size(); - while(iclu < nclus && ntries < 10*nclus){ - double zclu = _randflat.fire(zlen); - double phi = zclu*omega; - // build cluster position from these - Hep3Vector cp = hcent + rcurl*(-rdir*cos(phi) + pdir*sin(phi)) + zclu*bfdir; - // test - double rd2 = (cp-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); - if(rd2 - r2 < 1.0e-3){ - cpos[iclu] = cp; - ++iclu; - } else if (_debug > 0) { - cout << "cluster outside straw: helix " << sqrt(rd2) << endl; - } - ++ntries; - } - if(iclu != nclus){ - // failed to find valid steps. put any remining energy at the step - if(_debug > 0)cout << "mu2e::StrawDigisFromStrawGasSteps: Couldn't create enough clusters : "<< iclu << " wanted " << nclus << endl; - while(iclu < nclus){ - cpos[iclu] = step.position(); - ++iclu; - } - } - } - } - - void StrawDigisFromStrawGasSteps::fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& ne, std::vector& cen) { - // Loop until we've assigned energy + electrons to every cluster - unsigned mc(0); - double esum(0.0); - double etot = step.ionizingEdep(); - unsigned nc = ne.size(); - while(mc < nc){ - std::vector me(nc); - // fill an array of random# of electrons according to the measured distribution. These are returned sorted lowest-highest. - fillClusterNe(strawphys,me); - for(auto ie : me) { - // maximum energy for this cluster requires at least 1 electron for the rest of the cluster - double emax = etot - esum - (nc -mc -1)*strawphys.ionizationEnergy((unsigned)1); - double eele = strawphys.ionizationEnergy(ie); - if( eele < emax){ - ne[mc] = ie; - cen[mc] = eele; - ++mc; - esum += eele; - } else { - break; - } - } - } - // distribute any residual energy randomly to these clusters. This models delta rays - unsigned ns; - do{ - unsigned me = strawphys.nePerIon(_randflat.fire()); - double emax = etot - esum; - double eele = strawphys.ionizationEnergy(me); - if(eele < emax){ - // choose a random cluster to assign this energy to - unsigned mc = std::min(nc-1,static_cast(floor(_randflat.fire(nc)))); - ne[mc] += me; - cen[mc] += eele; - esum += eele; - } - // maximum energy for this cluster requires at least 1 electron for the rest of the cluster - ns = static_cast(floor((etot-esum)/strawphys.ionizationEnergy((unsigned)1))); - } while(ns > 0); - } + }//End of digiDiag - void StrawDigisFromStrawGasSteps::fillClusterNe(StrawPhysics const& strawphys,std::vector& me) { - for(size_t ie=0;ie < me.size(); ++ie){ - me[ie] = strawphys.nePerIon(_randflat.fire()); + void StrawDigisFromStrawGasSteps::stepDiag( StrawPhysics const& strawphys, StrawElectronics const& strawele, + StrawGasStep const& sgs, StepPointMC const& spmc) { + _steplen = sgs.pathLength(); + _stepE = sgs.ionizingEdep(); + _steptime = microbunchTime(strawele,sgs.time()); + _stype = sgs.stepType()._stype; + _partP = spmc.momentum().mag(); + _partPDG = spmc.simParticle()->pdgId(); + _nclust = (int)_clusters.size(); + _netot = 0; + _qsum = _esum = _eesum = 0.0; + for(auto const& clust : _clusters) { + _netot += clust._ne; + _qsum += clust._charge; + _esum += clust._eion; + _eesum += strawphys.meanElectronEnergy()*clust._ne; } - if(_sort)std::sort(me.begin(),me.end()); + _qe = strawphys.ionizationEnergy(_qsum); + _sdiag->Fill(); } - bool StrawDigisFromStrawGasSteps::readAll(StrawId const& sid) const { - - return sid.straw() >= _allStraw && - (std::find(_allPlanes.begin(),_allPlanes.end(),sid.plane()) != _allPlanes.end()); - } } // end namespace trackermc } // end namespace mu2e diff --git a/TrkDiag/src/StrawHitDiag_module.cc b/TrkDiag/src/StrawHitDiag_module.cc index d6f694d2e7..df9e10d63d 100644 --- a/TrkDiag/src/StrawHitDiag_module.cc +++ b/TrkDiag/src/StrawHitDiag_module.cc @@ -310,7 +310,7 @@ namespace mu2e _pdist = dprod.mag(); _pperp = dprod.perp(zdir); _pmom = spmcp->momentum().mag(); - _mcnsteps = mcdigi.stepPointMCs().size(); + _mcnsteps = 2; // FIXME! // compute energy sum _mcedep = mcdigi.energySum(); _mcetrig = mcdigi.triggerEnergySum(StrawEnd::cal); diff --git a/TrkDiag/src/TrkMCTools.cc b/TrkDiag/src/TrkMCTools.cc index 7ca44cc931..09315cc1e0 100644 --- a/TrkDiag/src/TrkMCTools.cc +++ b/TrkDiag/src/TrkMCTools.cc @@ -127,20 +127,21 @@ namespace mu2e { if(!found)sct.push_back(spcount(spp,isactive)); } if(saveall){ - // add the SimParticles that contributed non-trigger energy. These have 0 count - for(const auto& tshs : kseed.hits()) { - StrawDigiMC const& mcdigi = mcdigis.at(tshs.index()); - for(auto const& spmc : mcdigi.stepPointMCs()){ - bool found(false); - for(auto& spc : sct ) { - if(spc._spp == spmc->simParticle() ){ - found = true; - break; - } - } - if(!found)sct.push_back(spcount(spmc->simParticle())); - } - } + // FIXME! +// // add the SimParticles that contributed non-trigger energy. These have 0 count +// for(const auto& tshs : kseed.hits()) { +// StrawDigiMC const& mcdigi = mcdigis.at(tshs.index()); +// for(auto const& spmc : mcdigi.stepPointMCs()){ +// bool found(false); +// for(auto& spc : sct ) { +// if(spc._spp == spmc->simParticle() ){ +// found = true; +// break; +// } +// } +// if(!found)sct.push_back(spcount(spmc->simParticle())); +// } +// } } // sort by # of contributions sort(sct.begin(),sct.end(),spcountcomp()); diff --git a/Validation/src/ValStrawDigiMC.cc b/Validation/src/ValStrawDigiMC.cc index 5fc7bb9b45..1214a50c7d 100644 --- a/Validation/src/ValStrawDigiMC.cc +++ b/Validation/src/ValStrawDigiMC.cc @@ -33,9 +33,6 @@ int mu2e::ValStrawDigiMC::fill(const mu2e::StrawDigiMCCollection & coll, // check the Ptr's. If the products are not there, the accessors can crash bool ptrOK = true; - for(auto const& ap: sd.stepPointMCs()) { - if(!ap.isAvailable()) ptrOK = false; - } auto const& a0 = sd.stepPointMC(StrawEnd::cal); auto const& a1 = sd.stepPointMC(StrawEnd::hv); From 9b1100fa52b818f02b9335c4ebc56056dd1df7e2 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Sun, 10 Nov 2019 10:28:19 -0600 Subject: [PATCH 11/18] Refactor StrawDigiMC to use StrawGasStep, with downstream updates --- Analyses/src/BkgRates_module.cc | 771 ----------- Analyses/src/CosmicTuple_module.cc | 399 ------ Analyses/src/HitDisplay_module.cc | 879 ------------ Analyses/src/NeutronCRV_module.cc | 1 - Analyses/src/PointerCheck_module.cc | 6 +- Analyses/src/ReadStrawHit_module.cc | 399 ------ .../src/SimParticlesWithHitsExample_module.cc | 123 -- Analyses/src/StrawEnergy_module.cc | 186 --- Analyses/src/Summary01_module.cc | 385 ------ Analyses/src/TSig_module.cc | 642 --------- CalPatRec/inc/ObjectDumpUtils.hh | 1 - CalPatRec/src/CalHelixFinderDiag_tool.cc | 2 - CalPatRec/src/DeltaFinderAna_module.cc | 5 +- CalPatRec/src/ObjectDumpUtils.cc | 16 +- CalPatRec/src/PrefetchData_module.cc | 2 - CommonMC/src/SelectRecoMC_module.cc | 8 +- CosmicReco/src/CosmicAnalyzer_module.cc | 6 +- CosmicReco/src/CosmicMuonInfo_module.cc | 9 +- CosmicReco/src/CosmicTrackFinder_module.cc | 11 +- Filters/src/CalibCosmicFilter_module.cc | 423 ------ Filters/src/CompressDigiMCs_module.cc | 48 +- .../src/HitsInConversionTimeWindow_module.cc | 670 --------- Filters/src/StepPointsInDigis_module.cc | 21 +- Filters/src/StrawDigiMCFilter_module.cc | 12 +- MCDataProducts/inc/StrawDigiMC.hh | 53 +- MCDataProducts/inc/StrawGasStep.hh | 28 +- MCDataProducts/inc/StrawHitMCTruth.hh | 65 - .../inc/StrawHitMCTruthCollection.hh | 18 - MCDataProducts/src/StrawDigiMC.cc | 80 +- MCDataProducts/src/StrawHitMCTruth.cc | 35 - MCDataProducts/src/classes.h | 1 - MCDataProducts/src/classes_def.xml | 4 - Mu2eUtilities/inc/SimParticleInfo.hh | 85 -- Mu2eUtilities/inc/SimParticleTimeOffset.hh | 2 + Mu2eUtilities/inc/SimParticlesWithHits.hh | 97 -- Mu2eUtilities/inc/StrawHitMCInfo.hh | 113 -- Mu2eUtilities/inc/particleEnteringG4Volume.hh | 2 + Mu2eUtilities/src/SimParticleInfo.cc | 104 -- Mu2eUtilities/src/SimParticleTimeOffsets.cc | 5 + Mu2eUtilities/src/SimParticlesWithHits.cc | 180 --- Mu2eUtilities/src/StrawHitMCInfo.cc | 43 - Mu2eUtilities/src/particleEnteringG4Volume.cc | 4 + Print/src/SConscript | 1 + Print/src/StrawDigiMCPrinter.cc | 18 +- Sandbox/src/PtrBug01_module.cc | 309 ----- TrackCaloMatching/src/SConscript | 4 +- TrackCaloMatching/src/TrkExtrapol_module.cc | 2 - TrackerMC/inc/IonCluster.hh | 10 +- TrackerMC/inc/StrawCluster.hh | 43 +- TrackerMC/src/MakeStrawGasSteps_module.cc | 39 +- TrackerMC/src/StrawCluster.cc | 17 +- .../src/StrawDigisFromStepPointMCs_module.cc | 24 +- .../src/StrawDigisFromStrawGasSteps_module.cc | 1209 +++++++++-------- Trigger/src/ReadTriggerInfo_module.cc | 53 +- TrkDiag/inc/TrkMCTools.hh | 2 - TrkDiag/src/BkgDiag_module.cc | 21 +- TrkDiag/src/ComboHitDiag_module.cc | 2 +- TrkDiag/src/HelixDiag_module.cc | 40 +- TrkDiag/src/KalDiag.cc | 14 +- TrkDiag/src/StrawHitDiag_module.cc | 6 +- TrkDiag/src/TimeClusterDiag_module.cc | 43 +- TrkDiag/src/TrkMCTools.cc | 90 +- TrkDiag/src/TrkRecoDiag_module.cc | 20 +- TrkReco/src/TrkRecoMcUtils_tool.cc | 43 +- Validation/inc/ValStrawDigiMC.hh | 2 - Validation/src/ValStrawDigiMC.cc | 6 - 66 files changed, 941 insertions(+), 7021 deletions(-) delete mode 100644 Analyses/src/BkgRates_module.cc delete mode 100644 Analyses/src/CosmicTuple_module.cc delete mode 100644 Analyses/src/HitDisplay_module.cc delete mode 100644 Analyses/src/ReadStrawHit_module.cc delete mode 100644 Analyses/src/SimParticlesWithHitsExample_module.cc delete mode 100644 Analyses/src/StrawEnergy_module.cc delete mode 100644 Analyses/src/Summary01_module.cc delete mode 100644 Analyses/src/TSig_module.cc delete mode 100644 Filters/src/CalibCosmicFilter_module.cc delete mode 100644 Filters/src/HitsInConversionTimeWindow_module.cc delete mode 100644 MCDataProducts/inc/StrawHitMCTruth.hh delete mode 100644 MCDataProducts/inc/StrawHitMCTruthCollection.hh delete mode 100644 MCDataProducts/src/StrawHitMCTruth.cc delete mode 100644 Mu2eUtilities/inc/SimParticleInfo.hh delete mode 100644 Mu2eUtilities/inc/SimParticlesWithHits.hh delete mode 100644 Mu2eUtilities/inc/StrawHitMCInfo.hh delete mode 100644 Mu2eUtilities/src/SimParticleInfo.cc delete mode 100644 Mu2eUtilities/src/SimParticlesWithHits.cc delete mode 100644 Mu2eUtilities/src/StrawHitMCInfo.cc delete mode 100644 Sandbox/src/PtrBug01_module.cc diff --git a/Analyses/src/BkgRates_module.cc b/Analyses/src/BkgRates_module.cc deleted file mode 100644 index a534fcf57e..0000000000 --- a/Analyses/src/BkgRates_module.cc +++ /dev/null @@ -1,771 +0,0 @@ -// -// A module to study background rates in the detector subsystems. -// -// $Id: BkgRates_module.cc,v 1.42 2014/09/03 15:47:05 knoepfel Exp $ -// $Author: knoepfel $ -// $Date: 2014/09/03 15:47:05 $ -// -// Original author Gianni Onorato -// - -#include "CLHEP/Units/PhysicalConstants.h" -#include "CalorimeterGeom/inc/Calorimeter.hh" -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "GeometryService/inc/GeomHandle.hh" -#include "GeometryService/inc/GeometryService.hh" -#include "MCDataProducts/inc/CaloHitMCTruthCollection.hh" -#include "MCDataProducts/inc/GenParticleCollection.hh" -#include "MCDataProducts/inc/PhysicalVolumeInfoCollection.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" -#include "RecoDataProducts/inc/CaloCrystalHitCollection.hh" -#include "RecoDataProducts/inc/CaloHitCollection.hh" -#include "RecoDataProducts/inc/StrawHitCollection.hh" -#include "TFile.h" -#include "TNtuple.h" -#include "TrackerGeom/inc/Straw.hh" -#include "TrackerGeom/inc/Tracker.hh" -#include "art/Framework/Core/EDAnalyzer.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art_root_io/TFileDirectory.h" -#include "art_root_io/TFileService.h" -#include "art/Framework/Services/Registry/ServiceHandle.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Provenance.h" -#include "GeneralUtilities/inc/LinePointPCA.hh" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" -#include "MCDataProducts/inc/StatusG4.hh" -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace mu2e { - - - class BkgRates : public art::EDAnalyzer { - public: - - typedef vector Vint; - - explicit BkgRates(fhicl::ParameterSet const& pset): - art::EDAnalyzer(pset), - _diagLevel(pset.get("diagLevel",0)), - _trackerStepPoints(pset.get("trackerStepPoints","tracker")), - _makerModuleLabel(pset.get("makerModuleLabel")), - _generatorModuleLabel(pset.get("generatorModuleLabel", "generate")), - _g4ModuleLabel(pset.get("g4ModuleLabel", "g4run")), - _caloReadoutModuleLabel(pset.get("caloReadoutModuleLabel", "CaloReadoutHitsMaker")), - _caloCrystalModuleLabel(pset.get("caloCrystalModuleLabel", "CaloCrystalHitsMaker")), - _minimumEnergyTracker(pset.get("minimumEnergyTracker",0.0001)), // MeV - _minimumEnergyCalo(pset.get("minimumEnergyCalo",0.0001)), // MeV - _doStoppingTarget(pset.get("doStoppingTarget", 0)), - _nAnalyzed(0), - _tNtup(0), - _cNtup(0), - _tgtNtup(0), - _nBadG4Status(0), - _nOverflow(0), - _nKilled(0), - _totalcputime(0), - _totalrealtime(0) - { - Vint const & _particleToSkipInST = pset.get("pdgIdToSkipInST", Vint()); - if (_particleToSkipInST.size() > 0) { - for (size_t i = 0; i< _particleToSkipInST.size(); ++i){ - skipPDG.insert(_particleToSkipInST[i]); - } - } - cout << "Module BkgRates is starting" << endl; - } - virtual ~BkgRates() { - } - virtual void beginJob(); - virtual void endJob(); - - void analyze(art::Event const& e ); - - private: - - void doTracker(art::Event const& evt, bool skip); - - void doCalorimeter(art::Event const& evt, bool skip); - void doStoppingTarget(art::Event const& evt); - - // Diagnostic level - int _diagLevel; - - // Name of the tracker StepPoint collection - std::string _trackerStepPoints; - - // Label of the module that made the hits. - std::string _makerModuleLabel; - - // Label of the generator. - std::string _generatorModuleLabel; - - // Label of the G4 module - std::string _g4ModuleLabel; - - // Label of the calo readout hits maker - std::string _caloReadoutModuleLabel; - - // Label of the calo crystal hists maker - std::string _caloCrystalModuleLabel; - - double _minimumEnergyTracker, _minimumEnergyCalo; //minimum energy deposition of hits - - bool _doStoppingTarget; - - //number of analyzed events - int _nAnalyzed; - - TNtuple* _tNtup; - TNtuple* _cNtup; - TNtuple* _tgtNtup; - - bool _skipEvent; - - int _nBadG4Status, _nOverflow, _nKilled; - float _totalcputime, _totalrealtime; - - set skipPDG; - - }; - - void BkgRates::beginJob( ) { - } - - void BkgRates::analyze(art::Event const& evt ) { - - ++_nAnalyzed; - - //*****test code****** - static int ncalls(0); - ++ncalls; - - art::Handle g4StatusHandle; - evt.getByLabel( _g4ModuleLabel, g4StatusHandle); - StatusG4 const& g4Status = *g4StatusHandle; - - if ( g4Status.status() > 1 ) { - ++_nBadG4Status; - mf::LogError("G4") - << "Aborting BkgRates::analyze due to G4 status\n" - << g4Status; - return; - } - - if (g4Status.overflowSimParticles()) { - ++_nOverflow; - mf::LogError("G4") - << "Aborting BkgRates::analyze due to overflow of particles\n" - << g4Status; - return; - } - - if (g4Status.nKilledStepLimit() > 0) { - ++_nKilled; - mf::LogError("G4") - << "Aborting BkgRates::analyze due to nkilledStepLimit reached\n" - << g4Status; - return; - } - - _totalcputime += g4Status.cpuTime(); - _totalrealtime += g4Status.realTime(); - - art::ServiceHandle geom; - - if (ncalls == 1) { - - // cout << "This should be done only in the first event" << endl; - - - art::ServiceHandle tfs; - - if (geom->hasElement()) { - _tNtup = tfs->make( "StrawHits", "Straw Ntuple", - "evt:run:time:dt:eDep:lay:dev:sec:strawId:MChitX:MChitY:v:vMC:z:trkId:pdgId:isGen:P:CreationCode:StartVolume:StartX:StartY:StartZ:StartT:StoppingCode:EndVolume:EndX:EndY:EndZ:EndT:StepFromEva:EvaIsGen:EvaCreationCode:genId:genP:genE:genX:genY:genZ:genCosTh:genPhi:genTime:driftTime:driftDist" ); - } - - _cNtup = tfs->make( "CaloHits", "Calo Ntuple", - "evt:run:time:eDep:rad:crId:crVane:crX:crY:crZ:trkId:pdgId:isGen:P:CreationCode:StartVolume:StartX:StartY:StartZ:StartT:StoppingCode:EndVolume:EndX:EndY:EndZ:EndT:cryFrameEnterX:cryFrameEnterY:cryFrameEnterZ:StepFromEva:EvaIsGen:EvaCreationCode:genId:genP:genE:genX:genY:genZ:genCosTh:genPhi:genTime" ); - - if (_doStoppingTarget) { - _tgtNtup = tfs->make( "ST", "Particle dead in ST ntuple", - "evt:run:time:x:y:z:isGen:pdgId:trkId:stVol:isStopped"); - } - } - - - if (_doStoppingTarget) doStoppingTarget(evt); - - if (geom->hasElement()) { - doTracker(evt, _skipEvent); - } - doCalorimeter(evt, _skipEvent); - - } // end of analyze - - void BkgRates::endJob() { - cout << "BkgRates::endJob Number of events skipped " - << "due to G4 completion status: " - << _nBadG4Status - << "\nBkgRates::endJob Number of overflow events " - << "due to too many particles in G4: " - << _nOverflow - << "\nBkgRates::endJob Number of events with killed particles " - << "due to too many steps in G4: " - << _nKilled - << "\nBkgRates::endJob total CpuTime " - << _totalcputime - << "\nBkgRates::endJob total RealTime " - << _totalrealtime - << endl; - } - - void BkgRates::doTracker(art::Event const& evt, bool skip) { - - if (skip) return; - - const Tracker& tracker = *GeomHandle(); - - art::Handle pdataHandle; - evt.getByLabel(_makerModuleLabel,pdataHandle); - StrawHitCollection const* hits = pdataHandle.product(); - - art::Handle truthHandle; - evt.getByLabel(_makerModuleLabel,truthHandle); - StrawHitMCTruthCollection const* hits_truth = truthHandle.product(); - - art::Handle mcptrHandle; - evt.getByLabel(_makerModuleLabel,"StrawHitMCPtr",mcptrHandle); - PtrStepPointMCVectorCollection const* hits_mcptr = mcptrHandle.product(); - - if (!(hits->size() == hits_truth->size() && - hits_mcptr->size() == hits->size() ) ) { - throw cet::exception("RANGE") - << "Strawhits: " << hits->size() - << " MCTruthStrawHits: " << hits_truth->size() - << " MCPtr: " << hits_mcptr->size(); - } - - art::Handle genParticles; - evt.getByLabel(_generatorModuleLabel, genParticles); - - art::Handle simParticles; - evt.getByLabel(_g4ModuleLabel, simParticles); - - art::Handle volumes; - evt.getRun().getByLabel(_g4ModuleLabel, volumes); - - bool haveSimPart = ( simParticles.isValid() && volumes.isValid() ); - - // Other files might have empty collections. - if ( haveSimPart ){ - haveSimPart = !(simParticles->empty() || volumes->empty()); - } - - size_t nStrawPerEvent = hits->size(); - - for (size_t i=0; iat(i)); - StrawHitMCTruth const& truth(hits_truth->at(i)); - PtrStepPointMCVector const& mcptr(hits_mcptr->at(i)); - - //Skip the straw if the energy of the hit is smaller than the minimum required - if (hit.energyDep() < _minimumEnergyTracker) continue; - - tntpArray[idx++] = evt.id().event(); //leaf 1 - tntpArray[idx++] = evt.run(); //leaf 2 - - tntpArray[idx++] = hit.time(); //leaf 3 - tntpArray[idx++] = hit.dt(); //leaf 4 - tntpArray[idx++] = hit.energyDep(); //leaf 5 - - //Get hit straw - StrawId sid = hit.strawId(); - Straw str = tracker.getStraw(sid); - // LayerId lid = sid.getLayerId(); - // PlaneId did = sid.getPlaneId(); - // PanelId secid = sid.getPanelId(); - - tntpArray[idx++] = sid.getLayer(); //leaf 6 - tntpArray[idx++] = sid.getPlane(); //leaf 7 - tntpArray[idx++] = sid.getPanel(); //leaf 8 - tntpArray[idx++] = sid.getStraw(); //leaf 9 - - - - //Get coordinates of the hit: - - //X, Y and Z coordinate of the straw middle point - const CLHEP::Hep3Vector stMidPoint3 = str.getMidPoint(); - - //direction of the straw - const CLHEP::Hep3Vector stDirection3 = str.getDirection(); - - //Position along the wire using mctruth info - double vMC = truth.distanceToMid(); - - //Position along the wire using dt and propagation velocity (c) - const double signalVelocity = 299.792458; // mm/ns - double v = 10e4 * hit.dt()/(2*signalVelocity); - - const CLHEP::Hep3Vector HitPoint = stMidPoint3 + (v/stDirection3.mag())*stDirection3; - const CLHEP::Hep3Vector MCHitPoint = stMidPoint3 + (vMC/stDirection3.mag())*stDirection3; - - if (fabs(v) > str.halfLength()) { - if (_diagLevel > 0) cout << "Position along the wire bigger than halflength" << endl; - } - - tntpArray[idx++] = MCHitPoint.getX(); //leaf 10 - tntpArray[idx++] = MCHitPoint.getY(); //leaf 11 - tntpArray[idx++] = v; //leaf 12 - tntpArray[idx++] = vMC; //leaf 13 - tntpArray[idx++] = stMidPoint3.getZ(); //leaf 14 - - //Get related G4 hits to identify the track. - - - CLHEP::Hep3Vector const& strDir = str.direction(); - double strRadius = tracker.strawOuterRadius(); - bool foundTrack = false; - if ( haveSimPart ) { - for (size_t j = 0; j < mcptr.size(); ++j) { - - if (foundTrack) break; - - StepPointMC const& mchit = *mcptr[j]; - SimParticle const& sim = simParticles->at(mchit.trackId()); - - CLHEP::Hep3Vector const& StartPos = sim.startPosition(); - LinePointPCA lppca(stMidPoint3, strDir, StartPos); - double insideDistance = lppca.dca(); - if (insideDistance < strRadius) continue; - - tntpArray[idx++] = mchit.trackId().asInt(); //leaf 15 - tntpArray[idx++] = sim.pdgId();//leaf 16 - tntpArray[idx++] = sim.fromGenerator();//leaf 17 - tntpArray[idx++] = sim.startMomentum().vect().mag(); // leaf 21 - tntpArray[idx++] = sim.creationCode(); // leaf 22 - tntpArray[idx++] = sim.startVolumeIndex(); // leaf 23 - tntpArray[idx++] = sim.startPosition().x(); // leaf 24 - tntpArray[idx++] = sim.startPosition().y(); // leaf 25 - tntpArray[idx++] = sim.startPosition().z(); // leaf 26 - tntpArray[idx++] = sim.startGlobalTime(); // leaf 27 - tntpArray[idx++] = sim.stoppingCode(); // leaf 28 - tntpArray[idx++] = sim.endVolumeIndex(); // leaf 29 - tntpArray[idx++] = sim.endPosition().x(); // leaf 30 - tntpArray[idx++] = sim.endPosition().y(); // leaf 31 - tntpArray[idx++] = sim.endPosition().z(); // leaf 32 - tntpArray[idx++] = sim.endGlobalTime(); // leaf 33 - - int steps = 0; - bool foundEva = false; - int evaIsGen = 0; - int evaCreationCode = 0; - SimParticle& tempSim = const_cast(sim); - while (!foundEva) { - if (!(tempSim.hasParent()) ) { - foundEva = true; - if ( tempSim.fromGenerator()) { - evaIsGen = 1; - } - evaCreationCode = tempSim.creationCode(); - break; - } - - tempSim = const_cast(*tempSim.parent()); - steps++; - } - - tntpArray[idx++] = steps; // leaf 18 - tntpArray[idx++] = evaIsGen; // leaf 19 - tntpArray[idx++] = evaCreationCode; // leaf 20 - foundTrack = true; - - } - } else if ( !haveSimPart) { - - tntpArray[idx++] = 0; // leaf 15 - tntpArray[idx++] = 0; // leaf 16 - tntpArray[idx++] = 0; // leaf 17 - tntpArray[idx++] = 0; // leaf 18 - tntpArray[idx++] = 0; // leaf 19 - tntpArray[idx++] = 0; // leaf 20 - tntpArray[idx++] = 0; // leaf 21 - tntpArray[idx++] = 0; // leaf 22 - tntpArray[idx++] = 0; // leaf 23 - tntpArray[idx++] = 0; // leaf 24 - tntpArray[idx++] = 0; // leaf 25 - tntpArray[idx++] = 0; // leaf 26 - tntpArray[idx++] = 0; // leaf 27 - tntpArray[idx++] = 0; // leaf 28 - tntpArray[idx++] = 0; // leaf 29 - tntpArray[idx++] = 0; // leaf 30 - tntpArray[idx++] = 0; // leaf 31 - tntpArray[idx++] = 0; // leaf 32 - tntpArray[idx++] = 0; // leaf 33 - - } - - size_t ngen = genParticles->size(); - if (ngen>1) { - cout << "The plugin is supposed to analyze single background rates," - << "with one generated particle per event" - << "\nThis event has more than one genparticle. Only the " - << "first one will be stored" << endl; - } - - SimParticleCollection::key_type idxInSim = SimParticleCollection::key_type(1); - SimParticle const& geninSim = simParticles->at(idxInSim); - if (!geninSim.fromGenerator()) { - cout << "Watch out. First particle is not from generator. What's happening?" << endl; - } - - if (ngen > 0) { - GenParticle const& gen = genParticles->at(0); - tntpArray[idx++] = gen.generatorId().id();//leaf 34 - tntpArray[idx++] = gen.momentum().vect().mag();//leaf 35 - tntpArray[idx++] = gen.momentum().e();//leaf 36 - tntpArray[idx++] = gen.position().x();//leaf 37 - tntpArray[idx++] = gen.position().y();//leaf 38 - tntpArray[idx++] = gen.position().z();//leaf 39 - tntpArray[idx++] = gen.momentum().cosTheta();//leaf 40 - tntpArray[idx++] = gen.momentum().phi();//leaf 41 - tntpArray[idx++] = gen.time();//leaf 42 - } else if ( ngen == 0 ) { - tntpArray[idx++] = 0;//leaf 34 - tntpArray[idx++] = 0;//leaf 35 - tntpArray[idx++] = 0;//leaf 36 - tntpArray[idx++] = 0;//leaf 37 - tntpArray[idx++] = 0;//leaf 38 - tntpArray[idx++] = 0;//leaf 39 - tntpArray[idx++] = 0;//leaf 40 - tntpArray[idx++] = 0;//leaf 41 - tntpArray[idx++] = 0;//leaf 42 - } - - // Store MC truth data - tntpArray[idx++] = truth.driftTime(); //leaf 43 - tntpArray[idx++] = truth.driftDistance(); //leaf 44 - - _tNtup->Fill(tntpArray); - - } //end of Strawhits loop - - } // end of doTracker - - - void BkgRates::doCalorimeter(art::Event const& evt, bool skip) { - - if (skip) return; -/* - const double CrDensity = 7.4*(CLHEP::g/CLHEP::cm3); - - //Get handle to the calorimeter - art::ServiceHandle geom; - if( ! geom->hasElement() ) return; - - GeomHandle cg; - double CrMass = CrDensity*cg->caloInfo().crystalVolume(); - - - // Get handles to calorimeter collections - art::Handle caloHits; - art::Handle caloCrystalHits; - - // Get the persistent data about pointers to StepPointMCs - art::Handle mcptrHandle; - // art::Handle steps; - - evt.getByLabel(_caloReadoutModuleLabel,"CaloHitMCCrystalPtr",mcptrHandle); - // evt.getByLabel(_g4ModuleLabel,"calorimeter",steps); - evt.getByLabel(_caloReadoutModuleLabel, caloHits); - evt.getByLabel(_caloCrystalModuleLabel, caloCrystalHits); - - - PtrStepPointMCVectorCollection const* hits_mcptr = mcptrHandle.product(); - if ( !caloHits.isValid() ) return; - - - if (!caloCrystalHits.isValid()) {cout << "NO CaloCrystalHits" << endl; return;} - - - // Get handles to the generated and simulated particles. - art::Handle genParticles; - evt.getByLabel(_generatorModuleLabel, genParticles); - - art::Handle simParticles; - evt.getByLabel(_g4ModuleLabel, simParticles); - - // Handle to information about G4 physical volumes. - art::Handle volumes; - evt.getRun().getByLabel(_g4ModuleLabel, volumes); - - - // Some files might not have the SimParticle and volume information. - bool haveSimPart = ( simParticles.isValid() && volumes.isValid() ); - // Other files might have empty collections. - if ( haveSimPart ){ - haveSimPart = !(simParticles->empty() || volumes->empty()); - } - - if (caloCrystalHits->size()<=0) return; - - for ( size_t i=0; isize(); ++i ) { - - CaloCrystalHit const & hit = (*caloCrystalHits).at(i); - if (hit.energyDep() < _minimumEnergyCalo) continue; - - - std::vector > const& ROIds = hit.readouts(); - - // cout << "Event " << evt.id().event() << ". In the caloCrystalHits there are " << ROIds.size() << " RO associated" << endl; - - if (ROIds.size() < 1) { - // cout << " Event n. " << evt.id().event() - // << " \t got crystal hits but not ROhits" - // << '\t' << caloCrystalHits->size() - // << '\t' << ROIds.size() << endl; - continue; - } - - float cntpArray[41]; - int idx(0); - - - CLHEP::Hep3Vector firstHitPos(0,0,0); - CLHEP::Hep3Vector cryFrame(0,0,0); - - size_t collectionPosition = ROIds.at(0).key(); - CaloHit const & thehit = *ROIds.at(0); - - int crystalId = cg->caloInfo().crystalByRO(thehit.id()); - CLHEP::Hep3Vector cryCenter = cg->crystal(crystalId).position(); - int diskId = cg->crystal(crystalId).diskId(); - - - - cntpArray[idx++] = evt.id().event(); - cntpArray[idx++] = evt.run(); - cntpArray[idx++] = hit.time(); - cntpArray[idx++] = hit.energyDep(); - double dose = hit.energyDep() / CrMass / (CLHEP::joule/CLHEP::kg); - cntpArray[idx++] = dose; - cntpArray[idx++] = crystalId; - cntpArray[idx++] = diskId; - cntpArray[idx++] = cryCenter.getX() + 3904.; //value used to shift in tracker coordinate system - cntpArray[idx++] = cryCenter.getY(); - cntpArray[idx++] = cryCenter.getZ() - 10200; value used to shift in tracker coordinate system. The hardwired value should be changed to a parametrized version if this is ever uncommented. - - - PtrStepPointMCVector const & mcptr(hits_mcptr->at(collectionPosition)); - StepPointMC const& mchit = *mcptr[0]; - - - if (haveSimPart) { - // The simulated particle that made this hit. - SimParticleCollection::key_type trackId(mchit.trackId()); - - cntpArray[idx++] = trackId.asInt(); - - SimParticle const& sim = simParticles->at(trackId); - - cntpArray[idx++] = sim.pdgId(); - cntpArray[idx++] = sim.fromGenerator(); - - if (sim.stoppingCode() == ProcessCode::mu2eMaxSteps) { - cout << "Track " << sim.pdgId() << " dies at " - << sim.endGlobalTime() << endl; - } - - cntpArray[idx++] = sim.startMomentum().vect().mag(); - cntpArray[idx++] = sim.creationCode(); - cntpArray[idx++] = sim.startVolumeIndex(); - cntpArray[idx++] = sim.startPosition().x(); - cntpArray[idx++] = sim.startPosition().y(); - cntpArray[idx++] = sim.startPosition().z(); - cntpArray[idx++] = sim.startGlobalTime(); - - cntpArray[idx++] = sim.stoppingCode(); - cntpArray[idx++] = sim.endVolumeIndex(); - cntpArray[idx++] = sim.endPosition().x(); - cntpArray[idx++] = sim.endPosition().y(); - cntpArray[idx++] = sim.endPosition().z(); - cntpArray[idx++] = sim.endGlobalTime(); - - firstHitPos = mchit.position(); - cryFrame = cg->toCrystalFrame(crystalId, firstHitPos); - cntpArray[idx++] = cryFrame.x(); - cntpArray[idx++] = cryFrame.y(); - cntpArray[idx++] = cryFrame.z(); - - - int steps = 0; - bool foundEva = false; - int evaIsGen = 0; - int evaCreationCode = 0; - SimParticle& tempSim = const_cast(sim); - while (!foundEva) { - if (!(tempSim.hasParent()) ) { - foundEva = true; - if ( tempSim.fromGenerator()) { - evaIsGen = 1; - } - evaCreationCode = tempSim.creationCode(); - break; - } - - tempSim = const_cast(*tempSim.parent()); - steps++; - } - - cntpArray[idx++] = steps; - cntpArray[idx++] = evaIsGen; - cntpArray[idx++] = evaCreationCode; - - - - } else if (!haveSimPart) { - - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - cntpArray[idx++] = 0; - - } - - size_t ngen = genParticles->size(); - if (ngen>1) { - cout << "The plugin is supposed to analyze single background rates," - << "with one generated particle per event" - << "\nThis event has more than one genparticle. Only the " - << "first one will be stored" << endl; - } - if (ngen > 0) { - GenParticle const& gen = genParticles->at(0); - cntpArray[idx++] = gen.generatorId().id(); - cntpArray[idx++] = gen.momentum().vect().mag(); - cntpArray[idx++] = gen.momentum().e(); - cntpArray[idx++] = gen.position().x(); - cntpArray[idx++] = gen.position().y(); - cntpArray[idx++] = gen.position().z(); - cntpArray[idx++] = gen.momentum().cosTheta(); - cntpArray[idx++] = gen.momentum().phi(); - cntpArray[idx++] = gen.time(); - } else if ( ngen == 0 ) { - cntpArray[idx++] = 0.; - cntpArray[idx++] = 0.; - cntpArray[idx++] = 0.; - cntpArray[idx++] = 0.; - cntpArray[idx++] = 0.; - cntpArray[idx++] = 0.; - cntpArray[idx++] = 0.; - cntpArray[idx++] = 0.; - cntpArray[idx++] = 0.; - } - _cNtup->Fill(cntpArray); - } -*/ - } // end of doCalorimeter - - - - - - - - void BkgRates::doStoppingTarget(const art::Event& event) { - - bool generatedStopped = false; - - // Find original G4 steps in the stopping target - art::Handle sthits; - event.getByLabel(_g4ModuleLabel,"stoppingtarget",sthits); - - // SimParticles container - art::Handle simParticles; - event.getByLabel(_g4ModuleLabel, simParticles); - if( !(simParticles.isValid()) || simParticles->empty() ) return; - - art::Handle volumes; - event.getRun().getByLabel(_g4ModuleLabel, volumes); - - set stoppedtracks; - - // Loop over all hits in the stopping target - for ( size_t i=0; isize(); ++i ){ - - // This is G4 hit (step) in the target - const StepPointMC& hit = (*sthits)[i]; - - SimParticleCollection::key_type trackId = hit.trackId(); - - SimParticle const* sim = simParticles->getOrNull(trackId); - if( !sim ) continue; - - PhysicalVolumeInfo const& volInfo = volumes->at(sim->endVolumeIndex()); - - if (!(sim->fromGenerator())) continue; - - if (skipPDG.find(sim->pdgId()) != skipPDG.end()) { - if ( volInfo.name().compare(0,11,"TargetFoil_") == 0 ) { - generatedStopped = true; - - } - } - - if( stoppedtracks.insert(trackId).second ) { - float tgtntpArray[11]; - int idx(0); - tgtntpArray[idx++] = event.id().event(); - tgtntpArray[idx++] = event.run(); - tgtntpArray[idx++] = sim->endGlobalTime(); - tgtntpArray[idx++] = sim->endPosition().x(); - tgtntpArray[idx++] = sim->endPosition().y(); - tgtntpArray[idx++] = sim->endPosition().z(); - tgtntpArray[idx++] = sim->fromGenerator(); - tgtntpArray[idx++] = sim->pdgId(); - tgtntpArray[idx++] = trackId.asInt(); - tgtntpArray[idx++] = sim->endVolumeIndex(); - tgtntpArray[idx++] = (volInfo.name().compare(0,11,"TargetFoil_") == 0 ); - - _tgtNtup->Fill(tgtntpArray); - - } - } - - _skipEvent = generatedStopped; - } // end doStoppingTarget -} - -using mu2e::BkgRates; -DEFINE_ART_MODULE(BkgRates); - diff --git a/Analyses/src/CosmicTuple_module.cc b/Analyses/src/CosmicTuple_module.cc deleted file mode 100644 index b6ff5e0894..0000000000 --- a/Analyses/src/CosmicTuple_module.cc +++ /dev/null @@ -1,399 +0,0 @@ -// -// An EDAnalyzer module that reads back the hits created by G4 and makes histograms. -// -// $Id: CosmicTuple_module.cc,v 1.11 2013/09/27 16:03:41 gandr Exp $ -// $Author: gandr $ -// $Date: 2013/09/27 16:03:41 $ -// -// Original author Yury Kolomensky (Rob Kutschke) -// - -#include "CLHEP/Units/SystemOfUnits.h" -#include "GlobalConstantsService/inc/GlobalConstantsHandle.hh" -#include "GlobalConstantsService/inc/ParticleDataTable.hh" -#include "GeometryService/inc/GeomHandle.hh" -#include "GeometryService/inc/GeometryService.hh" -#include "MCDataProducts/inc/GenParticleCollection.hh" -#include "MCDataProducts/inc/ProcessCode.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "DataProducts/inc/PDGCode.hh" -#include "Mu2eUtilities/inc/SimParticlesWithHits.hh" -#include "TH1F.h" -#include "TNtuple.h" -#include "TrackerGeom/inc/Tracker.hh" -#include "art/Framework/Core/EDFilter.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art_root_io/TFileService.h" -#include "art/Framework/Principal/Handle.h" -#include "cetlib_except/exception.h" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" -#include -#include -#include -#include -#include - -using namespace std; - -namespace mu2e { - - class CosmicTuple : public art::EDFilter { - public: - - explicit CosmicTuple(fhicl::ParameterSet const& pset); - virtual ~CosmicTuple() { } - - virtual void beginJob(); - virtual bool beginRun(art::Run &r); - - // This is called for each event. - virtual bool filter(art::Event& e); - - private: - - // Module label of the geerator module. - std::string _generatorModuleLabel; - - // Module label of the g4 module that made the hits. - std::string _g4ModuleLabel; - - // Cut on the minimum energy. - double _minimump; - double _maximump; - int _minHits; - int _runNumber; - - // Number of events analyzed. - int _nAnalyzed; - - // Pointers to histograms & ntuples - TH1F* _hEventsize; - TNtuple* _ntupTrk; - - }; - - CosmicTuple::CosmicTuple(fhicl::ParameterSet const& pset) : - EDFilter{pset}, - _generatorModuleLabel(pset.get("generatorModuleLabel", "generate")), - _g4ModuleLabel(pset.get("g4ModuleLabel")), - _minimump(pset.get("minimump")), - _maximump(pset.get("maximump")), - _minHits(pset.get("minHits")), - - _nAnalyzed(0), - _hEventsize(0), - _ntupTrk(0) - - { - } - - void CosmicTuple::beginJob(){ - - // Get access to the TFile service. - art::ServiceHandle tfs; - - // Create some 1D histograms. - _hEventsize = tfs->make( "EventSize", "Size of the Event", 100, 0., 100000. ); - - // Create an ntuple. - _ntupTrk = tfs->make( "ntupTrk", "Trk ntuple", -"evt:trk:pid:pmag:genId:pidGen:eGen:thGen:xGen:yGen:zGen:nHits:ptrs:xtrs:ytrs:ztrs:pprs:xprs:yprs:zprs:prnId:time:calE:nCryst:nAPD:pAng:prCrea:prStop:trCrea:trStop:run:px:py:pz:E:vx:vy:vz:vt:isSh:ppre:xpre:ypre:zpre:trvs:trve:prvs:prve:calEi"); - } - - bool CosmicTuple:: beginRun(art::Run& run) { - _runNumber = run.id().run(); - return true; - } - - bool CosmicTuple::filter(art::Event& event) { - - typedef SimParticleCollection::key_type key_type; - - // Maintain a counter for number of events seen. - ++_nAnalyzed; - - if ( _nAnalyzed % 10000 == 0 ) { - mf::LogInfo("CosmicTuple") - << "Processing event " << _nAnalyzed; - } - - // Ask the event to give us a "handle" to the requested hits. - static const string collectionName("tracker"); - art::Handle hits; - event.getByLabel(_g4ModuleLabel,collectionName,hits); - - // Get handles to the generated and simulated particles. - art::Handle genParticles; - event.getByLabel(_generatorModuleLabel, genParticles); - - // Get handles to the generated and simulated particles. - art::Handle simParticles; - event.getByLabel(_g4ModuleLabel, simParticles); - - // Some files might not have the SimParticle and volume information. - bool haveSimPart = ( simParticles.isValid() ); - - // Other files might have empty collections. - if ( haveSimPart ){ - haveSimPart = !(simParticles->empty() ); - } - - // ntuple buffer. - //float ntT[_ntupTrk->GetNvar()]; - - bool pass = false; - /* - bool isSh = false; - double calEne = 0.; - double calEind = 0.; - int prntPdg = 0; - int prCr = 0; - int prSt = 0; - int trCr = 0; - int trSt = 0; - double px = 0.; - double py = 0.; - double pz = 0.; - double E = 0.; - double vx = 0.; - double vy = 0.; - double vz = 0.; - double vt = 0.; - double rmass = 0.; - unsigned trSVolume = 0; - unsigned trEVolume = 0; - unsigned prSVolume = 0; - unsigned prEVolume = 0; - */ - - map hit_crystals; - map hit_apds; - - art::ServiceHandle geom; - return pass; - /* - GeomHandle cg; - - // Fill some histograms - _hEventsize->Fill(simParticles->size()); - - if ( simParticles->size() >= 50000 ) return pass; - - art::Handle rohits; - event.getByLabel(_g4ModuleLabel,"calorimeter",rohits); - - art::Handle apdhits; - event.getByLabel(_g4ModuleLabel,"calorimeterRO",apdhits); - - GlobalConstantsHandle pdt; - - // Construct an object that ties together all of the simulated particle and hit info. - SimParticlesWithHits sims( event, - "g4run", - "makeSH", - "tracker", - 0.001, - 0 ); - - typedef SimParticlesWithHits::map_type map_type; - - for ( map_type::const_iterator i=sims.begin(); - i != sims.end(); ++i ){ - - // All information about this SimParticle - SimParticleInfo const& simInfo = i->second; - SimParticle const& sim = simInfo.simParticle(); - - // Information about primary ancestor - SimParticleAncestors ancestor( sim, - *simParticles, - *genParticles); - GenParticle const& gen_parent = ancestor.originalGen(); - - // Immediate parent particle - SimParticle const* sim_parent = 0; - if( sim.hasParent() ) sim_parent = simParticles->getOrNull(sim.parentId()); - - // Information about StrawHits that belong on this SimParticle. - vector const& infos = simInfo.strawHitInfos(); - int nHits = infos.size(); - - CLHEP::Hep3Vector y(0,-1,0); - CLHEP::Hep3Vector posGen = gen_parent.position(); - CLHEP::Hep3Vector trspos(0,0,0); - CLHEP::Hep3Vector prspos(0,0,0); - CLHEP::Hep3Vector trsmom(0,0,0); - CLHEP::Hep3Vector prsmom(0,0,0); - CLHEP::Hep3Vector prepos(0,0,0); - CLHEP::Hep3Vector premom(0,0,0); - - trspos = sim.startPosition(); - trsmom = sim.startMomentum(); - trSVolume = sim.startVolumeIndex(); - trEVolume = sim.endVolumeIndex(); - ProcessCode creationCode = sim.creationCode(); - ProcessCode stoppingCode = sim.stoppingCode(); - trCr = creationCode; - trSt = stoppingCode; - - if( sim.hasParent()) { - prspos = sim_parent->startPosition(); - prsmom = sim_parent->startMomentum(); - prepos = sim_parent->endPosition(); - premom = sim_parent->endMomentum(); - prSVolume = sim_parent->startVolumeIndex(); - prEVolume = sim_parent->endVolumeIndex(); - prntPdg= sim_parent->pdgId(); - prCr = sim_parent->creationCode(); - prSt = sim_parent->stoppingCode(); - } else { - prspos = posGen; - prsmom = gen_parent.momentum(); - prntPdg = gen_parent.pdgId(); - } - - double momentum = -1.; - double pitchAng = -1.; - - //Get particle mass - ParticleDataTable::maybe_ref e_data = pdt->particle(sim.pdgId()); - if ( e_data ){ - rmass = e_data.ref().mass().value(); - } else{ - - // If particle is unknown, set rest mass to 0. - rmass = 0.; - mf::LogWarning("PDGID") - << "Particle ID created by G4 not known to the particle data table: " - << sim.pdgId() - << "\n"; - } - - - // First StrawsHits to which this SimParticle contributed. - StrawHitMCInfo const& info = infos.at(0); - - // Loop over all StepPointMC's that contribute to this StrawHit. - std::vector const& steps = info.steps(); - - for ( size_t k=0; ksize(); ++i ) { - const StepPointMC & rohit = rohits->at(i); - calEne += rohit.eDep(); - int cid = rohit.volumeId(); - hit_crystals[cid] =1; - SimParticle const * csim = simParticles->getOrNull(rohit.trackId()); - while ( csim && csim->id() != sim.id() ) { - csim = simParticles->getOrNull(csim->parentId()); - } - if(csim){ - calEind += rohit.eDep(); - } - } - } else{ - calEne = -1; - calEind= -1; - } - - // Find original G4 steps in the APDs - if( apdhits.isValid() ) { - for ( size_t i=0; isize(); ++i ) { - const StepPointMC & apdhit = apdhits->at(i); - int apdid = apdhit.volumeId(); - int cida = cg->caloInfo().crystalByRO(apdid); - hit_apds[cida] =1; - } - } - - if( momentum < _minimump || momentum > _maximump ) continue; - if( nHits< _minHits ) continue; - pass = true; - - ntT[0] = event.id().event(); - ntT[1] = sim.id().asInt(); - ntT[2] = sim.pdgId(); - ntT[3] = momentum; - ntT[4] = gen_parent.generatorId().id(); - ntT[5] = gen_parent.pdgId(); - ntT[6] = gen_parent.momentum().e(); - ntT[7] = y.angle(gen_parent.momentum().vect()); - ntT[8] = posGen.x(); - ntT[9] = posGen.y(); - ntT[10] = posGen.z(); - ntT[11] = nHits; - ntT[12] = trsmom.mag(); - ntT[13] = trspos.x(); - ntT[14] = trspos.y(); - ntT[15] = trspos.z(); - ntT[16] = prsmom.mag(); - ntT[17] = prspos.x(); - ntT[18] = prspos.y(); - ntT[19] = prspos.z(); - ntT[20] = prntPdg; - ntT[21] = sim.startGlobalTime(); - ntT[22] = calEne; - ntT[23] = hit_crystals.size(); - ntT[24] = hit_apds.size(); - ntT[25] = pitchAng; - ntT[26] = prCr; - ntT[27] = prSt; - ntT[28] = trCr; - ntT[29] = trSt; - ntT[30] = _runNumber; - ntT[31] = px; - ntT[32] = py; - ntT[33] = pz; - ntT[34] = E; - ntT[35] = vx; - ntT[36] = vy; - ntT[37] = vz; - ntT[38] = vt; - ntT[39] = isSh; - ntT[40] = premom.mag(); - ntT[41] = prepos.x(); - ntT[42] = prepos.y(); - ntT[43] = prepos.z(); - ntT[44] = trSVolume ; - ntT[45] = trEVolume ; - ntT[46] = prSVolume ; - ntT[47] = prEVolume ; - ntT[48] = calEind; - - _ntupTrk->Fill(ntT); - - - } // end loop over hits. - - */ - return pass; - - } // end filter - -} // end namespace mu2e - -DEFINE_ART_MODULE(mu2e::CosmicTuple); diff --git a/Analyses/src/HitDisplay_module.cc b/Analyses/src/HitDisplay_module.cc deleted file mode 100644 index 1b5080bf21..0000000000 --- a/Analyses/src/HitDisplay_module.cc +++ /dev/null @@ -1,879 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// A half-interactive 2D event display. -// -// $Id: HitDisplay_module.cc,v 1.24 2014/08/01 20:57:44 echenard Exp $ -// $Author: echenard $ -// $Date: 2014/08/01 20:57:44 $ -// -// Contact person: Pavel Murat, Gianantonio Pezzulo -// -// What this event display shows: 2D view of the straw hits, tracks, and calorimeter clusters -// -// Straw hit display mode: -// ----------------------- -// displayBackgroundHits : false - respect hit flags set by FlagStrawHits_module (default) -// the timing hit flag check is commented out - I didn't have a MC file -// in hands to check -// : true - display all hits -// useStereoHits : true : displayed hit position errors are defined by the StrawHitPositionCollection -// : false: semi-random assignment (sigr=5mm, sigp = strawTimeDivisionErr/2.) -// -// small black triangles: MC truth on the trajectory -// -// red hits: hits on a track reconstructed as a downstream-moving conversion electron within the time window -// size of the timing window can be redefined via talk-to (input .fcl file) -// blue hits: hits of the conversion electron track, which fall outside the time window -// black hits: hits produced by anything, but the conversion electron -// -// a hit is displayed by a cross with the radial error bar of 5mm and the resolution -// along the straw of sigma(time division)/2, to better guide the eye -// -// green circles - contour of the disk-based calorimeter -// clusters on the 1st disk are shown in red, on the second disk - in pink -// -// there are few other features which we need to document -// -// .fcl file to use: Analyses/test/hitDisplay.fcl -/////////////////////////////////////////////////////////////////////////////// - -// C++ includes. -#include -#include - -// Framework includes. -#include "art/Framework/Core/EDAnalyzer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art_root_io/TFileService.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -// Mu2e includes. -#include "ConditionsService/inc/ConditionsHandle.hh" -#include "TrackerConditions/inc/StrawResponse.hh" - -#include "GeometryService/inc/GeometryService.hh" -#include "GeometryService/inc/GeomHandle.hh" - -#include "TrackerGeom/inc/Tracker.hh" -#include "CalorimeterGeom/inc/DiskCalorimeter.hh" -#include "CalorimeterGeom/inc/Calorimeter.hh" - -#include "Mu2eUtilities/inc/SimParticlesWithHits.hh" -#include "Mu2eUtilities/inc/SortedStepPoints.hh" -#include "Mu2eUtilities/inc/TrackTool.hh" -#include "Mu2eUtilities/inc/TwoLinePCA.hh" - -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "MCDataProducts/inc/GenParticleCollection.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" - -#include "BTrk/TrkBase/HelixParams.hh" -#include "BTrk/KalmanTrack/KalHit.hh" -#include "BTrk/ProbTools/ChisqConsistency.hh" - -#include "RecoDataProducts/inc/CaloCrystalHit.hh" -#include "RecoDataProducts/inc/CaloCrystalHitCollection.hh" -#include "RecoDataProducts/inc/CaloClusterCollection.hh" -#include "RecoDataProducts/inc/StrawHitCollection.hh" -#include "RecoDataProducts/inc/StrawHitPositionCollection.hh" -#include "RecoDataProducts/inc/StrawHitFlagCollection.hh" -#include "RecoDataProducts/inc/ComboHit.hh" - -#include "BTrkData/inc/TrkStrawHit.hh" -#include "RecoDataProducts/inc/KalRepCollection.hh" - -// ROOT includes -#include "TApplication.h" -#include "TArc.h" -#include "TArrow.h" -#include "TCanvas.h" -#include "TDirectory.h" -#include "TGraph.h" -#include "TH1F.h" -#include "TLine.h" -#include "TBox.h" -#include "TMarker.h" -#include "TEllipse.h" -#include "TText.h" -#include "TNtuple.h" - -// Other includes -#include "CLHEP/Units/SystemOfUnits.h" - -using namespace std; -using CLHEP::Hep3Vector; - -namespace mu2e { - - class HitDisplay : public art::EDAnalyzer { - private: -//----------------------------------------------------------------------------- -// Module labels -//----------------------------------------------------------------------------- - std::string moduleLabel_; // this module label - std::string generatorModuleLabel_; - std::string g4ModuleLabel_; - std::string fStrawHitMaker; - std::string fStrawHitPosMaker; - std::string fStrawHitFlagMaker; - - // Name of the tracker StepPoint collection - std::string trackerStepPoints_; - - // Cuts used inside SimParticleWithHits: - // - drop hits with too little energy deposited. - // - drop SimParticles with too few hits. - - double minEnergyDep_; - double timeWindow_; - size_t minHits_; - // Options to control the display - - bool fDisplayBackgroundHits; - bool clickToAdvance_; - bool printHits_; - int fUseStereoHits; - // hit flag bits which should be ON and OFF - mu2e::StrawHitFlag fGoodHitMask; - mu2e::StrawHitFlag fBadHitMask; - - TApplication* fApplication; - TCanvas* fCanvas; - - const mu2e::Calorimeter* fCal; // - - const mu2e::StrawHitCollection* fStrawHitColl; // - const mu2e::GenParticleCollection* fGenpColl; // - const mu2e::StrawHitPositionCollection* fStrawHitPosColl; // - const mu2e::StrawHitFlagCollection* fStrawHitFlagColl; // - const mu2e::CaloClusterCollection* fListOfClusters; // - const mu2e::PtrStepPointMCVectorCollection* hits_mcptr; - const mu2e::StepPointMCCollection* fSteps; - - int fNClusters; - // 4 hypotheses: dem, uep, dmm, ump - int fNTracks[4]; - - const mu2e::KalRepCollection* fDem; - - TMarker* fMarker; - - // Tracker conditions object. - ProditionsHandle strawResponse_h; - - public: - explicit HitDisplay(fhicl::ParameterSet const& pset); - virtual ~HitDisplay(); - - void getData(const art::Event* Evt); - - void printCaloCluster(const CaloCluster* Cl, const char* Opt) ; - void printKalRep(const KalRep* Trk, const char* Opt); -//----------------------------------------------------------------------------- -// overloaded virtual methods of the base class -//----------------------------------------------------------------------------- - void beginJob( ); - void analyze(art::Event const& e ); - }; - - - HitDisplay::HitDisplay(fhicl::ParameterSet const& pset): - art::EDAnalyzer(pset), - moduleLabel_ (pset.get("module_label" )), - generatorModuleLabel_ (pset.get("generatorModuleLabel" )), - g4ModuleLabel_ (pset.get("g4ModuleLabel" )), - fStrawHitMaker (pset.get("comboHitMakerModuleLabel" )), - fStrawHitPosMaker (pset.get("comboHitPosMakerModuleLabel" )), - fStrawHitFlagMaker (pset.get("comboHitFlagMakerModuleLabel")), - trackerStepPoints_ (pset.get("trackerStepPoints" )), - minEnergyDep_ (pset.get ("minEnergyDep",0 )), - timeWindow_ (pset.get ("timeWindow" ,1.e6 )), - minHits_ (pset.get ("minHits" )), - fDisplayBackgroundHits (pset.get ("displayBackgroundHits",false )), - clickToAdvance_ (pset.get ("clickToAdvance" ,false )), - printHits_ (pset.get ("printHits" ,false )), - fUseStereoHits (pset.get ("useStereoHits" ,false )), - fGoodHitMask (pset.get >("goodHitMask" )), - fBadHitMask (pset.get >("badHitMask" )) - { - - fApplication = 0; - fCanvas = 0; - fCal = 0; - } - -//----------------------------------------------------------------------------- - HitDisplay::~HitDisplay() { - if (fApplication) delete fApplication; - } - - - //----------------------------------------------------------------------------- - void HitDisplay::beginJob(){ - int tmp_argc(0); - char** tmp_argv(0); - - if (!gApplication) { - fApplication = new TApplication( "HitDisplay_module", &tmp_argc, tmp_argv ); - } - - // Create a canvas with a guaranteed unique name; the module label is unique within a job. - TString name = "canvas_" + moduleLabel_; - TString title = "Canvas for " + moduleLabel_; - - fCanvas = new TCanvas(name,title,800,800); - fMarker = new TMarker(0,0,20); - fMarker->SetMarkerSize(0.3); - } - - -//----------------------------------------------------------------------------- -// 'banner' : print banner -// 'data' : print track data -// 'hits' : print hits -//----------------------------------------------------------------------------- - void HitDisplay::printKalRep(const KalRep* Trk, const char* Opt) { - - TString opt = Opt; - - if ((opt == "") || (opt == "banner")) { - printf("------------------------------------------------------------------------------------------------\n"); - printf("TrkID Q momentum pt costh d0 z0 T0 Nact chi2 N(dof) FitConsistency\n"); - printf("------------------------------------------------------------------------------------------------\n"); - } - - if ((opt == "") || (opt.Index("data") >= 0)) { - // Trk->printAll(); - double mom = Trk->momentum().mag(); - double pt = Trk->momentum().perp(); - double costh = Trk->momentum().cosTheta(); - double d0 = Trk->helix(0).d0(); - double z0 = Trk->helix(0).z0(); - double chi2 = Trk->chisq(); - int ndof = Trk->nDof (); - int nact = Trk->nActive(); - double t0 = Trk->t0().t0(); - double fit_consistency = Trk->chisqConsistency().consistency(); - int q = Trk->charge(); - - printf("%2i %10.3f %10.3f %8.3f %8.3f %10.3f %10.3f %3i %10.3f %3i %10.3f\n", - q,mom,pt,costh,d0,z0,t0,nact,chi2,ndof,fit_consistency); - - if (opt.Index("hits") >= 0) { - //----------------------------------------------------------------------------- - // print detailed information about the track hits - //----------------------------------------------------------------------------- - TrkStrawHitVector tshv; - convert(Trk->hitVector(),tshv); - - printf("---------------------------------------------------------------------------"); - printf("-------------------------------------------------------------------------------\n"); - printf(" ih U A len rms x y z HitT HitDt"); - printf(" SInd Dev Sec Lay N Iamb T0 Rdrift Xs Ys Zs resid\n"); - printf("---------------------------------------------------------------------------"); - printf("-------------------------------------------------------------------------------\n"); - - int i(0); - for(auto ihit=tshv.begin(); ihit!= tshv.end(); ++ihit){ - // const KalHit* kh = (*it).kalHit(); - - // TrkStrawHit inherits from TrkHitOnTrk - - const TrkStrawHit* hit = (*ihit); - - const ComboHit* sh = &hit->comboHit(); - Straw* straw = (Straw*) &hit->straw(); - - double len = hit->fltLen(); - - HepPoint plen = Trk->position(len); - - printf("%3i %1i %1i %10.3f %6.3f %10.3f %10.3f %10.3f %8.3f %7.3f", - ++i, - hit->hitFlag(), - hit->isActive(), - len, - hit->hitRms(), - plen.x(),plen.y(),plen.z(), - sh->time(), sh->wireDist() - ); - - Hep3Vector pos; - hit->hitPosition(pos); - printf("%6i %3i %3i %3i %3i %3i %8.3f %8.3f %10.3f %10.3f %10.3f %10.3f\n", - straw->id().asUint16(), - straw->id().getPlane(), - straw->id().getPanel(), - straw->id().getLayer(), - straw->id().getStraw(), - - hit->ambig(), - hit->hitT0().t0(), - hit->driftRadius(), - pos.x(), - pos.y(), - pos.z(), - hit->resid() - ); - // trkhit->print(std::cout); - } - } - } - } - - //----------------------------------------------------------------------------- - // Opt: - // 'banner' : print banner - //----------------------------------------------------------------------------- - void HitDisplay::printCaloCluster(const CaloCluster* Cl, const char* Opt) { - - typedef art::Ptr< CaloCrystalHit> CaloCrystalHitPtr; - typedef std::vector CaloCrystalHitPtrVector; - - const char oname[] = "HitDisplay::printCaloCluster"; - - int ir, iz; - TString opt = Opt; - - art::ServiceHandle geom; - GeomHandle cg; - - printf("[%s] >>> ERROR : yet to learn how to print the crystal indices in case of disks\n", oname); - - if ((opt == "") || (opt.Index("banner") >= 0)) { - printf("-----------------------------------------------------------------------\n"); - printf("DISKID Time Row Col Energy X Y Z \n"); - printf("-----------------------------------------------------------------------\n"); - } - - if ((opt == "") || (opt.Index("data") >= 0)) { - - const CaloCrystalHitPtrVector caloClusterHits = Cl->caloCrystalHitsPtrVector(); - - int nh = caloClusterHits.size(); - Hep3Vector pos; - //----------------------------------------------------------------------------- - // print individual crystals in local disk coordinate system - //----------------------------------------------------------------------------- - for (int i=0; iid(); - - pos = cg->crystal(id).localPosition(); - - - iz = -1; - ir = -1; - - - - - printf("%6i %10.3f %5i %5i %8.3f %10.3f %10.3f %10.3f %10.3f\n", - id, - hit->time(), - iz,ir, - hit->energyDep(), - pos.x(), - pos.y(), - pos.z(), - hit->energyDepTot() - ); - } - } - } - -//----------------------------------------------------------------------------- -// get data from the event record -//----------------------------------------------------------------------------- - void HitDisplay::getData(const art::Event* Evt) { - // const char* oname = "HitDisplay::getData"; - -//----------------------------------------------------------------------------- -// MC truth - gen particles -//----------------------------------------------------------------------------- - art::Handle gensHandle; - Evt->getByLabel(generatorModuleLabel_,gensHandle); - fGenpColl = gensHandle.product(); - - // art::Handle simsHandle; - // Evt->getByLabel(g4ModuleLabel_,simsHandle); - // SimParticleCollection const& sims = *simsHandle; - - // art::Handle hitsTruthHandle; - // Evt->getByLabel(hitMakerModuleLabel_,hitsTruthHandle); - // StrawHitMCTruthCollection const& hitsTruth = *hitsTruthHandle; - - art::Handle mcptrHandle; - Evt->getByLabel(fStrawHitMaker,"StrawHitMCPtr",mcptrHandle); - hits_mcptr = mcptrHandle.product(); - - art::Handle stepsHandle; - Evt->getByLabel(g4ModuleLabel_,trackerStepPoints_,stepsHandle); - fSteps = stepsHandle.product(); -//----------------------------------------------------------------------------- -// straw hit information -//----------------------------------------------------------------------------- - art::Handle shH; - Evt->getByLabel(fStrawHitMaker,shH); - fStrawHitColl = shH.product(); - - art::Handle shpH; - Evt->getByLabel(fStrawHitPosMaker,shpH); - fStrawHitPosColl = shpH.product(); - - art::Handle shfH; - Evt->getByLabel(fStrawHitFlagMaker,shfH); - fStrawHitFlagColl = shfH.product(); -//----------------------------------------------------------------------------- -// calorimeter cluster data -//----------------------------------------------------------------------------- - art::Handle calo_cluster_handle; - Evt->getByLabel("makeCaloCluster","AlgoCLOSESTSeededByENERGY",calo_cluster_handle); - fListOfClusters = (CaloClusterCollection*) &(*calo_cluster_handle); - fNClusters = fListOfClusters->size(); -//----------------------------------------------------------------------------- -// tracking data - upstream moving electrons -//----------------------------------------------------------------------------- - art::Handle demHandle; - Evt->getByLabel("trkPatRec1","DownstreameMinus", demHandle); - fDem = demHandle.product(); - fNTracks[0] = fDem->size(); -//----------------------------------------------------------------------------- -// three other track collections -//----------------------------------------------------------------------------- - art::Handle uepHandle; - Evt->getByLabel("trkPatRec2","UpstreamePlus", uepHandle); - const KalRepCollection* uep = &(*uepHandle); - fNTracks[1] = uep->size(); - - // art::Handle dmmHandle; - // Evt->getByLabel("trkPatRec3","DownstreammuMinus", dmmHandle); - // const KalRepCollection* dmm = &(*dmmHandle); - // fNTracks[2] = dmm->size(); - - // art::Handle umpHandle; - // Evt->getByLabel("trkPatRec4","UpstreammuPlus", umpHandle); - // const KalRepCollection* ump = &(*umpHandle); - // fNTracks[3] = ump->size(); - - } - - //----------------------------------------------------------------------------- - void HitDisplay::analyze(art::Event const& Evt) { - const char* name = "HitDisplay::analyze"; - - TText t; - TEllipse* e; - TGraph* graph (0); - - TrackTool *tt(0), *tg(0), *tmid(0); - const GenParticle* gen; - - TObjArray list_of_ellipses; - int n_displayed_hits, color(-1), intime; - size_t nmc; - - const int module_color[2] = {kRed, kMagenta}; - - vector xStep,yStep; - - const KalRep* trk; - const CaloCluster* cl; - double xl, yl, event_time(-9999.); - TString opt; - - printf("[%s] RUN: %10i EVENT: %10i\n",name,Evt.run(),Evt.event()); - - // Geometry of tracker envelope. - GeomHandle tHandle; - const Tracker* tracker = tHandle.get(); - - TubsParams envelope(tracker->getInnerTrackerEnvelopeParams()); - - auto const& strawResponse = strawResponse_h.get(Evt.id()); - -//----------------------------------------------------------------------------- -// get event data -//----------------------------------------------------------------------------- - getData(&Evt); - - art::ServiceHandle geom; - - // Construct an object that ties together all of the simulated particle and hit info. - SimParticlesWithHits simsInfo( Evt, - g4ModuleLabel_, - fStrawHitMaker, - trackerStepPoints_, - minEnergyDep_, - minHits_ ); - - SimParticleCollection::key_type key(1); - - SimParticleInfo const* info(simsInfo.findOrNull(key)); - const StepPointMC* firstStep; - - if ( !info ) { - printf("[%s] *** ERROR: SimParticleInfo missing, SKIPPING EVENT: %10i\n",name,Evt.event()); - firstStep = 0; - // return; - } - else { - firstStep = &info->firstStepPointMCinTracker(); - } - - static TLine* line(0); - static TArc* arc(0); - static TArc* arccalo(0); - static TArrow* arrow(0); - static TBox* box(0); - - if (line == 0) { - line = new TLine; - arc = new TArc; - arccalo = new TArc; - arrow = new TArrow; - box = new TBox; - - box->SetFillStyle(3002); - box->SetFillColor(4); - box->SetLineColor(4); - } - - SortedStepPoints sortedSteps(key,*fSteps); - - const StepPointMC* midStep = & sortedSteps.middleByZ(); - - if ((midStep == 0) || (firstStep ==0)) { - printf("[%s] **** ERROR : firstStep = %8p midstep = %8p, BAIL OUT\n", - name,firstStep, midStep); - // goto END_OF_ROUTINE; - } - - Hep3Vector pos1, mom1, pos2, mom2; - if (firstStep ) { - pos1 = firstStep->position(); - mom1 = firstStep->momentum(); - } - else { - pos1.set(1.,1.,1.); - mom1.set(1.,1.,1.); - } - - if (midStep) { - pos2 = midStep->position(); - mom2 = midStep->momentum(); - } - else { - pos2.set(1.,1.,1.); - mom2.set(1.,1.,1.); - } - // The generated particle. - gen = &fGenpColl->at(0); - - tt = new TrackTool(gen->pdgId(), -1.,pos1,mom1,1.,Hep3Vector()); - tg = new TrackTool(gen->pdgId(), -1.,gen->position() ,gen->momentum() ,1.,Hep3Vector()); - tmid = new TrackTool(gen->pdgId(), -1.,pos2 ,mom2 ,1.,Hep3Vector()); - - int npt = fSteps->size(); - for (int ipt=0; iptat(ipt); - if ( step.totalEDep() > minEnergyDep_ ) { - xStep.push_back( step.position().x() ); - yStep.push_back( step.position().y() ); - } - } - - arc->SetFillStyle(0); - arccalo->SetFillStyle(0); - - // DISPLAY:; - - fCanvas->cd(0); - fCanvas->Clear(); -//----------------------------------------------------------------------------- -// Draw the frame -//----------------------------------------------------------------------------- - double plotLimits(850.); - fCanvas->DrawFrame(-plotLimits,-plotLimits,plotLimits,plotLimits); - - t.SetText(-800.,900.,Form("[%s] RUN: %10i EVENT: %10i NTRACKS: %4i NCLUSTERS: %4i", - name, Evt.run(),Evt.event(),fNTracks[0],fNClusters)); - t.SetTextSize(0.02); - t.Draw(); - - // Draw the inner and outer arc of the tracker. - arc->SetLineColor(kBlack); - arc->DrawArc(0.,0., envelope.outerRadius()); - arc->DrawArc(0.,0., envelope.innerRadius()); - arc->SetLineColor(kRed); - arc->DrawArc( tt->xc(), tt->yc(), tt->rho()); - arc->SetLineColor(kMagenta); - arc->DrawArc( tmid->xc(), tmid->yc(), tmid->rho()); - arc->SetLineColor(kRed); - //----------------------------------------------------------------------------- - // draw disks - //----------------------------------------------------------------------------- - int nv(0); - if( geom->hasElement() ){ - mu2e::GeomHandle dc; - nv = dc->nDisk(); - } - - double rmin, rmax; //x1(-1.),y1(-1.),x2(-1.),y2(-1.); - if(geom->hasElement()) { - - mu2e::GeomHandle dc; - // Draw the inner and outer arc of calorimeter - - for (int iv=0; ivdisk(iv).innerRadius(); - rmax = dc->disk(iv).outerRadius(); - arccalo->SetLineColor(kGreen+iv); - arccalo->DrawArc(0.,0., rmax); - arccalo->DrawArc(0.,0., rmin); - } - } -//----------------------------------------------------------------------------- -// print reconstructed tracks - all 4 hypotheses for comparison... -//----------------------------------------------------------------------------- - printf("[%s] NTRACKS = %4i, NCLUSTERS = %4i\n",name,fNTracks[0],fNClusters); - printf("\n"); - - opt = "data"; - if (printHits_) opt += "+hits"; - - if (fNTracks[0] > 0) { - printKalRep(0,"banner"); - for (int i=0; iget(i); - printf(" %2i dem ",i); - printKalRep(trk,opt); - } - } - - - if (fNClusters > 0) { - printCaloCluster(0,"banner"); - - for (int i=0; iat(i); - printCaloCluster(cl,opt); - // event time defined by the most energetic cluster - if (i == 0) { - event_time = cl->time()+15.; - } -//----------------------------------------------------------------------------- -// display only clusters with E > 5 MeV -//----------------------------------------------------------------------------- - if (cl->energyDep() > 5.) { - // poor-man's translation - xl = cl->cog3Vector().x()+3904.1; - yl = cl->cog3Vector().y(); - - e = new TEllipse(xl,yl,50.*cl->energyDep()/100.); - e->SetFillStyle(3001); - if(geom->hasElement()){ - color = module_color[cl->diskId()]; - } - e->SetFillColor(color); - e->SetLineColor(color); - - list_of_ellipses.Add(e); - - e->Draw(); - } - } - } -//----------------------------------------------------------------------------- -// Loop over straw hits. If flagBackgroundHits = true, filter them out -//----------------------------------------------------------------------------- - int n_straw_hits, display_hit; - bool isFromConversion; - double sigv, v, sigr; - const StrawHit* hit; - const StrawHitPosition* hitpos; - const StrawHitFlag* hit_id_word; - const CLHEP::Hep3Vector *mid, *w; - const Straw* straw; - const PtrStepPointMCVector* mcptr; - CLHEP::Hep3Vector vx0, vx1, vx2; - - n_displayed_hits = 0; - n_straw_hits = fStrawHitColl->size(); - - for (int ihit=0; ihitat(ihit); - hitpos = &fStrawHitPosColl->at(ihit); - hit_id_word = &fStrawHitFlagColl->at(ihit); - - display_hit = 1; - if (fDisplayBackgroundHits == false) { - if (! hit_id_word->hasAllProperties(fGoodHitMask)) display_hit = 0; - if (hit_id_word->hasAnyProperty(fBadHitMask) ) display_hit = 0; - } - - if (display_hit) { - - //StrawHitMCTruth const& truth(hitsTruth.at(ihit)); - mcptr = &hits_mcptr->at(ihit); - - // Get the straw information: - straw = &tracker->getStraw( hit->strawId() ); - mid = &straw->getMidPoint(); - w = &straw->getDirection(); - - isFromConversion = false; - - nmc = mcptr->size(); - for (size_t j=0; jat(j); - art::Ptr const& simptr = step.simParticle(); - SimParticleCollection::key_type trackId(step.trackId()); - SimParticle const& sim = *simptr; - if ( sim.fromGenerator() ){ - GenParticle* gen = (GenParticle*) &(*sim.genParticle()); - if ( gen->generatorId().isConversion()){ - isFromConversion = true; - break; - } - } - } - - Hep3Vector pos(tt->positionAtZ( mid->z())); - Hep3Vector mom(tt->momentumAtZ( mid->z())); - TwoLinePCA pca(pos, mom.unit(), *mid, *w); - - Hep3Vector posMid(tmid->positionAtZ( mid->z() ) ); - Hep3Vector momMid(tmid->momentumAtZ( mid->z() ) ); - TwoLinePCA pcaMid(posMid, momMid.unit(), *mid, *w); - - // Position along wire, from delta t. - double wdist, wderr,halfpv; - bool vStatus = strawResponse.wireDistance( *straw, hit->energyDep(), hit->dt(), wdist, wderr,halfpv); - v=wdist; - sigv=wderr; - cout << "return status: " << vStatus << endl; - - if (fUseStereoHits) { -//----------------------------------------------------------------------------- -// new default, hit position errors come from StrawHitPositionCollection -//----------------------------------------------------------------------------- - sigv = hitpos->posRes(StrawHitPosition::wire); - sigr = hitpos->posRes(StrawHitPosition::trans); - } - else { -//----------------------------------------------------------------------------- -// old default, draw semi-random errors -//----------------------------------------------------------------------------- - //sigv is now set in the call to wireDistance - sigr = 5.; // in mm - } - - vx0 = (*mid) + v *(*w); - vx1 = vx0 + sigv*(*w); - vx2 = vx0 - sigv*(*w); - - intime = fabs(hit->time()-event_time) < timeWindow_; - - if ( isFromConversion ) { - if (intime) color = kRed; - else color = kBlue; - } - else color = kBlack; - - if ((isFromConversion) || (intime)) { - line->SetLineColor(color); - line->DrawLine( vx1.x(), vx1.y(), vx2.x(), vx2.y() ); - - line->DrawLine(vx0.x()+sigr*w->y(),vx0.y()-sigr*w->x(),vx0.x()-sigr*w->y(),vx0.y()+sigr*w->x()); - n_displayed_hits++; - } - } - } - -//----------------------------------------------------------------------------- -// Draw the generated hits. -//----------------------------------------------------------------------------- - if (xStep.size() <= 0) { - } - else { - graph = new TGraph( xStep.size(), &xStep[0], &yStep[0]); - graph->SetMarkerStyle(kOpenTriangleUp); - graph->SetMarkerSize(0.5); - graph->Draw("PSAME"); - } -//----------------------------------------------------------------------------- -// red marker and arrow: first point on the track. -//----------------------------------------------------------------------------- - double xf1 = pos1.x(); - double yf1 = pos1.y(); - TGraph genPoint( 1, &xf1, &yf1 ); - genPoint.SetMarkerColor(kRed); - genPoint.SetMarkerSize(1.0); - genPoint.SetMarkerStyle(kFullCircle); - genPoint.Draw("PSAME"); - - double arrowLength(200.); - double xf2 = xf1 + arrowLength*mom1.x()/mom1.perp(); - double yf2 = yf1 + arrowLength*mom1.y()/mom1.perp(); - arrow->SetLineColor(kRed); - arrow->DrawArrow( xf1, yf1, xf2, yf2, 0.01, ">"); - - double d0x = tt->d0x(); - double d0y = tt->d0y(); - double d0x2 = tt->d0x() + arrowLength*tt->u0(); - double d0y2 = tt->d0y() + arrowLength*tt->v0(); - - arrow->SetLineColor(kBlue); - arrow->DrawArrow(d0x, d0y, d0x2, d0y2, 0.01, ">"); -//----------------------------------------------------------------------------- -// blue cross - origin. -//----------------------------------------------------------------------------- - double xo = 0.; - double yo = 0.; - TGraph genPointo( 1, &xo, &yo ); - genPointo.SetMarkerColor(kBlue); - genPointo.SetMarkerSize(2.5); - genPointo.SetMarkerStyle(kPlus); - genPointo.Draw("PSAME"); - - fCanvas->Modified(); - fCanvas->Update(); - - printf("N(hits) = %5i, N(displayed hits): %5i\n",n_straw_hits,n_displayed_hits); - printf("number of clusters : %5i\n",fNClusters); - - char junk(0); - - if ( clickToAdvance_ ) { - cerr << "Double click in the Canvas " << moduleLabel_ << " to continue:" ; - gPad->WaitPrimitive(); - } - else{ - cerr << "Enter any character to continue: "; - cin >> junk; - } - cerr << endl; -//----------------------------------------------------------------------------- -// memory cleanup -//----------------------------------------------------------------------------- - list_of_ellipses.Delete(); - - if (tt) { - delete tt; - delete tg; - delete tmid; - } - - if (graph) delete graph; - - } // end of ::analyze. - -} - -using mu2e::HitDisplay; -DEFINE_ART_MODULE(HitDisplay); diff --git a/Analyses/src/NeutronCRV_module.cc b/Analyses/src/NeutronCRV_module.cc index b5462695c4..34198b7ca9 100644 --- a/Analyses/src/NeutronCRV_module.cc +++ b/Analyses/src/NeutronCRV_module.cc @@ -52,7 +52,6 @@ #include "MCDataProducts/inc/StatusG4.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "RecoDataProducts/inc/StrawHitCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" #include "TrackerGeom/inc/Straw.hh" #include "CosmicRayShieldGeom/inc/CRSScintillatorBar.hh" diff --git a/Analyses/src/PointerCheck_module.cc b/Analyses/src/PointerCheck_module.cc index f052060272..ec2c3f8aa4 100644 --- a/Analyses/src/PointerCheck_module.cc +++ b/Analyses/src/PointerCheck_module.cc @@ -450,12 +450,12 @@ namespace mu2e { int n,np,nn,na,ni; n=np=nn=na=ni=0; - std::vector > ptrs; + std::vector > ptrs; for(auto const& d: coll) { // loop over the collection n++; // assemble all the pointer in the object - ptrs.push_back(d.stepPointMC(StrawEnd::cal)); - ptrs.push_back(d.stepPointMC(StrawEnd::hv )); + ptrs.push_back(d.strawGasStep(StrawEnd::cal)); + ptrs.push_back(d.strawGasStep(StrawEnd::hv )); // check them for(auto const& p: ptrs) { np++; diff --git a/Analyses/src/ReadStrawHit_module.cc b/Analyses/src/ReadStrawHit_module.cc deleted file mode 100644 index efe51dcc08..0000000000 --- a/Analyses/src/ReadStrawHit_module.cc +++ /dev/null @@ -1,399 +0,0 @@ -// -// Plugin to test that I can read back the persistent data about straw hits. -// Also tests the mechanisms to look back at the precursor StepPointMC objects. -// -// Original author Rob Kutschke. Updated by Ivan Logashenko. -// Updated by KLG -// - -// C++ includes. -#include -#include -#include - -// Framework includes. -#include "art/Framework/Core/EDAnalyzer.h" -#include "art/Framework/Principal/Event.h" -#include "fhiclcpp/ParameterSet.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Services/Registry/ServiceHandle.h" -#include "art_root_io/TFileService.h" -#include "art_root_io/TFileDirectory.h" -#include "messagefacility/MessageLogger/MessageLogger.h" -#include "art/Framework/Principal/Provenance.h" -#include "canvas/Utilities/Exception.h" - -// Root includes. -#include "TFile.h" -#include "TH1F.h" -#include "TNtuple.h" - -// Mu2e includes. -#include "GeometryService/inc/GeometryService.hh" -#include "GeometryService/inc/GeomHandle.hh" -#include "TrackerGeom/inc/Tracker.hh" -#include "RecoDataProducts/inc/StrawHitCollection.hh" -#include "MCDataProducts/inc/StrawDigiMCCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "ConditionsService/inc/ConditionsHandle.hh" -#include "TrackerConditions/inc/StrawResponse.hh" - -using namespace std; - -namespace mu2e { - - //-------------------------------------------------------------------- - // - // - class ReadStrawHit : public art::EDAnalyzer { - public: - explicit ReadStrawHit(fhicl::ParameterSet const& pset); - - virtual void beginJob() override; - - void analyze( art::Event const& e) override; - - private: - - // Diagnostics level. - int _diagLevel; - - // Limit on number of events for which there will be full printout. - int _maxFullPrint; - - // Name of the tracker StepPoint collection - std::string _trackerStepPoints; - - // Label of the module that made the hits. - std::string _simModuleLabel, _recoModuleLabel; - - // Some reconstruction related data - double _minimumLength; - double _enableFlightTimeCorrection; - - // Some diagnostic histograms. - TH1F* _hHitTime; - TH1F* _hHitTime1; - TH1F* _hHitDeltaTime; - TH1F* _hHitAmplitude; - TH1F* _hHitEnergy; - TH1F* _hNHits; - TH1F* _hNHits1; - TH1F* _hNHitsPerWire; - TH1F* _hDriftTime; - TH1F* _hDriftDistance; - TH1F* _hDistanceToMid; - TH1F* _hFractionalDistanceToMid; - TH1F* _hNG4Steps; - TH1F* _hG4StepLength; - TH1F* _hG4StepEdep; - TH1F* _hG4StepRelTimes; - TNtuple* _ntup; - TNtuple* _detntup; - - // Tracker conditions object. - ProditionsHandle strawResponse_h; - - }; - - ReadStrawHit::ReadStrawHit(fhicl::ParameterSet const& pset): - art::EDAnalyzer(pset), - _diagLevel(pset.get("diagLevel",0)), - _maxFullPrint(pset.get("maxFullPrint",5)), - _trackerStepPoints(pset.get("trackerStepPoints","tracker")), - _simModuleLabel(pset.get("simModuleLabel")), - _recoModuleLabel(pset.get("recoModuleLabel")), - _minimumLength(pset.get("minimumLength",0.01)), // mm - _enableFlightTimeCorrection(pset.get("flightTimeCorrection",false)), - _hHitTime(0), - _hHitTime1(0), - _hHitDeltaTime(0), - _hHitAmplitude(0), - _hHitEnergy(0), - _hNHits(0), - _hNHits1(0), - _hNHitsPerWire(0), - _hDriftTime(0), - _hDriftDistance(0), - _hDistanceToMid(0), - _hFractionalDistanceToMid(0), - _hNG4Steps(0), - _hG4StepLength(0), - _hG4StepEdep(0), - _hG4StepRelTimes(0), - _ntup(0), - _detntup(0){ - } - - void ReadStrawHit::beginJob(){ - - if ( _diagLevel > 0 ) { - cout << "ReadStrawHit Diaglevel: " - << _diagLevel << " " - << _maxFullPrint - << endl; - } - - art::ServiceHandle tfs; - - _hHitTime = tfs->make( "hHitTime", "Hit Time (ns)", 200, 0., 2000. ); - _hHitTime1 = tfs->make( "hHitTime1", "Hit Time (ns)", 200, 0., 20000. ); - _hHitDeltaTime = tfs->make( "hHitDeltaTime", "Hit Delta Time (ns)", 80, -20.0, 20. ); - _hHitEnergy = tfs->make( "hHitEnergy", "Hit Energy (keV)", 100, 0., 100. ); - _hNHits = tfs->make( "hNHits", "Number of straw hits", 500, 0., 500. ); - _hNHits1 = tfs->make( "hNHits1", "Number of straw hits", 200, 0., 4000. ); - _hNHitsPerWire = tfs->make( "hNHitsPerWire", "Number of hits per straw", 10, 0., 10. ); - _hDriftTime = tfs->make( "hDriftTime", "Drift time, ns", 100, 0., 100. ); - _hDriftDistance= tfs->make( "hDriftDistance","Drift Distance, mm", 100, 0., 3. ); - _hDistanceToMid= tfs->make( "hDistanceToMid","Distance to wire center, mm", 160, -1600., 1600. ); - _hFractionalDistanceToMid - = tfs->make( "hFractionalDistanceToMid","(Distance to wire center)(half length of wire)", 100, -1., 1. ); - _hNG4Steps = tfs->make( "hNG4Steps", "Number of G4Steps per hit", 100, 0., 100. ); - _hG4StepLength = tfs->make( "hG4StepLength", "Length of G4Steps, mm", 100, 0., 10. ); - _hG4StepEdep = tfs->make( "hG4StepEdep", "Energy deposition of G4Steps, keV", 100, 0., 10. ); - _hG4StepRelTimes = tfs->make( "hG4StepRelTimes", "Hit Relative Times of G4Steps, ns", 100, -100., 100.); - - _ntup = tfs->make( "ntup", "Straw Hit ntuple", - "evt:lay:did:sec:hl:mpx:mpy:mpz:dirx:diry:dirz:time:dtime:eDep:driftT:driftDistance:distanceToMid:id:hitx:hity:hitz:fracDistanceToMid"); - _detntup = tfs->make( "detntup", "Straw ntuple", - "id:lay:did:sec:hl:mpx:mpy:mpz:dirx:diry:dirz"); - } - - void - ReadStrawHit::analyze(art::Event const& evt) { - - static int ncalls(0); - ++ncalls; - - // Geometry info for the Tracker. - const Tracker& tracker = *GeomHandle(); - - // Get the persistent data about the StrawHits. - - if (ncalls==1){ - const auto & allstraws = tracker.getStraws(); - float detnt[11]; - // for ( const auto & str : allstraws) - for (size_t i = 0; iFill(detnt); - } - } - - auto const& hits = *evt.getValidHandle(_recoModuleLabel); - ( _diagLevel > 0 ) && - std::cout << "ReadStrawHit: " - << __func__ << " getting data by getByLabel: label, instance, result " << std::endl - << "ReadStrawHit: StrawHitCollection _recoModuleLabel: " << _recoModuleLabel << endl; - - auto const& hits_SDtruth = *evt.getValidHandle(_simModuleLabel); - ( _diagLevel > 0 ) && - std::cout << "ReadStrawHit: " - << __func__ << " getting data by getByLabel: label, instance, result " << std::endl - << " ReadStrawHit: StrawDigiMCCollection _simModuleLabel: " << _simModuleLabel << endl; - - // Get the persistent data about pointers to StepPointMCs - auto const& hits_mcptr= *evt.getValidHandle(_simModuleLabel); - ( _diagLevel > 0 ) && - std::cout << "ReadStrawHit: " - << __func__ << " getting data by getByLabel: label, instance, result " << std::endl - << " ReadStrawHit: PtrStepPointMCVectorCollection _simModuleLabel: " << _simModuleLabel << endl; - - auto const& srep = strawResponse_h.get(evt.id()); - - // Fill histograms - _hNHits->Fill(hits.size()); - _hNHits1->Fill(hits.size()); - - std::map nhperwire; - - if ( _diagLevel > 2 ) { - cout << "ReadStrawHit: Total number of straw hits = " << hits.size() << endl; - } - - for ( size_t i=0; iFill(hit.time()); - _hHitTime1->Fill(hit.time()); - _hHitDeltaTime->Fill(hit.dt()); - _hHitEnergy->Fill(hit.energyDep()*1000.0); - - StrawId sid = hit.strawId(); - - // Use data from G4 hits - _hNG4Steps->Fill(mcptr.size()); - for( size_t j=0; jFill(mchit.stepLength()); - - // Fixme: correct for proton time map and muon time map. - //_hG4StepRelTimes->Fill((mchit.time()-hit.time())); - _hG4StepEdep->Fill(mchit.eDep()*1000.0); - } - - const unsigned id = sid.asUint16(); - Straw str = tracker.getStraw(sid); - int lid = sid.getLayer(); - int did = sid.getPlane(); - int secid = sid.getPanel(); - - double fracDist = SDtruth.distanceToMid(StrawEnd::cal)/str.halfLength(); - - // Use MC truth data - _hDriftTime->Fill(0.0); - _hDriftDistance->Fill(SDtruth.driftDistance(StrawEnd::cal)); - _hDistanceToMid->Fill(SDtruth.distanceToMid(StrawEnd::cal)); - _hFractionalDistanceToMid->Fill(fracDist); - - const CLHEP::Hep3Vector smidp = str.getMidPoint(); - const CLHEP::Hep3Vector sdir = str.getDirection(); - - // calculate the hit position - double dw, dwerr, halfpv; - srep.wireDistance(str,hit.energyDep(),hit.dt(),dw,dwerr,halfpv); - CLHEP::Hep3Vector pos = str.getMidPoint()+dw*str.getDirection(); - - // we may also need the truth hit position, do we need another function? - - // Fill the ntuple: - float nt[_ntup->GetNvar()]; - nt[0] = evt.id().event(); - nt[1] = lid; - nt[2] = did; - nt[3] = secid; - nt[4] = str.halfLength(); - nt[5] = smidp.getX(); - nt[6] = smidp.getY(); - nt[7] = smidp.getZ(); - nt[8] = sdir.getX(); - nt[9] = sdir.getY(); - nt[10] = sdir.getZ(); - nt[11] = hit.time(); - nt[12] = hit.dt(); - nt[13] = hit.energyDep(); - nt[14] = 0.0; - nt[15] = SDtruth.driftDistance(StrawEnd::cal); - nt[16] = SDtruth.distanceToMid(StrawEnd::cal); - nt[17] = id; - nt[18] = pos.getX(); - nt[19] = pos.getY(); - nt[20] = pos.getZ(); - nt[21] = fracDist; - - _ntup->Fill(nt); - - // Calculate number of hits per wire - ++nhperwire[hit.strawId()]; - - if ( int(evt.id().event()) < _maxFullPrint ) { - cout << "ReadStrawHit: " - << evt.id().event() << " #" - << sid << " " - << hit.time() << " " - << hit.dt() << " " - << hit.energyDep() << " " - << ( SDtruth.distanceToMid(StrawEnd::cal) ) << " |"; - for ( size_t j=0; j 2 ) { - for( size_t j=0; j::iterator it=nhperwire.begin(); it!= nhperwire.end(); ++it ) { - _hNHitsPerWire->Fill(it->second); - } - - } // end of ::analyze. - -} - - -using mu2e::ReadStrawHit; -DEFINE_ART_MODULE(ReadStrawHit); diff --git a/Analyses/src/SimParticlesWithHitsExample_module.cc b/Analyses/src/SimParticlesWithHitsExample_module.cc deleted file mode 100644 index f09e26bfae..0000000000 --- a/Analyses/src/SimParticlesWithHitsExample_module.cc +++ /dev/null @@ -1,123 +0,0 @@ -// -// Plugin to show how to use the SimParticlesWithHits class. -// -// $Id: SimParticlesWithHitsExample_module.cc,v 1.6 2013/10/21 21:13:18 kutschke Exp $ -// $Author: kutschke $ -// $Date: 2013/10/21 21:13:18 $ -// -// Original author Rob Kutschke. -// - -// C++ includes. -#include -#include - -// Framework includes. -#include "art/Framework/Core/EDAnalyzer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -// Mu2e includes. -#include "GeometryService/inc/GeomHandle.hh" -#include "TrackerGeom/inc/Tracker.hh" -#include "Mu2eUtilities/inc/SimParticlesWithHits.hh" - -using namespace std; - -namespace mu2e { - - class SimParticlesWithHitsExample : public art::EDAnalyzer { - public: - explicit SimParticlesWithHitsExample(fhicl::ParameterSet const& pset): - art::EDAnalyzer(pset), - _g4ModuleLabel(pset.get("g4ModuleLabel")), - _hitMakerModuleLabel(pset.get("hitMakerModuleLabel")), - _trackerStepPoints(pset.get("trackerStepPoints")), - _minEnergyDep(pset.get("minEnergyDep")), - _minHits(pset.get("minHits")){ - } - virtual ~SimParticlesWithHitsExample() { } - - void analyze( art::Event const& e ); - - private: - - // Label of the modules that created the data products. - std::string _g4ModuleLabel; - std::string _hitMakerModuleLabel; - - // Name of the tracker StepPoint collection - std::string _trackerStepPoints; - - // Cuts used inside SimParticleWithHits: - // - drop hits with too little energy deposited. - // - drop SimParticles with too few hits. - double _minEnergyDep; - size_t _minHits; - - }; - - void - SimParticlesWithHitsExample::analyze(art::Event const& evt ) { - - const Tracker& tracker = *GeomHandle(); - - // Construct an object that ties together all of the simulated particle and hit info. - SimParticlesWithHits sims( evt, - _g4ModuleLabel, - _hitMakerModuleLabel, - _trackerStepPoints, - _minEnergyDep, - _minHits ); - - typedef SimParticlesWithHits::map_type map_type; - // int n(0); - for ( map_type::const_iterator i=sims.begin(); - i != sims.end(); ++i ){ - - // All information about this SimParticle - SimParticleInfo const& simInfo = i->second; - - // Information about StrawHits that belong on this SimParticle. - vector const& infos = simInfo.strawHitInfos(); - - cout << "SimParticle: " - << " Event: " << evt.id().event() - << " Track: " << i->first - << " PdgId: " << simInfo.simParticle().pdgId() - << " |p|: " << simInfo.simParticle().startMomentum().vect().mag() - << " Hits: " << infos.size() - << endl; - - // Loop over all StrawsHits to which this SimParticle contributed. - for ( size_t j=0; j const& steps = info.steps(); - for ( size_t k=0; k -#include -#include - -using namespace std; -using CLHEP::Hep3Vector; - -namespace mu2e { - // simple structs - - class StrawEnergy : public art::EDAnalyzer { - public: - - explicit StrawEnergy(fhicl::ParameterSet const& pset); - virtual ~StrawEnergy() { } - - virtual void beginJob(); - virtual void endJob(); - - // This is called for each event. - virtual void analyze(const art::Event& e); - - private: - int _diagLevel; - std::string _makerModuleLabel,_mcdigislabel; - TTree* _estraw; -// branch variables - Int_t _plane, _panel, _layer, _straw; - Int_t _mcpdg, _mcgen, _mcproc; - Int_t _mcppdg; - XYZVec _mcpspos, _mcpsmom; - Float_t _mcpke, _mcptime; - Float_t _edep, _mce; - Float_t _hittime; - Float_t _strawx, _strawrho, _strawz; - // helper functions - art::Ptr findPrimary(StepPointMC const& mcstep) const; -}; - - - StrawEnergy::StrawEnergy(fhicl::ParameterSet const& pset) : - art::EDAnalyzer(pset), - // Run time parameters - _diagLevel(pset.get("diagLevel",0)), - _makerModuleLabel(pset.get("makerModuleLabel","makeSH")), - _mcdigislabel(pset.get("StrawHitMCLabel","makeSH")) - { - - } - - void StrawEnergy::beginJob(){ - // Get access to the TFile service. - art::ServiceHandle tfs; - _estraw=tfs->make("estraw","straw energy"); - _estraw->Branch("plane",&_plane,"plane/I"); - _estraw->Branch("panel",&_panel,"panel/I"); - _estraw->Branch("layer",&_layer,"layer/I"); - _estraw->Branch("straw",&_straw,"straw/I"); - _estraw->Branch("mcpdg",&_mcpdg,"mcpdg/I"); - _estraw->Branch("mcgen",&_mcgen,"mcgen/I"); - _estraw->Branch("mcproc",&_mcproc,"mcproc/I"); - _estraw->Branch("mce",&_mce,"mce/F"); - _estraw->Branch("mcppdg",&_mcppdg,"mcppdg/I"); - _estraw->Branch("mcpspos",&_mcpspos,"pspx/F:pspy/F:pspz/F"); - _estraw->Branch("mcpsmom",&_mcpsmom,"psmx/F:psmy/F:psmz/F"); - _estraw->Branch("mcpke",&_mcpke,"mcpke/F"); - _estraw->Branch("mcptime",&_mcptime,"mcptime/F"); - _estraw->Branch("edep",&_edep,"edep/F"); - _estraw->Branch("hittime",&_hittime,"hittime/F"); - _estraw->Branch("strawx",&_strawx,"strawx/F"); - _estraw->Branch("strawrho",&_strawrho,"strawrho/F"); - _estraw->Branch("strawz",&_strawz,"strawz/F"); - } - - void StrawEnergy::endJob(){ - } - - void StrawEnergy::analyze(const art::Event& event) { - GlobalConstantsHandle pdt; - const Tracker& tracker = *GeomHandle(); - - art::Handle pdataHandle; - event.getByLabel(_makerModuleLabel,pdataHandle); - StrawHitCollection const* hits = pdataHandle.product(); - - art::Handle mcdigisHandle; - event.getByLabel(_mcdigislabel,"StrawHitMC",mcdigisHandle); - StrawDigiMCCollection const* mcdigis = mcdigisHandle.product(); - - // Loop over all hits - for ( size_t ihit=0; ihitsize(); ++ihit ){ - - StrawHit const& hit(hits->at(ihit)); - _edep = hit.energyDep(); - _hittime = hit.time(); - // Get the hit poosition information. This requires MC truth - CLHEP::Hep3Vector mcpos; -// find MC truth information - StrawDigiMC const& mcdigi = mcdigis->at(ihit); - // use TDC channel 0 to define the MC match - StrawEnd itdc(StrawEnd::cal); - art::Ptr const& spmcp = mcdigi.stepPointMC(itdc); - art::Ptr const& spp = spmcp->simParticle(); - _mcpdg = spp->pdgId(); - _mcgen = -1; - if(spp->genParticle().isNonnull()) - _mcgen = spp->genParticle()->generatorId().id(); - _mcproc = spp->creationCode(); - _mce = mcdigi.energySum(); -// follow this StepPointMC SimParticle back to the 'primary', and record it's info - art::Ptr primary = findPrimary(*spmcp); - if(primary.isNonnull()){ - _mcppdg = primary->pdgId(); - _mcpsmom = primary->startMomentum(); - _mcpspos = primary->startPosition(); - mcpos = primary->startPosition(); - double mass = pdt->particle(primary->pdgId()).ref().mass(); - _mcpke = primary->startMomentum().e()-mass; - _mcptime = primary->startGlobalTime(); - } else { - _mcppdg = 0; - _mcpsmom = Hep3Vector(0.0,0.0,0.0); - _mcpspos = Hep3Vector(0.0,0.0,0.0); - mcpos = Hep3Vector(0.0,0.0,0.0); - _mcpke = 0.0; - _mcptime = 0.0; - } -// Get the straw information: - const Straw& straw = tracker.getStraw( hit.strawId() ); - _plane = straw.id().getPlane(); - _panel = straw.id().getPanel(); - _layer = straw.id().getLayer(); - _straw = straw.id().getStraw(); - const CLHEP::Hep3Vector& mid = straw.getMidPoint(); - const CLHEP::Hep3Vector& w = straw.getDirection(); -// define position using straw - _strawx = w.dot(mcpos-mid); - _strawrho = mid.perp(); - _strawz = mid.z(); -// fill the tree - _estraw->Fill(); - } - } - -// find the virtual detector hits and SimParticles for this event - art::Ptr - StrawEnergy::findPrimary(StepPointMC const& mcstep) const { - // start by finding the immediate parent - art::Ptr simp = mcstep.simParticle(); - // loop backwards until this is a primary - while(simp.isNonnull() && !simp->isPrimary()){ - simp = simp->parent(); - } - return simp; - } -} - -DEFINE_ART_MODULE(mu2e::StrawEnergy); diff --git a/Analyses/src/Summary01_module.cc b/Analyses/src/Summary01_module.cc deleted file mode 100644 index 92285aa822..0000000000 --- a/Analyses/src/Summary01_module.cc +++ /dev/null @@ -1,385 +0,0 @@ -// -// Plugin to show how to use the SimParticlesWithHits class. -// -// $Id: Summary01_module.cc,v 1.10 2013/10/21 20:44:04 genser Exp $ -// $Author: genser $ -// $Date: 2013/10/21 20:44:04 $ -// -// Original author Rob Kutschke. -// - -// C++ includes. -#include -#include -#include - -// Framework includes. -#include "art/Framework/Core/EDAnalyzer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "messagefacility/MessageLogger/MessageLogger.h" -#include "art_root_io/TFileService.h" - -// Mu2e includes. -#include "TrackerGeom/inc/Tracker.hh" -#include "Mu2eUtilities/inc/SimParticlesWithHits.hh" -#include "DataProducts/inc/PDGCode.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/PhysicalVolumeInfoCollection.hh" -#include "MCDataProducts/inc/StatusG4.hh" - -// ROOT includes -#include "TH1F.h" - -using namespace std; - -namespace mu2e { - - class Summary01 : public art::EDAnalyzer { - public: - explicit Summary01(fhicl::ParameterSet const& pset): - art::EDAnalyzer(pset), - g4ModuleLabel_(pset.get("g4ModuleLabel")), - strawHitMakerModuleLabel_(pset.get("strawHitMakerModuleLabel")), - trackerStepPoints_(pset.get("trackerStepPoints")), - calorimeterStepPoints_(pset.get("calorimeterStepPoints")), - calorimeterROStepPoints_(pset.get("calorimeterROStepPoints")), - crvStepPoints_(pset.get("crvStepPoints")), - minEnergyDep_(pset.get("minEnergyDep")), - minHits_(pset.get("minHits")), - simsPlotMax_(pset.get("simsPlotMax",400.)), - productionMode_(pset.get("productionMode",true)), - deltaRayParentId_(), - deltaRayVolumeId_(), - nBadG4_(0), - - // Histograms - hG4Status_(0), - hDeltaRayEKine0_(0), - hDeltaRayEKine1_(0), - hDeltaRayEKine2_(0), - hSimsSize_(0), - hTrkSimsSize_(0), - hCalSimsSize_(0), - hTrkSimsRatio_(0), - hCalSimsRatio_(0){ - } - virtual ~Summary01() { } - - void beginJob(); - void endJob(); - - void analyze( art::Event const& e ); - - void endRun( art::Run const& ); - - - private: - - // Label of the modules that created the data products. - std::string g4ModuleLabel_; - std::string strawHitMakerModuleLabel_; - - // Names of the interesting StepPoint collections. - std::string trackerStepPoints_; - std::string calorimeterStepPoints_; - std::string calorimeterROStepPoints_; - std::string crvStepPoints_; - - // Cuts used inside SimParticleWithHits: - // - drop hits with too little energy deposited. - // - drop SimParticles with too few hits. - double minEnergyDep_; - size_t minHits_; - - // Maximum size of the plots to study compression of the SimParticleCollection. - double simsPlotMax_; - - // If true then development code is turned off and verbosity is dropped. - bool productionMode_; - - std::map deltaRayParentId_; - std::map deltaRayVolumeId_; - - int nBadG4_; - - TH1F* hG4Status_; - - TH1F* hDeltaRayEKine0_; - TH1F* hDeltaRayEKine1_; - TH1F* hDeltaRayEKine2_; - - TH1F* hSimsSize_; - TH1F* hTrkSimsSize_; - TH1F* hCalSimsSize_; - TH1F* hTrkSimsRatio_; - TH1F* hCalSimsRatio_; - - void deltaRaySpectra( art::Event const& ); - void compressSims( art::Event const& ); - - }; - - void - Summary01::beginJob( ){ - - // Get access to the TFile service. - art::ServiceHandle tfs; - - hG4Status_ = tfs->make( "hG4Status", "Non-zero Values of G4 Status word", 40, 0., 40. ); - - hDeltaRayEKine0_ = tfs->make( "hDeltaRayEKine0", "Kinetic Energy of delta-ray;(MeV)", 100, 0., 100. ); - hDeltaRayEKine1_ = tfs->make( "hDeltaRayEKine1", "Kinetic Energy of delta-ray;(MeV)", 100, 0., 5. ); - hDeltaRayEKine2_ = tfs->make( "hDeltaRayEKine2", "Kinetic Energy of delta-ray;(MeV)", 100, 0., 0.05 ); - - - hSimsSize_ = tfs->make( "hSimsSize", "Size of SimParticleColleciton", 100, 0., simsPlotMax_ ); - hTrkSimsSize_ = tfs->make( "hTrkSimsSize", "SimParticleColleciton: size for non-Cal", 100, 0., simsPlotMax_ ); - hCalSimsSize_ = tfs->make( "hCalSimsSize", "SimParticleColleciton: size for all Hits", 100, 0., simsPlotMax_ ); - - // Make sure that 100% is in the plot. - hTrkSimsRatio_ = tfs->make( "hTrkSimsRatio", "SimParticleColleciton: Ratio for non-Cal", 101, 0., 1.01 ); - hCalSimsRatio_ = tfs->make( "hCalSimsRatio", "SimParticleColleciton: Ratio for all Hits", 101, 0., 1.01 ); - - } - - void - Summary01::analyze(art::Event const& event ) { - - // Skip event if G4 did not complete OK. - art::Handle g4StatusHandle; - event.getByLabel( g4ModuleLabel_, g4StatusHandle); - StatusG4 const& g4Status = *g4StatusHandle; - if ( g4Status.status() > 1 ){ - ++nBadG4_; - hG4Status_->Fill( g4Status.status() ); - mf::LogError("G4") - << "Summary01::analyze skipping event because of bad G4 status.\n" - << g4Status; - return; - } - - // Ask the event to give us a "handle" to the requested hits. - //art::Handle stepsHandle; - //event.getByLabel( g4ModuleLabel_, trackerStepPoints_,stepsHandle); - //StepPointMCCollection const& steps = *stepsHandle; - - //art::Handle simsHandle; - //event.getByLabel( g4ModuleLabel_, simsHandle); - //SimParticleCollection const& sims = *simsHandle; - - art::Handle volsHandle; - event.getRun().getByLabel( g4ModuleLabel_, volsHandle); - PhysicalVolumeInfoCollection const& vols = *volsHandle; - - // Fill plots of the spectra of delta rays. - deltaRaySpectra( event ); - compressSims( event ); - - // Stuff below here is under development. - if ( productionMode_ ) return; - - // Construct an object that ties together all of the simulated particle and hit info. - SimParticlesWithHits simsWithHits( event, - g4ModuleLabel_, - strawHitMakerModuleLabel_, - trackerStepPoints_, - minEnergyDep_, - minHits_ ); - - typedef SimParticlesWithHits::map_type map_type; - - for ( map_type::const_iterator i=simsWithHits.begin(); - i != simsWithHits.end(); ++i ){ - - // All information about this SimParticle - SimParticleInfo const& simInfo = i->second; - - // Information about StrawHits that belong on this SimParticle. - vector const& infos = simInfo.strawHitInfos(); - - if ( infos.size() > 5 && i->first != SimParticleCollection::key_type(1) ){ - - SimParticle const& sim = simInfo.simParticle(); - - cout << "SimParticle: " - << " Event: " << event.id().event() - << " Track: " << i->first - << " PdgId: " << sim.pdgId() - << " |p|: " << sim.startMomentum().vect().mag() - << " Hits: " << infos.size() - << " | " - << vols[sim.startVolumeIndex()] << " " - << vols[sim.endVolumeIndex()] - << endl; - } - - } - - } // end of ::analyze. - - void - Summary01::deltaRaySpectra( art::Event const& event ){ - - art::Handle simsHandle; - event.getByLabel( g4ModuleLabel_, simsHandle); - SimParticleCollection const& sims = *simsHandle; - - // Plot the energy spectrum of delta rays. - for ( SimParticleCollection::const_iterator i=sims.begin(); - i!=sims.end(); ++i ){ - SimParticle const& sim = i->second; - - if ( sim.pdgId() != PDGCode::e_minus ) continue; - if ( !sim.madeInG4() ) continue; - if ( sim.creationCode() != ProcessCode::eIoni ) continue; - - SimParticle const& parent = sims[sim.parentId()]; - if ( parent.pdgId() == PDGCode::gamma ) continue; - - // Kinetic energy - double ek = sim.startMomentum().e()-sim.startMomentum().restMass(); - - // Fill histograms - hDeltaRayEKine0_->Fill(ek); - hDeltaRayEKine1_->Fill(ek); - hDeltaRayEKine2_->Fill(ek); - - // Count how many delta rays came from each parent. - ++deltaRayParentId_[parent.pdgId()]; - - ++deltaRayVolumeId_[sim.startVolumeIndex()]; - } - - } // end Summary01::deltaRaySpectra - - - // Out of class utility function used in compressSims. - // Navigate from each StepPointMC back to the PrimaryGeneratorAction particle - // and mark each track along the way as being on the path to a hit. - void markChainToHit( map& used, - StepPointMCCollection const& steps, - SimParticleCollection const& sims ){ - - typedef SimParticleCollection::key_type key_type; - - for ( size_t i=0; ihasParent() ){ - key_type parentKey = sim->parentId(); - ++used[parentKey]; - sim = &sims[parentKey]; - } - } - } - - - // Investigate how much space we can save by compressing the SimParticleCollection. - void - Summary01::compressSims( art::Event const& event ){ - - art::Handle trkStepsHandle; - event.getByLabel( g4ModuleLabel_, trackerStepPoints_,trkStepsHandle); - StepPointMCCollection const& trkSteps = *trkStepsHandle; - - art::Handle calStepsHandle; - event.getByLabel( g4ModuleLabel_, calorimeterStepPoints_,calStepsHandle); - StepPointMCCollection const& calSteps = *calStepsHandle; - - art::Handle cROStepsHandle; - event.getByLabel( g4ModuleLabel_, calorimeterROStepPoints_,cROStepsHandle); - StepPointMCCollection const& cROSteps = *cROStepsHandle; - - art::Handle crvStepsHandle; - event.getByLabel( g4ModuleLabel_, calorimeterROStepPoints_,crvStepsHandle); - StepPointMCCollection const& crvSteps = *crvStepsHandle; - - art::Handle simsHandle; - event.getByLabel( g4ModuleLabel_, simsHandle); - SimParticleCollection const& sims = *simsHandle; - - // Count how often each track is on the path from - // a StepPointMC to a generated particle. - typedef SimParticleCollection::key_type key_type; - map used; - - // Contribution from tracker StepPointMCs. - markChainToHit( used, trkSteps, sims); - //size_t size1 = used.size(); - - // Contribution from CRV StepPointMCs. - markChainToHit( used, crvSteps, sims); - //size_t size2 = used.size(); - - // Contribution from calorimeter RO StepPointMCs. - markChainToHit( used, cROSteps, sims); - size_t size3 = used.size(); - - // Contribution from calorimeter crystal StepPointMCs. - // This is the big one. - markChainToHit( used, calSteps, sims); - size_t size4 = used.size(); - - // Fill histograms to document this. - size_t simsSize=sims.size(); - hSimsSize_->Fill(simsSize); - hTrkSimsSize_->Fill(size3); - hCalSimsSize_->Fill(size4); - hTrkSimsRatio_->Fill( double(size3)/double(simsSize)); - hCalSimsRatio_->Fill( double(size4)/double(simsSize)); - - } - - void Summary01::endRun( art::Run const& run ){ - - // Skip immature verbose printout. - if ( productionMode_ ) return; - - art::Handle volsHandle; - run.getByLabel( g4ModuleLabel_, volsHandle); - PhysicalVolumeInfoCollection const& vols = *volsHandle; - - cout << "\n Creation volumes of Delta Rays: " << endl; - for ( std::map::const_iterator i=deltaRayVolumeId_.begin(); - i !=deltaRayVolumeId_.end(); ++i ){ - cout << " Volume: " - << i->first << " " - << vols[i->first] << " " - << i->second - << endl; - } - - cout << "\n Parents of Delta Rays: " << endl; - for ( std::map::const_iterator i=deltaRayParentId_.begin(); - i !=deltaRayParentId_.end(); ++i ){ - cout << " " - << i->first << " " - << i->second - << endl; - } - - } // Summary01::endRun - - - void Summary01::endJob(){ - if ( nBadG4_ > 0 ){ - cout << "\nNumber of events with failed G4: " << nBadG4_ << endl; - } else{ - cout << "\nAll events completed G4 correctly" << endl; - } - } // end Summary01::endJob - -} - -using mu2e::Summary01; -DEFINE_ART_MODULE(Summary01); diff --git a/Analyses/src/TSig_module.cc b/Analyses/src/TSig_module.cc deleted file mode 100644 index faeee72b6b..0000000000 --- a/Analyses/src/TSig_module.cc +++ /dev/null @@ -1,642 +0,0 @@ -// -// A module to study background rates in the detector subsystems. -// -// $Id: TSig_module.cc,v 1.3 2014/09/03 15:51:18 knoepfel Exp $ -// $Author: knoepfel $ -// $Date: 2014/09/03 15:51:18 $ -// -// Original author G. Tassielli -// - -#include "CLHEP/Units/PhysicalConstants.h" -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "GeometryService/inc/GeomHandle.hh" -#include "GeometryService/inc/GeometryService.hh" -#include "MCDataProducts/inc/GenParticleCollection.hh" -#include "MCDataProducts/inc/PhysicalVolumeInfoCollection.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" -#include "MCDataProducts/inc/VisibleGenElTrack.hh" -#include "MCDataProducts/inc/VisibleGenElTrackCollection.hh" -#include "DataProducts/inc/VirtualDetectorId.hh" -#include "RecoDataProducts/inc/StrawHitCollection.hh" -#include "TFile.h" -#include "TNtuple.h" -#include "TrackerGeom/inc/Straw.hh" -#include "TrackerGeom/inc/Tracker.hh" -#include "art/Framework/Core/EDAnalyzer.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art_root_io/TFileDirectory.h" -#include "art_root_io/TFileService.h" -#include "art/Framework/Services/Registry/ServiceHandle.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Provenance.h" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" -#include "MCDataProducts/inc/StatusG4.hh" -#include "GeometryService/inc/VirtualDetector.hh" -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -namespace mu2e { - - class TSig : public art::EDAnalyzer { - public: - - explicit TSig(fhicl::ParameterSet const& pset): - art::EDAnalyzer(pset), - _diagLevel(pset.get("diagLevel",0)), - _trackerStepPoints(pset.get("trackerStepPoints","tracker")), - _swiresStepPoints(pset.get("swiresStepPoints","trackerSWires")), - _wallsStepPoints(pset.get("wallsStepPoints","trackerWalls")), - _makerModuleLabel(pset.get("makerModuleLabel")), - _generatorModuleLabel(pset.get("generatorModuleLabel", "generate")), - _g4ModuleLabel(pset.get("g4ModuleLabel", "g4run")), - _extractElectronsData(pset.get("elextractModuleLabel")), - _minimumEnergyTracker(pset.get("minimumEnergyTracker",0.0001)), // MeV - _vdStepPoints(pset.get("vdStepPoints","virtualdetector")), - _nAnalyzed(0), - _tNtup(0), - _nBadG4Status(0), - _nOverflow(0), - _nKilled(0), - _totalcputime(0), - _totalrealtime(0) - { - cout << "Module TSig is starting" << endl; - } - virtual ~TSig() { - } - virtual void beginJob(); - virtual void endJob(); - - void analyze(art::Event const& e ); - - fstream* wirestxt; - - private: - - void doTracker(art::Event const& evt); - - // Diagnostic level - int _diagLevel; - - // Name of the tracker StepPoint collection - std::string _trackerStepPoints; - std::string _swiresStepPoints; - std::string _wallsStepPoints; - - // Label of the module that made the hits. - std::string _makerModuleLabel; - - // Label of the generator. - std::string _generatorModuleLabel; - - // Label of the G4 module - std::string _g4ModuleLabel; - - // Label of the module that made the hits. - std::string _extractElectronsData; - - double _minimumEnergyTracker; //minimum energy deposition of hits - - - std::string _vdStepPoints; - - //number of analyzed events - int _nAnalyzed; - - TNtuple* _tNtup; - TTree* _tSingleWallData; - int _nHit; - double _wallEloss[1000]; - double _wallPath[1000]; - TTree* _tSingleCellData; - int _nCells; - double _cellEloss[1000]; - double _cellPath[1000]; - - int _nBadG4Status, _nOverflow, _nKilled; - float _totalcputime, _totalrealtime; - int _nVaribles; - - }; - - void TSig::beginJob( ) { - } - - void TSig::analyze(art::Event const& evt ) { - - ++_nAnalyzed; - - //*****test code****** - static int ncalls(0); - ++ncalls; - - art::Handle g4StatusHandle; - evt.getByLabel( _g4ModuleLabel, g4StatusHandle); - StatusG4 const& g4Status = *g4StatusHandle; - - if ( g4Status.status() > 1 ) { - ++_nBadG4Status; - mf::LogError("G4") - << "Aborting TSig::analyze due to G4 status\n" - << g4Status; - return; - } - - if (g4Status.overflowSimParticles()) { - ++_nOverflow; - mf::LogError("G4") - << "Aborting TSig::analyze due to overflow of particles\n" - << g4Status; - return; - } - - if (g4Status.nKilledStepLimit() > 0) { - ++_nKilled; - mf::LogError("G4") - << "Aborting TSig::analyze due to nkilledStepLimit reached\n" - << g4Status; - return; - } - - _totalcputime += g4Status.cpuTime(); - _totalrealtime += g4Status.realTime(); - - art::ServiceHandle geom; - - if (ncalls == 1) { - - // cout << "This should be done only in the first event" << endl; - - wirestxt = new fstream("HitWires.txt",ios::out); - - art::ServiceHandle tfs; - - std::string generalInfo ="evt:run:nCells:nCellsSig:eDep:eDepSig:firstSigP:lastSigP:SigTotPath:SigInChamberTotPath"; - std::string electLoopInfo =":SigNloop:SigFrstLoopNHits:SigFrstLoopPath:SigScndLoopNHits:SigScndLoopPath:SigTrdLoopNHits:SigTrdLoopPath"; - std::string hitSWireInfo =":hitSWires:stepInSWires:pathInSWires:eDepInSWires:hitSWiresSig:stepInSWiresSig:pathInSWiresSig:eDepInSWiresSig"; - std::string hitWallInfo =":hitWalls:stepInWalls:pathInWalls:eDepInWalls:hitWallsSig:stepInWallsSig:pathInWallsSig:eDepInWallsSig"; - std::string vdInfo =":enteringVd:enteringTime:enteringP:exitingVd:exitingTime:exitingP"; - _nVaribles = std::count(generalInfo.begin(), generalInfo.end(), ':')+1; - _nVaribles += std::count(electLoopInfo.begin(), electLoopInfo.end(), ':'); - _nVaribles += std::count(hitSWireInfo.begin(), hitSWireInfo.end(), ':'); - _nVaribles += std::count(hitWallInfo.begin(), hitWallInfo.end(), ':'); - _nVaribles += std::count(vdInfo.begin(), vdInfo.end(), ':'); - _tNtup = tfs->make( "CellHits", "Cell Ntuple", (generalInfo+electLoopInfo+hitSWireInfo+hitWallInfo+vdInfo).c_str() ); - - _tSingleWallData = tfs->make( "singleWallData", "Eloss for each Cell"); - _tSingleWallData->Branch("nHit",&_nHit,"_nHit/I"); - _tSingleWallData->Branch("wallEloss",_wallEloss,"_wallEloss[_nHit]/D"); - _tSingleWallData->Branch("wallPath",_wallPath,"_wallPath[_nHit]/D"); - - _tSingleCellData = tfs->make( "singleCellData", "Eloss for each Cell"); - _tSingleCellData->Branch("nCells",&_nCells,"_nCells/I"); - _tSingleCellData->Branch("cellEloss",_cellEloss,"_cellEloss[_nCells]/D"); - _tSingleCellData->Branch("cellPath",_cellPath,"_cellPath[_nCells]/D"); - - } - - doTracker(evt); - - } // end of analyze - - void TSig::endJob() { - - wirestxt->close(); - delete wirestxt; - - cout << "TSig::endJob Number of events skipped " - << "due to G4 completion status: " - << _nBadG4Status - << "\nTSig::endJob Number of overflow events " - << "due to too many particles in G4: " - << _nOverflow - << "\nTSig::endJob Number of events with killed particles " - << "due to too many steps in G4: " - << _nKilled - << "\nTSig::endJob total CpuTime " - << _totalcputime - << "\nTSig::endJob total RealTime " - << _totalrealtime - << endl; - } - - void TSig::doTracker(art::Event const& evt) { - - art::Handle pdataHandle; - evt.getByLabel(_makerModuleLabel,pdataHandle); - StrawHitCollection const* hits = pdataHandle.product(); - - // Get the persistent data about pointers to StepPointMCs - art::Handle mcptrHandle; - evt.getByLabel(_makerModuleLabel,"StrawHitMCPtr",mcptrHandle); - PtrStepPointMCVectorCollection const* hits_mcptr = mcptrHandle.product(); - - // Get handles to the generated and simulated particles. - art::Handle genParticles; - evt.getByLabel(_generatorModuleLabel, genParticles); - - art::Handle simParticles; - evt.getByLabel(_g4ModuleLabel, simParticles); - - // Handle to information about G4 physical volumes. - art::Handle volumes; - evt.getRun().getByLabel(_g4ModuleLabel, volumes); - - - //Handle to VD steps - art::Handle vdHits; - evt.getByLabel(_g4ModuleLabel,_vdStepPoints,vdHits); - - // Find original G4 steps in the wires; - art::Handle wShits; - evt.getByLabel(_g4ModuleLabel,_swiresStepPoints,wShits); - art::Handle wllhits; - evt.getByLabel(_g4ModuleLabel,_wallsStepPoints,wllhits); - - art::Handle genEltrksHandle; - evt.getByLabel(_extractElectronsData,genEltrksHandle); - VisibleGenElTrackCollection const* genEltrks = genEltrksHandle.product(); - - // cout << "event " << evt.id().event() << ": reading stuff" << endl; - - size_t nSWHits = wShits->size(); - size_t nWlHits = wllhits->size(); - - // Some files might not have the SimParticle and volume information. - bool haveSimPart = ( simParticles.isValid() && volumes.isValid() ); - - // Other files might have empty collections. - if ( haveSimPart ){ - haveSimPart = !(simParticles->empty() || volumes->empty()); - } - - size_t nCells = hits->size(); - - float nCellsSig(0); - double eDep(0), eDepSig(0); - - float *tntpArray = new float [_nVaribles]; - for (int iv=0; iv<_nVaribles; ++iv) { - tntpArray[iv]=0.0; - } - - // cout << "event " << evt.id().event() << ": first fills" << endl; - - int idx(0); - tntpArray[idx++] = evt.id().event(); //1 - tntpArray[idx++] = evt.run();//2 - - SimParticleCollection::key_type trackId; - // cout << "event " << evt.id().event() << ": looking at cells" << endl; - - double tempsigfirsttime = 10e9; - int jsigfirst = -1; - int isigfirst = -1; - double tempsiglasttime = -100; - int jsiglast = -1; - int isiglast = -1; - - bool *sigCellNotDone = new bool [nCells]; - for (size_t iscd=0; iscdat(i)); - PtrStepPointMCVector const& mcptr(hits_mcptr->at(i)); - - //Skip the straw if the energy of the hit is smaller than the minimum required - if (hit.energyDep() < _minimumEnergyTracker) continue; - - eDep += hit.energyDep(); - - //Find the first stepPointMC by time of flight - double temptime = 10e9; - size_t jfirst = 0; - for (size_t j = 0; j < mcptr.size(); ++j) { - if (mcptr[j]->time() < temptime) { - temptime = mcptr[j]->time(); - jfirst = j; - } - } - - if (sigCellNotDone[(int)nCellsSig]) { - _cellEloss[(int)nCellsSig]=0; - _cellPath[(int)nCellsSig]=0; - } - //Find the first sigstepPointMC by time of flight - for (size_t j = 0; j < mcptr.size(); ++j) { - if (simParticles->at(mcptr[j]->trackId()).fromGenerator() && simParticles->at(mcptr[j]->trackId()).pdgId()==11) { - if (mcptr[j]->time() < tempsigfirsttime) { - tempsigfirsttime = mcptr[j]->time(); - jsigfirst = j; - isigfirst = i; - } - - _cellEloss[(int)nCellsSig]+=mcptr[j]->eDep(); - _cellPath[(int)nCellsSig]+=mcptr[j]->stepLength(); - sigCellNotDone[(int)nCellsSig] = false; - - } - } - - //Find the last stepPointMC by time of flight - for (size_t j = 0; j < mcptr.size(); ++j) { - if (simParticles->at(mcptr[j]->trackId()).fromGenerator() && simParticles->at(mcptr[j]->trackId()).pdgId()==11) { - if (mcptr[j]->time() > tempsiglasttime) { - tempsiglasttime = mcptr[j]->time(); - jsiglast = j; - isiglast = i; - } - } - } - - // cout << "cell " << i << ": looking at first steppoint" << endl; - - StepPointMC const& mchit = *mcptr[jfirst]; - - // The simulated particle that made this hit. - trackId=mchit.trackId(); - SimParticle const& sim = simParticles->at(trackId); - if ( sim.fromGenerator() && sim.pdgId()==11 ) { - eDepSig += hit.energyDep(); - ++nCellsSig; - } - } - - tntpArray[idx++] = nCells; - tntpArray[idx++] = nCellsSig; - tntpArray[idx++] = eDep; - tntpArray[idx++] = eDepSig; - - _nCells=nCellsSig; - - if (jsigfirst != -1) { - PtrStepPointMCVector const& mcptrFirstV(hits_mcptr->at(isigfirst)); - PtrStepPointMCVector const& mcptrLastV(hits_mcptr->at(isiglast)); - tntpArray[idx++] = mcptrFirstV[jsigfirst]->momentum().mag(); - tntpArray[idx++] = mcptrLastV[jsiglast]->momentum().mag(); - } else { - tntpArray[idx++] = -10; - tntpArray[idx++] = -10; - } - if (genEltrks->size()>0) { - - for ( std::vector::const_iterator genEltrk_it = genEltrks->begin(); genEltrk_it!= genEltrks->end(); ++genEltrk_it ){ - VisibleGenElTrack &iEltrk = const_cast(*genEltrk_it); - if (iEltrk.getTrkID()==trackId) { - - // cout << "element 0 done. Go with the 1" << endl; - tntpArray[idx++] = iEltrk.getTotPath(); - // cout << "element 1 done. Go with the 2" << endl; - tntpArray[idx++] = iEltrk.getInChamberTotPath(); - // cout << "element 2 done. Go with the 3" << endl; - tntpArray[idx++] = iEltrk.getNumOfLoops(); - // cout << "element 3 done. Go with the 4" << endl; - // cout << "element 4 done. Go with the 5" << endl; - tntpArray[idx++] = iEltrk.getithLoopNHit(0); - // cout << "element 5 done. Go with the 6" << endl; - tntpArray[idx++] = iEltrk.getithLoopTOF(0)*CLHEP::c_light; - // cout << "element 6 done. Go with the 7" << endl; - tntpArray[idx++] = iEltrk.getithLoopNHit(1); - // cout << "element 7 done. Go with the 8" << endl; - tntpArray[idx++] = iEltrk.getithLoopTOF(1)*CLHEP::c_light; - // cout << "element 8 done. Go with the 9" << endl; - tntpArray[idx++] = iEltrk.getithLoopNHit(2); - // cout << "element 9 done. Go with the 10" << endl; - tntpArray[idx++] = iEltrk.getithLoopTOF(2)*CLHEP::c_light; - // cout << "Cool!" << endl; - } - } - } else { - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - } - - // float nHitWires(0); - - // cout << "event " << evt.id().event() << ": looking at wires" << endl; - if (nSWHits>0) { - - // cout << "Some sense wire has been hit!" << endl; - - size_t wSSteps = wShits->size(); - - // cout << "Precisely they are " << wSSteps << endl; - - float wSStepsSig(0); - - set wires, sigwires; - double totPathInWires(0.0), totPathInWiresSig(0.0); - double totEDepInWires(0.0), totEDepInWiresSig(0.0); - - for (size_t i=0; igetOrNull(trackId); - if( !sim ) continue; - wires.insert(whit.volumeId()); - totPathInWires+=whit.stepLength(); - totEDepInWires+=whit.eDep(); - *wirestxt << "Hit n. " << i+1 << " in the sense wire " << whit.volumeId() - << " made by " << sim->pdgId() << endl; - if (sim->isPrimary() && sim->pdgId()==11 /*sim->fromGenerator()*/) { - wSStepsSig++; - sigwires.insert(whit.volumeId()); - totPathInWiresSig+=whit.stepLength(); - totEDepInWiresSig+=whit.eDep(); - } - } - tntpArray[idx++] = wires.size(); - tntpArray[idx++] = nSWHits; - tntpArray[idx++] = totPathInWires; - tntpArray[idx++] = totEDepInWires; - tntpArray[idx++] = sigwires.size(); - tntpArray[idx++] = wSStepsSig; - tntpArray[idx++] = totPathInWiresSig; - tntpArray[idx++] = totEDepInWiresSig; - //_tNtup->Fill(tntpArray); - } else { - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - } - - - if (nWlHits>0) { - - // cout << "Some field wire has been hit!" << endl; - - size_t wlSteps = wllhits->size(); - - // cout << "Precisely they are " << wlSteps << endl; - - float wlStepsSig(0); - - set walls, sigwalls, prevSigwalls; - unsigned long old_wallId(0); - bool noFirstWall(false); - std::pair< set::iterator, bool > insertInSW; - double totPathInWalls(0.0), totPathInWallsSig(0.0); - double totEDepInWalls(0.0), totEDepInWallsSig(0.0); - size_t iHit=0; - _nHit=0; - - for (size_t i=0; igetOrNull(trackId); - if( !sim ) continue; - walls.insert(whit.volumeId()); - totPathInWalls+=whit.stepLength(); - totEDepInWalls+=whit.eDep(); - *wirestxt << "Hit n. " << i+1 << " in the wall " << whit.volumeId() - << " made by " << sim->pdgId() << endl; - if (sim->isPrimary() && sim->pdgId()==11 /*sim->fromGenerator()*/) { - //std::cout<<"sgn el strp in wall: "<Fill(tntpArray); - } else { - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - - _nHit=0; - } - - - - //Loop over vd hits - bool foundin = false; - bool foundout = false; - int vdIn(0), vdOut(0); - double pIn(0), pOut(0); - double intime = 1e15; - double outtime = -1e15; - size_t inIndex(0), outIndex(0); - // cout << "event " << evt.id().event() << ": looking at VD steps" << endl; - if (vdHits.isValid()) { - for (size_t i=0; isize(); ++i) { - const StepPointMC& hit = (*vdHits)[i]; - if (simParticles->at(hit.trackId()).fromGenerator()) { - int id = hit.volumeId(); - //if (id >= 40 && id <= 42) { - if (id == VirtualDetectorId::TT_InSurf|| - id==VirtualDetectorId::TT_FrontPA|| - id==VirtualDetectorId::TT_Back) { - if (hit.time() < intime) { - pIn = hit.momentum().mag(); - foundin = true; - vdIn = id; - inIndex = i; - intime = hit.time(); - } - if (hit.time() > outtime) { - pOut = hit.momentum().mag(); - foundout = true; - vdOut = id; - outIndex = i; - outtime = hit.time(); - } - } - } - } - } - - if (foundin && foundout && (inIndex!=outIndex) && (intime < outtime)) { - tntpArray[idx++] = vdIn; - tntpArray[idx++] = intime; - tntpArray[idx++] = pIn; - tntpArray[idx++] = vdOut; - tntpArray[idx++] = outtime; - tntpArray[idx++] = pOut; - } else { - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - tntpArray[idx++] = 0; - } - - - - - _tNtup->Fill(tntpArray); - _tSingleWallData->Fill(); - _tSingleCellData->Fill(); - - delete [] tntpArray; - - } // end of doTracker - -} - -using mu2e::TSig; -DEFINE_ART_MODULE(TSig); - diff --git a/CalPatRec/inc/ObjectDumpUtils.hh b/CalPatRec/inc/ObjectDumpUtils.hh index 9c72a54c4c..cf355a20f1 100644 --- a/CalPatRec/inc/ObjectDumpUtils.hh +++ b/CalPatRec/inc/ObjectDumpUtils.hh @@ -27,7 +27,6 @@ class KalRep; namespace mu2e { class StrawHit; // class StrawHitPosition; - class StrawHitMCTruth; class CaloCluster; class CaloProtoCluster; class StepPointMC; diff --git a/CalPatRec/src/CalHelixFinderDiag_tool.cc b/CalPatRec/src/CalHelixFinderDiag_tool.cc index 7561748951..dbc8e75209 100644 --- a/CalPatRec/src/CalHelixFinderDiag_tool.cc +++ b/CalPatRec/src/CalHelixFinderDiag_tool.cc @@ -15,8 +15,6 @@ #include "CalPatRec/inc/CalHelixFinder_types.hh" #include "Mu2eUtilities/inc/ModuleHistToolBase.hh" -#include "MCDataProducts/inc/StrawHitMCTruth.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "Mu2eUtilities/inc/SimParticleTimeOffset.hh" diff --git a/CalPatRec/src/DeltaFinderAna_module.cc b/CalPatRec/src/DeltaFinderAna_module.cc index 0b6d78bb4d..2ddbf532a0 100644 --- a/CalPatRec/src/DeltaFinderAna_module.cc +++ b/CalPatRec/src/DeltaFinderAna_module.cc @@ -45,10 +45,9 @@ #include #include #include "CLHEP/Vector/ThreeVector.h" +#include "MCDataProducts/inc/StrawGasStep.hh" #include "MCDataProducts/inc/StepPointMC.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruth.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" using namespace std; using CLHEP::Hep3Vector; @@ -584,7 +583,7 @@ namespace mu2e { const mu2e::StrawDigiMC* mcdigi = &_mcdigis->at(i); - const mu2e::StepPointMC *stmc; + const mu2e::StrawGasStep *stmc; if (mcdigi->wireEndTime(mu2e::StrawEnd::cal) < mcdigi->wireEndTime(mu2e::StrawEnd::hv)) { stmc = mcdigi->stepPointMC(mu2e::StrawEnd::cal).get(); } diff --git a/CalPatRec/src/ObjectDumpUtils.cc b/CalPatRec/src/ObjectDumpUtils.cc index 75c0dfd0b2..e6579cb393 100644 --- a/CalPatRec/src/ObjectDumpUtils.cc +++ b/CalPatRec/src/ObjectDumpUtils.cc @@ -29,10 +29,9 @@ #include "MCDataProducts/inc/GenParticleCollection.hh" #include "MCDataProducts/inc/SimParticle.hh" #include "MCDataProducts/inc/SimParticleCollection.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" #include "MCDataProducts/inc/StepPointMC.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruth.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" #include "MCDataProducts/inc/PhysicalVolumeInfo.hh" #include "MCDataProducts/inc/PhysicalVolumeInfoCollection.hh" @@ -301,13 +300,13 @@ void ObjectDumpUtils::printKalRep(const KalRep* Krep, const char* Opt, const cha if (_ListOfMCStrawHits) nstraws = _ListOfMCStrawHits->size(); - const mu2e::StepPointMC* step(0); + const mu2e::StrawGasStep* step(0); for (int i=0; iat(i); - const mu2e::StepPointMC *step; + const mu2e::StrawGasStep *step; if (mcdigi->wireEndTime(mu2e::StrawEnd::cal) < mcdigi->wireEndTime(mu2e::StrawEnd::hv)) { step = mcdigi->stepPointMC(mu2e::StrawEnd::cal).get(); } @@ -315,7 +314,8 @@ void ObjectDumpUtils::printKalRep(const KalRep* Krep, const char* Opt, const cha step = mcdigi->stepPointMC(mu2e::StrawEnd::hv ).get(); } - vol_id = step->volumeId(); +// vol_id = step->volumeId(); + vol_id = step->strawId().asUint16(); if (vol_id == straw->id().asUint16()) { // step found - use the first one in the straw break; @@ -328,11 +328,11 @@ void ObjectDumpUtils::printKalRep(const KalRep* Krep, const char* Opt, const cha const Hep3Vector* v1 = &straw->getMidPoint(); HepPoint p1(v1->x(),v1->y(),v1->z()); - const Hep3Vector* v2 = &step->position(); - HepPoint p2(v2->x(),v2->y(),v2->z()); + Hep3Vector v2 = step->position(); + HepPoint p2(v2.x(),v2.y(),v2.z()); TrkLineTraj trstraw(p1,straw->getDirection() ,0.,0.); - TrkLineTraj trstep (p2,step->momentum().unit(),0.,0.); + TrkLineTraj trstep (p2,Geom::Hep3Vec(step->momentum().unit()),0.,0.); TrkPoca poca(trstep, 0., trstraw, 0.); diff --git a/CalPatRec/src/PrefetchData_module.cc b/CalPatRec/src/PrefetchData_module.cc index 2ceabe9a76..fbceeb4886 100644 --- a/CalPatRec/src/PrefetchData_module.cc +++ b/CalPatRec/src/PrefetchData_module.cc @@ -36,8 +36,6 @@ #include "CLHEP/Vector/ThreeVector.h" #include "MCDataProducts/inc/StepPointMC.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruth.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" #include "Mu2eUtilities/inc/TwoLinePCA.hh" using namespace std; using CLHEP::Hep3Vector; diff --git a/CommonMC/src/SelectRecoMC_module.cc b/CommonMC/src/SelectRecoMC_module.cc index e6b2ec9481..ba234f59b3 100644 --- a/CommonMC/src/SelectRecoMC_module.cc +++ b/CommonMC/src/SelectRecoMC_module.cc @@ -286,7 +286,7 @@ namespace mu2e { const auto& mcstep = *(sdmc.earlyStepPointMC()); tshmc._cpos = Geom::toXYZVec(sdmc.clusterPosition(sdmc.earlyEnd())); tshmc._mom = mcstep.momentum(); - tshmc._time = fmod(_toff.timeWithOffsetsApplied(mcstep),_mbtime); + tshmc._time = fmod(mcstep.time(),_mbtime); tshmc._strawId = sdmc.strawId(); mcseed._tshmcs.push_back(tshmc); } @@ -301,7 +301,8 @@ namespace mu2e { auto const& spc = spcc[isp]; for (size_t isdmc=0; isdmc < sdmcc.size(); isdmc++){ auto const& sdmc = sdmcc[isdmc]; - if(sdmc.earlyStepPointMC()->simParticle() == spc._spp){ + auto const& mcstep = *(sdmc.earlyStrawGasStep()); + if(mcstep.simParticle() == spc._spp){ // search to see if the associated digi is already on the track bool used(false); for(auto const& tshmc : mcseed._tshmcs ) { @@ -316,10 +317,9 @@ namespace mu2e { tshmc._sdmcindex = isdmc; tshmc._spindex = isp; tshmc._energySum = sdmc.triggerEnergySum(sdmc.earlyEnd()); - const auto& mcstep = *(sdmc.earlyStepPointMC()); tshmc._cpos = Geom::toXYZVec(sdmc.clusterPosition(sdmc.earlyEnd())); tshmc._mom = mcstep.momentum(); - tshmc._time = fmod(_toff.timeWithOffsetsApplied(mcstep),_mbtime); + tshmc._time = sdmc.clusterTime(sdmc.earlyEnd()); tshmc._strawId = sdmc.strawId(); mcseed._tshmcs.push_back(tshmc); } diff --git a/CosmicReco/src/CosmicAnalyzer_module.cc b/CosmicReco/src/CosmicAnalyzer_module.cc index 25887a31b6..c35b43f603 100644 --- a/CosmicReco/src/CosmicAnalyzer_module.cc +++ b/CosmicReco/src/CosmicAnalyzer_module.cc @@ -836,7 +836,7 @@ CosmicTrackMCInfo CosmicAnalyzer::FitMC(const StrawDigiMCCollection*& _mcdigis){ StrawDigiMC first = (*_mcdigis)[0]; //Get StepPointMC: - art::Ptr const& spmcp0= first.stepPointMC(StrawEnd::cal); + auto const& spmcp0= first.stepPointMC(StrawEnd::cal); XYZVec pos0(spmcp0->position().x(), spmcp0->position().y(), spmcp0->position().z()); XYZVec dir0(spmcp0->momentum().x(), spmcp0->momentum().y(), spmcp0->momentum().z()); @@ -844,11 +844,11 @@ CosmicTrackMCInfo CosmicAnalyzer::FitMC(const StrawDigiMCCollection*& _mcdigis){ hitP1 = (*_mcdigis)[ich]; //Get StepPointMC: - art::Ptr const& spmcp = hitP1.stepPointMC(StrawEnd::cal); + auto const& spmcp = hitP1.stepPointMC(StrawEnd::cal); XYZVec posN(spmcp->position().x(), spmcp->position().y(), spmcp->position().z()); //Use Step Point MC direction as the True Axes: - XYZVec ZPrime = Geom::toXYZVec(spmcp->momentum().unit()); + XYZVec ZPrime = spmcp->momentum().unit(); //Store True Track details: TrackAxes TrueAxes = ParametricFit::GetTrackAxes(ZPrime); diff --git a/CosmicReco/src/CosmicMuonInfo_module.cc b/CosmicReco/src/CosmicMuonInfo_module.cc index 7f6ff74869..6586ea65ab 100644 --- a/CosmicReco/src/CosmicMuonInfo_module.cc +++ b/CosmicReco/src/CosmicMuonInfo_module.cc @@ -66,7 +66,6 @@ namespace mu2e { TH1D* _thetaMC = nullptr; TH1D* _phiMCcuts = nullptr; TH1D* _thetaMCcuts = nullptr; - TH1D* _driftDistance = nullptr; TH1D* _hNStrawHits = nullptr; TH1D* _hNPanelHits = nullptr; TH1D* _hUniquePanel = nullptr; @@ -147,7 +146,7 @@ namespace { auto const& sim_cal = digimc.stepPointMC(mu2e::StrawEnd::cal)->simParticle(); auto const& sim_hv = digimc.stepPointMC(mu2e::StrawEnd::cal)->simParticle(); if ( sim_cal == sim_hv ){ - double p = digimc.stepPointMC(mu2e::StrawEnd::cal)->momentum().mag(); + double p = sqrt(digimc.stepPointMC(mu2e::StrawEnd::cal)->momentum().mag2()); _bySim[digimc.stepPointMC(mu2e::StrawEnd::cal)->simParticle()].addIndex(++n,p); ++_sum; }else{ @@ -224,7 +223,6 @@ mu2e::CosmicMuonInfo::CosmicMuonInfo(fhicl::ParameterSet const& pset): art::ServiceHandle tfs; - _driftDistance = tfs->make( "Drift Distance", "Drift Distance", 100, -5, 5 ); _phiMC = tfs->make( "#phi_{MC}", "Angle #phi_{MC} of Muon MC tracks All", 100, -3.141529, 3.141529 ); _thetaMC = tfs->make( "#theta_{MC}", "Angle #theta_{MC} of Muon MC tracks All", 20, 0, 3.141529 ); _phiMCcuts = tfs->make( "#phi_after_cuts_{MC}", "Angle #phi_{MC} of Muon MC tracks after MC cuts", 100, -3.141529, 3.141529 ); @@ -305,11 +303,6 @@ bool mu2e::CosmicMuonInfo::filter(art::Event& event) { << endl; } - for(auto const& digi : *strawDigiMCs){ - double driftDistance = digi.driftDistance(mu2e::StrawEnd::cal); - _driftDistance->Fill(driftDistance); - - } _hnBadDigis->Fill( digisBySim.nBad() ); for ( auto const& combo : *comboHits ){ diff --git a/CosmicReco/src/CosmicTrackFinder_module.cc b/CosmicReco/src/CosmicTrackFinder_module.cc index 63342ede74..87184f6864 100644 --- a/CosmicReco/src/CosmicTrackFinder_module.cc +++ b/CosmicReco/src/CosmicTrackFinder_module.cc @@ -26,7 +26,6 @@ // MC data #include "MCDataProducts/inc/SimParticle.hh" #include "MCDataProducts/inc/StrawDigiMC.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" //MU2E: #include "RecoDataProducts/inc/StrawHitCollection.hh" #include "RecoDataProducts/inc/StrawHitPositionCollection.hh" @@ -72,14 +71,14 @@ namespace{ struct ycomp_digi : public std::binary_function { bool operator()(mu2e::StrawDigiMC const& p1, mu2e::StrawDigiMC const& p2) { - art::Ptr const& spmcp1 = p1.stepPointMC(mu2e::StrawEnd::cal); - art::Ptr const& spmcp2 = p2.stepPointMC(mu2e::StrawEnd::cal); + auto const& spmcp1 = p1.strawGasStep(mu2e::StrawEnd::cal); + auto const& spmcp2 = p2.strawGasStep(mu2e::StrawEnd::cal); return spmcp1->position().y() > spmcp2->position().y(); } }; //For MC StrawDigis: struct ycomp_MC : public std::binary_function { - bool operator()(art::Ptr const& spmcp1, art::Ptr const& spmcp2) { + bool operator()(art::Ptr const& spmcp1, art::Ptr const& spmcp2) { return spmcp1->position().y() > spmcp2->position().y(); } }; struct zcomp : public std::binary_function { @@ -254,8 +253,8 @@ namespace mu2e{ if(_mcdiag > 0 && _stResult._chHitsToProcess.size() > 0){ OrderHitsYMC(_stResult, event); for(auto const & mcd : _stResult._mcDigisToProcess){ - art::Ptr const& spmcp = mcd.stepPointMC(StrawEnd::cal); - XYZVec posN(spmcp->position().x(), spmcp->position().y(), spmcp->position().z()); + auto const& spmcp = mcd.strawGasStep(StrawEnd::cal); + XYZVec posN(spmcp->startPosition()); } diff --git a/Filters/src/CalibCosmicFilter_module.cc b/Filters/src/CalibCosmicFilter_module.cc deleted file mode 100644 index 185e9edb24..0000000000 --- a/Filters/src/CalibCosmicFilter_module.cc +++ /dev/null @@ -1,423 +0,0 @@ -// -// This module will take a set of products and re-write them -// after updating the Simparticle and StepPointMC art::Ptr's. -// The algorithm assumes there are only unique Simparticle -// numbers (keys), even if there are multiple collections. -// This is the case for production-style multi-stage jobs, -// but you can make a mess where this is not true. -// The main input, determining what should be saved is based on -// three collections: -// strawDigiMCs, caloShowerSteps, and CRV StepPointMC's -// this is a natural choice for calibration cosmics, but not -// very general. -// The rest of input is the SimParticle and StepPointMC collection -// tags of the collections to read, repoint the Ptr's, and write. -// Only certain products are implemented, since each product -// requires custom code. -// Optionally, you can filter based on the inputs. -// -// - -#include -#include -#include -#include -#include - -// art includes. -#include "fhiclcpp/ParameterSet.h" -#include "cetlib_except/exception.h" -#include "art/Framework/Core/EDFilter.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/SelectorBase.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "canvas/Persistency/Provenance/ProductID.h" -#include "canvas/Persistency/Common/Ptr.h" -// the products that can be re-written -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/SimParticlePtrCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/MCTrajectoryCollection.hh" -#include "MCDataProducts/inc/StrawDigiMCCollection.hh" -#include "MCDataProducts/inc/CaloShowerStepCollection.hh" -#include "MCDataProducts/inc/CaloShowerStepROCollection.hh" -#include "MCDataProducts/inc/CrvDigiMCCollection.hh" -#include "Mu2eUtilities/inc/compressSimParticleCollection.hh" - - -namespace mu2e { - - // a set of SimParticle numbers - typedef std::set::key_type> SPset; - - namespace { - // Adapter for compressSimParticleCollection() - class ParticleSelector { - public: - ParticleSelector(const SPset& m):spset(m) { } - bool operator[]( cet::map_vector_key key ) const { - return spset.find(key.asUint()) != spset.end(); - } - - private: - SPset spset; - }; - } // end namespace - - class CalibCosmicFilter : public art::EDFilter { - - typedef std::vector InputTags; - typedef std::vector VS; - - art::InputTag _SPtag; // the tracker StrawDigiMC collection - art::InputTag _trkDMCtag; // the tracker StrawDigiMC collection - art::InputTag _calCSStag; // the CaloShowerStep coll - art::InputTag _crvSPMCtag; // the CaloShowerStep coll - art::InputTag _crvDMCtag; // the CaloShowerStep coll - InputTags _copySPMC; // StepPointMCs to repoint - VS _copySPMCnames; // output names - InputTags _copyTraj; // Trajectories to repoint - VS _copyTrajNames; // output names - - public: - explicit CalibCosmicFilter(const fhicl::ParameterSet& pset); - virtual bool filter(art::Event& event) override; - virtual void endJob() override; - private: - std::size_t _minTrkDigis; - double _minCalEnergy; - std::size_t _minCrvSteps; - std::size_t _minCrvDigis; - int _verbose; - }; - - //================================================================ - CalibCosmicFilter::CalibCosmicFilter(const fhicl::ParameterSet& pset): - art::EDFilter{pset} - { - _trkDMCtag = art::InputTag(pset.get("strawDigiMCs","MakeSD")); - _calCSStag = art::InputTag(pset.get("caloShowerSteps", - "CaloShowerStepFromStepPt")); - _crvSPMCtag = art::InputTag(pset.get("crvSteps","")); - _crvDMCtag = art::InputTag(pset.get("crvDigiMCs","")); - // will need to re-write these collections - produces(_trkDMCtag.instance()); - produces(_calCSStag.instance()); - if(_crvDMCtag!="") { - produces(_crvDMCtag.instance()); - } - - // new filtered SimParticle collection - produces(""); - - VS slist; - - // lists of StepPointMC collections to copy and re-point - slist = pset.get("copyHits",VS()); - for(auto const& i: slist) _copySPMC.emplace_back(art::InputTag(i)); - _copySPMCnames = pset.get("copyHitsNames",VS()); - for(auto const& i:_copySPMCnames) produces(i); - - if (slist.size() != _copySPMCnames.size()) { - throw cet::exception("BADCONFIG") << "the number of collections" - << " in copyHits and copyHitsNames must be the same\n"; - } - - // lists of MCTrajectory collections to copy and re-point - slist = pset.get("copyTrajs",VS()); - for(auto const& i: slist) _copyTraj.emplace_back(art::InputTag(i)); - _copyTrajNames = pset.get("copyTrajsNames",VS()); - for(auto const& i:_copyTrajNames) produces(i); - - if (slist.size() != _copyTrajNames.size()) { - throw cet::exception("BADCONFIG") << "the number of collections" - << " in copyTrajs and copyTrajsNames must be the same\n"; - } - - // filter requirements - _minTrkDigis = pset.get("minTrkDigis",0); - _minCalEnergy = pset.get("minCalEnergy",-1.0); - _minCrvSteps = pset.get("minCrvSteps",0); - _minCrvDigis = pset.get("minCrvDigis",0); - - _verbose = pset.get("verbose",0); - - } - - //================================================================ - bool CalibCosmicFilter::filter(art::Event& event) { - - bool passed = false; - - auto trkDMC = - event.getValidHandle(_trkDMCtag); - auto calCSS = - event.getValidHandle(_calCSStag); - auto simPh = - event.getValidHandle("g4run"); - auto const& simP = *simPh; - - // compute filtering result - if(trkDMC->size()>=_minTrkDigis) passed = true; - - double energy = 0; - for(auto const& s: *calCSS) energy += s.energyMC(); - if(energy>=_minCalEnergy) passed = true; - - int ncrvSPMC = 0; - if(_crvSPMCtag!="") { - auto crvSPMC = event.getValidHandle(_crvSPMCtag); - if(crvSPMC->size()>=_minCrvSteps) passed = true; - ncrvSPMC = crvSPMC->size(); - } - - int ncrvDMC = 0; - if(_crvDMCtag!="") { - auto crvDMC = event.getValidHandle(_crvDMCtag); - if(crvDMC->size()>=_minCrvDigis) passed = true; - ncrvDMC = crvDMC->size(); - } - - if(_verbose>3) { std::cout - << "CalibCosmicFilter results of filtering:" << std::endl - << " trk hits: " << std::setw(4) << trkDMC->size() - << " cut:" << std::setw(4) << _minTrkDigis << std::endl - << " cal energy: " - << std::setw(9) << std::setprecision(3) << energy - << " cut:" - << std::setw(9) << std::setprecision(3) << _minCalEnergy << std::endl - << " crv steps: " << std::setw(4) << ncrvSPMC - << " cut:" << std::setw(4) << _minCrvSteps << std::endl - << " crv digis: " << std::setw(4) << ncrvDMC - << " cut:" << std::setw(4) << _minCrvDigis << std::endl - << " passed: " << passed << std::endl; - } - - //************* make the list of saved SimParticles - SPset SPsave; // std::set of SP keys - - // save SimParticles from tracker StrawDigiMC - for(auto const& sd : *trkDMC) { // loop over StrawDigiMC - SPsave.insert(sd.stepPointMC(StrawEnd::cal)->simParticle().key()); - SPsave.insert(sd.stepPointMC(StrawEnd::hv )->simParticle().key()); - } - if(_verbose>5) std::cout - << "CalibCosmicFilter SimParticles saved after tracker " - << SPsave.size() << std::endl; - - // save the SimParticles pointed to by the CaloShowerSteps - for(auto const& s: *calCSS) SPsave.insert(s.simParticle().key()); - if(_verbose>5) std::cout - << "CalibCosmicFilter SimParticles saved after cal " - << SPsave.size() << std::endl; - - // save SimParticles for CRV - if(_crvDMCtag!="") { - auto crvDMC = event.getValidHandle(_crvDMCtag); - for(auto const& cd : *crvDMC) { - // CrvDigiMC SimParticle may be null - if(cd.GetSimParticle().isAvailable()) { - SPsave.insert(cd.GetSimParticle().key()); - } - for(auto const& s: cd.GetStepPoints()) { - // CrvDigiMC SPMC may be null - if(s.isAvailable()) { - SPsave.insert(s->simParticle().key()); - } - } - } - if(_verbose>5) std::cout - << "CalibCosmicFilter SimParticles saved after CrvDigis " - << SPsave.size() << std::endl; - } - - // save the SimParticles pointed to by SPMcs - for(auto const& tag: _copySPMC) { // loop over string of input tags - auto h = event.getValidHandle(tag); - for(auto const& i : *h) { // loop over the SPMC - SPsave.insert(i.simParticle().key()); - } - } - if(_verbose>5) std::cout - << "CalibCosmicFilter SimParticles saved after copyHits " - << SPsave.size() << std::endl; - - // save the SimParticles pointed to by MCTrajectory - for(auto const& tag: _copyTraj) { // loop over string of input tags - auto h = event.getValidHandle(tag); - for(auto const& i : *h) { // loop over the SPMC - SPsave.insert(i.first.key()); - } - } - if(_verbose>5) std::cout - << "CalibCosmicFilter SimParticles saved after trajHits " - << SPsave.size() << std::endl; - - // save parents of saved SimParticles - auto tempSave = SPsave; - for(const auto& iid : tempSave) { - auto ptr = simP.find(cet::map_vector_key(iid))->second.parent(); - while(ptr.isNonnull()) { - SPsave.insert(ptr.key()); - ptr = ptr->parent(); - } - } - if(_verbose>5) std::cout - << "CalibCosmicFilter SimParticles saved after parents " - << SPsave.size() << std::endl; - - //********** write filtered output collection of SimParticles - - // these are needed to set the art::Ptrs - // create map of old SimP to new SimP - auto SPpid = event.getProductID(""); - auto SPpg = event.productGetter(SPpid); - // make a set of new SimParticle art pointers for use later - // save in a map that converts a key to an art::Ptr - std::map> SPPtrmap; - for(auto const& i : SPsave) { // list of saved SimParticle keys - SPPtrmap[i] = art::Ptr(SPpid,i,SPpg); - } - // add that null goes to null for CRV - SPPtrmap[-1] = art::Ptr(); - - std::unique_ptr - outSPp(new mu2e::SimParticleCollection()); - auto& outSP = *outSPp; - - ParticleSelector sel(SPsave); - compressSimParticleCollection(SPpid, SPpg, simP, sel, outSP); - - if(_verbose>5) std::cout - << "CalibCosmicFilter SimParticles written " - << outSP.size() << std::endl; - - // write out the new SimParticle collection - event.put(std::move(outSPp), ""); - - //***************** write the rest of the re-pointed collections - - //re-write StepPointMC collections - // big translation map, will need it later - std::map,art::Ptr> SPMCmap; - - for(std::size_t i=0; i<_copySPMC.size(); i++) { // loop input tags - auto pid = event.getProductID(_copySPMCnames[i]); - auto pg = event.productGetter(pid); - - std::unique_ptr - outSPMCp(new mu2e::StepPointMCCollection()); - auto h = event.getValidHandle(_copySPMC[i]); - size_t j = 0; - for(auto const& hit : *h) { // loop over the SPMC - outSPMCp->emplace_back(hit); // copy hit - outSPMCp->back().simParticle() = - SPPtrmap[hit.simParticle().key()]; // update Ptr - // save Ptr translation - SPMCmap[art::Ptr(h,j)] = art::Ptr(pid,j,pg); - j++; - } - // add a null goes to null for CRV - SPMCmap[art::Ptr()] = art::Ptr(); - - if(_verbose>5) std::cout - << "CalibCosmicFilter StepPointMCs written " - << _copySPMCnames[i] << " " - << outSPMCp->size() << std::endl; - - event.put(std::move(outSPMCp), _copySPMCnames[i]); - } - - //re-write MCTrajectory collections - for(std::size_t i=0; i<_copyTraj.size(); i++) { // loop over input tags - std::unique_ptr - outTrajp(new mu2e::MCTrajectoryCollection()); - auto& outTraj = *outTrajp; - auto h = event.getValidHandle(_copyTraj[i]); - for(auto const& trp : *h) { // loop over the SPMC - // trajectory coll is a map of art ptr and traj - outTraj[ SPPtrmap[trp.first.key()] ] = trp.second; - outTraj[ SPPtrmap[trp.first.key()] ].sim() = SPPtrmap[trp.first.key()]; - } - - if(_verbose>5) std::cout - << "CalibCosmicFilter MCTrajectory written " - << _copyTrajNames[i] << " " - << outTrajp->size() << std::endl; - - event.put(std::move(outTrajp), _copyTrajNames[i]); - } - - //re-write StrawDigiMC collection - std::unique_ptr - outDMCp(new mu2e::StrawDigiMCCollection()); - auto& outDMC = *outDMCp; - art::Ptr stepMC[2]; - for(auto d: *trkDMC) { - stepMC[StrawEnd::cal] = SPMCmap[d.stepPointMC(StrawEnd::cal)]; - stepMC[StrawEnd::hv ] = SPMCmap[d.stepPointMC(StrawEnd::hv )]; - outDMC.push_back( mu2e::StrawDigiMC(d, stepMC) ); - } // loop over digis - - if(_verbose>5) std::cout - << "CalibCosmicFilter StrawDigiMC written " - << _trkDMCtag.instance() << " " - << outDMCp->size() << std::endl; - - event.put(std::move(outDMCp), _trkDMCtag.instance()); - - - //re-write CaloShowerStep collection - already have handle to old - std::unique_ptr - outCSSp(new mu2e::CaloShowerStepCollection()); - auto& outCSS = *outCSSp; - for(auto c: *calCSS) { - outCSS.push_back(c); - outCSS.back().setSimParticle(SPPtrmap[c.simParticle().key()]); - } // loop over steps - - if(_verbose>5) std::cout - << "CalibCosmicFilter CaloShowerStep written " - << _calCSStag.instance() << " " - << outCSSp->size() << std::endl; - - event.put(std::move(outCSSp), _calCSStag.instance()); - - - //re-write CrvDigiMC collection - if(_crvDMCtag!="") { - std::unique_ptr - outCrvDMCp(new mu2e::CrvDigiMCCollection()); - auto& outCrvDMC = *outCrvDMCp; - - auto crvDMC = event.getValidHandle(_crvDMCtag); - std::vector > stepMCs; - for(auto d: *crvDMC) { - stepMCs.clear(); - for(auto i:d.GetStepPoints()) stepMCs.push_back(SPMCmap[i]); - outCrvDMC.push_back( mu2e::CrvDigiMC( - d.GetVoltages(),stepMCs,SPPtrmap[d.GetSimParticle().key()], - d.GetStartTime(),d.GetScintillatorBarIndex(),d.GetSiPMNumber()) ); - } // loop over digis - - if(_verbose>5) std::cout - << "CalibCosmicFilter CrvDigiMC written " - << _crvDMCtag.instance() << " " - << outCrvDMCp->size() << std::endl; - - event.put(std::move(outCrvDMCp), _crvDMCtag.instance()); - } - - return passed; - - } - - //================================================================ - void CalibCosmicFilter::endJob() { - } - - //================================================================ -} // namespace mu2e - -DEFINE_ART_MODULE(mu2e::CalibCosmicFilter); diff --git a/Filters/src/CompressDigiMCs_module.cc b/Filters/src/CompressDigiMCs_module.cc index 72383cef7a..467fcbcf2a 100644 --- a/Filters/src/CompressDigiMCs_module.cc +++ b/Filters/src/CompressDigiMCs_module.cc @@ -34,6 +34,7 @@ #include "MCDataProducts/inc/CaloShowerStepROCollection.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" #include "MCDataProducts/inc/SimParticleCollection.hh" #include "Mu2eUtilities/inc/compressSimParticleCollection.hh" #include "MCDataProducts/inc/GenParticleCollection.hh" @@ -80,6 +81,7 @@ namespace mu2e { typedef std::string InstanceLabel; typedef std::map KeyRemap; typedef std::map, art::Ptr > StepPointMCRemap; + typedef std::map, art::Ptr > StrawGasStepRemap; } @@ -102,6 +104,7 @@ class mu2e::CompressDigiMCs : public art::EDProducer { void copyStrawDigiMC(const mu2e::StrawDigiMC& old_straw_digi_mc); void copyCrvDigiMC(const mu2e::CrvDigiMC& old_crv_digi_mc); art::Ptr copyStepPointMC(const mu2e::StepPointMC& old_step, const InstanceLabel& instance); + art::Ptr copyStrawGasStep(const mu2e::StrawGasStep& old_step); art::Ptr copyCaloShowerStep(const mu2e::CaloShowerStep& old_calo_shower_step); void copyCaloShowerSim(const mu2e::CaloShowerSim& old_calo_shower_sim, const CaloShowerStepRemap& remap); void copyCaloShowerStepRO(const mu2e::CaloShowerStepRO& old_calo_shower_step_ro, const CaloShowerStepRemap& remap); @@ -135,6 +138,7 @@ class mu2e::CompressDigiMCs : public art::EDProducer { std::unique_ptr _newStrawDigiMCs; std::unique_ptr _newCrvDigiMCs; std::map > _newStepPointMCs; + std::unique_ptr _newStrawGasSteps; std::unique_ptr _newSimParticles; std::unique_ptr _newGenParticles; std::vector > _newSimParticleTimeMaps; @@ -145,6 +149,8 @@ class mu2e::CompressDigiMCs : public art::EDProducer { // for StepPointMCs, SimParticles and GenParticles we also need reference their new locations with art::Ptrs and so need their ProductIDs and Getters std::map _newStepPointMCsPID; std::map _newStepPointMCGetter; + art::ProductID _newStrawGasStepsPID; + const art::EDProductGetter* _newStrawGasStepGetter; art::ProductID _newSimParticlesPID; const art::EDProductGetter* _newSimParticleGetter; art::ProductID _newGenParticlesPID; @@ -156,7 +162,6 @@ class mu2e::CompressDigiMCs : public art::EDProducer { // record the SimParticles that we are keeping so we can use compressSimParticleCollection to do all the work for us std::map _simParticlesToKeep; - InstanceLabel _trackerOutputInstanceLabel; InstanceLabel _crvOutputInstanceLabel; std::vector _newStepPointMCInstances; @@ -200,7 +205,6 @@ mu2e::CompressDigiMCs::CompressDigiMCs(fhicl::ParameterSet const & pset) _caloShowerStepTags(pset.get >("caloShowerStepTags")), _caloShowerSimTag(pset.get("caloShowerSimTag")), _caloShowerStepROTag(pset.get("caloShowerStepROTag")), - _trackerOutputInstanceLabel(pset.get("trackerOutputInstanceLabel", "tracker")), _crvOutputInstanceLabel(pset.get("crvOutputInstanceLabel", "CRV")), _strawDigiMCIndexMapTag(pset.get("strawDigiMCIndexMapTag", "")), _crvDigiMCIndexMapTag(pset.get("crvDigiMCIndexMapTag", "")), @@ -215,7 +219,6 @@ mu2e::CompressDigiMCs::CompressDigiMCs(fhicl::ParameterSet const & pset) produces(); produces(); - _newStepPointMCInstances.push_back(_trackerOutputInstanceLabel); // will always be a tracker and CRV instance _newStepPointMCInstances.push_back(_crvOutputInstanceLabel); // filled with the StepPointMCs referenced by their DigiMCs for (std::vector::const_iterator i_tag = _extraStepPointMCTags.begin(); i_tag != _extraStepPointMCTags.end(); ++i_tag) { _newStepPointMCInstances.push_back( (*i_tag).instance() ); @@ -224,7 +227,7 @@ mu2e::CompressDigiMCs::CompressDigiMCs(fhicl::ParameterSet const & pset) for (const auto& i_instance : _newStepPointMCInstances) { produces( i_instance ); } - + produces(); produces(); produces(); @@ -651,43 +654,26 @@ void mu2e::CompressDigiMCs::produce(art::Event & event) void mu2e::CompressDigiMCs::copyStrawDigiMC(const mu2e::StrawDigiMC& old_straw_digi_mc) { - StepPointMCRemap step_remap; + StrawGasStepRemap step_remap; // Need to update the Ptrs for the StepPointMCs - art::Ptr newTriggerStepPtr[StrawEnd::nends]; + StrawDigiMC::SGSPA newTriggerStepPtr; for(int i_end=0;i_end(i_end); - const art::Ptr& old_step_point = old_straw_digi_mc.stepPointMC(end); + const auto& old_step_point = old_straw_digi_mc.stepPointMC(end); const auto& newStepPtrIter = step_remap.find(old_step_point); if (newStepPtrIter == step_remap.end()) { if (old_step_point.isAvailable()) { - step_remap[old_step_point] = copyStepPointMC( *old_step_point, _trackerOutputInstanceLabel ); + step_remap[old_step_point] = copyStrawGasStep( *old_step_point); } else { // this is a null Ptr but it should be added anyway to keep consistency (not expected for StrawDigis) step_remap[old_step_point] = old_step_point; } } - art::Ptr new_step_point = step_remap.at(old_step_point); + art::Ptr new_step_point = step_remap.at(old_step_point); newTriggerStepPtr[i_end] = new_step_point; } - -// std::vector > newWaveformStepPtrs; -// for (const auto& i_step_mc : old_straw_digi_mc.stepPointMCs()) { -// const auto& newStepPtrIter = step_remap.find(i_step_mc); -// if (newStepPtrIter == step_remap.end()) { -// if (i_step_mc.isAvailable()) { -// step_remap[i_step_mc] = copyStepPointMC( *i_step_mc, _trackerOutputInstanceLabel ); -// } -// else { // this is a null Ptr but it should be added anyway to keep consistency (not expected for StrawDigis) -// step_remap[i_step_mc] = i_step_mc; -// } -// } -// art::Ptr new_step_point = step_remap.at(i_step_mc); -// newWaveformStepPtrs.push_back(new_step_point); -// } - -// StrawDigiMC new_straw_digi_mc(old_straw_digi_mc, newTriggerStepPtr, newWaveformStepPtrs); // copy everything except the Ptrs from the old StrawDigiMC StrawDigiMC new_straw_digi_mc(old_straw_digi_mc, newTriggerStepPtr); // copy everything except the Ptrs from the old StrawDigiMC _newStrawDigiMCs->push_back(new_straw_digi_mc); } @@ -805,6 +791,16 @@ art::Ptr mu2e::CompressDigiMCs::copyStepPointMC(const mu2e::S return art::Ptr(_newStepPointMCsPID.at(instance), _newStepPointMCs.at(instance)->size()-1, _newStepPointMCGetter.at(instance)); } +art::Ptr mu2e::CompressDigiMCs::copyStrawGasStep(const mu2e::StrawGasStep& old_step) { + + keepSimParticle(old_step.simParticle()); + + StrawGasStep new_step(old_step); + _newStrawGasSteps->push_back(new_step); + + return art::Ptr(_newStrawGasStepsPID, _newStrawGasSteps->size()-1, _newStrawGasStepGetter); +} + void mu2e::CompressDigiMCs::keepSimParticle(const art::Ptr& sim_ptr) { // Also need to add all the parents too diff --git a/Filters/src/HitsInConversionTimeWindow_module.cc b/Filters/src/HitsInConversionTimeWindow_module.cc deleted file mode 100644 index 51894c8f4b..0000000000 --- a/Filters/src/HitsInConversionTimeWindow_module.cc +++ /dev/null @@ -1,670 +0,0 @@ -// -// This is not yet general purpose code; it still contains some elements that are -// specific to the job of selecting subsets of events for use in the event displays -// shown at the December 2011 PAC meeting. -// -// Find the conversion electron and all StrawHits to which it contributes. -// Select all StrawHits in a time window around the conversion electron; add these -// and their MC truth as new data products in the event. Create new SimParticle and -// PointTrajectory collections that they contain only those tracks that either create -// one of the selected hits or are an ancestor of such a track. Put these new -// collections into the event. -// -// For mixed events, there is only one new StrawHitCollection but there are many new -// SimParticleCollections and PointTrajectoryCollections. -// -// We anticipate a future development in which this module will look for both StrawHits -// and CaloHits that are in time with the conversion electron, and will keep all -// particles in the ancestry of any such hit. -// -// $Id: HitsInConversionTimeWindow_module.cc,v 1.3 2013/03/15 15:52:04 kutschke Exp $ -// $Author: kutschke $ -// $Date: 2013/03/15 15:52:04 $ -// -// Contact person Rob Kutschke. -// -// To do: -// 1) Check all G4Status object, not just the g4run one. -// 2) Get instance names from the pset. Check that instance names match the branch names. -// Not 100% sure what match means. -// 3) Remove unneeded headers. - -// Mu2e includes. -#include "GeneralUtilities/inc/SequenceStatistics.hh" -#include "MCDataProducts/inc/GenParticleCollection.hh" -#include "MCDataProducts/inc/StatusG4.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/PointTrajectoryCollection.hh" -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" -#include "Mu2eUtilities/inc/compressSimParticleCollection.hh" -#include "Mu2eUtilities/inc/compressPointTrajectoryCollection.hh" -#include "Mu2eUtilities/inc/checkSimParticleCollection.hh" -#include "RecoDataProducts/inc/StrawHitCollection.hh" -#include "RecoDataProducts/inc/CaloCrystalHitCollection.hh" - -// art includes. -#include "art/Framework/Core/EDFilter.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/Selector.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art_root_io/TFileService.h" - -// Root includes -#include "TH1F.h" -#include "TNtuple.h" - -// Other includes -#include "CLHEP/Units/SystemOfUnits.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -// C++ includes -#include -#include - -using namespace std; - -namespace mu2e { - - // A helper struct to hold information about one SimParticle. - struct Info { - Info(): - simId(), - hitCount(0), - hasTrajectory(false), - onPathToHit(false), - isPrimary(false){} - - Info( cet::map_vector_key id, bool primary ): - simId(id), - hitCount(0), - hasTrajectory(false), - onPathToHit(false), - isPrimary(primary){} - - cet::map_vector_key simId; // The id of this SimParticle. - int hitCount; // Does this particle have hits? - bool hasTrajectory; // Is there an associated PointTrajectory object? - bool onPathToHit; // Is this particle in the ancestry of a hit? - bool isPrimary; // Is this particle a primary particle? - - }; - - // A collection of Info objects that is indexed in parallel to a SimParticleCollection object. - typedef cet::map_vector SimInfoCollection; - - class HitsInConversionTimeWindow : public art::EDFilter { - public: - explicit HitsInConversionTimeWindow(fhicl::ParameterSet const& pset); - virtual ~HitsInConversionTimeWindow() { } - - virtual bool filter( art::Event& event); - - virtual bool beginRun(art::Run &run); - virtual void endJob(); - - private: - - // A map type to convert a product ID into an index into the Handle collections. - typedef map IdMap; - - // Cut to define the time window around the selected conversion electron. - double timeWindow_; - - // Module label of the g4 module that made the generated particles - std::string generatorModuleLabel_; - - // Module label of the module that made the StepPointMCCollections. - std::string g4ModuleLabel_; - - // Module labels of the modules that made the collection of reco hits. - std::string strawHitMakerLabel_; - std::string crystalHitMakerLabel_; - - std::vector instanceNames_; - - // Instance names of the StepPointMCCollections. - std::string trackerStepPoints_; - std::string caloStepPoints_; - std::string caloROStepPoints_; - std::string foilStepPoints_; - std::string crvStepPoints_; - std::string vDetStepPoints_; - - // Histogram pointers. - TH1F* hNhits_; - TH1F* hNhitsAll_; - TH1F* hNhitsIn_; - TH1F* hTime_; - TH1F* hTimeAll_; - TH1F* hEnergy_; - TH1F* hEnergyAll_; - TH1F* hEnergyIn_; - TH1F* hDeltaT_; - TH1F* htRMS_; - TH1F* hTSpread_; - TH1F* hTSpreadAll_; - - // Number of events that pass the filter. - int nPassed_; - - // Some utility functions that break the complete job into smaller pieces. - - GenParticle const& findConversionGenParticle( GenParticleCollection const& gens); - SimParticle const& findConversionSimParticle( SimParticleCollection const& sims, GenParticle const& conversion); - - void findStrawHits ( SimParticle const& sim, - StrawHitCollection const& strawHits, - PtrStepPointMCVectorCollection const& mcptrs, - std::vector& conversionStrawHits, - SequenceStatistics& stats ); - - void fillIdMap( std::vector >const& simHandles, - IdMap& idmap ); - - void checkNames( std::vector >const& simHandles, - std::vector >const& trajHandles ); - - void doThreeJobs ( StrawHitCollection const& strawHits, - StrawHitMCTruthCollection const& strawHitTruths, - PtrStepPointMCVectorCollection const& mcptrs, - double t0, - art::Event& event, - set >& contributingSims ); - - void fillSimInfo( std::vector > const& simHandles, - std::vector > const& trajHandles, - set > const& inTimeSims, - vector & counts - ); - - - }; - - HitsInConversionTimeWindow::HitsInConversionTimeWindow(fhicl::ParameterSet const& pset): - art::EDFilter{pset}, - timeWindow_(pset.get("timeWindow",50)), - generatorModuleLabel_(pset.get("generatorModuleLabel")), - g4ModuleLabel_(pset.get("g4ModuleLabel")), - strawHitMakerLabel_(pset.get("strawHitMakerLabel")), - instanceNames_(), - hNhits_(0), - hNhitsAll_(0), - hNhitsIn_(0), - hTime_(0), - hTimeAll_(0), - hEnergy_(0), - hEnergyAll_(0), - hEnergyIn_(0), - hDeltaT_(0), - htRMS_(0), - hTSpread_(0), - hTSpreadAll_(0), - nPassed_(0){ - - instanceNames_.push_back("dioMixer"); - instanceNames_.push_back("neutronMixer"); - instanceNames_.push_back("photonMixer"); - instanceNames_.push_back("protonMixer"); - instanceNames_.push_back("conversion"); - - produces(); - produces(); - produces("StrawHitMCPtr"); - - for ( size_t i=0; i(instanceNames_.at(i)); - produces(instanceNames_.at(i)); - } - - } - - // An adapter class that allows compressSimParticleCollection to access the std::map of Info objects. - class CompressSimAdapter{ - public: - CompressSimAdapter ( SimInfoCollection const& m ): - m_(m){} - - bool operator[]( cet::map_vector_key key ) const { - Info const& info(m_[key]); - bool keepsim = info.hitCount > 0 || info.onPathToHit; - return keepsim; - } - - private: - SimInfoCollection const& m_; - }; - - // An adapter class that allows compressPointTrajectoryCollection to access the std::map of Info objects. - class CompressTrajectoryAdapter{ - public: - CompressTrajectoryAdapter ( SimInfoCollection const& m ): - m_(m){} - - bool operator[]( cet::map_vector_key key ) const { - Info const& info(m_[key]); - bool keep = info.hasTrajectory && ( info.hitCount > 0 || info.onPathToHit ); - return keep; - } - - private: - SimInfoCollection const& m_; - }; - - bool HitsInConversionTimeWindow::beginRun(art::Run& ){ - - art::ServiceHandle tfs; - - hNhits_ = tfs->make( "hNhits", "Number of Straw Hits, Conversion", 200, 0., 200. ); - hNhitsAll_ = tfs->make( "hNhitsAll", "Number of Straw Hits, All", 200, 0., 5000. ); - hNhitsIn_ = tfs->make( "hNhitsIn", "Number of Straw Hits, In window", 200, 0., 500. ); - hTime_ = tfs->make( "hTime", "Hit time, Conversion;(ns)", 200, 0., 2000. ); - hTimeAll_ = tfs->make( "hTimeAll", "Hit time, All;(ns)", 200, 0., 2000. ); - hEnergy_ = tfs->make( "hEnergy", "Hit EnergyDeposit Conversion;[keV]", 100, 0., 10. ); - hEnergyAll_ = tfs->make( "hEnergyAll", "Hit EnergyDeposit All;[keV]", 100, 0., 10. ); - hEnergyIn_ = tfs->make( "hEnergyIn", "Hit EnergyDeposit All;[keV]", 100, 0., 10. ); - hDeltaT_ = tfs->make( "hDeltaT", "Hit Delta time, Conversion;(ns)", 200, 0., 200. ); - htRMS_ = tfs->make( "htRMS", "rms time spread, Conversion;(ns)", 200, 0., 200. ); - hTSpread_ = tfs->make( "hTSpread", "Time-tmean, Conversion;(ns)", 200, -100., 100. ); - hTSpreadAll_ = tfs->make( "hTSpreadAll","Time-tmean, Conversion;(ns)", 200, -100., 100. ); - - return true; - } - - bool HitsInConversionTimeWindow::filter(art::Event& event) { - - art::Handle g4StatusHandle; - event.getByLabel( g4ModuleLabel_, g4StatusHandle); - StatusG4 const& g4Status = *g4StatusHandle; - - // Accept only events with good status from G4. - // Expand this to check all of the mixing status objects or the overall status object. - if ( g4Status.status() > 1 ) { - return false; - } - - art::Handle gensHandle; - event.getByLabel( generatorModuleLabel_, gensHandle); - GenParticleCollection const& gens(*gensHandle); - - art::Handle simsHandle; - event.getByLabel(g4ModuleLabel_,simsHandle); - SimParticleCollection const& sims(*simsHandle); - - art::Handle strawHitsHandle; - event.getByLabel(strawHitMakerLabel_, strawHitsHandle); - StrawHitCollection const& strawHits(*strawHitsHandle); - - art::Handle strawHitTruthsHandle; - event.getByLabel(strawHitMakerLabel_, strawHitTruthsHandle); - StrawHitMCTruthCollection const& strawHitTruths(*strawHitTruthsHandle); - - art::Handle mcptrsHandle; - event.getByLabel(strawHitMakerLabel_, "StrawHitMCPtr", mcptrsHandle); - PtrStepPointMCVectorCollection const& mcptrs(*mcptrsHandle); - - // Find the GenParticle and the SimParticle corresponding to the conversion electron. - // Expect exactly one per event; if this is no longer true, we must update the find functions. - GenParticle const& gen(findConversionGenParticle(gens)); - SimParticle const& sim(findConversionSimParticle(sims,gen)); - - // Identify the subset of StrawHits that have some energy contribution from the conversion electron. - // Collect some statistics about them. - std::vector conversionStrawHits; - conversionStrawHits.reserve(200); - SequenceStatistics stats; - findStrawHits ( sim, strawHits, mcptrs, conversionStrawHits, stats); - - // The set of all SimParticles that contribute to any in-time hit. - // In-time means within +/- tWindow_ of stat.mean(). - set > inTimeSims; - - // Do three jobs at once to avoid repeating a double loop. - // - Create the three output data products, newStrawHits, newTruthHits, newMCptrs, - // fill them and add them to the event. - // - Fill the inTimeSims variable - // - Fill some diagnostics histograms. - doThreeJobs ( strawHits, - strawHitTruths, - mcptrs, - stats.moments().mean(), - event, - inTimeSims ); - bool keep = !inTimeSims.empty(); - - // Get the SimParticle and PointTrajectory Collections from the event. - art::ProductInstanceNameSelector selector(""); - std::vector > simHandles; - std::vector > trajHandles; - event.getMany( selector, simHandles); - event.getMany( selector, trajHandles); - - // Check that the SimParticle and PointTrajectory collections are properly matched up. - checkNames( simHandles, trajHandles); - - // Fill information about each SimParticle. - vector simsInfos; - fillSimInfo( simHandles, trajHandles, inTimeSims, simsInfos ); - - // Form the compressed SimParticle and PointTrajectory collections; write them out. - for ( size_t i=0; i(instanceNames_.at(i))); - art::EDProductGetter const * productGetter = event.productGetter(simsProductId); - - // Adapters to translate from the Info map to the format needed by the compress functions. - CompressSimAdapter simAdapter(simsInfos.at(i)); - CompressTrajectoryAdapter trajAdapter(simsInfos.at(i)); - - // Make a new data products: a compressed list of SimParticles and one of PointTrajectories. - unique_ptr newsimTest( new SimParticleCollection ); - unique_ptr newtraj( new PointTrajectoryCollection ); - - compressSimParticleCollection ( simsProductId, productGetter, *simHandles.at(i), simAdapter, *newsimTest); - compressPointTrajectoryCollection ( simsProductId, productGetter, *trajHandles.at(i), trajAdapter, *newtraj ); - - // Check self-consistency. - checkSimParticleCollection(*newsimTest,true); - - event.put(std::move(newsimTest), instanceNames_.at(i) ); - event.put(std::move(newtraj), instanceNames_.at(i) ); - - } - - if ( keep ) ++nPassed_; - - return keep; - - } // end of ::analyze. - - void HitsInConversionTimeWindow::endJob() { - mf::LogInfo("Summary") - << "HitsInConversionTimeWindow_module: Number of events passing the filter: " - << nPassed_ - << "\n"; - } - - // Find the genParticle corresponding to the conversion electron. - // This is a fast and dirty algorithm that works for the files we have now; it assumes - // that the generated event is a single conversion electron. Need to make it more general. - GenParticle const& HitsInConversionTimeWindow::findConversionGenParticle( GenParticleCollection const& gens){ - - if ( gens.size() != 1 ){ - throw cet::exception("RANGE") - << "HitsInConversionTimeWindow_module::findConversionGenParticle: unexpected size of GenParticle Collection: " - << gens.size() - << "\n"; - } - GenParticle const& gen(gens.at(0)); - - if ( !gen.generatorId().isConversion() ){ - throw cet::exception("RANGE") - << "HitsInConversionTimeWindow_module::findConversionGenParticle: unexpected generator type: " - << gen.generatorId() - << "\n"; - } - - return gen; - } // end findConversionGenParticle - - // Find the SimParticle corresponding to the conversion electron. - // This is a fast and dirty algorithm that works for the files we have now; it assumes - // that the generated event is a single conversion electron. Need to make it more general. - SimParticle const& HitsInConversionTimeWindow::findConversionSimParticle( SimParticleCollection const& sims, GenParticle const& gen){ - - if ( sims.empty() ){ - throw cet::exception("RANGE") - << "HitsInConversionTimeWindow_module::findConversionSimParticle: SimParticleCollection is empty: " - << sims.size() - << "\n"; - } - SimParticle const& sim(sims[cet::map_vector_key(1)]); - - if ( sim.genParticle().get() != &gen ){ - throw cet::exception("RANGE") - << "HitsInConversionTimeWindow_module::findConversionSimParticle: SimParticle Ptr to gen appears to be wrong: " - << sim.genParticle().id() << " " - << sim.genParticle().key() - << "\n"; - } - - return sim; - } // end findConversionSimParticle - - // Find all straw hits that contain one or more contributions from the SimParticle passed in as the first argument. - // Also fill some histogrms and accumulate some statistics about the hits: tmin, tmax, mean, rms. - void HitsInConversionTimeWindow::findStrawHits ( SimParticle const& sim, - StrawHitCollection const& strawHitsIn, - PtrStepPointMCVectorCollection const& mcptrs, - std::vector& strawHitsOut, - SequenceStatistics& stats ){ - - for ( size_t i=0; i< mcptrs.size(); ++i ){ - - PtrStepPointMCVector const& mcptr(mcptrs.at(i)); - StrawHit const& hit(strawHitsIn.at(i)); - - for ( size_t j=0; jFill(t); - hEnergy_->Fill(e/CLHEP::keV); - strawHitsOut.push_back(&hit); - break; - } - } - } - - // Some diagnostic histograms. - hNhits_ ->Fill( stats.n() ); - hNhitsAll_ ->Fill( strawHitsIn.size() ); - htRMS_ ->Fill( stats.moments().rms()); - hDeltaT_ ->Fill( stats.limits().delta() ); - for ( size_t i=0; iFill(strawHitsOut.at(i)->time()-stats.moments().mean()); - } - - - } // end findStrawHits - - // Fill the idmap variable. - void HitsInConversionTimeWindow::fillIdMap( std::vector >const& simHandles, - IdMap& idmap ){ - - for ( size_t i=0; i >const& simHandles, - std::vector >const& trajHandles ){ - - if ( simHandles.size() != trajHandles.size() ){ - throw cet::exception("DATA") - << "HitsInConversionTimeWindow_module::checkNames: SimPartile and PointTrajectory Data products have different numbers: \n" - << "Sims: " << simHandles.size() << "\n" - << "Trajectories: " << trajHandles.size() << "\n"; - } - - for ( size_t i=0; i >& inTimeSims ){ - - // A guess at the reserved size of the output StrawHit info. - static const int initialSize = 500; - - // Create output collections for the StrawHits and their MC truth. - unique_ptr newStrawHits(new StrawHitCollection); - unique_ptr newTruthHits(new StrawHitMCTruthCollection); - unique_ptr newMCptrs(new PtrStepPointMCVectorCollection); - newStrawHits->reserve(initialSize); - newTruthHits->reserve(initialSize); - newMCptrs->reserve(initialSize); - - for ( size_t i=0; iFill(hit.time()); - hEnergyAll_->Fill(hit.energyDep()/CLHEP::keV); - hTSpreadAll_->Fill(hit.time()-t0); - - // Select hits that are in time with the conversion electron. - if ( std::abs(hit.time()-t0) < timeWindow_ ){ - - // Fill histograms - hEnergyIn_->Fill(hit.energyDep()/CLHEP::keV); - - // Fill output data products. - newStrawHits->push_back(hit); - newTruthHits->push_back( strawHitTruths.at(i)); - newMCptrs->push_back( mcptr); - - // Append to the set of SimParticles that contribute to any in-time hit. - for ( size_t j=0; jFill(newStrawHits->size()); - - // Add data products to the event. - event.put(std::move(newStrawHits)); - event.put(std::move(newTruthHits)); - event.put(std::move(newMCptrs),"StrawHitMCPtr"); - - - } // end doThreeJobs - - // Fill-in the simsInfo object, that holds information about each SimParticle in the event. - void HitsInConversionTimeWindow::fillSimInfo( std::vector > const& simHandles, - std::vector > const& trajHandles, - set > const& inTimeSims, - vector & simsInfos - ){ - - // A map from ProductID into to the position within the sumHandles and trajHandles. - IdMap idmap; - fillIdMap( simHandles, idmap); - - for ( size_t i=0; isize()); - - // Initialize the SimInfoCollection with basic information about all SimParticles. - for ( SimParticleCollection::const_iterator j=sims.begin(), je=sims.end(); - j !=je; ++j ){ - infomap[j->first] = Info(j->first,j->second.isPrimary()); - } - - // Record which SimParticles have PointTrajectories. - for ( PointTrajectoryCollection::const_iterator j=trajs.begin(),je=trajs.end(); - j != je; ++j){ - cet::map_vector::iterator k = infomap.find(j->first); - if ( k == infomap.end() ){ - throw cet::exception("DATA") - << "HitsInConversionTimeWindow_module::fillSimInfo: PointTrajectory does not have a matching infomap entry: \n" - << "Collection number: " << i << " " - << trajHandles.at(i).provenance()->branchName() << "\n" - << "Particle number: " << j->first << " " << j->second.simId() << "\n"; - } - k->second.hasTrajectory = true; - } - } // end loop over simHandles - - - // Update simsInfo with information about which particles made hits. - for ( set >::const_iterator i=inTimeSims.begin(), e=inTimeSims.end(); - i != e; ++i){ - - // Which SimParticleCollection is this SimParticle from? - cet::map_vector_key key(i->key()); - int idx = idmap[i->id()]; - - // Find the corresponding SimsInfoCollection. - SimInfoCollection& infomap = simsInfos.at(idx); - - // Record that this SimParticle made a hit. - SimInfoCollection::iterator k = infomap.find(key); - if ( k == infomap.end() ){ - throw cet::exception("DATA") - << "HitsInConversionTimeWindow_module::fillSimInfo: inTimeSims does not have a matching infomap entry: \n" - << "Idx: " << idx << " Particle id: " << key << "\n"; - } - Info& info(k->second); - ++info.hitCount; - info.onPathToHit = true; - - // Mark all ancestors of this SimParticle. - SimParticle const* particle = i->get(); - while ( particle->isSecondary() ){ - cet::map_vector_key parentKey = cet::map_vector_key(particle->parent().key()); - SimInfoCollection::iterator k = infomap.find(parentKey); - if ( k == infomap.end() ){ - throw cet::exception("DATA") - << "HitsInConversionTimeWindow_module::fillSimInfo: cannot find parent: \n" - << "Idx: " << idx << " Particle id: " << particle->id() - << " Parent id: " << parentKey - << "\n"; - } - Info& parentInfo(k->second); - parentInfo.onPathToHit = true; - - particle = particle->parent().get(); - } - - } - } // end HitsInConversionTimeWindow::fillSimInfo - -} // end namespace mu2e - -DEFINE_ART_MODULE(mu2e::HitsInConversionTimeWindow); diff --git a/Filters/src/StepPointsInDigis_module.cc b/Filters/src/StepPointsInDigis_module.cc index ab29e87f0c..f237399504 100644 --- a/Filters/src/StepPointsInDigis_module.cc +++ b/Filters/src/StepPointsInDigis_module.cc @@ -55,6 +55,7 @@ class mu2e::StepPointsInDigis : public art::EDAnalyzer { // Other functions void fillTree(const mu2e::StepPointMC& old_step); + void fillTree(const mu2e::StrawGasStep& old_step); private: @@ -119,8 +120,7 @@ void mu2e::StepPointsInDigis::analyze(art::Event const& event) for(int i_end=0;i_end(i_end); - - const art::Ptr& old_step_point = i_strawDigiMC.stepPointMC(end); + auto const& old_step_point = i_strawDigiMC.stepPointMC(end); if (old_step_point.isAvailable()) { fillTree( *old_step_point ); } @@ -160,5 +160,22 @@ void mu2e::StepPointsInDigis::fillTree(const mu2e::StepPointMC& old_step) { _steps->Fill(); } +void mu2e::StepPointsInDigis::fillTree(const mu2e::StrawGasStep& old_step) { + + _stepX = old_step.position().x(); + _stepY = old_step.position().y(); + _stepZ = old_step.position().z(); + _stepRawTime = old_step.time(); + _stepOffsettedTime = _toff.timeWithOffsetsApplied(old_step); + _stepEDep = old_step.totalEDep(); + art::Ptr simPtr = old_step.simParticle(); + while (simPtr->isSecondary()) { + simPtr = simPtr->parent(); + } + _stepGenId = simPtr->genParticle()->generatorId().id(); + _stepProductId = simPtr.id().value(); + _steps->Fill(); +} + DEFINE_ART_MODULE(mu2e::StepPointsInDigis) diff --git a/Filters/src/StrawDigiMCFilter_module.cc b/Filters/src/StrawDigiMCFilter_module.cc index 55199e59b4..d141fa7acd 100644 --- a/Filters/src/StrawDigiMCFilter_module.cc +++ b/Filters/src/StrawDigiMCFilter_module.cc @@ -66,17 +66,15 @@ namespace mu2e { std::map,unsigned> pmap; for(auto const& mcdigi : *mcdigis) { // look at the early end - StrawEnd fend(StrawEnd::cal); - if(mcdigi.wireEndTime(StrawEnd::hv) < mcdigi.wireEndTime(StrawEnd::cal)) - fend = StrawEnd(StrawEnd::hv); - art::Ptrstep = mcdigi.stepPointMC(fend); + StrawEnd fend = mcdigi.earlyEnd(); + auto const& step = mcdigi.stepPointMC(fend); art::Ptr const& sp = step->simParticle(); - CLHEP::Hep3Vector const& mom = step->momentum(); // cast to 3-vector - if(debug_ > 0)std::cout <<"SimParticle PDG = " << sp->pdgId() << " Mom = " << mom.mag() << std::endl; + auto const& mom = step->momentum(); // cast to 3-vector + if(debug_ > 0)std::cout <<"SimParticle PDG = " << sp->pdgId() << " Mom = " << sqrt(mom.mag2()) << std::endl; bool goodpdg(true); if(pdgs_.size() > 0) goodpdg = std::find(pdgs_.begin(),pdgs_.end(),sp->pdgId()) != pdgs_.end(); - if(goodpdg && mom.mag() > minpmom_ && mom.mag() < maxpmom_ ){ + if(goodpdg && sqrt(mom.mag2()) > minpmom_ && sqrt(mom.mag2()) < maxpmom_ ){ auto mapfnd = pmap.find(sp); if(mapfnd == pmap.end()) pmap[sp] = 1; diff --git a/MCDataProducts/inc/StrawDigiMC.hh b/MCDataProducts/inc/StrawDigiMC.hh index bf6908cf93..a21c20aeab 100644 --- a/MCDataProducts/inc/StrawDigiMC.hh +++ b/MCDataProducts/inc/StrawDigiMC.hh @@ -1,13 +1,14 @@ #ifndef MCDataProducts_StrawDigiMC_hh #define MCDataProducts_StrawDigiMC_hh // -// Summary of MC information used to create a StrawDigi +// Summary of MC information used to create a StrawDigi. Everything is referenced by the thresold digitization end // // Original author David Brown, LBNL // // Mu2e includes #include "DataProducts/inc/StrawId.hh" #include "DataProducts/inc/StrawEnd.hh" +#include "DataProducts/inc/XYZVec.hh" #include "MCDataProducts/inc/StrawGasStep.hh" #include "MCDataProducts/inc/StepPointMC.hh" // CLHEP includes @@ -27,34 +28,33 @@ namespace mu2e { class StrawDigiMC{ public: + typedef art::Ptr SGSP; + typedef std::array SGSPA; + typedef std::array PA; + typedef std::array FA; StrawDigiMC(); // construct from hitlets - StrawDigiMC(StrawId sid, double wetime[2], - CLHEP::HepLorentzVector cpos[2], - art::Ptr sgs[2], art::Ptr stepMC[2]); + StrawDigiMC(StrawId sid, PA cpos, FA ctime, FA wetime, SGSPA sgs); // temporary legacy construtctor fot testing FIXME! StrawDigiMC(StrawId sid, double wetime[2], CLHEP::HepLorentzVector cpos[2], art::Ptr stepMC[2], std::vector > const& stepmcs); - // copy construcors - StrawDigiMC(const StrawDigiMC& rhs); // default: don't copy art::Ptrs - StrawDigiMC(const StrawDigiMC& rhs, art::Ptr stepMC[2] ); + // use compuater copy construcors + StrawDigiMC(const StrawDigiMC& rhs, SGSPA sgsp ); // update the Ptrs // Accessors StrawId strawId() const { return _strawid; } - double wireEndTime(StrawEnd strawend) const { return _wetime[strawend]; } - - CLHEP::HepLorentzVector const& clusterPosition(StrawEnd strawend) const { return _cpos[strawend]; } - double driftDistance(StrawEnd strawend) const; - double distanceToMid(StrawEnd strawend) const; - art::Ptr const& stepPointMC(StrawEnd strawend) const { return _stepMC[strawend]; } - std::array,StrawEnd::nends> const& stepPointMCs() const { return _stepMC; } - art::Ptr const& strawGasStep(StrawEnd strawend) const { return _sgs[strawend]; } - StrawEnd earlyEnd() const { return (_wetime[StrawEnd::cal] < _wetime[StrawEnd::hv]) ? StrawEnd::cal : StrawEnd::hv; } - art::Ptr const& earlyStepPointMC() const { return stepPointMC(earlyEnd()); } - art::Ptr const& earlyStrawGasStep() const { return strawGasStep(earlyEnd()); } + SGSP const& strawGasStep(StrawEnd strawend) const { return _sgspa[strawend]; } + SGSPA const& strawGasSteps() const { return _sgspa; } + StrawEnd earlyEnd() const { return (_wtime[StrawEnd::cal] < _wtime[StrawEnd::hv]) ? StrawEnd::cal : StrawEnd::hv; } + SGSP const& earlyStrawGasStep() const { return strawGasStep(earlyEnd()); } double energySum() const;// sum of all MC true energy deposited + + XYZVec const& clusterPos(StrawEnd strawend) const { return _cpos[strawend]; } + // note that all the time functions below have time offsets already applied! + float clusterTime(StrawEnd strawend) const { return _ctime[strawend]; } // time the ion cluster was created + float wireEndTime(StrawEnd strawend) const { return _wtime[strawend]; } // time the signal reaches the end of the wire // energy sum of particle that triggered the discriminator double triggerEnergySum(StrawEnd strawend) const; // check if this digi was created by cross-talk @@ -62,15 +62,18 @@ namespace mu2e { // Print contents of the object. void print( std::ostream& ost = std::cout, bool doEndl = true ) const; +// legacy functions + SGSP const& stepPointMC(StrawEnd strawend) const { return _sgspa[strawend]; } + SGSPA const& stepPointMCs() const { return _sgspa; } + SGSP const& earlyStepPointMC() const { return stepPointMC(earlyEnd()); } + CLHEP::HepLorentzVector clusterPosition(StrawEnd strawend) const { return CLHEP::HepLorentzVector(Geom::Hep3Vec(_cpos[strawend]),_ctime[strawend]); } + private: StrawId _strawid; // Straw sid - std::array _cpos; // Positions of the clusters responsible - // for the TDC firings on each end (can be the same) - std::array _wetime; // times at the wire ends of the signals which fired the TDC. This needs double precision as neutrons can take seconds (!) to generate signals - // in ns from event window marker - - std::array,StrawEnd::nends> _sgs; // Ptr into StrawGasStep collection of step which - std::array,StrawEnd::nends> _stepMC; // Ptr into StepPointMC collection of step which + PA _cpos; // Positions of the trigger clusters + FA _ctime; // times of the trigger clusters + FA _wtime; // times at the wire ends of the signals which fired the TDC. + SGSPA _sgspa; // StrawGasStep collection that triggered each end }; inline std::ostream& operator<<( std::ostream& ost, diff --git a/MCDataProducts/inc/StrawGasStep.hh b/MCDataProducts/inc/StrawGasStep.hh index 1dfc840565..a414b31926 100644 --- a/MCDataProducts/inc/StrawGasStep.hh +++ b/MCDataProducts/inc/StrawGasStep.hh @@ -9,9 +9,10 @@ #include "canvas/Persistency/Common/Assns.h" #include "MCDataProducts/inc/StepPointMC.hh" -#include "MCDataProducts/inc/ProcessCode.hh" +#include "MCDataProducts/inc/SimParticle.hh" #include "DataProducts/inc/StrawId.hh" #include "DataProducts/inc/XYZVec.hh" +#include "CLHEP/Vector/ThreeVector.h" #include namespace mu2e { @@ -36,20 +37,29 @@ namespace mu2e { StrawGasStep() : _eIon(0.0), _pathLen(0.), _width(0.0), _time(0.0) {} StrawGasStep( StrawId strawId, StepType stype, - Float_t Edep, Float_t pathLength, Float_t width, Double_t time, - XYZVec const& startPosition, XYZVec const& endPosition) : + Float_t Edep, Float_t stepLength, Float_t width, Double_t time, + XYZVec const& startPosition, XYZVec const& endPosition, XYZVec const& mom, art::Ptr const& simp) : _strawId(strawId), _stype(stype), _eIon(Edep), - _pathLen(pathLength), _width(width), _time(time), - _startpos(startPosition), _endpos(endPosition) {} + _pathLen(stepLength), _width(width), _time(time), + _startpos(startPosition), _endpos(endPosition), + _mom(mom), _simp(simp) {} StrawId strawId() const { return _strawId;} StepType stepType() const { return _stype; } Float_t ionizingEdep() const { return _eIon; } - Float_t pathLength() const { return _pathLen; } + Float_t stepLength() const { return _pathLen; } Float_t width() const { return _width; } - Double_t time() const { return _time; } + Double_t time() const { return _time; } // time the particle entered the gas (without offsets!) XYZVec const& startPosition() const { return _startpos; } XYZVec const& endPosition() const { return _endpos; } + XYZVec const& momentum() const { return _mom; } + art::Ptr const& simParticle() const { return _simp; } + + // legacy accessors, for compatibility with StepPointMC consumers + CLHEP::Hep3Vector position() const { return Geom::Hep3Vec(_startpos); } + CLHEP::Hep3Vector momvec() const { return Geom::Hep3Vec(_mom); } + float eDep() const { return _eIon; } + float totalEDep() const { return _eIon; } private: StrawId _strawId; // straw StepType _stype; // type of step: used downstream in response simulation @@ -58,6 +68,8 @@ namespace mu2e { Float_t _width; // transverse RMS of the charge cloud WRT the wire Double_t _time; // time particle enters this gas volume; must be double to allow for long-lived particles XYZVec _startpos, _endpos; //entrance and exit to the gas volume + XYZVec _mom; //momentum at the start of this step + art::Ptr _simp; // primary simparticle of this step }; typedef std::vector StrawGasStepCollection; @@ -65,7 +77,7 @@ namespace mu2e { inline std::ostream& operator<<( std::ostream& ost, StrawGasStep const& sgs){ ost << "StrawGasStep StrawId " << sgs.strawId() << " Type " << sgs.stepType()._stype - << " Ionization " << sgs.ionizingEdep() << " path length " << sgs.pathLength() + << " Ionization " << sgs.ionizingEdep() << " path length " << sgs.stepLength() << " Width " << sgs.width(); return ost; } diff --git a/MCDataProducts/inc/StrawHitMCTruth.hh b/MCDataProducts/inc/StrawHitMCTruth.hh deleted file mode 100644 index f760577454..0000000000 --- a/MCDataProducts/inc/StrawHitMCTruth.hh +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef MCDataProducts_StrawHitMCTruth_hh -#define MCDataProducts_StrawHitMCTruth_hh -// -// This is a place to put additional information produced by HitMaker, -// like true drift distance, signal propagation time, etc. -// -// Original author Ivan Logashenko -// - -// C++ includes -#include -#include - -// Mu2e includes - -namespace mu2e { - - struct StrawHitMCTruth{ - - public: - - StrawHitMCTruth(): - _driftTime(0.), - _driftDistance(0.), - _distanceToMid(0.) { - } - - // Constructor for a hit that came from an unpacked digi, either - // from data or from the full MC chain. - StrawHitMCTruth( - float driftTime, - float driftDistance, - float distanceToMid) : - _driftTime(driftTime), - _driftDistance(driftDistance), - _distanceToMid(distanceToMid) { - } - - // Accessors - float driftTime() const { return _driftTime;} - float driftDistance() const { return _driftDistance;} - float distanceToMid() const { return _distanceToMid; } - - // Accept compiler generated versions of d'tor, copy c'tor, assignment operator. - - // Print contents of the object. - void print( std::ostream& ost = std::cout, bool doEndl = true ) const; - - private: - - float _driftTime; // ns - float _driftDistance; // mm - float _distanceToMid; // mm - - }; - - inline std::ostream& operator<<( std::ostream& ost, - StrawHitMCTruth const& hit){ - hit.print(ost,false); - return ost; - } - -} // namespace mu2e - -#endif /* MCDataProducts_StrawHitMCTruth_hh */ diff --git a/MCDataProducts/inc/StrawHitMCTruthCollection.hh b/MCDataProducts/inc/StrawHitMCTruthCollection.hh deleted file mode 100644 index b2838cf2b5..0000000000 --- a/MCDataProducts/inc/StrawHitMCTruthCollection.hh +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MCDataProducts_StrawHitMCTruthCollection_hh -#define MCDataProducts_StrawHitMCTruthCollection_hh - -// -// Define a type for a collection of StrawHitMCTruth objects. -// -// Original author Ivan Logashenko -// - -#include - -#include "MCDataProducts/inc/StrawHitMCTruth.hh" - -namespace mu2e { - typedef std::vector StrawHitMCTruthCollection; -} - -#endif /* MCDataProducts_StrawHitMCTruthCollection_hh */ diff --git a/MCDataProducts/src/StrawDigiMC.cc b/MCDataProducts/src/StrawDigiMC.cc index 0acc515958..f6000b8528 100644 --- a/MCDataProducts/src/StrawDigiMC.cc +++ b/MCDataProducts/src/StrawDigiMC.cc @@ -6,8 +6,6 @@ // Mu2e includes #include "GeometryService/inc/GeomHandle.hh" #include "MCDataProducts/inc/StrawDigiMC.hh" -#include "TrackerGeom/inc/Tracker.hh" -#include "TrackerGeom/inc/Straw.hh" #include "DataProducts/inc/StrawEnd.hh" // Framework includes. #include "cetlib_except/exception.h" @@ -23,101 +21,51 @@ namespace mu2e { : _strawid(StrawId::_invalid) {} - StrawDigiMC::StrawDigiMC(StrawId sid, double wetime[2], - CLHEP::HepLorentzVector cpos[2], - art::Ptr sgs[2], art::Ptr stepmc[2]) : - _strawid(sid) - { - for(size_t strawend=0;strawend<2;++strawend){ - _wetime[strawend] = wetime[strawend]; - _cpos[strawend] = cpos[strawend]; - _sgs[strawend] = sgs[strawend]; - _stepMC[strawend] = stepmc[strawend]; - } - } + StrawDigiMC::StrawDigiMC(StrawId sid, PA cpos, FA ctime, FA wetime, SGSPA sgs): + _strawid(sid), _cpos(cpos), _ctime(ctime), _wtime(wetime), _sgspa(sgs) + {} // legacy constructor: StrawGasSteps will be empty! StrawDigiMC::StrawDigiMC(StrawId sid, double wetime[2], CLHEP::HepLorentzVector cpos[2], art::Ptr stepMC[2], std::vector > const& stepmcs) :_strawid(sid) { for(size_t strawend=0;strawend<2;++strawend){ - _wetime[strawend] = wetime[strawend]; + _wtime[strawend] = wetime[strawend]; _cpos[strawend] = cpos[strawend]; - _stepMC[strawend] = stepMC[strawend]; - } - } - - StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs) : _strawid(rhs.strawId()) { - for(int i_end=0;i_end(i_end); - _wetime[end] = rhs.wireEndTime(end); - _cpos[end] = rhs.clusterPosition(end); - _sgs[end] = rhs.strawGasStep(end); - _stepMC[end] = rhs.stepPointMC(end); - } - } - - StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs, art::Ptr stepMC[2] ) : _strawid(rhs.strawId()) { - for(int i_end=0;i_end(i_end); - _wetime[end] = rhs.wireEndTime(end); - _cpos[end] = rhs.clusterPosition(end); - _sgs[end] = rhs.strawGasStep(end); - _stepMC[end] = stepMC[i_end]; } } - double StrawDigiMC::driftDistance(StrawEnd strawend) const { - double retval = -100.0; - if(!_stepMC[strawend].isNull()){ - const Tracker& tracker = *GeomHandle(); - // use the MC true sid, not the straws sid (digi could be from x-talk) - Straw const& straw = tracker.getStraw(_stepMC[strawend]->strawId()); - retval = (_cpos[strawend] - straw.getMidPoint()).perp(straw.getDirection()); - } - return retval; - } - - double StrawDigiMC::distanceToMid(StrawEnd strawend) const { - double retval = -100.0; - if(!_stepMC[strawend].isNull()){ - const Tracker& tracker = *GeomHandle(); - Straw const& straw = tracker.getStraw(_stepMC[strawend]->strawId()); - retval = (_cpos[strawend] - straw.getMidPoint()).dot(straw.getDirection()); - } - return retval; + StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs, SGSPA sgspa ) : StrawDigiMC(rhs) { + _sgspa = sgspa; // can't initialize after delecated construtor } bool StrawDigiMC::isCrossTalk(StrawEnd strawend) const { bool retval(false); - if(!_stepMC[strawend].isNull()){ - retval = _strawid == _stepMC[strawend]->strawId(); + if(!_sgspa[strawend].isNull()){ + retval = _strawid != _sgspa[strawend]->strawId(); } return retval; } double StrawDigiMC::energySum() const { - return _sgs[0]->ionizingEdep(); + if(_sgspa[0] == _sgspa[1] ) + return _sgspa[0]->ionizingEdep(); + else + return _sgspa[0]->ionizingEdep() + _sgspa[1]->ionizingEdep(); } - double StrawDigiMC::triggerEnergySum(StrawEnd strawend) const { - return _sgs[strawend]->ionizingEdep(); + return _sgspa[strawend]->ionizingEdep(); } // Print the information found in this hit. void StrawDigiMC::print( ostream& ost, bool doEndl ) const { - ost << "Straw Digi MC Truth for straw ends " << StrawEnd(StrawEnd::cal) << " : " << StrawEnd(StrawEnd::hv) - << " cluster times : " << _cpos[0].t() << " : " << _cpos[1].t() - << " drift distance: " << driftDistance(StrawEnd::cal) << " : " << driftDistance(StrawEnd::hv) - << " distance to wire center: " << distanceToMid(StrawEnd::cal) << " : " << distanceToMid(StrawEnd::hv) + << " cluster times : " << _ctime[0] << " : " << _ctime[1] << " Energy: " << energySum(); if ( doEndl ){ ost << endl; } - } - } diff --git a/MCDataProducts/src/StrawHitMCTruth.cc b/MCDataProducts/src/StrawHitMCTruth.cc deleted file mode 100644 index ebb773cb90..0000000000 --- a/MCDataProducts/src/StrawHitMCTruth.cc +++ /dev/null @@ -1,35 +0,0 @@ -// -// This is a place to put additional information produced by HitMaker, -// like true drift distance, signal propagation time, etc. -// -// Original author Ivan Logashenko -// - -// C++ includes -#include - -// Framework includes. -#include "cetlib_except/exception.h" - -// Mu2e includes -#include "MCDataProducts/inc/StrawHitMCTruth.hh" - -using namespace std; - -namespace mu2e { - - // Print the information found in this hit. - void StrawHitMCTruth::print( ostream& ost, bool doEndl ) const { - - ost << "Straw Hit MC Truth:" - << " drift time: " << _driftTime - << " drift distance: " << _driftDistance - << " distance to wire center: " << _distanceToMid; - - if ( doEndl ){ - ost << endl; - } - - } - -} // namespace mu2e diff --git a/MCDataProducts/src/classes.h b/MCDataProducts/src/classes.h index 257c463c41..d23aa75338 100644 --- a/MCDataProducts/src/classes.h +++ b/MCDataProducts/src/classes.h @@ -63,7 +63,6 @@ #include "MCDataProducts/inc/CaloHitSimPartMCCollection.hh" #include "MCDataProducts/inc/CaloClusterMC.hh" // straws -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" #include "MCDataProducts/inc/StrawDigiMC.hh" #include "MCDataProducts/inc/StrawGasStep.hh" diff --git a/MCDataProducts/src/classes_def.xml b/MCDataProducts/src/classes_def.xml index 3958e880a9..4be737baa4 100644 --- a/MCDataProducts/src/classes_def.xml +++ b/MCDataProducts/src/classes_def.xml @@ -203,10 +203,6 @@ - - - - diff --git a/Mu2eUtilities/inc/SimParticleInfo.hh b/Mu2eUtilities/inc/SimParticleInfo.hh deleted file mode 100644 index f16169e991..0000000000 --- a/Mu2eUtilities/inc/SimParticleInfo.hh +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef Mu2eUtilities_SimParticleInfo_hh -#define Mu2eUtilities_SimParticleInfo_hh -// -// Information about one SimParticle and all StrawHits that are -// associated with hit. This is a building block of the -// the class SimParticlesWithHits. -// -// $Id: SimParticleInfo.hh,v 1.8 2011/05/24 17:19:03 kutschke Exp $ -// $Author: kutschke $ -// $Date: 2011/05/24 17:19:03 $ -// -// Original author Rob Kutschke. -// - -// C++ includes. -#include - -// Mu2e includes. -#include "Mu2eUtilities/inc/StrawHitMCInfo.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" - -namespace art{ - class Event; -} - - -namespace mu2e { - - class SimParticleInfo{ - - // This class should only ever be created within SimParticlesWithHits. - friend class SimParticlesWithHits; - - public: - typedef SimParticleCollection::key_type key_type; - - key_type id() const { return _simId; } - SimParticle const& simParticle() const { return *_simParticle; } - - size_t nHits() const { return _hitInfos.size(); } - - std::vectorconst& strawHitInfos() const { return _hitInfos; } - - StepPointMC const& firstStepPointMCinTracker() const; - StepPointMC const& lastStepPointMCinTracker() const; - - // Compiler generated code is Ok for: - // d'tor, copy c'tor assignment operator. - // Once this class mature we will make the copy c'tor and assignment operator private. - - private: - - // This class should only ever be created by SimParticlesWithHits. - // Therefore c'tor and non-const accessors are private. - SimParticleInfo():_simId(-1){} - - SimParticleInfo( key_type simId, - SimParticle const& simParticle, - art::Event const& event); - - std::vector& strawHitInfos() { return _hitInfos; } - - // ID of this particle in the SimParticleCollection. - key_type _simId; - - // Pointer to the SimParticle - SimParticle const* _simParticle; - - // The event in which this information is found. - art::Event const* _event; - - // Vector of information about the StrawHits to which this track contributed. - std::vector _hitInfos; - - // First StepPointMC in tracker. Lazy evaluated, therefore mutable. - mutable StepPointMC const* _firstInTracker; - - // Last StepPointMC in tracker. Lazy evaluated, therefore mutable. - mutable StepPointMC const* _lastInTracker; - - }; - -} // namespace mu2e - -#endif /* Mu2eUtilities_SimParticleInfo_hh */ diff --git a/Mu2eUtilities/inc/SimParticleTimeOffset.hh b/Mu2eUtilities/inc/SimParticleTimeOffset.hh index 5ce405e155..974572c83a 100644 --- a/Mu2eUtilities/inc/SimParticleTimeOffset.hh +++ b/Mu2eUtilities/inc/SimParticleTimeOffset.hh @@ -23,6 +23,7 @@ namespace fhicl { class ParameterSet; } namespace mu2e { class StepPointMC; + class StrawGasStep; class SimParticleTimeOffset { public: @@ -44,6 +45,7 @@ namespace mu2e { double totalTimeOffset(art::Ptr p) const; double totalTimeOffset(const StepPointMC& s) const; double timeWithOffsetsApplied(const StepPointMC& s) const; + double timeWithOffsetsApplied(const StrawGasStep& s) const; private: std::vector inputs_; diff --git a/Mu2eUtilities/inc/SimParticlesWithHits.hh b/Mu2eUtilities/inc/SimParticlesWithHits.hh deleted file mode 100644 index 3261dc0b6b..0000000000 --- a/Mu2eUtilities/inc/SimParticlesWithHits.hh +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef Mu2eUtilities_SimParticlesWithHits_hh -#define Mu2eUtilities_SimParticlesWithHits_hh -// -// This class makes available a collection of SimParticles that -// have more than a minimum number of StrawHits with energy deposition -// in the gas above some cut. The class can also return a -// vector of information about all of the StrawHits on each track -// in the collection. If a StrawHit contains contributions from -// more than one SimParticle, that StrawHit will appear in the hit lists -// for all of the contributing SimParticles. -// -// This class is not designed to be peristable. -// -// $Id: SimParticlesWithHits.hh,v 1.9 2011/06/07 21:41:08 kutschke Exp $ -// $Author: kutschke $ -// $Date: 2011/06/07 21:41:08 $ -// -// Original author Rob Kutschke. -// - -// C++ includes. -#include -#include - -// Mu2e includes. -#include "Mu2eUtilities/inc/SimParticleInfo.hh" -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "RecoDataProducts/inc/StrawHitCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" - -namespace art{ - class Event; -} - -namespace mu2e { - - class SimParticlesWithHits{ - public: - - typedef SimParticleCollection::key_type key_type; - typedef SimParticleInfo mapped_type; - typedef std::map map_type; - typedef map_type::const_iterator const_iterator; - - // No default c'tor by design. - - SimParticlesWithHits( const art::Event& evt, - std::string const& _g4ModuleLabel, - std::string const& _hitMakerModuleLabel, - std::string const& _trackerStepPoints, - double minEnergyDep, - size_t minHits ); - - // Compiler generated code is Ok for: - // d'tor, copy c'tor assignment operator. - - // Find info for the requested SimParticle. Return by pointer and - // return a null pointer if the information is not in the map. - mapped_type const* findOrNull( key_type key); - - // Find info for the requested SimParticle; throw if the particle - // is not in the map. - mapped_type const& at( key_type key); - - // Synonym for the at() function. - mapped_type const& operator[]( key_type key){ - return at(key); - } - - // Iterators over the collection. - const_iterator begin() const { return _hitsPerTrack.begin(); } - const_iterator end() const { return _hitsPerTrack.end(); } - - // Number of particles with hits. - size_t size() const { return _hitsPerTrack.size(); } - - // Access all of the information - map_type const& getMap() const { return _hitsPerTrack; } - - private: - - // List of hits on each generated track. - std::map _hitsPerTrack; - - // Pointer to a collection within the event; needed by both the c'tor and selfTest(). - PtrStepPointMCVectorCollection const* _hits_mcptr; - - // Check that the object was built correctly. - void selfTest(); - - }; - -} // namespace mu2e - -#endif /* Mu2eUtilities_SimParticlesWithHits_hh */ diff --git a/Mu2eUtilities/inc/StrawHitMCInfo.hh b/Mu2eUtilities/inc/StrawHitMCInfo.hh deleted file mode 100644 index 50fbd89426..0000000000 --- a/Mu2eUtilities/inc/StrawHitMCInfo.hh +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef Mu2eUtilities_StrawHitMCInfo_hh -#define Mu2eUtilities_StrawHitMCInfo_hh -// -// Integrated access to all information about a StrawHit that was -// created by a SimParticle. This class is a building block of -// the SimParticlesWithHits class. If a StrawHit contains contributions -// from two SimParticles, then there will usually be one two StrawHitMCInfo -// objects, one attached to each SimParticle. -// -// $Id: StrawHitMCInfo.hh,v 1.8 2011/06/07 21:41:08 kutschke Exp $ -// $Author: kutschke $ -// $Date: 2011/06/07 21:41:08 $ -// -// Original author Rob Kutschke. -// -// Notes: -// 1) The time returned by this class is defined as follows -// Loop over all StepPointMCs that contributed to this hit. Of these -// select only those that were created by the trackId of this StrawHitMCInfo. -// Of these, find the one with the earliest time. - -// C++ includes. -#include - -// Mu2e includes. -#include "MCDataProducts/inc/PtrStepPointMCVector.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" - -// Forward declarations. -namespace art{ - class Event; -} - - -namespace mu2e { - - // Forward declarations - class StrawHit; - class StrawHitMCTruth; - class StepPointMC; - - class StrawHitMCInfo{ - public: - - typedef SimParticleCollection::key_type key_type; - - // No default c'tor by design. - - StrawHitMCInfo( art::Event const& event, - key_type trackId, - size_t index, - StrawHit const& strawHit, - StrawHitMCTruth const& strawHitMCTruth, - PtrStepPointMCVector const& strawHitMCPtr, - int nSimParticles ): - _index(index), - _hit(&strawHit), - _truth(&strawHitMCTruth), - _mcPtr(&strawHitMCPtr), - _nSimParticles(nSimParticles), - _time(std::numeric_limits::max()){ - fillStepPointMCs(event,trackId); - } - - // Compiler generated code is Ok for: - // d'tor, copy c'tor assignment operator. - - size_t index() const { return _index; } - StrawHit const& hit() const { return *_hit;} - StrawHitMCTruth const& truth() const { return *_truth;} - PtrStepPointMCVector const& stepsByPrr() const { return *_mcPtr;} - bool isShared() const { return _nSimParticles>1;} - double time() const { return _time; } - - std::vector const& steps() const { - return _stepPointMCs; - } - - // Return true if this hit occured before hit rhs. - // The metric is the time of the earliest StepPointMC that - // belongs to this hit and was made by the track to which it - // is attached. - bool operator<( StrawHitMCInfo const& rhs) const { - return ( _time < rhs._time ); - } - - private: - - // Index into: - // StrawHitCollection, StrawHitMCTruthCollection, PtrStepPointMCVectorCollection. - size_t _index; - - // Non-owning pointers to the StrawHit, StrawHitMCTruth and PtrStepPointMCVector. - StrawHit const* _hit; - StrawHitMCTruth const* _truth; - PtrStepPointMCVector const* _mcPtr; - - // Non-owning pointers to all StepPointMCs that contributed to this track. - std::vector _stepPointMCs; - - // The number of distinct SimParticles that contribute to this hit. - int _nSimParticles; - - // The time of this hit. See note 1. - double _time; - - // Fill _stepPointMCs and fill the variable time. - void fillStepPointMCs(art::Event const& event, key_type trackId ); - }; - -} // namespace mu2e - -#endif /* Mu2eUtilities_StrawHitMCInfo_hh */ diff --git a/Mu2eUtilities/inc/particleEnteringG4Volume.hh b/Mu2eUtilities/inc/particleEnteringG4Volume.hh index f0e122e04b..ed7c46d254 100644 --- a/Mu2eUtilities/inc/particleEnteringG4Volume.hh +++ b/Mu2eUtilities/inc/particleEnteringG4Volume.hh @@ -11,9 +11,11 @@ #include "canvas/Persistency/Common/Ptr.h" #include "MCDataProducts/inc/SimParticle.hh" #include "MCDataProducts/inc/StepPointMC.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" namespace mu2e{ art::Ptr particleEnteringG4Volume(const StepPointMC& step); + art::Ptr particleEnteringG4Volume(const StrawGasStep& step); } #endif /* Mu2eUtilities_inc_particleEnteringG4Volume_hh */ diff --git a/Mu2eUtilities/src/SimParticleInfo.cc b/Mu2eUtilities/src/SimParticleInfo.cc deleted file mode 100644 index 6725d81cbd..0000000000 --- a/Mu2eUtilities/src/SimParticleInfo.cc +++ /dev/null @@ -1,104 +0,0 @@ -// -// Integrated access to all information about a StrawHit that was -// created by a SimParticle. This class is a building block of -// the SimParticlesWithHits class. If a StrawHit contains contributions -// from two SimParticles, then there will usually be one two StrawHitMCInfo -// objects, one attached to each SimParticle. -// -// $Id: SimParticleInfo.cc,v 1.7 2011/10/28 18:47:07 greenc Exp $ -// $Author: greenc $ -// $Date: 2011/10/28 18:47:07 $ -// -// See the notes in the header file for the meaning of the member datum _time. -// - - -// Framework includes -#include "art/Framework/Principal/Event.h" - -// Mu2e includes -#include "Mu2eUtilities/inc/SimParticleInfo.hh" -#include "Mu2eUtilities/inc/StrawHitMCInfo.hh" -#include "MCDataProducts/inc/StepPointMC.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" - -// C++ includes. -#include - -namespace mu2e { - - SimParticleInfo::SimParticleInfo( - key_type simId, - SimParticle const& simParticle, - const art::Event& evt): - _simId(simId), - _simParticle(&simParticle), - _event(&evt), - _hitInfos(), - _firstInTracker(0), - _lastInTracker(0){} - - - // calculate the first StepPointMC in track - StepPointMC const& SimParticleInfo::firstStepPointMCinTracker() const { - - if ( _firstInTracker ) return *_firstInTracker; - else if ( _hitInfos.size() == 0 ) { - throw cet::exception("HITS") - << "_hitInfos is empty at " << __func__ << "\n"; - } - - double currentFirstTime = DBL_MAX; - StepPointMC const* currentStepPoint = 0; - - // Straws are already ordered by earliest time of StepMCPoint - std::vector const& steps = _hitInfos.front().steps(); - - // loop over all StepPointMC objects - for ( std::vector::const_iterator stepsit = steps.begin(); stepsit!=steps.end(); ++stepsit){ - - if ( (*stepsit)->trackId() == _simId ) { - double time = (*stepsit)->time(); - if ( time < currentFirstTime ) { - currentFirstTime = time; - currentStepPoint = *stepsit; - } - } - } - _firstInTracker = currentStepPoint; - return *_firstInTracker; - } - - // calculate the last StepPointMC in track - StepPointMC const& SimParticleInfo::lastStepPointMCinTracker() const { - - if ( _lastInTracker ) return *_lastInTracker; - else if ( _hitInfos.size() == 0 ) { - throw cet::exception("HITS") - << "_hitInfos is empty at " << __func__ << "\n"; - } - - double currentLastTime = -1; - StepPointMC const* currentStepPoint = 0; - - // loop over all straws - for ( std::vector::const_iterator strawsit = _hitInfos.begin(); strawsit!= _hitInfos.end(); ++strawsit ) { - std::vector const& steps = strawsit->steps(); - - // loop over all StepPointMC objects - for ( std::vector::const_iterator stepsit = steps.begin(); stepsit!=steps.end(); ++stepsit){ - - if ( (*stepsit)->trackId() == _simId ) { - double time = (*stepsit)->time(); - if ( time > currentLastTime ) { - currentLastTime = time; - currentStepPoint = *stepsit; - } - } - } - } - _lastInTracker = currentStepPoint; - return *_lastInTracker; - } - -} // end of namespace diff --git a/Mu2eUtilities/src/SimParticleTimeOffsets.cc b/Mu2eUtilities/src/SimParticleTimeOffsets.cc index 80a0e38921..d0950475bb 100644 --- a/Mu2eUtilities/src/SimParticleTimeOffsets.cc +++ b/Mu2eUtilities/src/SimParticleTimeOffsets.cc @@ -6,6 +6,7 @@ #include "art/Framework/Principal/Event.h" #include "MCDataProducts/inc/StepPointMC.hh" +#include "MCDataProducts/inc/StrawGasStep.hh" namespace mu2e { @@ -95,4 +96,8 @@ namespace mu2e { return s.time() + totalTimeOffset(s); } + double SimParticleTimeOffset::timeWithOffsetsApplied(const StrawGasStep& s) const { + return s.time() + totalTimeOffset(s.simParticle()); + } + } diff --git a/Mu2eUtilities/src/SimParticlesWithHits.cc b/Mu2eUtilities/src/SimParticlesWithHits.cc deleted file mode 100644 index 236a057ed4..0000000000 --- a/Mu2eUtilities/src/SimParticlesWithHits.cc +++ /dev/null @@ -1,180 +0,0 @@ -// -// This class makes available a collection of SimParticles that -// have more than a minimum number of StrawHits with energy deposition -// in the gas above some cut. The class can also return a -// vector of information about all of the StrawHits on each track -// in the collection. If a StrawHit contains contributions from -// more than one SimParticle, that StrawHit will appear in the hit lists -// for all of the contributing SimParticles. -// -// This class is not designed to be peristable. -// -// $Id: SimParticlesWithHits.cc,v 1.10 2014/05/01 00:33:33 murat Exp $ -// $Author: murat $ -// $Date: 2014/05/01 00:33:33 $ -// -// Original author Rob Kutschke. -// -// Notes: -// 1) Near the end of the c'tor we loop over a map and remove entries with -// too few hits. To make erase work properly we must use the -// postincrement ++ on the iterator that is the argument to erase. See -// Josuttis (1999) section 6.6 p 205. - -// Framework includes -#include "art/Framework/Principal/Event.h" - -// Mu2e includes -#include "Mu2eUtilities/inc/SimParticlesWithHits.hh" - -using namespace std; - -namespace mu2e{ - - SimParticlesWithHits::SimParticlesWithHits( const art::Event& evt, - string const& _g4ModuleLabel, - string const& _hitMakerModuleLabel, - string const& _trackerStepPoints, - double minEnergyDep, - size_t minHits ): - _hitsPerTrack(), - _hits_mcptr(0){ - - // Get information from the event. - art::Handle pdataHandle; - evt.getByLabel(_hitMakerModuleLabel,pdataHandle); - StrawHitCollection const& hits = *pdataHandle; - - art::Handle truthHandle; - evt.getByLabel(_hitMakerModuleLabel,truthHandle); - - if (!truthHandle.isValid()) { - printf(" ERROR in SimParticlesWithHits::SimParticlesWithHits: StrawHitMCTruthCollection by %s not found\n", - _hitMakerModuleLabel.data()); - return; - } - - StrawHitMCTruthCollection const& hits_truth = *truthHandle; - - art::Handle mcptrHandle; - evt.getByLabel(_hitMakerModuleLabel,"StrawHitMCPtr",mcptrHandle); - _hits_mcptr = mcptrHandle.product(); - - art::Handle simsHandle; - evt.getByLabel(_g4ModuleLabel,simsHandle); - if (!simsHandle.isValid()) { - printf(" ERROR in SimParticlesWithHits::SimParticlesWithHits: SimParticleCollection by %s not found\n", - _g4ModuleLabel.data()); - return; - } - SimParticleCollection const& sims = *simsHandle; - - // Loop over all straw hits. - for ( size_t ihit=0; ihitat(ihit)); - - // Skip hits with too little energy deposited in the straw. - if ( hit.energyDep() < minEnergyDep ){ - continue; - } - - // Find all simulated tracks that contribute to this hit. - set contributingTracks; - for ( size_t istep = 0; istep::const_iterator icontrib=contributingTracks.begin(); - icontrib != contributingTracks.end(); ++icontrib){ - - key_type key=*icontrib; - if(!sims.has(key)) continue; //this is only a quick bug fix - //this case occurs if the number of sim particles - //is manually limited in the geometry config file - //via g4.particlesSizeLimit - - // Find the SimParticleInfo in the map; if absent, create it. - map::iterator ii = _hitsPerTrack.find(key); - if ( ii == _hitsPerTrack.end() ){ - pair::iterator,bool> yy = _hitsPerTrack.insert( - make_pair(key,SimParticleInfo( key, sims[*icontrib], evt)) ); - ii = yy.first; - } - - // Add information about this hit to this track. - vector& vv = ii->second.strawHitInfos(); - vv.push_back(StrawHitMCInfo(evt,key,ihit,hit,truth,mcptr,contributingTracks.size()) ); - - } - } - - // Remove tracks with too few hits. - // For tracks that remain, sort in order of increasing time. - // See note 1 about using erase on a map. - for ( map_type::iterator i=_hitsPerTrack.begin(); - i != _hitsPerTrack.end(); ){ - vector& v = i->second.strawHitInfos(); - if ( v.size() < minHits ){ - _hitsPerTrack.erase(i++); - } else{ - sort ( v.begin(), v.end() ); - ++i; - } - } - - // Check that the map is self consistent. - selfTest(); - - } // end c'tor - - SimParticlesWithHits::mapped_type const* SimParticlesWithHits::findOrNull( key_type key){ - const_iterator i = _hitsPerTrack.find(key); - if ( i == _hitsPerTrack.end() ) return 0; - return &i->second; - } - - SimParticlesWithHits::mapped_type const& SimParticlesWithHits::at( key_type key){ - mapped_type const* p = findOrNull(key); - if ( !p ){ - ostringstream out; - out << "SimParticlesWithHits: no such key " << key; - throw std::out_of_range( out.str() ); - } - return *p; - } - - // Follow pointers from SimParticles to StepPointMC and check that the StepPointMCs - // are indeed created by this SimParticle. - void SimParticlesWithHits::selfTest(){ - - for ( map_type::const_iterator i=_hitsPerTrack.begin(); - i != _hitsPerTrack.end(); ++i ){ - key_type simId = i->first; - vector const& v = i->second.strawHitInfos(); - for ( size_t j=0; jat(info.index())); - bool ok = false; - for ( size_t k=0; ksize(); ++i){ - - StepPointMC const* step = _mcPtr->at(i).get(); - _stepPointMCs.push_back( step ); - - if ( step->trackId() == trackId ){ - double t = step->time(); - _time = ( t < _time ) ? t : _time; - } - - } - - } // StrawHitMCInfo::fillStepPointMCs - -} // namespace mu2e diff --git a/Mu2eUtilities/src/particleEnteringG4Volume.cc b/Mu2eUtilities/src/particleEnteringG4Volume.cc index 66b146bb7f..93e7d894a0 100644 --- a/Mu2eUtilities/src/particleEnteringG4Volume.cc +++ b/Mu2eUtilities/src/particleEnteringG4Volume.cc @@ -14,3 +14,7 @@ art::Ptr mu2e::particleEnteringG4Volume(const StepPointMC& st return p; } +art::Ptr mu2e::particleEnteringG4Volume(const StrawGasStep& step) { + art::Ptr p = step.simParticle(); + return p; +} diff --git a/Print/src/SConscript b/Print/src/SConscript index 4a46ab9b27..ee6d1cfbfd 100644 --- a/Print/src/SConscript +++ b/Print/src/SConscript @@ -20,6 +20,7 @@ mainlib = helper.make_mainlib ( [ 'mu2e_GeometryService', 'mu2e_MCDataProducts', 'mu2e_Mu2eInterfaces', 'mu2e_RecoDataProducts', + 'mu2e_DataProducts', babarlibs, 'art_Framework_Core', 'art_Framework_Principal', diff --git a/Print/src/StrawDigiMCPrinter.cc b/Print/src/StrawDigiMCPrinter.cc index 9d2435b92e..a49460f04d 100644 --- a/Print/src/StrawDigiMCPrinter.cc +++ b/Print/src/StrawDigiMCPrinter.cc @@ -97,10 +97,6 @@ mu2e::StrawDigiMCPrinter::Print(const mu2e::StrawDigiMC& obj, int ind, std::ostr << obj.wireEndTime(StrawEnd::cal) << " " << std::setw(8) << std::setprecision(2) << obj.wireEndTime(StrawEnd::hv) - << " " << std::setw(8) << std::setprecision(4) - << obj.driftDistance(StrawEnd::cal) - << " " << std::setw(8) << std::setprecision(4) - << obj.driftDistance(StrawEnd::hv) << " " << std::setw(8) << std::setprecision(4) << energy << " " << std::setw(6) << obj.isCrossTalk(StrawEnd::cal) << " " << std::setw(6) << obj.isCrossTalk(StrawEnd::hv) @@ -114,18 +110,8 @@ mu2e::StrawDigiMCPrinter::Print(const mu2e::StrawDigiMC& obj, int ind, std::ostr << obj.wireEndTime(StrawEnd::cal) << " time1: " << std::setw(8) << std::setprecision(2) << obj.wireEndTime(StrawEnd::hv) - << " drift0: " << std::setw(8) << std::setprecision(4) - << obj.driftDistance(StrawEnd::cal) - << " drift1:" << std::setw(8) << std::setprecision(4) - << obj.driftDistance(StrawEnd::hv) << " " ; os << std::endl; - os << " driftMid0: " << std::setw(10) << std::setprecision(4) - << obj.distanceToMid(StrawEnd::cal) - << " driftMid1:" << std::setw(10) << std::setprecision(4) - << obj.distanceToMid(StrawEnd::hv) - << " energy: " << std::setw(8) << std::setprecision(4) << energy; - os << std::endl; os << " trigEnergy0: " << std::setw(8) << std::setprecision(4) << tenergy0 << " trigEnergy1: " << std::setw(8) << std::setprecision(4) @@ -159,7 +145,7 @@ mu2e::StrawDigiMCPrinter::Print(const mu2e::StrawDigiMC& obj, int ind, std::ostr os << " StepPointMC_0: " << " key: " << std::setw(5) << a0.key() << " energy: " << std::setw(8) << std::setprecision(6) - << a0->totalEDep() + << a0->eDep() << " Simparticle: " << std::setw(5) << isim; os << std::endl; } @@ -172,7 +158,7 @@ mu2e::StrawDigiMCPrinter::Print(const mu2e::StrawDigiMC& obj, int ind, std::ostr os << " StepPointMC_1: " << " key: " << std::setw(5) << a1.key() << " energy: " << std::setw(8) << std::setprecision(4) - << a1->totalEDep() + << a1->eDep() << " SimParticle: " << std::setw(5) << isim; os << std::endl; } diff --git a/Sandbox/src/PtrBug01_module.cc b/Sandbox/src/PtrBug01_module.cc deleted file mode 100644 index 9254366853..0000000000 --- a/Sandbox/src/PtrBug01_module.cc +++ /dev/null @@ -1,309 +0,0 @@ -// -// Tests for the bad Ptr bug -// -// $Id: PtrBug01_module.cc,v 1.5 2013/10/21 21:01:23 kutschke Exp $ -// $Author: kutschke $ -// $Date: 2013/10/21 21:01:23 $ -// -// Original author Rob Kutschke -// - -// Framework includes. -#include "art/Framework/Core/EDAnalyzer.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -// Mu2e includes. -#include "MCDataProducts/inc/GenParticleCollection.hh" -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "MCDataProducts/inc/SimParticleCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" -#include "RecoDataProducts/inc/CaloCrystalHitCollection.hh" -#include "RecoDataProducts/inc/StrawHitCollection.hh" - -// C++ includes. -#include -#include -#include - -using namespace std; - -namespace mu2e { - - class PtrBug01 : public art::EDAnalyzer { - public: - - explicit PtrBug01(fhicl::ParameterSet const& pset); - virtual ~PtrBug01() { } - - // The framework calls this for each event. - void analyze(const art::Event& e); - - private: - - int which_; - - void bug01a( art::Event const& event); - void bug01b( art::Event const& event); - void bug01c( art::Event const& event); - void bug01d( art::Event const& event); - void bug01e( art::Event const& event); - void bug01f( art::Event const& event); - - - }; - - PtrBug01::PtrBug01(fhicl::ParameterSet const& pset ) - : art::EDAnalyzer(pset){ - cerr << "Select a test by entering a number: " << endl; - cerr << " 1 - From std::vector into another std::vector." << endl; - cerr << " 2 - From std::vector into a map_vector." << endl; - cerr << " 3 - From mapvector into a std::vector" << endl; - cerr << " 4 - Self reference into the same mapvector, mother" << endl; - cerr << " 5 - Self reference into the same mapvector, daughters" << endl; - cerr << " 6 - From vector to vector." << endl; - cin >> which_; - } - - void PtrBug01::analyze(const art::Event& event) { - - switch (which_){ - - case 1: - bug01a(event); - break; - - case 2: - bug01b(event); - break; - - case 3: - bug01c(event); - break; - - case 4: - bug01d(event); - break; - - case 5: - bug01e(event); - break; - - case 6: - bug01f(event); - break; - - default: - cerr << "No such test: " << endl; - - } - } - - // For an object inside a std::vector, follow a Ptr to - // another object in a different std::vector. - void PtrBug01::bug01a(const art::Event& event) { - - art::Handle crystalsHandle; - event.getByLabel("CaloCrystalHitsMaker", crystalsHandle); - CaloCrystalHitCollection const& crystals(*crystalsHandle); - cout << "CrystalHits.size: " << event.id() << " " << crystals.size() << endl; - - typedef CaloCrystalHitCollection::const_iterator Iter; - for ( Iter i=crystals.begin(), e=crystals.end(); i != e; ++i){ - CaloCrystalHit const& crystal(*i); - cerr << "Crystal: " - << crystal.id() << " " - << crystal.energyDep() << " " - << crystal.nROId() - << endl; - /* - std::vector > const & readouts = crystal.readouts(); - for ( std::vector >::const_iterator j=readouts.begin(), je=readouts.end(); - j != je; ++j ){ - art::Ptr const& p(*j); - cerr << " " - << p.id() << " " - << p.key() << " " - << p.productGetter() - << endl; - cerr << " " - << p->id() << " " - << p->energyDep() << " " - << endl; - } - */ - } - - } // end bug01a - - // For an object inside a std::vector, follow a Ptr to - // an object in a map_vector. - void PtrBug01::bug01b(const art::Event& event) { - - art::Handle stepsHandle; - event.getByLabel("g4run", "tracker", stepsHandle); - StepPointMCCollection const& steps(*stepsHandle); - - cout << "Steps.size: " << event.id() << " " << steps.size() << endl; - for ( StepPointMCCollection::const_iterator i=steps.begin(), e=steps.end(); - i != e; ++i){ - StepPointMC const& step(*i); - - cout << "Step: " - << step.volumeId() << " " - << step.totalEDep()*1000. << " " // keV - << step.simParticle().id() << " " - << step.simParticle().key() << " | " - << step.simParticle().productGetter() - << endl; - - cout << " Step 1: " - << step.simParticle()->id() - << endl; - cout << " Step 2: " << endl; - } - - } // end bug01b - - // For an object inside a map_vector, follow a Ptr to - // an object in a std::vector. - void PtrBug01::bug01c(const art::Event& event) { - - art::Handle simsHandle; - event.getByLabel("g4run", simsHandle); - SimParticleCollection const& sims(*simsHandle); - - cout << "Sims.size: " << event.id() << " " << sims.size() << endl; - for ( SimParticleCollection::const_iterator i=sims.begin(), e=sims.end(); - i != e; ++i){ - SimParticle const& sim(i->second); - cout << "Sim: " - << sim.id() << " " - << sim.genParticle().id() << " " - << sim.genParticle().key() << " " - << sim.genParticle().productGetter() - << endl; - if ( sim.isPrimary() ){ - cout << " Gen 1: " - << sim.genParticle()->pdgId() - << endl; - cout << " Gen 2: " << endl; - } - } - - } // end bug01c - - // For an object inside a map_vector, follow a Ptr to - // another object in the same map_vector. - void PtrBug01::bug01d(const art::Event& event) { - - art::Handle simsHandle; - event.getByLabel("g4run", simsHandle); - SimParticleCollection const& sims(*simsHandle); - - cout << "Sims.size: " << sims.size() << endl; - for ( SimParticleCollection::const_iterator i=sims.begin(), e=sims.end(); - i != e; ++i){ - SimParticle const& sim(i->second); - cout << "Sim: " - << sim.id() << " " - << sim.parent().id() << " " - << sim.parent().key() << " " - << sim.parent().productGetter() - << endl; - if ( sim.hasParent() ){ - cout << ": " - << sim.parent()->id() - << endl; - } - } - - } // end bug01d - - // For an object inside a map_vector, follow a vector to - // objects in the same map_vector. - void PtrBug01::bug01e(const art::Event& event) { - - art::Handle simsHandle; - event.getByLabel("g4run", simsHandle); - SimParticleCollection const& sims(*simsHandle); - - cout << "Sims.size: " << sims.size() << endl; - for ( SimParticleCollection::const_iterator i=sims.begin(), e=sims.end(); - i != e; ++i){ - SimParticle const& sim(i->second); - std::vector > const& daughters(sim.daughters()); - cout << "Sim: " - << sim.id() << " " - << daughters.size() << " " - << endl; - for ( std::vector >::const_iterator j=daughters.begin(), je=daughters.end(); - j != je; ++j){ - art::Ptr const& dau(*j); - cout << " Dau: " - << dau.id() << " " - << dau.key() << " " - << dau.productGetter() << " " - << endl; - cout << " " << dau->id() << endl; - } - } - - } // end bug01e - - // For an object inside a map_vector, follow a vector to - // objects in the same map_vector. - void PtrBug01::bug01f(const art::Event& event) { - - art::Handle strawsHandle; - event.getByLabel("makeSH", strawsHandle); - StrawHitCollection const& straws(*strawsHandle); - - art::Handle stepPtrsHandle; - event.getByLabel("makeSH", "StrawHitMCPtr", stepPtrsHandle); - PtrStepPointMCVectorCollection const& stepPtrs(*stepPtrsHandle); - - cout << "Straws.size: " << straws.size() << endl; - for ( size_t i=0; i p(steps[j]); - cout << " " - << j << " " - << p.id() << " " - << p.key() << " " - << p.productGetter() << " " - << endl; - cout << " " - << p->trackId() << " " - << p->volumeId() << " " - << p->totalEDep()*1000. // keV - << endl; - sum += p->totalEDep(); - } - cout << " Sum: " - << sum*1000. << " " - << straw.energyDep()*1000.<< " " // keV - << ( sum - straw.energyDep())*1000 - << endl; - } - - } // end bug01f - - -} // end namespace mu2e - -// Part of the magic that makes this class a module. -// create an instance of the module. It also registers -using mu2e::PtrBug01; -DEFINE_ART_MODULE(PtrBug01) diff --git a/TrackCaloMatching/src/SConscript b/TrackCaloMatching/src/SConscript index b441b52b36..8316961bf5 100644 --- a/TrackCaloMatching/src/SConscript +++ b/TrackCaloMatching/src/SConscript @@ -21,6 +21,7 @@ mainlib = helper.make_mainlib ( [ 'mu2e_CalorimeterGeom', 'mu2e_Mu2eInterfaces', 'mu2e_RecoDataProducts', + 'mu2e_DataProducts', babarlibs, rootlibs, 'art_Framework_Services_Registry', @@ -38,8 +39,9 @@ helper.make_plugins( [ mainlib, 'mu2e_ConditionsService', 'mu2e_GeometryService', - 'mu2e_RecoDataProducts', 'mu2e_MCDataProducts', + 'mu2e_RecoDataProducts', + 'mu2e_DataProducts', 'mu2e_CalorimeterGeom', 'mu2e_TrackerGeom', 'mu2e_ConfigTools', diff --git a/TrackCaloMatching/src/TrkExtrapol_module.cc b/TrackCaloMatching/src/TrkExtrapol_module.cc index 22e8c38d19..11b2b9f404 100644 --- a/TrackCaloMatching/src/TrkExtrapol_module.cc +++ b/TrackCaloMatching/src/TrkExtrapol_module.cc @@ -42,8 +42,6 @@ #include "RecoDataProducts/inc/StrawHitCollection.hh" #include "RecoDataProducts/inc/StrawHit.hh" #include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "MCDataProducts/inc/StrawHitMCTruth.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "RecoDataProducts/inc/TrkToCaloExtrapol.hh" diff --git a/TrackerMC/inc/IonCluster.hh b/TrackerMC/inc/IonCluster.hh index 7f76d2097a..fa8ca8e1df 100644 --- a/TrackerMC/inc/IonCluster.hh +++ b/TrackerMC/inc/IonCluster.hh @@ -1,16 +1,16 @@ #ifndef TrackerMC_IonCluster_hh #define TrackerMC_IonCluster_hh -#include "CLHEP/Vector/ThreeVector.h" +#include "DataProducts/inc/XYZVec.hh" #include "Rtypes.h" namespace mu2e { struct IonCluster { // ion charge cluster before drift or amplification - CLHEP::Hep3Vector _pos; // position of this cluster - Float_t _phi; //JB: initial angle of the cluster WRT the wire and the BField + XYZVec _pos; // position of this cluster + Float_t _phi; // initial angle of the cluster WRT the wire and the BField Float_t _charge; // charge of this cluster, in pC. Note: this is pre-gain!!! Float_t _eion; // ionization energy of this cluster, in MeV UInt_t _ne; // number of electrons in this cluster - IonCluster(CLHEP::Hep3Vector const& pos, double phi, double charge, double eion, unsigned ne): - _pos(pos), _phi(phi),_charge(charge),_eion(eion),_ne(ne) {} //JB ADDED PHI + IonCluster(XYZVec const& pos, double phi, double charge, double eion, unsigned ne): + _pos(pos), _phi(phi),_charge(charge),_eion(eion),_ne(ne) {} IonCluster() : _charge(0.0), _eion(0.0), _ne(0) {} }; } diff --git a/TrackerMC/inc/StrawCluster.hh b/TrackerMC/inc/StrawCluster.hh index e9ff388fdb..b8ab3bbc48 100644 --- a/TrackerMC/inc/StrawCluster.hh +++ b/TrackerMC/inc/StrawCluster.hh @@ -35,7 +35,7 @@ namespace mu2e { explicit StrawCluster(const StrawCluster& primary, double deltat); explicit StrawCluster(ClusterType type,StrawId sid, StrawEnd end, - double time, + float time, float charge, float ddist, float phi, @@ -43,6 +43,18 @@ namespace mu2e { float drifttime, float proptime, art::Ptr const& sgs, + XYZVec const& cpos, float ctime); + + // legacy constructor + explicit StrawCluster(ClusterType type,StrawId sid, + StrawEnd end, + double time, + float charge, + float ddist, + float phi, + float wdist, + float drifttime, + float proptime, art::Ptr const& stepmc, CLHEP::HepLorentzVector const& cpos); // use compiler version of copy, assignment @@ -58,24 +70,27 @@ namespace mu2e { float driftTime() const { return _drifttime; } float propTime() const { return _proptime; } art::Ptr const& strawGasStep() const { return _sgsptr; } - art::Ptr const& stepPointMC() const { return _spmcptr; } - CLHEP::HepLorentzVector const& clusterPosition() const { return _cpos; } + float cluTime() const { return _ctime; } + XYZVec const& cluPos() const { return _cpos; } + art::Ptr const& stepPointMC() const { return _spmcptr; } // Legacy function FIXME + CLHEP::HepLorentzVector clusterPosition() const { return CLHEP::HepLorentzVector(Geom::Hep3Vec(_cpos),_ctime); } // legacy function FIXME // Print contents of the object. void print( std::ostream& ost = std::cout, bool doEndl = true ) const; private: - ClusterType _type; // type of clust + ClusterType _type; // type of cluster StrawId _strawId; // Straw id StrawEnd _end; // which end of the straw - double _time; // microbunch time at the wire end, in ns since EventWindowMarker - float _charge; // charge at the wire end, in units of pC - float _ddist; // drift distance charge traveled to the wire - float _phi; //JB: angle between E and B at ionization event - float _wdist; // distance along the wire the charge has traveled, used to calculate dispersion - float _drifttime; - float _proptime; - art::Ptr _sgsptr; // reference to step - art::Ptr _spmcptr; // legacy ref to StepPointMC FIXME! - CLHEP::HepLorentzVector _cpos; // position and time of the cluster that created this clust + float _time; // microbunch time at the wire end, in ns since EventWindowMarker, offsets and wrapping applied + float _charge; // charge at the wire end, in units of pC + float _ddist; // drift distance charge traveled to the wire + float _phi; // angle between E and B at ionization event + float _wdist; // distance along the wire the charge has traveled, used to calculate dispersion + float _drifttime; // drift time to the wire + float _proptime; // propagation time to the wire end + art::Ptr _sgsptr; + art::Ptr _spmcptr; // legacy ref to StepPointMC should be removed after testing FIXME! + XYZVec _cpos; + float _ctime; }; } // namespace TrackerMC } // namespace mu2e diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index 83cbf12ce4..bd78dc8216 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -75,7 +75,6 @@ namespace mu2e { Comment("Dont combine Deltas from this module's collection")}; fhicl::Atom startSize { Name("StartSize"), Comment("Starting size for straw-particle vector"),4}; - fhicl::Sequence SPTO { Name("TimeOffsets"), Comment("Sim Particle Time Offset Maps")}; fhicl::Atom allStepsAssns{ Name("AllStepsAssns"), Comment("Build the association to all the contributing StepPointMCs"),false}; }; @@ -108,7 +107,6 @@ namespace mu2e { float _curlfac, _linefac; float _curlmom, _linemom; unsigned _csize, _ssize; - SimParticleTimeOffset _toff; // time offsets string _keepDeltas; // StepPointMC selector // This selector will select only data products with the given instance name. @@ -142,7 +140,6 @@ namespace mu2e { _linefac(config().lineRatio()), _csize(config().csize()), _ssize(config().startSize()), - _toff(config().SPTO()), _keepDeltas(config().keepDeltas()), _selector{art::ProductInstanceNameSelector(config().trackerSteps()) && !art::ModuleLabelSelector(config().stepsToSkip()) }, @@ -150,9 +147,8 @@ namespace mu2e { { consumesMany(); produces (); - // 2 associations: one to all the constituent StepPointMCs, the other to the first (in time) primary - produces ("Primary"); - if(_allAssns)produces ("All"); + // associations: to all the constituent StepPointMCs + if(_allAssns)produces (); } void MakeStrawGasSteps::beginJob(){ @@ -202,12 +198,10 @@ namespace mu2e { const Tracker& tracker = *GeomHandle(); GlobalConstantsHandle pdt; DeadStraw const& deadStraw = _deadStraw_h.get(event.id()); - _toff.updateMap(event); // create output unique_ptr sgsc(new StrawGasStepCollection); sgsc->reserve(_csize); - unique_ptr sgsa_primary(new StrawGasStepAssns); - unique_ptr sgsa_all(new StrawGasStepAssns); + unique_ptr sgsa(new StrawGasStepAssns); // needed for making Ptrs auto StrawGasStepCollectionPID = event.getProductID(); auto StrawGasStepCollectionGetter = event.productGetter(StrawGasStepCollectionPID); @@ -263,19 +257,17 @@ namespace mu2e { SPMCP spmcptr; fillStep(spmcptrs,straw,pdata,pid,sgs,spmcptr); sgsc->push_back(sgs); - // create the Assns to the 'trigger' StepPointMC - auto sgsp = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); - sgsa_primary->addSingle(sgsp,spmcptr); + auto sgsptr = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); // optionall add Assns for all StepPoints, including delta-rays if(_allAssns){ for(auto const& spmcptr : spmcptrs) - sgsa_all->addSingle(sgsp,spmcptr); + sgsa->addSingle(sgsptr,spmcptr); } if(_diag > 0)fillStepDiag(straw,sgs,spmcptr,spmcptrs); if(_debug > 1){ // checks and printout - cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << spmcptr->simParticle().id() - << " edep = " << sgs.ionizingEdep() << " pathlen = " << sgs.pathLength() << " glen = " << sqrt((sgs.endPosition()-sgs.startPosition()).mag2()) << " width = " << sgs.width() + cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << sgs.simParticle()->id() + << " edep = " << sgs.ionizingEdep() << " pathlen = " << sgs.stepLength() << " glen = " << sqrt((sgs.endPosition()-sgs.startPosition()).mag2()) << " width = " << sgs.width() << " time = " << sgs.time() << endl; // check if end is inside physical straw @@ -291,8 +283,7 @@ namespace mu2e { cout << "Total number of StrawGasSteps " << sgsc->size() << " , StepPointMCs = " << nspmcs << endl; } event.put(move(sgsc)); - event.put(move(sgsa_primary),"Primary"); - if(_allAssns) event.put(move(sgsa_all),"All"); + if(_allAssns) event.put(move(sgsa)); } // end of produce void MakeStrawGasSteps::fillStep(SPMCPV const& spmcptrs, Straw const& straw, @@ -331,8 +322,6 @@ namespace mu2e { } if(first.isNull() || last.isNull()) throw cet::exception("SIM")<<"mu2e::MakeStrawGasSteps: No first or last step" << endl; - // for now, define the first StepPoint as the 'trigger' for this step. Eventually - // this might be the one closest to the wire FIXME! spmcptr = first; // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last XYZVec start = Geom::toXYZVec(first->position()); @@ -344,7 +333,9 @@ namespace mu2e { // compute the end position and step type // in future we should store the end position in the StepPointMC FIXME! XYZVec end = endPosition(last,straw,charge,stype); - float mom = 0.5*(first->momentum().mag() + last->momentum().mag()); // average first and last momentum + + XYZVec momvec = Geom::toXYZVec(0.5*(first->momentum() + last->momentum())); // average first and last momentum + float mom = sqrt(momvec.mag2()); // determine the width from the sigitta or curl radius auto pdir = first->momentum().unit(); auto pperp = pdir.perp(_bdir); @@ -354,12 +345,10 @@ namespace mu2e { static const float prms(1.0/(12.0*sqrt(5.0))); // RMS for a parabola. This includes a factor 1/8 for the sagitta calculation too float sagrms = prms*sint*pathlen*pathlen*_bnom*pperp/mom; double width = std::min(sagrms,bendrms); // choose the smaller: different approximations work for different momenta/directions - // apply the time offsets - double stime = _toff.timeWithOffsetsApplied(*first); // create the gas step sgs = StrawGasStep( first->strawId(), stype, - (float)eion,(float)pathlen, (float)width, (float)stime, - start, end); + (float)eion,(float)pathlen, (float)width, first->time(), + start, end, momvec, first->simParticle()); } void MakeStrawGasSteps::fillMap(Tracker const& tracker,DeadStraw const& deadStraw, @@ -506,7 +495,7 @@ namespace mu2e { _hendrad->Fill(_erad); _hphi->Fill(_brot); if(_diag > 1){ - _prilen = sgs.pathLength(); + _prilen = sgs.stepLength(); _pridist = sqrt((sgs.endPosition()-sgs.startPosition()).mag2()); _partP = spmcptr->momentum().mag(); _partPDG = spmcptr->simParticle()->pdgId(); diff --git a/TrackerMC/src/StrawCluster.cc b/TrackerMC/src/StrawCluster.cc index 6db3648810..b8d8bbed97 100644 --- a/TrackerMC/src/StrawCluster.cc +++ b/TrackerMC/src/StrawCluster.cc @@ -12,7 +12,21 @@ namespace mu2e { namespace TrackerMC { StrawCluster::StrawCluster() : _type(unknown), _strawId(0), _end(StrawEnd::cal), _time(0.0), _charge(0.0), _ddist(0.0),_phi(0.0), _wdist(0.0), _drifttime(0.0), _proptime(0.0) {} + StrawCluster::StrawCluster(ClusterType type,StrawId sid, + StrawEnd end, + float time, + float charge, + float ddist, + float phi, + float wdist, + float drifttime, + float proptime, + art::Ptr const& sgsptr, + XYZVec const& cpos, float ctime) : _type(type), _strawId(sid), _end(end), _time(time), + _charge(charge), _ddist(ddist), _phi(phi),_wdist(wdist), _drifttime(drifttime), _proptime(proptime), _sgsptr(sgsptr), _cpos(cpos), _ctime(ctime) {} + + StrawCluster::StrawCluster(ClusterType type,StrawId sid, StrawEnd end, double time, float charge, @@ -21,10 +35,9 @@ namespace mu2e { float wdist, float drifttime, float proptime, - art::Ptr const& sgs, art::Ptr const& stepmc, CLHEP::HepLorentzVector const& cpos) : _type(type), _strawId(sid), _end(end), _time(time), - _charge(charge), _ddist(ddist), _phi(phi),_wdist(wdist), _drifttime(drifttime), _proptime(proptime), _sgsptr(sgs), _spmcptr(stepmc), _cpos(cpos) + _charge(charge), _ddist(ddist), _phi(phi),_wdist(wdist), _drifttime(drifttime), _proptime(proptime), _spmcptr(stepmc), _cpos(cpos) {} // delegating constructors in C++11! diff --git a/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc b/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc index 82dbf7846d..747d50c4ef 100644 --- a/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc +++ b/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc @@ -552,7 +552,6 @@ namespace mu2e { art::Ptr const& spmcptr, Straw const& straw, StrawClusterSequencePair& shsp) { StepPointMC const& step = *spmcptr; - art::Ptr sgsptr;// kludge for backwards compatibility StrawId sid = straw.id(); // get time offset for this step double tstep = _toff.timeWithOffsetsApplied(step); @@ -595,8 +594,9 @@ namespace mu2e { // convert from double ctime = microbunchTime(strawele,gtime); // create the clust - StrawCluster clust(StrawCluster::primary,sid,end,ctime,weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time, - sgsptr,spmcptr,CLHEP::HepLorentzVector(iclu->_pos,mbtime)); //JB: + wireq._phi + StrawCluster clust(StrawCluster::primary,sid,end,ctime, + weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time, + spmcptr,CLHEP::HepLorentzVector(Geom::Hep3Vec(iclu->_pos),mbtime)); // add the clusts to the appropriate sequence. shsp.clustSequence(end).insert(clust); @@ -618,8 +618,8 @@ namespace mu2e { } // get tracker information - const Tracker& tracker = *GeomHandle(); //JB - const Straw& straw = tracker.getStraw(step.strawId());//JB + const Tracker& tracker = *GeomHandle(); + const Straw& straw = tracker.getStraw(step.strawId()); // if the step length is small compared to the mean free path, or this is an // uncharged particle, put all the energy in a single cluster if (charge == 0.0 || step.stepLength() < strawphys.meanFreePath()){ @@ -627,11 +627,11 @@ namespace mu2e { double fne = cen/strawphys.meanElectronEnergy(); unsigned ne = std::max( static_cast(_randP(fne)),(unsigned)1); - Hep3Vector cdir = (step.position()-straw.getMidPoint());//JB - cdir -= straw.getDirection()*(cdir.dot(straw.getDirection()));//JB - double phi = cdir.theta(); //JB + Hep3Vector cdir = (step.position()-straw.getMidPoint()); + cdir -= straw.getDirection()*(cdir.dot(straw.getDirection())); + double phi = cdir.theta(); for (size_t i=0;i threshpart = mcdigi.stepPointMC(StrawEnd::cal); + auto threshpart = mcdigi.stepPointMC(StrawEnd::cal); if(threshpart.isNull()) threshpart = mcdigi.stepPointMC(StrawEnd::hv); for(auto imcs = mcdigi.stepPointMCs().begin(); imcs!= mcdigi.stepPointMCs().end(); ++ imcs){ // if the SimParticle for this step is the same as the one which fired the discrim, add the energy diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc index b49b9d7427..541339159f 100644 --- a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -68,193 +68,195 @@ namespace mu2e { using namespace TrkTypes; struct WireCharge { // charge at the wire after drift - double _charge; // charge at the wire, in units of pC - double _time; // relative time at the wire, relative to ionzation time (ns) - double _dd; // transverse distance drifted to the wrie - double _phi; //JB: angle between E and B at ionization event - double _wpos; // position long the wire, WRT the wire center, signed by the wire direction + float _charge; // charge at the wire, in units of pC + float _time; // relative time at the wire, relative to ionzation time (ns) + float _dd; // transverse distance drifted to the wrie + float _phi; // angle between E and B at ionization event + float _wpos; // position long the wire, WRT the wire center, signed by the wire direction }; struct WireEndCharge { // charge at one end of the wire after propagation - double _charge; // charge at the wire, in units of pC - double _time; // time at the wire end, relative to the time the charge reached the wire (ns) - double _wdist; // propagation distance from the point of collection to the end + float _charge; // charge at the wire, in units of pC + float _time; // time at the wire end, relative to the time the charge reached the wire (ns) + float _wdist; // propagation distance from the point of collection to the end }; class StrawDigisFromStrawGasSteps : public art::EDProducer { - public: - using Name=fhicl::Name; - using Comment=fhicl::Comment; - - struct Config { - fhicl::Atom debug{ Name("debugLevel"), Comment("Debug Level"), 0}; - fhicl::Atom diag{ Name("diagLevel"), Comment("Diag Level"), 0}; - fhicl::Atom print{ Name("printLevel"), Comment("Print Level"), 0}; - fhicl::Atom maxhist{ Name("MaxHist"), Comment("Maximum number of waveform histograms"), 100}; - fhicl::Atom xtalkhist{ Name("CrossTalkHist"), Comment("Histogram of cross-talk"), false}; - fhicl::Atom minnxinghist{ Name("MinNXingHist"), Comment("Minimum # of crossings to histogram waveform"),1}; - fhicl::Atom tstep { Name("WaveformStep"), Comment("WaveformStep (nsec)"),0.1 }; - fhicl::Atom nfall{ Name("WaveformTail"), Comment("# of decay lambda past last signal to record waveform"),10.0}; - fhicl::Atom maxFullPrint{ Name("maxFullPrint"), Comment("Limit on number of events for which there will be full printout") ,2}; - fhicl::Atom addXtalk{ Name("addCrossTalk"), Comment("Should we add cross talk hits?"),false }; - fhicl::Atom ctMinCharge{ Name("xtalkMinimumCharge"), Comment("minimum charge to add cross talk (for performance issues)") ,0}; - fhicl::Atom addNoise{ Name("addNoise"), Comment("should we add noise hits? NOT CURRENTLY IMPLEMENTED FIXME!"),false }; - fhicl::Atom preampxtalk{ Name("preAmplificationCrossTalk"), Comment("Pre-amplification (straw) X-talk coupling"), 0.0 }; - fhicl::Atom postampxtalk{ Name("postAmplificationCrossTalk"), Comment("Post-amplification (board) X-talk coupling") ,0.02}; - fhicl::Atom bgcut{ Name("BetaGammaCut"), Comment("treat particles with beta-gamma above this as minimum-ionizing"),0.5 }; - fhicl::Atom minstepE{ Name("minstepE"), Comment(" minimum step energy depostion to turn into a straw signal (MeV)"),2.0e-6 }; - fhicl::Atom ewMarkerTag{ Name("EventWindowMarker"), Comment("EventWindowMarker producer"),"EWMProducer" }; - fhicl::Atom StrawGasStepCollectionTag{ Name("StrawGasStepCollection"), Comment("StrawGasStepCollection producer"),"SGSMaker" }; - fhicl::Atom steptimebuf{ Name("StrawGasStepTimeBuffer"), Comment("buffer for MC step point times (nsec) ") ,100.0 }; - fhicl::Atom flashBuffer{ Name("FlashTimeBuffer"), Comment("buffer for flash blanking times (nsec) ") ,10.0 }; - fhicl::Atom tdcbuf{ Name("TDCTimeBuffer"), Comment("buffer for TDC jitter (nsec) ") ,2.0 }; - fhicl::Atom allStraw{ Name("AllHitsStraw"), Comment("minimum straw # to read all hits") ,90}; - fhicl::Sequence allPlanes{ Name("AllHitsPlanes"), Comment("planes to read all hits"), std::vector{} }; - fhicl::Atom diagpath{ Name("DiagPath"), Comment("Digitization Path for waveform diagnostics") ,0 }; - fhicl::Atom sort{ Name("SortClusterEnergy"), Comment("Sort clusters by energy before digitizing") ,false }; - fhicl::Atom spinstance { Name("StrawGasStepInstance"), Comment("StrawGasStep Instance name"),""}; - }; + public: + using Name=fhicl::Name; + using Comment=fhicl::Comment; - typedef art::Ptr SGSPtr; - typedef art::Ptr SPMCPtr; - typedef map StrawClusterMap; // clusts by straw - // work with pairs of waveforms, one for each straw end - typedef std::array SWFP; - typedef std::array WFXP; - typedef list WFXPList; - typedef WFXPList::const_iterator WFXPI; + struct Config { + fhicl::Atom debug{ Name("debugLevel"), Comment("Debug Level"), 0}; + fhicl::Atom diag{ Name("diagLevel"), Comment("Diag Level"), 0}; + fhicl::Atom print{ Name("printLevel"), Comment("Print Level"), 0}; + fhicl::Atom maxhist{ Name("MaxHist"), Comment("Maximum number of waveform histograms"), 100}; + fhicl::Atom xtalkhist{ Name("CrossTalkHist"), Comment("Histogram of cross-talk"), false}; + fhicl::Atom minnxinghist{ Name("MinNXingHist"), Comment("Minimum # of crossings to histogram waveform"),1}; + fhicl::Atom tstep { Name("WaveformStep"), Comment("WaveformStep (nsec)"),0.1 }; + fhicl::Atom nfall{ Name("WaveformTail"), Comment("# of decay lambda past last signal to record waveform"),10.0}; + fhicl::Atom maxFullPrint{ Name("maxFullPrint"), Comment("Limit on number of events for which there will be full printout") ,2}; + fhicl::Atom addXtalk{ Name("addCrossTalk"), Comment("Should we add cross talk hits?"),false }; + fhicl::Atom ctMinCharge{ Name("xtalkMinimumCharge"), Comment("minimum charge to add cross talk (for performance issues)") ,0}; + fhicl::Atom addNoise{ Name("addNoise"), Comment("should we add noise hits? NOT CURRENTLY IMPLEMENTED FIXME!"),false }; + fhicl::Atom preampxtalk{ Name("preAmplificationCrossTalk"), Comment("Pre-amplification (straw) X-talk coupling"), 0.0 }; + fhicl::Atom postampxtalk{ Name("postAmplificationCrossTalk"), Comment("Post-amplification (board) X-talk coupling") ,0.02}; + fhicl::Atom minstepE{ Name("minstepE"), Comment(" minimum step energy depostion to turn into a straw signal (MeV)"),2.0e-6 }; + fhicl::Atom ewMarkerTag{ Name("EventWindowMarker"), Comment("EventWindowMarker producer"),"EWMProducer" }; + fhicl::Atom StrawGasStepCollectionTag{ Name("StrawGasStepCollection"), Comment("StrawGasStepCollection producer"),"SGSMaker" }; + fhicl::Atom steptimebuf{ Name("StrawGasStepTimeBuffer"), Comment("buffer for MC step point times (nsec) ") ,100.0 }; + fhicl::Atom flashBuffer{ Name("FlashTimeBuffer"), Comment("buffer for flash blanking times (nsec) ") ,10.0 }; + fhicl::Atom tdcbuf{ Name("TDCTimeBuffer"), Comment("buffer for TDC jitter (nsec) ") ,2.0 }; + fhicl::Atom allStraw{ Name("AllHitsStraw"), Comment("minimum straw # to read all hits") ,90}; + fhicl::Sequence allPlanes{ Name("AllHitsPlanes"), Comment("planes to read all hits"), std::vector{} }; + fhicl::Atom diagpath{ Name("DiagPath"), Comment("Digitization Path for waveform diagnostics") ,0 }; + fhicl::Atom sort{ Name("SortClusterEnergy"), Comment("Sort clusters by energy before digitizing") ,false }; + fhicl::Atom spinstance { Name("StrawGasStepInstance"), Comment("StrawGasStep Instance name"),""}; + fhicl::Sequence SPTO { Name("TimeOffsets"), Comment("Sim Particle Time Offset Maps")}; - using Parameters = art::EDProducer::Table; - explicit StrawDigisFromStrawGasSteps(const Parameters& config); - // Accept compiler written d'tor. + }; - private: + typedef art::Ptr SGSPtr; + typedef art::Ptr SPMCPtr; + typedef map StrawClusterMap; // clusts by straw + // work with pairs of waveforms, one for each straw end + typedef std::array SWFP; + typedef std::array WFXP; + typedef list WFXPList; + typedef WFXPList::const_iterator WFXPI; - void beginJob() override; - void beginRun(art::Run& run) override; - void produce(art::Event& e) override; + using Parameters = art::EDProducer::Table; + explicit StrawDigisFromStrawGasSteps(const Parameters& config); + // Accept compiler written d'tor. - // Diagnostics - int _debug, _diag, _printLevel; - unsigned _maxhist; - bool _xtalkhist; - unsigned _minnxinghist; - double _tstep, _nfall; - // Limit on number of events for which there will be full printout. - int _maxFullPrint; + private: - // Parameters - bool _addXtalk; - double _ctMinCharge; - bool _addNoise; - double _preampxtalk, _postampxtalk;// these should come from conditions, FIXME!! - double _bgcut; - double _minstepE; - art::InputTag _ewMarkerTag; - double _mbtime; - double _mbbuffer; - double _flashbuffer; - double _adcbuffer; - double _steptimebuf; - double _tdcbuf; - uint16_t _allStraw; - std::vector _allPlanes; - StrawElectronics::Path _diagpath; - unsigned _maxnclu; - bool _sort; // sort cluster sizes before filling energy - // Random number distributions - art::RandomNumberGenerator::base_engine_t& _engine; - CLHEP::RandGaussQ _randgauss; - CLHEP::RandFlat _randflat; - CLHEP::RandExponential _randexp; - CLHEP::RandPoisson _randP; - // A category for the error logger. - const string _messageCategory; - // Give some informationation messages only on the first event. - bool _firstEvent; - // Proditions - ProditionsHandle _strawphys_h; - ProditionsHandle _strawele_h; - art::Selector _selector; - // diagnostics - TTree* _swdiag; - Int_t _swplane, _swpanel, _swlayer, _swstraw, _ndigi; - Float_t _hqsum[2], _vmax[2], _tvmax[2], _sesum[2]; - Int_t _wmcpdg[2], _wmcproc[2], _nxing[2], _nclu[2]; - Int_t _nsteppoint[2], _npart[2]; - Float_t _mce[2], _slen[2], _sedep[2]; - Float_t _tmin[2], _tmax[2], _txing[2], _xddist[2], _xwdist[2], _xpdist[2]; - TTree* _sddiag; - Int_t _sdplane, _sdpanel, _sdlayer, _sdstraw; - Int_t _ncludd[2], _iclust[2]; - Int_t _nstep; - Float_t _ectime[2], _ecddist[2], _ecdtime[2], _ecptime[2]; - Float_t _xtime[2], _tctime[2], _charge[2], _ddist[2], _dtime[2], _ptime[2]; - Float_t _wdist[2], _vstart[2], _vcross[2]; - Float_t _phi[2]; //JB - Float_t _mcenergy, _mctrigenergy, _mcthreshenergy; - Double_t _mctime; - Int_t _mcthreshpdg, _mcthreshproc, _mcnstep; - Float_t _mcdca, _mcdcaphi, _mcdcadtime; - Int_t _dmcpdg, _dmcproc, _dmcgen; - Float_t _dmcmom; - Bool_t _xtalk; - vector _adc; - Int_t _tdc[2], _tot[2]; - TTree* _sdiag; - Float_t _steplen, _stepE, _qsum, _esum, _eesum, _qe, _partP, _steptime; - Int_t _nclust, _netot, _partPDG, _stype; - vector _clusters; - Float_t _ewMarkerOffset; - array _ewMarkerROCdt; + void beginJob() override; + void beginRun(art::Run& run) override; + void produce(art::Event& e) override; + + // Diagnostics + int _debug, _diag, _printLevel; + unsigned _maxhist; + bool _xtalkhist; + unsigned _minnxinghist; + double _tstep, _nfall; + // Limit on number of events for which there will be full printout. + int _maxFullPrint; + + // Parameters + bool _addXtalk; + double _ctMinCharge; + bool _addNoise; + double _preampxtalk, _postampxtalk;// these should come from conditions, FIXME!! + double _minstepE; + art::InputTag _ewMarkerTag; + double _mbtime; + double _mbbuffer; + double _flashbuffer; + double _adcbuffer; + double _steptimebuf; + double _tdcbuf; + uint16_t _allStraw; + std::vector _allPlanes; + StrawElectronics::Path _diagpath; + unsigned _maxnclu; + bool _sort; // sort cluster sizes before filling energy + // Random number distributions + art::RandomNumberGenerator::base_engine_t& _engine; + CLHEP::RandGaussQ _randgauss; + CLHEP::RandFlat _randflat; + CLHEP::RandExponential _randexp; + CLHEP::RandPoisson _randP; + // A category for the error logger. + const string _messageCategory; + // Give some informationation messages only on the first event. + bool _firstEvent; + // Proditions + ProditionsHandle _strawphys_h; + ProditionsHandle _strawele_h; + art::Selector _selector; + SimParticleTimeOffset _toff; // time offsets + // diagnostics + TTree* _swdiag; + Int_t _swplane, _swpanel, _swlayer, _swstraw, _ndigi; + Float_t _hqsum[2], _vmax[2], _tvmax[2], _sesum[2]; + Int_t _wmcpdg[2], _wmcproc[2], _nxing[2], _nclu[2]; + Int_t _nsteppoint[2], _npart[2]; + Float_t _mce[2], _slen[2], _sedep[2]; + Float_t _tmin[2], _tmax[2], _txing[2], _xddist[2], _xwdist[2], _xpdist[2]; + TTree* _sddiag; + Int_t _sdplane, _sdpanel, _sdlayer, _sdstraw; + Int_t _ncludd[2], _iclust[2]; + Int_t _nstep; + Float_t _ectime[2], _ecddist[2], _ecdtime[2], _ecptime[2]; + Float_t _xtime[2], _tctime[2], _charge[2], _ddist[2], _dtime[2], _ptime[2]; + Float_t _wdist[2], _vstart[2], _vcross[2]; + Float_t _phi[2]; + Float_t _mcenergy, _mctrigenergy, _mcthreshenergy; + Double_t _mctime; + Int_t _mcthreshpdg, _mcthreshproc, _mcnstep; + Float_t _mcdca, _mcdcaphi, _mcdcadtime; + Int_t _dmcpdg, _dmcproc, _dmcgen; + Float_t _dmcmom; + Bool_t _xtalk; + vector _adc; + Int_t _tdc[2], _tot[2]; + TTree* _sdiag; + Float_t _steplen, _stepE, _qsum, _esum, _eesum, _qe, _partP, _steptime; + Int_t _nclust, _netot, _partPDG, _stype; + vector _clusters; + Float_t _ewMarkerOffset; + array _ewMarkerROCdt; - // helper functions - void fillClusterMap(StrawPhysics const& strawphys, - StrawElectronics const& strawele,Tracker const& tracker, - art::Event const& event, StrawClusterMap & hmap); - void addStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - Straw const& straw, - SGSPtr const& sgsptr, - SPMCPtr const& spmcptr, - StrawClusterSequencePair& shsp); - void divideStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - Straw const& straw, - StrawGasStep const& step, - vector& clusters); - void driftCluster(StrawPhysics const& strawphys, Straw const& straw, - IonCluster const& cluster, WireCharge& wireq); - void propagateCharge(StrawPhysics const& strawphys, Straw const& straw, - WireCharge const& wireq, StrawEnd end, WireEndCharge& weq); - double microbunchTime(StrawElectronics const& strawele, double globaltime) const; - void addGhosts(StrawElectronics const& strawele, StrawCluster const& clust,StrawClusterSequence& shs); - void addNoise(StrawClusterMap& hmap); - void findThresholdCrossings(StrawElectronics const& strawele, SWFP const& swfp, WFXPList& xings); - void createDigis(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StrawClusterSequencePair const& hsp, - XTalk const& xtalk, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis); - void fillDigis(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - WFXPList const& xings,SWFP const& swfp , StrawId sid, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis); - bool createDigi(StrawElectronics const& strawele,WFXP const& xpair, SWFP const& wf, StrawId sid, StrawDigiCollection* digis); - void findCrossTalkStraws(Straw const& straw,vector& xtalk); - void fillClusterNe(StrawPhysics const& strawphys,std::vector& me); - void fillClusterPositions(StrawGasStep const& step, std::vector& cpos); - void fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& me, std::vector& cen); - bool readAll(StrawId const& sid) const; - // diagnostic functions - void waveformHist(StrawElectronics const& strawele, - SWFP const& wf, WFXPList const& xings); - void waveformDiag(StrawElectronics const& strawele, - SWFP const& wf, WFXPList const& xings); - void digiDiag(StrawPhysics const& strawphys, SWFP const& wf, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi); - void stepDiag(StrawPhysics const& strawphys, StrawElectronics const& strawele, - StrawGasStep const& sgs, StepPointMC const& spmc); + // helper functions + void fillClusterMap(StrawPhysics const& strawphys, + StrawElectronics const& strawele,Tracker const& tracker, + art::Event const& event, StrawClusterMap & hmap); + void addStep(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + Straw const& straw, + SGSPtr const& sgsptr, + SPMCPtr const& spmcptr, + StrawClusterSequencePair& shsp); + void divideStep(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + Straw const& straw, + StrawGasStep const& step, + vector& clusters); + void driftCluster(StrawPhysics const& strawphys, Straw const& straw, + IonCluster const& cluster, WireCharge& wireq); + void propagateCharge(StrawPhysics const& strawphys, Straw const& straw, + WireCharge const& wireq, StrawEnd end, WireEndCharge& weq); + double microbunchTime(StrawElectronics const& strawele, double globaltime) const; + void addGhosts(StrawElectronics const& strawele, StrawCluster const& clust,StrawClusterSequence& shs); + void addNoise(StrawClusterMap& hmap); + void findThresholdCrossings(StrawElectronics const& strawele, SWFP const& swfp, WFXPList& xings); + void createDigis(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + StrawClusterSequencePair const& hsp, + XTalk const& xtalk, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis); + void fillDigis(StrawPhysics const& strawphys, + StrawElectronics const& strawele, + WFXPList const& xings,SWFP const& swfp , StrawId sid, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis); + bool createDigi(StrawElectronics const& strawele,WFXP const& xpair, SWFP const& wf, StrawId sid, StrawDigiCollection* digis); + void findCrossTalkStraws(Straw const& straw,vector& xtalk); + void fillClusterNe(StrawPhysics const& strawphys,std::vector& me); + void fillClusterPositions(StrawGasStep const& step, std::vector& cpos); + void fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& me, std::vector& cen); + bool readAll(StrawId const& sid) const; + // diagnostic functions + void waveformHist(StrawElectronics const& strawele, + SWFP const& wf, WFXPList const& xings); + void waveformDiag(StrawElectronics const& strawele, + SWFP const& wf, WFXPList const& xings); + void digiDiag(StrawPhysics const& strawphys, SWFP const& wf, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi); + void stepDiag(StrawPhysics const& strawphys, StrawElectronics const& strawele, + StrawGasStep const& sgs, StepPointMC const& spmc); + float EBAngle(XYZVec const& cpos,Straw const& straw) const; }; StrawDigisFromStrawGasSteps::StrawDigisFromStrawGasSteps(const Parameters& config) : @@ -273,7 +275,6 @@ namespace mu2e { _addNoise(config().addNoise()), _preampxtalk(config().preampxtalk()), _postampxtalk(config().postampxtalk()), - _bgcut(config().bgcut()), _minstepE(config().minstepE()), _ewMarkerTag(config().ewMarkerTag()), _flashbuffer(config().flashBuffer()), @@ -292,16 +293,17 @@ namespace mu2e { _messageCategory("HITS"), _firstEvent(true), // Control some information messages. // This selector will select only data products with the given instance name. - _selector{ art::ProductInstanceNameSelector(config().spinstance()) } - { - // Tell the framework what we consume. - consumesMany(); - consumesMany(); - consumes(_ewMarkerTag); - // Tell the framework what we make. - produces(); - produces(); - } + _selector{ art::ProductInstanceNameSelector(config().spinstance())}, + _toff(config().SPTO()) + { + // Tell the framework what we consume. + consumesMany(); + consumesMany(); + consumes(_ewMarkerTag); + // Tell the framework what we make. + produces(); + produces(); + } void StrawDigisFromStrawGasSteps::beginJob(){ @@ -319,87 +321,87 @@ namespace mu2e { _sdiag->Branch("steptime",&_steptime,"steptime/F"); _sdiag->Branch("nclust",&_nclust,"nclust/I"); _sdiag->Branch("netot",&_netot,"netot/I"); - _sdiag->Branch("partPDG",&_partPDG,"partPDG/I"); - _sdiag->Branch("stepType",&_stype,"stepType/I"); - _sdiag->Branch("clusters",&_clusters); + _sdiag->Branch("partPDG",&_partPDG,"partPDG/I"); + _sdiag->Branch("stepType",&_stype,"stepType/I"); + _sdiag->Branch("clusters",&_clusters); - _swdiag =tfs->make("swdiag","StrawWaveform diagnostics"); - _swdiag->Branch("plane",&_swplane,"plane/I"); - _swdiag->Branch("panel",&_swpanel,"panel/I"); - _swdiag->Branch("layer",&_swlayer,"layer/I"); - _swdiag->Branch("straw",&_swstraw,"straw/I"); - _swdiag->Branch("ndigi",&_ndigi,"ndigi/I"); - _swdiag->Branch("hqsum",&_hqsum,"hqsumcal/F:hqsumhv/F"); - _swdiag->Branch("vmax",&_vmax,"vmaxcal/F:vmaxhv/F"); - _swdiag->Branch("tvmax",&_tvmax,"tvmaxcal/F:tvmaxhv/F"); - _swdiag->Branch("mcpdg",&_wmcpdg,"mcpdgcal/I:mcpdghv/I"); - _swdiag->Branch("mcproc",&_wmcproc,"mcproccal/I:mcprochv/I"); - _swdiag->Branch("mce",&_mce,"mcecal/F:mcehv/F"); - _swdiag->Branch("slen",&_slen,"slencal/F:slenhv/F"); - _swdiag->Branch("sedep",&_sedep,"sedepcal/F:sedephv/F"); - _swdiag->Branch("nxing",&_nxing,"nxingcal/I:nxinghv/I"); - _swdiag->Branch("nclust",&_nclu,"nclucal/I:ncluhv/I"); - _swdiag->Branch("nstep",&_nsteppoint,"nscal/I:nshv/I"); - _swdiag->Branch("sesum",&_sesum,"sesumcal/F:sesumhv/F"); - _swdiag->Branch("npart",&_npart,"npart/I"); - _swdiag->Branch("tmin",&_tmin,"tmincal/F:tminhv/F"); - _swdiag->Branch("tmax",&_tmax,"tmaxcal/F:tmaxhv/F"); - _swdiag->Branch("txing",&_txing,"txcal/F:txhv/F"); - _swdiag->Branch("xddist",&_xddist,"xdcal/F:xdhv/F"); - _swdiag->Branch("xwdist",&_xwdist,"xwdcal/F:xwdhv/F"); - _swdiag->Branch("xpdist",&_xpdist,"xpdcal/F:xpdhv/F"); + _swdiag =tfs->make("swdiag","StrawWaveform diagnostics"); + _swdiag->Branch("plane",&_swplane,"plane/I"); + _swdiag->Branch("panel",&_swpanel,"panel/I"); + _swdiag->Branch("layer",&_swlayer,"layer/I"); + _swdiag->Branch("straw",&_swstraw,"straw/I"); + _swdiag->Branch("ndigi",&_ndigi,"ndigi/I"); + _swdiag->Branch("hqsum",&_hqsum,"hqsumcal/F:hqsumhv/F"); + _swdiag->Branch("vmax",&_vmax,"vmaxcal/F:vmaxhv/F"); + _swdiag->Branch("tvmax",&_tvmax,"tvmaxcal/F:tvmaxhv/F"); + _swdiag->Branch("mcpdg",&_wmcpdg,"mcpdgcal/I:mcpdghv/I"); + _swdiag->Branch("mcproc",&_wmcproc,"mcproccal/I:mcprochv/I"); + _swdiag->Branch("mce",&_mce,"mcecal/F:mcehv/F"); + _swdiag->Branch("slen",&_slen,"slencal/F:slenhv/F"); + _swdiag->Branch("sedep",&_sedep,"sedepcal/F:sedephv/F"); + _swdiag->Branch("nxing",&_nxing,"nxingcal/I:nxinghv/I"); + _swdiag->Branch("nclust",&_nclu,"nclucal/I:ncluhv/I"); + _swdiag->Branch("nstep",&_nsteppoint,"nscal/I:nshv/I"); + _swdiag->Branch("sesum",&_sesum,"sesumcal/F:sesumhv/F"); + _swdiag->Branch("npart",&_npart,"npart/I"); + _swdiag->Branch("tmin",&_tmin,"tmincal/F:tminhv/F"); + _swdiag->Branch("tmax",&_tmax,"tmaxcal/F:tmaxhv/F"); + _swdiag->Branch("txing",&_txing,"txcal/F:txhv/F"); + _swdiag->Branch("xddist",&_xddist,"xdcal/F:xdhv/F"); + _swdiag->Branch("xwdist",&_xwdist,"xwdcal/F:xwdhv/F"); + _swdiag->Branch("xpdist",&_xpdist,"xpdcal/F:xpdhv/F"); - if(_diag > 1){ - _sddiag =tfs->make("sddiag","StrawDigi diagnostics"); - _sddiag->Branch("plane",&_sdplane,"plane/I"); - _sddiag->Branch("panel",&_sdpanel,"panel/I"); - _sddiag->Branch("layer",&_sdlayer,"layer/I"); - _sddiag->Branch("straw",&_sdstraw,"straw/I"); - _sddiag->Branch("nstep",&_nstep,"nstep/I"); - _sddiag->Branch("xtime",&_xtime,"xtimecal/F:xtimehv/F"); - _sddiag->Branch("tctime",&_tctime,"tctimecal/F:tctimehv/F"); - _sddiag->Branch("ectime",&_ectime,"ectimecal/F:ectimehv/F"); - _sddiag->Branch("ecdtime",&_ecdtime,"ecdtimecal/F:ecdtimehv/F"); - _sddiag->Branch("ecptime",&_ecptime,"ecptimecal/F:ecptimehv/F"); - _sddiag->Branch("charge",&_charge,"chargecal/F:chargehv/F"); - _sddiag->Branch("wdist",&_wdist,"wdistcal/F:wdisthv/F"); - _sddiag->Branch("phi",&_phi,"phical/F:phihv/F");//JB - _sddiag->Branch("ecddist",&_ecddist,"ecddistcal/F:ecddisthv/F"); - _sddiag->Branch("vstart",&_vstart,"vstartcal/F:vstarthv/F"); - _sddiag->Branch("vcross",&_vcross,"vcrosscal/F:vcrosshv/F"); - _sddiag->Branch("ddist",&_ddist,"ddistcal/F:ddisthv/F"); - _sddiag->Branch("dtime",&_dtime,"dtimecal/F:dtimehv/F"); - _sddiag->Branch("ptime",&_ptime,"ptimecal/F:ptimehv/F"); - _sddiag->Branch("nclust",&_ncludd,"nclustcal/I:nclusthv/I"); - _sddiag->Branch("iclust",&_iclust,"iclustcal/I:iclusthv/I"); - _sddiag->Branch("tdc",&_tdc,"tdccal/I:tdchv/I"); - _sddiag->Branch("tot",&_tot,"totcal/I:tothv/I"); - _sddiag->Branch("adc",&_adc); - _sddiag->Branch("mctime",&_mctime,"mctime/D"); - _sddiag->Branch("mcenergy",&_mcenergy,"mcenergy/F"); - _sddiag->Branch("mctrigenergy",&_mctrigenergy,"mctrigenergy/F"); - _sddiag->Branch("mcthreshenergy",&_mcthreshenergy,"mcthreshenergy/F"); - _sddiag->Branch("mcthreshpdg",&_mcthreshpdg,"mcthreshpdg/I"); - _sddiag->Branch("mcthreshproc",&_mcthreshproc,"mcthreshproc/I"); - _sddiag->Branch("mcnstep",&_mcnstep,"mcnstep/I"); - _sddiag->Branch("mcdca",&_mcdca,"mcdca/F"); - _sddiag->Branch("mcdcaphi",&_mcdcaphi,"mcdcaphi/F"); - _sddiag->Branch("mcdcadtime",&_mcdcadtime,"mcdcadtime/F"); - _sddiag->Branch("mcpdg",&_dmcpdg,"mcpdg/I"); - _sddiag->Branch("mcproc",&_dmcproc,"mcproc/I"); - _sddiag->Branch("mcgen",&_dmcgen,"mcgen/I"); - _sddiag->Branch("mcmom",&_dmcmom,"mcmom/F"); - _sddiag->Branch("xtalk",&_xtalk,"xtalk/B"); + if(_diag > 1){ + _sddiag =tfs->make("sddiag","StrawDigi diagnostics"); + _sddiag->Branch("plane",&_sdplane,"plane/I"); + _sddiag->Branch("panel",&_sdpanel,"panel/I"); + _sddiag->Branch("layer",&_sdlayer,"layer/I"); + _sddiag->Branch("straw",&_sdstraw,"straw/I"); + _sddiag->Branch("nstep",&_nstep,"nstep/I"); + _sddiag->Branch("xtime",&_xtime,"xtimecal/F:xtimehv/F"); + _sddiag->Branch("tctime",&_tctime,"tctimecal/F:tctimehv/F"); + _sddiag->Branch("ectime",&_ectime,"ectimecal/F:ectimehv/F"); + _sddiag->Branch("ecdtime",&_ecdtime,"ecdtimecal/F:ecdtimehv/F"); + _sddiag->Branch("ecptime",&_ecptime,"ecptimecal/F:ecptimehv/F"); + _sddiag->Branch("charge",&_charge,"chargecal/F:chargehv/F"); + _sddiag->Branch("wdist",&_wdist,"wdistcal/F:wdisthv/F"); + _sddiag->Branch("phi",&_phi,"phical/F:phihv/F"); + _sddiag->Branch("ecddist",&_ecddist,"ecddistcal/F:ecddisthv/F"); + _sddiag->Branch("vstart",&_vstart,"vstartcal/F:vstarthv/F"); + _sddiag->Branch("vcross",&_vcross,"vcrosscal/F:vcrosshv/F"); + _sddiag->Branch("ddist",&_ddist,"ddistcal/F:ddisthv/F"); + _sddiag->Branch("dtime",&_dtime,"dtimecal/F:dtimehv/F"); + _sddiag->Branch("ptime",&_ptime,"ptimecal/F:ptimehv/F"); + _sddiag->Branch("nclust",&_ncludd,"nclustcal/I:nclusthv/I"); + _sddiag->Branch("iclust",&_iclust,"iclustcal/I:iclusthv/I"); + _sddiag->Branch("tdc",&_tdc,"tdccal/I:tdchv/I"); + _sddiag->Branch("tot",&_tot,"totcal/I:tothv/I"); + _sddiag->Branch("adc",&_adc); + _sddiag->Branch("mctime",&_mctime,"mctime/D"); + _sddiag->Branch("mcenergy",&_mcenergy,"mcenergy/F"); + _sddiag->Branch("mctrigenergy",&_mctrigenergy,"mctrigenergy/F"); + _sddiag->Branch("mcthreshenergy",&_mcthreshenergy,"mcthreshenergy/F"); + _sddiag->Branch("mcthreshpdg",&_mcthreshpdg,"mcthreshpdg/I"); + _sddiag->Branch("mcthreshproc",&_mcthreshproc,"mcthreshproc/I"); + _sddiag->Branch("mcnstep",&_mcnstep,"mcnstep/I"); + _sddiag->Branch("mcdca",&_mcdca,"mcdca/F"); + _sddiag->Branch("mcdcaphi",&_mcdcaphi,"mcdcaphi/F"); + _sddiag->Branch("mcdcadtime",&_mcdcadtime,"mcdcadtime/F"); + _sddiag->Branch("mcpdg",&_dmcpdg,"mcpdg/I"); + _sddiag->Branch("mcproc",&_dmcproc,"mcproc/I"); + _sddiag->Branch("mcgen",&_dmcgen,"mcgen/I"); + _sddiag->Branch("mcmom",&_dmcmom,"mcmom/F"); + _sddiag->Branch("xtalk",&_xtalk,"xtalk/B"); - } + } } } void StrawDigisFromStrawGasSteps::beginRun( art::Run& run ){ if ( _printLevel > 0 ) { - auto const& strawphys = _strawphys_h.get(run.id()); - strawphys.print(cout); + auto const& strawphys = _strawphys_h.get(run.id()); + strawphys.print(cout); } } @@ -407,12 +409,12 @@ namespace mu2e { if ( _printLevel > 1 ) cout << "StrawDigisFromStrawGasSteps: produce() begin; event " << event.id().event() << endl; static int ncalls(0); ++ncalls; - // update conditions caches. + // update conditions caches, etc ConditionsHandle accPar("ignored"); StrawPhysics const& strawphys = _strawphys_h.get(event.id()); StrawElectronics const& strawele = _strawele_h.get(event.id()); const Tracker& tracker = *GeomHandle(); - + _toff.updateMap(event); _mbtime = accPar->deBuncherPeriod; art::Handle ewMarkerHandle; event.getByLabel(_ewMarkerTag, ewMarkerHandle); @@ -420,7 +422,7 @@ namespace mu2e { _ewMarkerOffset = ewMarker.timeOffset(); // calculate event window marker jitter for this microbunch for each panel for (size_t i=0;isecond; - // create primary digis from this clust sequence - XTalk self(hsp.strawId()); // this object represents the straws coupling to itself, ie 100% - createDigis(strawphys,strawele,hsp,self,digis.get(),mcdigis.get()); - // if we're applying x-talk, look for nearby coupled straws - if(_addXtalk) { - // only apply if the charge is above a threshold - double totalCharge = 0; - for(auto ih=hsp.clustSequence(StrawEnd::cal).clustList().begin();ih!= hsp.clustSequence(StrawEnd::cal).clustList().end();++ih){ - totalCharge += ih->charge(); - } - if( totalCharge > _ctMinCharge){ - vector xtalk; - Straw const& straw = tracker.getStraw(hsp.strawId()); - findCrossTalkStraws(straw,xtalk); - for(auto ixtalk=xtalk.begin();ixtalk!=xtalk.end();++ixtalk){ - createDigis(strawphys,strawele,hsp,*ixtalk,digis.get(),mcdigis.get()); - } - } - } + StrawClusterSequencePair const& hsp = ihsp->second; + // create primary digis from this clust sequence + XTalk self(hsp.strawId()); // this object represents the straws coupling to itself, ie 100% + createDigis(strawphys,strawele,hsp,self,digis.get(),mcdigis.get()); + // if we're applying x-talk, look for nearby coupled straws + if(_addXtalk) { + // only apply if the charge is above a threshold + double totalCharge = 0; + for(auto ih=hsp.clustSequence(StrawEnd::cal).clustList().begin();ih!= hsp.clustSequence(StrawEnd::cal).clustList().end();++ih){ + totalCharge += ih->charge(); + } + if( totalCharge > _ctMinCharge){ + vector xtalk; + Straw const& straw = tracker.getStraw(hsp.strawId()); + findCrossTalkStraws(straw,xtalk); + for(auto ixtalk=xtalk.begin();ixtalk!=xtalk.end();++ixtalk){ + createDigis(strawphys,strawele,hsp,*ixtalk,digis.get(),mcdigis.get()); + } + } + } } // store the digis in the event event.put(move(digis)); @@ -468,14 +470,14 @@ namespace mu2e { } // end produce void StrawDigisFromStrawGasSteps::createDigis( - StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StrawClusterSequencePair const& hsp, - XTalk const& xtalk, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis) { + StrawPhysics const& strawphys, + StrawElectronics const& strawele, + StrawClusterSequencePair const& hsp, + XTalk const& xtalk, + StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis) { // instantiate waveforms for both ends of this straw SWFP waveforms ={ StrawWaveform(hsp.clustSequence(StrawEnd::cal),xtalk), - StrawWaveform(hsp.clustSequence(StrawEnd::hv),xtalk) }; + StrawWaveform(hsp.clustSequence(StrawEnd::hv),xtalk) }; // find the threshold crossing points for these waveforms WFXPList xings; // find the threshold crossings @@ -494,32 +496,32 @@ namespace mu2e { event.getMany( _selector, stepsHandles); // Informational message on the first event. if ( _firstEvent ) { - mf::LogInfo log(_messageCategory); - log << "StrawDigisFromStrawGasSteps::fillHitMap will use StrawGasSteps from: \n"; - for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); - i != e; ++i ){ - art::Provenance const& prov(*(i->provenance())); - log << " " << prov.branchName() << "\n"; - } + mf::LogInfo log(_messageCategory); + log << "StrawDigisFromStrawGasSteps::fillHitMap will use StrawGasSteps from: \n"; + for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); + i != e; ++i ){ + art::Provenance const& prov(*(i->provenance())); + log << " " << prov.branchName() << "\n"; + } } if(stepsHandles.empty()){ - throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StrawGasStep collections found for tracker" << endl; + throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StrawGasStep collections found for tracker" << endl; } // Loop over StrawGasStep collections for ( auto const& sgsch : stepsHandles) { - StrawGasStepCollection const& steps(*sgsch); + StrawGasStepCollection const& steps(*sgsch); // find the associated Assns for this sgsch art::Handle sgsah; if(!event.getByLabel(sgsch.provenance()->moduleLabel(),sgsch.provenance()->productInstanceName(),sgsah)){ throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StrawGasStepAssns found for module " - << sgsch.provenance()->moduleLabel() << " instance " - << sgsch.provenance()->productInstanceName() << endl; + << sgsch.provenance()->moduleLabel() << " instance " + << sgsch.provenance()->productInstanceName() << endl; } StrawGasStepAssns const& sgsa = *sgsah; - // Loop over the StrawGasSteps in this collection + // Loop over the StrawGasSteps in this collection for(size_t isgs = 0; isgs < steps.size(); isgs++){ auto const& sgs = steps[isgs]; - // lookup straw here, to avoid having to find the tracker for every step + // lookup straw here, to avoid having to find the tracker for every step StrawId const & sid = sgs.strawId(); Straw const& straw = tracker.getStraw(sid); if(sgs.ionizingEdep() > _minstepE){ @@ -532,7 +534,7 @@ namespace mu2e { auto const& spmcptr = isgsa.second; // create a clust from this step, and add it to the clust map addStep(strawphys,strawele,straw,sgsptr,spmcptr,hmap[sid]); - } + } } } } @@ -544,10 +546,11 @@ namespace mu2e { StrawClusterSequencePair& shsp) { auto const& sgs = *sgsptr; StrawId sid = sgs.strawId(); + // apply time offsets, and take module with MB + double ctime = microbunchTime(strawele,sgs.time() + _toff.totalTimeOffset(sgs.simParticle())); // test if this step point is roughly in the digitization window - double mbtime = microbunchTime(strawele,sgs.time()); - if( (mbtime > strawele.flashEnd() - _steptimebuf - && mbtime < strawele.flashStart()) || readAll(sid)) { + if( (ctime > strawele.flashEnd() - _steptimebuf + && ctime < strawele.flashStart()) || readAll(sid)) { // Subdivide the StrawGasStep into ionization clusters _clusters.clear(); divideStep(strawphys,strawele,straw,sgs,_clusters); @@ -562,18 +565,17 @@ namespace mu2e { // compute the longitudinal propagation effects WireEndCharge weq; propagateCharge(strawphys,straw,wireq,end,weq); - // compute the total time incuding propagation delays, modulo the microbunch - double gtime = sgs.time() + wireq._time + weq._time; - double ctime = microbunchTime(strawele,gtime); - CLHEP::HepLorentzVector cpos(iclu->_pos,mbtime); - // create the clust - StrawCluster clust(StrawCluster::primary,sid,end,ctime,weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time,sgsptr,spmcptr,cpos); - // add the clusts to the appropriate sequence. - shsp.clustSequence(end).insert(clust); - // if required, add a 'ghost' copy of this clust - addGhosts(strawele,clust,shsp.clustSequence(end)); - } - } + // time of this cluster was produced, including offset + // compute the time the signal arrives at the wire end + double gtime = ctime + wireq._time + weq._time; + // create the clust + StrawCluster clust(StrawCluster::primary,sid,end,(float)gtime,weq._charge,wireq._dd,wireq._phi,weq._wdist,(float)wireq._time,(float)weq._time,sgsptr,iclu->_pos,(float)ctime); + // add the clusts to the appropriate sequence. + shsp.clustSequence(end).insert(clust); + // if required, add a 'ghost' copy of this clust + addGhosts(strawele,clust,shsp.clustSequence(end)); + } + } if(_diag > 0) stepDiag(strawphys, strawele, sgs, *spmcptr); } } @@ -584,20 +586,19 @@ namespace mu2e { StrawGasStep const& sgs, vector& clusters) { // single cluster - if (sgs.stepType().shape() == StrawGasStep::StepType::point || sgs.pathLength() < strawphys.meanFreePath()){ - double cen = sgs.ionizingEdep(); - double fne = cen/strawphys.meanElectronEnergy(); + if (sgs.stepType().shape() == StrawGasStep::StepType::point || sgs.stepLength() < strawphys.meanFreePath()){ + float cen = sgs.ionizingEdep(); + float fne = cen/strawphys.meanElectronEnergy(); unsigned ne = std::max( static_cast(_randP(fne)),(unsigned)1); - Hep3Vector cdir = (Geom::Hep3Vec(sgs.startPosition())-straw.getMidPoint());//JB - cdir -= straw.getDirection()*(cdir.dot(straw.getDirection()));//JB - double phi = cdir.theta(); //JB + float phi = EBAngle(sgs.startPosition(),straw); for (size_t i=0;i(_randP.fire(fnc)),(unsigned)1); // if not minion, limit the number of steps geometrically @@ -606,11 +607,11 @@ namespace mu2e { // require clusters not exceed the energy sum required for single-electron clusters nc = std::min(nc,static_cast(floor(sgs.ionizingEdep()/strawphys.ionizationEnergy((unsigned)1)))); // generate random positions for the clusters - std::vector cposv(nc); + std::vector cposv(nc); fillClusterPositions(sgs,cposv); // generate electron counts and energies for these clusters: minion model is more detailed std::vector ne(nc); - std::vector cen(nc); + std::vector cen(nc); if(minion){ fillClusterMinion(strawphys,sgs,ne,cen); } else { @@ -624,14 +625,13 @@ namespace mu2e { // create the cluster objects for(unsigned ic=0;ic _mbtime - _mbbuffer) shs.insert(StrawCluster(clust,-_mbtime)); } @@ -694,7 +694,7 @@ namespace mu2e { double strawnoise = _randgauss.fire(0,strawele.strawNoise()); // add specifics for each end double thresh[2] = {_randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(0))+strawnoise,strawele.analogNoise(StrawElectronics::thresh)), - _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(1))+strawnoise,strawele.analogNoise(StrawElectronics::thresh))}; + _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(1))+strawnoise,strawele.analogNoise(StrawElectronics::thresh))}; // Initialize search when the electronics becomes enabled: double tstart =strawele.flashEnd() - _flashbuffer; // for reading all hits, make sure we start looking for clusters at the minimum possible cluster time @@ -704,37 +704,37 @@ namespace mu2e { // search for coherent crossings on both ends bool crosses[2]; for(size_t iend=0;iend<2;++iend){ - crosses[iend] = swfp[iend].crossesThreshold(strawele,thresh[iend],wfx[iend]); + crosses[iend] = swfp[iend].crossesThreshold(strawele,thresh[iend],wfx[iend]); } // loop until we hit the end of the waveforms. Require both in time. Buffer to account for eventual TDC jitter // this is a loose pre-selection, final selection is done at digitization while( crosses[0] && crosses[1] && std::max(wfx[0]._time,wfx[1]._time) - < strawele.flashStart() + strawele.electronicsTimeDelay() + _tdcbuf){ - // see if the crossings match - if(strawele.combineEnds(wfx[0]._time,wfx[1]._time)){ - // put the pair of crossings in the crosing list - // make sure the time is positive in case this was a hit from the 'previous' microbunch - if(std::min(wfx[0]._time,wfx[1]._time) > 0.0 )xings.push_back(wfx); - // search for next crossing: - // update threshold for straw noise - strawnoise = _randgauss.fire(0,strawele.strawNoise()); - for(unsigned iend=0;iend<2;++iend){ - // insure a minimum time buffer between crossings - wfx[iend]._time += strawele.deadTimeAnalog(); - // skip to the next clust - ++(wfx[iend]._iclust); - // update threshold for incoherent noise - thresh[iend] = _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(iend)),strawele.analogNoise(StrawElectronics::thresh)); - // find next crossing - crosses[iend] = swfp[iend].crossesThreshold(strawele,thresh[iend],wfx[iend]); - } - } else { - // skip to the next crossing on the earlier waveform - unsigned iearly = wfx[0]._time < wfx[1]._time ? 0 : 1; - ++(wfx[iearly]._iclust); - wfx[iearly]._time += strawele.deadTimeAnalog(); - crosses[iearly] = swfp[iearly].crossesThreshold(strawele,thresh[iearly],wfx[iearly]); - } + < strawele.flashStart() + strawele.electronicsTimeDelay() + _tdcbuf){ + // see if the crossings match + if(strawele.combineEnds(wfx[0]._time,wfx[1]._time)){ + // put the pair of crossings in the crosing list + // make sure the time is positive in case this was a hit from the 'previous' microbunch + if(std::min(wfx[0]._time,wfx[1]._time) > 0.0 )xings.push_back(wfx); + // search for next crossing: + // update threshold for straw noise + strawnoise = _randgauss.fire(0,strawele.strawNoise()); + for(unsigned iend=0;iend<2;++iend){ + // insure a minimum time buffer between crossings + wfx[iend]._time += strawele.deadTimeAnalog(); + // skip to the next clust + ++(wfx[iend]._iclust); + // update threshold for incoherent noise + thresh[iend] = _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(iend)),strawele.analogNoise(StrawElectronics::thresh)); + // find next crossing + crosses[iend] = swfp[iend].crossesThreshold(strawele,thresh[iend],wfx[iend]); + } + } else { + // skip to the next crossing on the earlier waveform + unsigned iearly = wfx[0]._time < wfx[1]._time ? 0 : 1; + ++(wfx[iearly]._iclust); + wfx[iearly]._time += strawele.deadTimeAnalog(); + crosses[iearly] = swfp[iearly].crossesThreshold(strawele,thresh[iearly],wfx[iearly]); + } } } @@ -745,45 +745,44 @@ namespace mu2e { StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis ) { // loop over crossings for(auto xpair : xings) { - // create a digi from this pair. This also performs a finial test - // on whether the pair should make a digi - if(createDigi(strawele,xpair,wf,sid,digis)){ - // fill associated MC truth matching. Only count the same step once - double wetime[2] = {-100.,-100.}; - CLHEP::HepLorentzVector cpos[2]; - art::Ptr sgs[2]; - art::Ptr stepMC[2]; - for (size_t iend=0;iend<2;++iend){ - StrawCluster const& sc = *(xpair[iend]._iclust); - wetime[iend] = sc.time(); - cpos[iend] = sc.clusterPosition(); - sgs[iend] = sc.strawGasStep(); - stepMC[iend] = sc.stepPointMC(); - } - // choose the minimum time from either end, as the ADC sums both - double ptime = 1.0e10; - for (size_t iend=0;iend<2;++iend){ - ptime = std::min(ptime,wetime[iend]); - } - // subtract a small buffer - ptime -= _adcbuffer; - mcdigis->push_back(StrawDigiMC(sid,wetime,cpos,sgs,stepMC)); + // create a digi from this pair. This also performs a finial test + // on whether the pair should make a digi + if(createDigi(strawele,xpair,wf,sid,digis)){ + // fill associated MC truth matching. Only count the same step once + StrawDigiMC::SGSPA sgspa; + StrawDigiMC::PA cpos; + StrawDigiMC::FA ctime, wetime; + for (size_t iend=0;iend<2;++iend){ + StrawCluster const& sc = *(xpair[iend]._iclust); + wetime[iend] = sc.time(); + ctime[iend] = sc.cluTime(); + cpos[iend] = sc.cluPos(); + sgspa[iend] = sc.strawGasStep(); + } + // choose the minimum time from either end, as the ADC sums both + float ptime = 1.0e10; + for (size_t iend=0;iend<2;++iend){ + ptime = std::min(ptime,wetime[iend]); + } + // subtract a small buffer + ptime -= _adcbuffer; + mcdigis->push_back(StrawDigiMC(sid,cpos,ctime,wetime,sgspa)); if(_diag > 1){ digiDiag(strawphys,wf,xpair,digis->back(),mcdigis->back()); } - } + } } // waveform diags if ( _diag > 1 && (wf[0].clusts().clustList().size() > 0 || - wf[1].clusts().clustList().size() > 0 ) ) { - // waveform xing diagnostics - _ndigi = digis->size(); - waveformDiag(strawele,wf,xings); + wf[1].clusts().clustList().size() > 0 ) ) { + // waveform xing diagnostics + _ndigi = digis->size(); + waveformDiag(strawele,wf,xings); } } bool StrawDigisFromStrawGasSteps::createDigi(StrawElectronics const& strawele, WFXP const& xpair, SWFP const& waveform, - StrawId sid, StrawDigiCollection* digis){ + StrawId sid, StrawDigiCollection* digis){ // initialize the float variables that we later digitize TDCTimes xtimes = {0.0,0.0}; TrkTypes::TOTValues tot; @@ -797,38 +796,38 @@ namespace mu2e { double dt = _ewMarkerROCdt[sid.getPanel()]; // loop over the associated crossings for(size_t iend = 0;iend<2; ++iend){ - WFX const& wfx = xpair[iend]; - // record the crossing time for this end, including clock jitter These already include noise effects - // add noise for TDC on each side - double tdc_jitter = _randgauss.fire(0.0,strawele.TDCResolution()); - xtimes[iend] = wfx._time+dt+tdc_jitter; - // randomize threshold using the incoherent noise - double threshold = _randgauss.fire(wfx._vcross,strawele.analogNoise(StrawElectronics::thresh)); - // find TOT - tot[iend] = waveform[iend].digitizeTOT(strawele,threshold,wfx._time + dt); - // sample ADC - waveform[iend].sampleADCWaveform(strawele,adctimes,wf[iend]); + WFX const& wfx = xpair[iend]; + // record the crossing time for this end, including clock jitter These already include noise effects + // add noise for TDC on each side + double tdc_jitter = _randgauss.fire(0.0,strawele.TDCResolution()); + xtimes[iend] = wfx._time+dt+tdc_jitter; + // randomize threshold using the incoherent noise + double threshold = _randgauss.fire(wfx._vcross,strawele.analogNoise(StrawElectronics::thresh)); + // find TOT + tot[iend] = waveform[iend].digitizeTOT(strawele,threshold,wfx._time + dt); + // sample ADC + waveform[iend].sampleADCWaveform(strawele,adctimes,wf[iend]); } // uncalibrate strawele.uncalibrateTimes(xtimes,sid); // add ends and add noise ADCVoltages wfsum; wfsum.reserve(adctimes.size()); for(unsigned isamp=0;isamppush_back(StrawDigi(sid,tdcs,tot,adc)); + TrkTypes::ADCWaveform adc; + strawele.digitizeWaveform(sid,wfsum,adc); + // create the digi from this + digis->push_back(StrawDigi(sid,tdcs,tot,adc)); } return digitize; } @@ -845,10 +844,10 @@ namespace mu2e { vector const& preampNeighbors = straw.preampNeighboursById(); // convert these to cross-talk for(auto isid=strawNeighbors.begin();isid!=strawNeighbors.end();++isid){ - xtalk.push_back(XTalk(selfid,*isid,_preampxtalk,0)); + xtalk.push_back(XTalk(selfid,*isid,_preampxtalk,0)); } for(auto isid=preampNeighbors.begin();isid!=preampNeighbors.end();++isid){ - xtalk.push_back(XTalk(selfid,*isid,0,_postampxtalk)); + xtalk.push_back(XTalk(selfid,*isid,0,_postampxtalk)); } } @@ -858,7 +857,7 @@ namespace mu2e { // create random noise clusts and add them to the sequences of random straws. } - void StrawDigisFromStrawGasSteps::fillClusterPositions(StrawGasStep const& sgs, std::vector& cposv) { + void StrawDigisFromStrawGasSteps::fillClusterPositions(StrawGasStep const& sgs, std::vector& cposv) { // generate a random position between the start and end points. Also smear perp to the path by the width XYZVec path = sgs.endPosition() - sgs.startPosition(); for(auto& cpos : cposv) { @@ -867,7 +866,7 @@ namespace mu2e { } } - void StrawDigisFromStrawGasSteps::fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& ne, std::vector& cen) { + void StrawDigisFromStrawGasSteps::fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& ne, std::vector& cen) { // Loop until we've assigned energy + electrons to every cluster unsigned mc(0); double esum(0.0); @@ -879,52 +878,52 @@ namespace mu2e { fillClusterNe(strawphys,me); for(auto ie : me) { // maximum energy for this cluster requires at least 1 electron for the rest of the cluster - double emax = etot - esum - (nc -mc -1)*strawphys.ionizationEnergy((unsigned)1); - double eele = strawphys.ionizationEnergy(ie); - if( eele < emax){ - ne[mc] = ie; - cen[mc] = eele; - ++mc; - esum += eele; - } else { - break; - } - } + double emax = etot - esum - (nc -mc -1)*strawphys.ionizationEnergy((unsigned)1); + double eele = strawphys.ionizationEnergy(ie); + if( eele < emax){ + ne[mc] = ie; + cen[mc] = eele; + ++mc; + esum += eele; + } else { + break; + } + } } // distribute any residual energy randomly to these clusters. This models delta rays unsigned ns; do{ - unsigned me = strawphys.nePerIon(_randflat.fire()); - double emax = etot - esum; - double eele = strawphys.ionizationEnergy(me); - if(eele < emax){ - // choose a random cluster to assign this energy to - unsigned mc = std::min(nc-1,static_cast(floor(_randflat.fire(nc)))); - ne[mc] += me; - cen[mc] += eele; - esum += eele; - } - // maximum energy for this cluster requires at least 1 electron for the rest of the cluster - ns = static_cast(floor((etot-esum)/strawphys.ionizationEnergy((unsigned)1))); + unsigned me = strawphys.nePerIon(_randflat.fire()); + double emax = etot - esum; + double eele = strawphys.ionizationEnergy(me); + if(eele < emax){ + // choose a random cluster to assign this energy to + unsigned mc = std::min(nc-1,static_cast(floor(_randflat.fire(nc)))); + ne[mc] += me; + cen[mc] += eele; + esum += eele; + } + // maximum energy for this cluster requires at least 1 electron for the rest of the cluster + ns = static_cast(floor((etot-esum)/strawphys.ionizationEnergy((unsigned)1))); } while(ns > 0); } void StrawDigisFromStrawGasSteps::fillClusterNe(StrawPhysics const& strawphys,std::vector& me) { for(size_t ie=0;ie < me.size(); ++ie){ - me[ie] = strawphys.nePerIon(_randflat.fire()); + me[ie] = strawphys.nePerIon(_randflat.fire()); } if(_sort)std::sort(me.begin(),me.end()); } bool StrawDigisFromStrawGasSteps::readAll(StrawId const& sid) const { return sid.straw() >= _allStraw && - (std::find(_allPlanes.begin(),_allPlanes.end(),sid.plane()) != _allPlanes.end()); + (std::find(_allPlanes.begin(),_allPlanes.end(),sid.plane()) != _allPlanes.end()); } -// diagnostic functions + // diagnostic functions void StrawDigisFromStrawGasSteps::waveformDiag( - StrawElectronics const& strawele, - SWFP const& wfs, WFXPList const& xings) { + StrawElectronics const& strawele, + SWFP const& wfs, WFXPList const& xings) { const Tracker& tracker = *GeomHandle(); const Straw& straw = tracker.getStraw( wfs[0].clusts().strawId() ); _swplane = straw.id().getPlane(); @@ -932,73 +931,73 @@ namespace mu2e { _swlayer = straw.id().getLayer(); _swstraw = straw.id().getStraw(); for(size_t iend=0;iend<2; ++iend){ - ClusterList const& clusts = wfs[iend].clusts().clustList(); - size_t nclust = clusts.size(); - set > steps; - set > parts; - _nxing[iend] = 0; - _txing[iend] = strawele.flashStart() + _mbbuffer; - _xddist[iend] = _xwdist[iend] = _xpdist[iend] = -1.0; - for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ - ++_nxing[iend]; - _txing[iend] = min(_txing[iend],static_cast(ixing->at(iend)._time)); - _xddist[iend] = ixing->at(iend)._iclust->driftDistance(); - _xwdist[iend] = ixing->at(iend)._iclust->wireDistance(); - // compute direction perpendicular to wire and momentum - auto const& spp = ixing->at(iend)._iclust->stepPointMC(); - if(!spp.isNull()){ - Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); - // project the differences in position to get the perp distance - _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); - } - } - if(_nxing[iend] == 0){ - // no xings: just take the 1st clust - if(nclust > 0 ){ - _xddist[iend] = clusts.front().driftDistance(); - _xwdist[iend] = clusts.front().wireDistance(); - auto const& spp = clusts.front().stepPointMC(); - if(!spp.isNull()){ - Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); - // project the differences in position to get the perp distance - _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); - } - } - } - if(nclust > 0){ - _tmin[iend] = clusts.begin()->time(); - _tmax[iend] = clusts.rbegin()->time(); - } else { - _tmin[iend] = _mbtime+_mbbuffer; - _tmax[iend] = -100.0; - } + ClusterList const& clusts = wfs[iend].clusts().clustList(); + size_t nclust = clusts.size(); + set > steps; + set > parts; + _nxing[iend] = 0; + _txing[iend] = strawele.flashStart() + _mbbuffer; + _xddist[iend] = _xwdist[iend] = _xpdist[iend] = -1.0; + for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ + ++_nxing[iend]; + _txing[iend] = min(_txing[iend],static_cast(ixing->at(iend)._time)); + _xddist[iend] = ixing->at(iend)._iclust->driftDistance(); + _xwdist[iend] = ixing->at(iend)._iclust->wireDistance(); + // compute direction perpendicular to wire and momentum + auto const& spp = ixing->at(iend)._iclust->strawGasStep(); + if(!spp.isNull()){ + Hep3Vector pdir = straw.getDirection().cross(Geom::Hep3Vec(spp->momentum())).unit(); + // project the differences in position to get the perp distance + _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); + } + } + if(_nxing[iend] == 0){ + // no xings: just take the 1st clust + if(nclust > 0 ){ + _xddist[iend] = clusts.front().driftDistance(); + _xwdist[iend] = clusts.front().wireDistance(); + auto const& spp = clusts.front().stepPointMC(); + if(!spp.isNull()){ + Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); + // project the differences in position to get the perp distance + _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); + } + } + } + if(nclust > 0){ + _tmin[iend] = clusts.begin()->time(); + _tmax[iend] = clusts.rbegin()->time(); + } else { + _tmin[iend] = _mbtime+_mbbuffer; + _tmax[iend] = -100.0; + } - _hqsum[iend] = 0.0; - _vmax[iend] = _tvmax[iend] = 0.0; - _wmcpdg[iend] = _wmcproc[iend] = 0; - for(auto iclu=clusts.begin();iclu!=clusts.end();++iclu){ - if(iclu->stepPointMC().isNonnull()){ - steps.insert(iclu->stepPointMC()); - parts.insert(iclu->stepPointMC()->simParticle()); - _hqsum[iend] += iclu->charge(); - double ctime = iclu->time()+strawele.maxResponseTime(_diagpath,iclu->wireDistance()); - double vout = wfs[iend].sampleWaveform(strawele,_diagpath,ctime); - if(vout > _vmax[iend]){ - _vmax[iend] = vout; - _tvmax[iend] = ctime; - _wmcpdg[iend] = iclu->stepPointMC()->simParticle()->pdgId(); - _wmcproc[iend] = iclu->stepPointMC()->simParticle()->creationCode(); - _mce[iend] = iclu->stepPointMC()->simParticle()->startMomentum().e(); - _slen[iend] = iclu->stepPointMC()->stepLength(); - _sedep[iend] = iclu->stepPointMC()->ionizingEdep(); - } - } - } - _nsteppoint[iend] = steps.size(); - _npart[iend] = parts.size(); - _sesum[iend] = 0.0; - for(auto istep=steps.begin();istep!=steps.end();++istep) - _sesum [iend]+= (*istep)->ionizingEdep(); + _hqsum[iend] = 0.0; + _vmax[iend] = _tvmax[iend] = 0.0; + _wmcpdg[iend] = _wmcproc[iend] = 0; + for(auto iclu=clusts.begin();iclu!=clusts.end();++iclu){ + if(iclu->stepPointMC().isNonnull()){ + steps.insert(iclu->stepPointMC()); + parts.insert(iclu->stepPointMC()->simParticle()); + _hqsum[iend] += iclu->charge(); + double ctime = iclu->time()+strawele.maxResponseTime(_diagpath,iclu->wireDistance()); + double vout = wfs[iend].sampleWaveform(strawele,_diagpath,ctime); + if(vout > _vmax[iend]){ + _vmax[iend] = vout; + _tvmax[iend] = ctime; + _wmcpdg[iend] = iclu->stepPointMC()->simParticle()->pdgId(); + _wmcproc[iend] = iclu->stepPointMC()->simParticle()->creationCode(); + _mce[iend] = iclu->stepPointMC()->simParticle()->startMomentum().e(); + _slen[iend] = iclu->stepPointMC()->stepLength(); + _sedep[iend] = iclu->stepPointMC()->ionizingEdep(); + } + } + } + _nsteppoint[iend] = steps.size(); + _npart[iend] = parts.size(); + _sesum[iend] = 0.0; + for(auto istep=steps.begin();istep!=steps.end();++istep) + _sesum [iend]+= (*istep)->ionizingEdep(); } _swdiag->Fill(); // waveform histograms @@ -1009,43 +1008,43 @@ namespace mu2e { // histogram individual waveforms static unsigned nhist(0);// maximum number of histograms per job! for(size_t iend=0;iend<2;++iend){ - // step to the 1st cluster past the blanking time to avoid double-counting - ClusterList const& clist = wfs[iend].clusts().clustList(); - auto icl = clist.begin(); - while(icl->time() < strawele.flashEnd()) - icl++; - if(icl != clist.end() && nhist < _maxhist && xings.size() >= _minnxinghist && - ( ((!_xtalkhist) && wfs[iend].xtalk().self()) || (_xtalkhist && !wfs[iend].xtalk().self()) ) ) { - double tstart = icl->time()-_tstep; - double tfall = strawele.fallTime(_diagpath); - double tend = clist.rbegin()->time() + _nfall*tfall; - ADCTimes times; - ADCVoltages volts; - times.reserve(size_t(ceil(tend-tstart)/_tstep)); - volts.reserve(size_t(ceil(tend-tstart)/_tstep)); - double t = tstart; - while(t tfs; - char name[60]; - char title[100]; - snprintf(name,60,"SWF%i_%i",wfs[iend].clusts().strawId().asUint16(),nhist); - snprintf(title,100,"Electronic output for straw %i end %i path %i;time (nSec);Waveform (mVolts)",wfs[iend].clusts().strawId().asUint16(),(int)iend,_diagpath); - TH1F* wfh = tfs->make(name,title,volts.size(),times.front(),times.back()); - for(size_t ibin=0;ibinSetBinContent(ibin+1,volts[ibin]); - TList* flist = wfh->GetListOfFunctions(); - for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ - TMarker* smark = new TMarker(ixing->at(iend)._time,ixing->at(iend)._vcross,8); - smark->SetMarkerColor(kGreen); - smark->SetMarkerSize(2); - flist->Add(smark); - } - } + // step to the 1st cluster past the blanking time to avoid double-counting + ClusterList const& clist = wfs[iend].clusts().clustList(); + auto icl = clist.begin(); + while(icl->time() < strawele.flashEnd()) + icl++; + if(icl != clist.end() && nhist < _maxhist && xings.size() >= _minnxinghist && + ( ((!_xtalkhist) && wfs[iend].xtalk().self()) || (_xtalkhist && !wfs[iend].xtalk().self()) ) ) { + double tstart = icl->time()-_tstep; + double tfall = strawele.fallTime(_diagpath); + double tend = clist.rbegin()->time() + _nfall*tfall; + ADCTimes times; + ADCVoltages volts; + times.reserve(size_t(ceil(tend-tstart)/_tstep)); + volts.reserve(size_t(ceil(tend-tstart)/_tstep)); + double t = tstart; + while(t tfs; + char name[60]; + char title[100]; + snprintf(name,60,"SWF%i_%i",wfs[iend].clusts().strawId().asUint16(),nhist); + snprintf(title,100,"Electronic output for straw %i end %i path %i;time (nSec);Waveform (mVolts)",wfs[iend].clusts().strawId().asUint16(),(int)iend,_diagpath); + TH1F* wfh = tfs->make(name,title,volts.size(),times.front(),times.back()); + for(size_t ibin=0;ibinSetBinContent(ibin+1,volts[ibin]); + TList* flist = wfh->GetListOfFunctions(); + for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ + TMarker* smark = new TMarker(ixing->at(iend)._time,ixing->at(iend)._vcross,8); + smark->SetMarkerColor(kGreen); + smark->SetMarkerSize(2); + flist->Add(smark); + } + } } } @@ -1058,47 +1057,47 @@ namespace mu2e { _sdstraw = straw.id().getStraw(); for(size_t iend=0;iend<2;++iend){ - _xtime[iend] = xpair[iend]._time; - _tctime[iend] = xpair[iend]._iclust->time(); - _charge[iend] = xpair[iend]._iclust->charge(); - _ddist[iend] = xpair[iend]._iclust->driftDistance(); - _dtime[iend] = xpair[iend]._iclust->driftTime(); - _ptime[iend] = xpair[iend]._iclust->propTime(); - _phi[iend] = xpair[iend]._iclust->phi(); //JB - _wdist[iend] = xpair[iend]._iclust->wireDistance(); - _vstart[iend] = xpair[iend]._vstart; - _vcross[iend] = xpair[iend]._vcross; - _tdc[iend] = digi.TDC(xpair[iend]._iclust->strawEnd()); - _tot[iend] = digi.TOT(xpair[iend]._iclust->strawEnd()); - ClusterList const& clist = wfs[iend].clusts().clustList(); - auto ctrig = xpair[iend]._iclust; - _ncludd[iend] = clist.size(); - // find the earliest cluster from the same particle that triggered the crossing - auto iclu = clist.begin(); - while( iclu != clist.end() && ctrig->stepPointMC()->simParticle() != iclu->stepPointMC()->simParticle() ){ - ++iclu; - } - if(iclu != clist.end() ){ - _ectime[iend] = iclu->time(); - _ecddist[iend] = iclu->driftDistance(); - _ecdtime[iend] = iclu->driftTime(); - _ecptime[iend] = iclu->propTime(); - // count how many clusters till we get to the trigger cluster - size_t iclust(0); - while( iclu != clist.end() && iclu != ctrig){ - ++iclu; - ++iclust; - } - _iclust[iend] = iclust; - } + _xtime[iend] = xpair[iend]._time; + _tctime[iend] = xpair[iend]._iclust->time(); + _charge[iend] = xpair[iend]._iclust->charge(); + _ddist[iend] = xpair[iend]._iclust->driftDistance(); + _dtime[iend] = xpair[iend]._iclust->driftTime(); + _ptime[iend] = xpair[iend]._iclust->propTime(); + _phi[iend] = xpair[iend]._iclust->phi(); + _wdist[iend] = xpair[iend]._iclust->wireDistance(); + _vstart[iend] = xpair[iend]._vstart; + _vcross[iend] = xpair[iend]._vcross; + _tdc[iend] = digi.TDC(xpair[iend]._iclust->strawEnd()); + _tot[iend] = digi.TOT(xpair[iend]._iclust->strawEnd()); + ClusterList const& clist = wfs[iend].clusts().clustList(); + auto ctrig = xpair[iend]._iclust; + _ncludd[iend] = clist.size(); + // find the earliest cluster from the same particle that triggered the crossing + auto iclu = clist.begin(); + while( iclu != clist.end() && ctrig->stepPointMC()->simParticle() != iclu->stepPointMC()->simParticle() ){ + ++iclu; + } + if(iclu != clist.end() ){ + _ectime[iend] = iclu->time(); + _ecddist[iend] = iclu->driftDistance(); + _ecdtime[iend] = iclu->driftTime(); + _ecptime[iend] = iclu->propTime(); + // count how many clusters till we get to the trigger cluster + size_t iclust(0); + while( iclu != clist.end() && iclu != ctrig){ + ++iclu; + ++iclust; + } + _iclust[iend] = iclust; + } } if(xpair[0]._iclust->stepPointMC() == xpair[1]._iclust->stepPointMC()) - _nstep = 1; + _nstep = 1; else - _nstep = 2; + _nstep = 2; _adc.clear(); for(auto iadc=digi.adcWaveform().begin();iadc!=digi.adcWaveform().end();++iadc){ - _adc.push_back(*iadc); + _adc.push_back(*iadc); } // mc truth information _dmcpdg = _dmcproc = _dmcgen = 0; @@ -1110,24 +1109,20 @@ namespace mu2e { if(!sgsptr.isNull() && !spmcptr.isNull()){ auto const& sgs = *sgsptr; auto const& spmc = *spmcptr; - _mctime = sgs.time(); - // compute the doca for this step - TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), - Geom::Hep3Vec(sgs.startPosition()), Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()) ); - _mcdca = pca.dca(); - - Hep3Vector mccdir = (pca.point2()-straw.getMidPoint()); - mccdir -= straw.getDirection()*(mccdir.dot(straw.getDirection())); - _mcdcaphi = mccdir.theta(); - _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); //JB: this is now from the lorentz corrected r-component of the drift - - if(!spmc.simParticle().isNull()){ + _mctime = sgs.time() + _toff.totalTimeOffset(sgs.simParticle()); + // compute the doca for this step + TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), + Geom::Hep3Vec(sgs.startPosition()), Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()) ); + _mcdca = pca.dca(); + _mcdcaphi = EBAngle(Geom::toXYZVec(pca.point2()),straw); + _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); + if(!spmc.simParticle().isNull()){ auto const& sp = *spmc.simParticle(); - _dmcpdg = sp.pdgId(); - _dmcproc = sp.creationCode(); - if(sp.genParticle().isNonnull()) - _dmcgen = sp.genParticle()->generatorId().id(); - _dmcmom = spmc.momentum().mag(); + _dmcpdg = sp.pdgId(); + _dmcproc = sp.creationCode(); + if(sp.genParticle().isNonnull()) + _dmcgen = sp.genParticle()->generatorId().id(); + _dmcmom = spmc.momentum().mag(); _mcthreshpdg = spmc.simParticle()->pdgId(); _mcthreshproc = spmc.simParticle()->creationCode(); } @@ -1145,9 +1140,9 @@ namespace mu2e { void StrawDigisFromStrawGasSteps::stepDiag( StrawPhysics const& strawphys, StrawElectronics const& strawele, StrawGasStep const& sgs, StepPointMC const& spmc) { - _steplen = sgs.pathLength(); + _steplen = sgs.stepLength(); _stepE = sgs.ionizingEdep(); - _steptime = microbunchTime(strawele,sgs.time()); + _steptime = microbunchTime(strawele,sgs.time()+ _toff.totalTimeOffset(sgs.simParticle())); _stype = sgs.stepType()._stype; _partP = spmc.momentum().mag(); _partPDG = spmc.simParticle()->pdgId(); @@ -1164,6 +1159,14 @@ namespace mu2e { _sdiag->Fill(); } + float StrawDigisFromStrawGasSteps::EBAngle(XYZVec const& cpos,Straw const& straw) const { + // this assumes E points along the radial direction and B along Z FIXME! + XYZVec smid = Geom::toXYZVec(straw.getMidPoint()); + XYZVec sdir = Geom::toXYZVec(straw.getDirection()); + XYZVec cdir = cpos - smid; + cdir -= sdir*(cdir.Dot(sdir)); + return cdir.theta(); + } } // end namespace trackermc } // end namespace mu2e diff --git a/Trigger/src/ReadTriggerInfo_module.cc b/Trigger/src/ReadTriggerInfo_module.cc index 96ae394fb9..4157eb7f55 100644 --- a/Trigger/src/ReadTriggerInfo_module.cc +++ b/Trigger/src/ReadTriggerInfo_module.cc @@ -55,7 +55,6 @@ #include "MCDataProducts/inc/StepPointMC.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "MCDataProducts/inc/ProtonBunchIntensity.hh" -#include "TrkDiag/inc/TrkMCTools.hh" #include "GlobalConstantsService/inc/GlobalConstantsHandle.hh" #include "GlobalConstantsService/inc/ParticleDataTable.hh" @@ -906,7 +905,7 @@ namespace mu2e { int hitIndex = int(KSeed->hits().at(j).index()); hit = &_chcol->at(hitIndex); loc = hit - hit_0; - const mu2e::StepPointMC* step(0); + const mu2e::StrawGasStep* step(0); const mu2e::StrawDigiMC* sdmc = &_mcdigis->at(loc); if (sdmc->wireEndTime(mu2e::StrawEnd::cal) < sdmc->wireEndTime(mu2e::StrawEnd::hv)) { step = sdmc->stepPointMC(mu2e::StrawEnd::cal).get(); @@ -941,25 +940,15 @@ namespace mu2e { } //finally, get the info of the first StrawDigi - const mu2e::StepPointMC* step(0); const mu2e::StrawDigiMC* sdmc = &_mcdigis->at(mostvalueindex); - if (sdmc->wireEndTime(mu2e::StrawEnd::cal) < sdmc->wireEndTime(mu2e::StrawEnd::hv)) { - step = sdmc->stepPointMC(mu2e::StrawEnd::cal).get(); - } - else { - step = sdmc->stepPointMC(mu2e::StrawEnd::hv ).get(); - } - - const mu2e::SimParticle * sim (0); - - if (step) { - art::Ptr const& simptr = step->simParticle(); + art::Ptr const& simptr = sdmc->earlyStrawGasStep()->simParticle(); int pdg = simptr->pdgId(); art::Ptr mother = simptr; - while(mother->hasParent()) mother = mother->parent(); - sim = mother.operator ->(); - int pdgM = sim->pdgId(); + while(mother->hasParent()) + mother = mother->parent(); + //sim = mother.operator->(); + int pdgM = mother->pdgId(); double pXMC = simptr->startMomentum().x(); double pYMC = simptr->startMomentum().y(); double pZMC = simptr->startMomentum().z(); @@ -991,7 +980,6 @@ namespace mu2e { Hist._hTrkInfo[TrkTrigIndex][18]->Fill(origin_r); Hist._hTrkInfo[TrkTrigIndex][19]->Fill(pdgM); Hist._hTrkInfo[TrkTrigIndex][20]->Fill(energy); - } } } @@ -1039,18 +1027,14 @@ namespace mu2e { for (size_t k=0; kat(shids[k]); - art::Ptr spmcp; - mu2e::TrkMCTools::stepPoint(spmcp,*sdmc); - const mu2e::StepPointMC* step = spmcp.get(); - if (step) { - art::Ptr const& simptr = step->simParticle(); + auto const& spmcp = sdmc->earlyStepPointMC(); + art::Ptr const& simptr = spmcp->simParticle(); int sim_id = simptr->id().asInt(); - float dz = step->position().z();// - trackerZ0; + float dz = spmcp->position().z();// - trackerZ0; hits_simp_id.push_back (sim_id); hits_simp_index.push_back(shids[k]); hits_simp_z.push_back(dz); break; - } } }//end loop over the hits @@ -1071,22 +1055,16 @@ namespace mu2e { //finally, get the info of the first StrawDigi const mu2e::StrawDigiMC* sdmc = &_mcdigis->at(mostvalueindex); - art::Ptr spmcp; - mu2e::TrkMCTools::stepPoint(spmcp,*sdmc); - const mu2e::StepPointMC* step = spmcp.get(); - const mu2e::SimParticle * sim (0); - - if (step) { - art::Ptr const& simptr = step->simParticle(); + auto const& spmcp = sdmc->earlyStepPointMC(); + art::Ptr const& simptr = spmcp->simParticle(); int pdg = simptr->pdgId(); art::Ptr mother = simptr; while(mother->hasParent()) mother = mother->parent(); - sim = mother.operator ->(); - int pdgM = sim->pdgId(); - double pXMC = step->momentum().x(); - double pYMC = step->momentum().y(); - double pZMC = step->momentum().z(); + int pdgM = mother->pdgId(); + double pXMC = spmcp->momentum().x(); + double pYMC = spmcp->momentum().y(); + double pZMC = spmcp->momentum().z(); double mass(-1.);// = part->Mass(); double energy(-1.);// = sqrt(px*px+py*py+pz*pz+mass*mass); mass = pdt->particle(pdg).ref().mass(); @@ -1116,7 +1094,6 @@ namespace mu2e { Hist._hHelInfo[HelTrigIndex][18]->Fill(origin_r); Hist._hHelInfo[HelTrigIndex][19]->Fill(pdgM); Hist._hHelInfo[HelTrigIndex][20]->Fill(energy); - } } } //-------------------------------------------------------------------------------- diff --git a/TrkDiag/inc/TrkMCTools.hh b/TrkDiag/inc/TrkMCTools.hh index d9453ea401..71093b4744 100644 --- a/TrkDiag/inc/TrkMCTools.hh +++ b/TrkDiag/inc/TrkMCTools.hh @@ -27,8 +27,6 @@ namespace mu2e { ///////////////////////////// // Straw Hit Level Utilities - // return the earliest StepPointMC associated with the threshold crossing. - int stepPoint(art::Ptr& sp, StrawDigiMC const& mcdigi); // determine if a hit was generated by signal (conversion electron) bool CEDigi(StrawDigiMC const& mcdigi); // count the number of digis produced by the given particle diff --git a/TrkDiag/src/BkgDiag_module.cc b/TrkDiag/src/BkgDiag_module.cc index 5e3d49ee7f..fe971c237d 100644 --- a/TrkDiag/src/BkgDiag_module.cc +++ b/TrkDiag/src/BkgDiag_module.cc @@ -206,9 +206,7 @@ namespace mu2e std::vector dids; _chcol->fillStrawDigiIndices(event,ich,dids); StrawDigiMC const& mcdigi = _mcdigis->at(dids[0]);// taking 1st digi: is there a better idea?? - StrawEnd itdc(StrawEnd::cal); - art::Ptr const& spmcp = mcdigi.stepPointMC(itdc); - art::Ptr const& spp = spmcp->simParticle(); + art::Ptr const& spp = mcdigi.earlyStrawGasStep()->simParticle(); _hitPdg[_nhits] = spp->pdgId(); _hitCrCode[_nhits] = spp->creationCode(); _hitGen[_nhits] = -1; @@ -373,13 +371,11 @@ namespace mu2e void BkgDiag::findPrimary(std::vectorconst& dids, art::Ptr& pptr,double& pmom, std::vector& icontrib) const { - static StrawEnd itdc(StrawEnd::cal); // find the unique simparticles which produced these hits std::set > pp; for(auto id : dids) { StrawDigiMC const& mcdigi = _mcdigis->at(id); - art::Ptr const& spmcp = mcdigi.stepPointMC(itdc); - art::Ptr const& spp = spmcp->simParticle(); + art::Ptr const& spp = mcdigi.earlyStrawGasStep()->simParticle(); if(spp.isNonnull()){ pp.insert(spp); } @@ -468,11 +464,11 @@ namespace mu2e for(auto id : dids) { StrawDigiMC const& mcdigi = _mcdigis->at(id); // use TDC channel 0 to define the MC match - art::Ptr const& spmcp = mcdigi.stepPointMC(itdc); + auto const& spmcp = mcdigi.earlyStepPointMC(); art::Ptr const& spp = spmcp->simParticle(); if(spp == pptr){ - pmom = spmcp->momentum().mag(); + pmom = sqrt(spmcp->momentum().mag2()); break; } } @@ -480,11 +476,10 @@ namespace mu2e void BkgDiag::fillStrawHitInfoMC(StrawDigiMC const& mcdigi, art::Ptrconst& pptr, StrawHitInfo& shinfo) const { // use TDC channel 0 to define the MC match - StrawEnd itdc(StrawEnd::cal); - art::Ptr const& spmcp = mcdigi.stepPointMC(itdc); + auto const& spmcp = mcdigi.earlyStrawGasStep(); art::Ptr const& spp = spmcp->simParticle(); shinfo._mct0 = _toff.timeWithOffsetsApplied(*spmcp); - shinfo._mcht = mcdigi.wireEndTime(itdc); + shinfo._mcht = mcdigi.wireEndTime(mcdigi.earlyEnd()); shinfo._mcpdg = spp->pdgId(); shinfo._mcproc = spp->creationCode(); shinfo._mcedep = mcdigi.energySum(); @@ -495,8 +490,8 @@ namespace mu2e shinfo._mcpos = spmcp->position(); shinfo._mctime = shinfo._mct0; shinfo._mcedep = mcdigi.energySum();; - shinfo._mcmom = spmcp->momentum().mag(); - double cosd = spmcp->momentum().cosTheta(); + shinfo._mcmom = sqrt(spmcp->momentum().mag2()); + double cosd = cos(spmcp->momentum().Theta()); shinfo._mctd = cosd/sqrt(1.0-cosd*cosd); // relationship to parent shinfo._relation=MCRelationship::none; diff --git a/TrkDiag/src/ComboHitDiag_module.cc b/TrkDiag/src/ComboHitDiag_module.cc index f9fa15620a..417c8ac889 100644 --- a/TrkDiag/src/ComboHitDiag_module.cc +++ b/TrkDiag/src/ComboHitDiag_module.cc @@ -236,7 +236,7 @@ namespace mu2e throw cet::exception("DIAG")<<"mu2e::ComboHitDiag: invalid ComboHit" << std::endl; // use the 1st hit to define the MC match; this is arbitrary should be an average FIXME! StrawDigiMC const& mcd1 = _mcdigis->at(shids[0]); - art::Ptr const& spmcp = mcd1.stepPointMC(StrawEnd::cal); + auto const& spmcp = mcd1.stepPointMC(StrawEnd::cal); art::Ptr spp = spmcp->simParticle(); _mctime = _toff.timeWithOffsetsApplied(*spmcp); _mcpdg = spp->pdgId(); diff --git a/TrkDiag/src/HelixDiag_module.cc b/TrkDiag/src/HelixDiag_module.cc index e781e2a993..ea54d416ac 100644 --- a/TrkDiag/src/HelixDiag_module.cc +++ b/TrkDiag/src/HelixDiag_module.cc @@ -275,11 +275,9 @@ namespace mu2e { hhits.fillStrawDigiIndices(evt,ihh,sdis); for(auto idigi : sdis) { StrawDigiMC const& mcdigi = _mcdigis->at(idigi); - art::Ptr spmcp; - if (TrkMCTools::stepPoint(spmcp,mcdigi) >= 0 && - spmcp->simParticle() == pspp ){ + if ( mcdigi.earlyStrawGasStep()->simParticle() == pspp ){ ++nmc; - _mct0 += _toff.timeWithOffsetsApplied(*spmcp); + _mct0 += _toff.timeWithOffsetsApplied(*mcdigi.earlyStrawGasStep()); if(!hhit._flag.hasAnyProperty(StrawHitFlag::outlier))++_npused; } } @@ -538,8 +536,8 @@ namespace mu2e { _chcol->fillStrawDigiIndices(evt,ich,sdis); for(auto isd : sdis) { StrawDigiMC const& mcdigi = _mcdigis->at(isd); - art::Ptr spmcp; - if (TrkMCTools::stepPoint(spmcp,mcdigi) >= 0 && spmcp->simParticle() == pspp){ + auto const& spmcp = mcdigi.earlyStrawGasStep(); + if ( spmcp->simParticle() == pspp ){ double mcdphi = atan2(spmcp->position().y()-_mch.centery(),spmcp->position().x()-_mch.centerx()) - _mch.circleAzimuth(spmcp->position().z()); mcdphi -= rint(mcdphi/CLHEP::twopi)*CLHEP::twopi; TMarker* mch = new TMarker(spmcp->position().z(),mcdphi,20); @@ -719,8 +717,8 @@ namespace mu2e { _chcol->fillStrawDigiIndices(evt,ich,sdis); for(auto isd : sdis) { StrawDigiMC const& mcdigi = _mcdigis->at(isd); - art::Ptr spmcp; - if (TrkMCTools::stepPoint(spmcp,mcdigi) >= 0 && spmcp->simParticle() == pspp){ + auto const& spmcp = mcdigi.earlyStrawGasStep(); + if ( spmcp->simParticle() == pspp ){ TMarker* mch = new TMarker(spmcp->position().x()-pcent.x(),spmcp->position().y()-pcent.y(),20); mch->SetMarkerColor(kBlue); mch->SetMarkerSize(1); @@ -751,18 +749,15 @@ namespace mu2e { void HelixDiag::fillHitInfoMC(const art::Ptr& pspp, StrawDigiMC const& digimc, HitInfoMC& hinfomc) { hinfomc.reset(); - art::Ptr spp; - art::Ptr spmcp; - if(TrkMCTools::simParticle(spp,digimc) > 0 && TrkMCTools::stepPoint(spmcp,digimc) >= 0 ){ - hinfomc._pdg = spp->pdgId(); - hinfomc._proc = spp->originParticle().creationCode(); - if(spp->genParticle().isNonnull()) - hinfomc._gen = spp->genParticle()->generatorId().id(); - MCRelationship rel(pspp,spp); - hinfomc._rel = rel.relationship(); - hinfomc._t0 = _toff.timeWithOffsetsApplied(*spmcp); - } - } + auto const& spp = digimc.earlyStrawGasStep()->simParticle(); + hinfomc._pdg = spp->pdgId(); + hinfomc._proc = spp->originParticle().creationCode(); + if(spp->genParticle().isNonnull()) + hinfomc._gen = spp->genParticle()->generatorId().id(); + MCRelationship rel(pspp,spp); + hinfomc._rel = rel.relationship(); + hinfomc._t0 = _toff.timeWithOffsetsApplied(*digimc.earlyStrawGasStep()); + } bool HelixDiag::fillMCHelix(art::Ptr const& pspp) { bool retval(false); @@ -793,7 +788,7 @@ namespace mu2e { for(auto imcd = _mcdigis->begin();imcd != _mcdigis->end(); ++imcd){ auto const& stepptr = imcd->stepPointMC(imcd->earlyEnd()); if(stepptr->simParticle() == pspp){ - mom = stepptr->momentum(); + mom = Geom::Hep3Vec(stepptr->momentum()); pos = stepptr->position(); retval = true; break; @@ -826,8 +821,7 @@ namespace mu2e { bool HelixDiag::primary(art::Ptr const& pspp, size_t index) { StrawDigiMC const& mcdigi = _mcdigis->at(index); - art::Ptr spmcp; - return TrkMCTools::stepPoint(spmcp,mcdigi) >= 0 && spmcp->simParticle() == pspp; + return (mcdigi.earlyStrawGasStep()->simParticle() == pspp ); } bool diff --git a/TrkDiag/src/KalDiag.cc b/TrkDiag/src/KalDiag.cc index 997a46aa8d..3b225a9f02 100644 --- a/TrkDiag/src/KalDiag.cc +++ b/TrkDiag/src/KalDiag.cc @@ -456,7 +456,7 @@ namespace mu2e void KalDiag::fillHitInfoMC(art::Ptr const& pspp, StrawDigiMC const& mcdigi,Straw const& straw, TrkStrawHitInfoMC& tshinfomc) const { - art::Ptr const& spmcp = mcdigi.earlyStepPointMC(); + auto const& spmcp = mcdigi.earlyStepPointMC(); art::Ptr const& spp = spmcp->simParticle(); // create MC info and fill tshinfomc._t0 = _toff.timeWithOffsetsApplied(*spmcp); @@ -470,8 +470,8 @@ namespace mu2e tshinfomc._rel = rel.relationship(); // find the step midpoint Hep3Vector mcsep = spmcp->position()-straw.getMidPoint(); - Hep3Vector dir = spmcp->momentum().unit(); - tshinfomc._mom = spmcp->momentum().mag(); + Hep3Vector dir = Geom::Hep3Vec(spmcp->momentum()).unit(); + tshinfomc._mom = sqrt(spmcp->momentum().mag2()); tshinfomc._cpos = mcdigi.clusterPosition(mcdigi.earlyEnd()); tshinfomc._len = mcsep.dot(straw.getDirection()); Hep3Vector mcperp = (dir.cross(straw.getDirection())).unit(); @@ -517,7 +517,7 @@ namespace mu2e const TrkStrawHit* tsh = *ihit; if(tsh != 0){ StrawDigiMC const& mcdigi = _mcdata._mcdigis->at(tsh->index()); - art::Ptr const& spmcp = mcdigi.earlyStepPointMC(); + auto const& spmcp = mcdigi.earlyStepPointMC(); if(spp == spmcp->simParticle()){ ++mcinfo._nhits; // easiest way to get MC ambiguity is through info object @@ -538,7 +538,7 @@ namespace mu2e for(auto imcd = _mcdata._mcdigis->begin(); imcd !=_mcdata._mcdigis->end();++imcd){ if( imcd->stepPointMC(StrawEnd::cal)->simParticle() == spp){ mcinfo._ndigi++; - if(imcd->stepPointMC(StrawEnd::cal)->momentum().mag()/mcmom > _mingood) + if(sqrt(imcd->stepPointMC(StrawEnd::cal)->momentum().mag2())/mcmom > _mingood) mcinfo._ndigigood++; } } @@ -719,9 +719,9 @@ namespace mu2e unsigned nstrs = mcData()._mcdigis->size(); for(unsigned istr=0; istrat(istr); - art::Ptr const& spmcp = mcdigi.earlyStepPointMC(); + auto const& spmcp = mcdigi.earlyStepPointMC(); art::Ptr const& spp = spmcp->simParticle(); - bool conversion = (spp->genParticle().isNonnull() && spp->genParticle()->generatorId().isConversion() && spmcp->momentum().mag()>90.0); + bool conversion = (spp->genParticle().isNonnull() && spp->genParticle()->generatorId().isConversion() && sqrt(spmcp->momentum().mag2())>90.0); if(conversion){ ++ncehits; } diff --git a/TrkDiag/src/StrawHitDiag_module.cc b/TrkDiag/src/StrawHitDiag_module.cc index df9e10d63d..b3f4e72a11 100644 --- a/TrkDiag/src/StrawHitDiag_module.cc +++ b/TrkDiag/src/StrawHitDiag_module.cc @@ -302,14 +302,14 @@ namespace mu2e StrawDigiMC const& mcdigi = _mcdigis->at(istr); // use TDC channel 0 to define the MC match StrawEnd itdc; - art::Ptr const& spmcp = mcdigi.stepPointMC(itdc); + auto const& spmcp = mcdigi.stepPointMC(itdc); art::Ptr const& spp = spmcp->simParticle(); SimParticle const& osp = spp->originParticle(); Hep3Vector dprod = spmcp->position()-det->toDetector(osp.startPosition()); static Hep3Vector zdir(0.0,0.0,1.0); _pdist = dprod.mag(); _pperp = dprod.perp(zdir); - _pmom = spmcp->momentum().mag(); + _pmom = sqrt(spmcp->momentum().mag2()); _mcnsteps = 2; // FIXME! // compute energy sum _mcedep = mcdigi.energySum(); @@ -334,7 +334,7 @@ namespace mu2e _mcoe = osp.startMomentum().e(); _mcom = osp.startMomentum().vect().mag(); _mcshlen = (spmcp->position()-straw.getMidPoint()).dot(straw.getDirection()); - Hep3Vector mdir = spmcp->momentum().unit(); + Hep3Vector mdir = Geom::Hep3Vec(spmcp->momentum()).unit(); Hep3Vector tdir = (straw.getDirection().cross(mdir)).unit(); _mcshd = (spmcp->position()-straw.getMidPoint()).dot(tdir); double scos = mdir.dot(straw.getDirection()); diff --git a/TrkDiag/src/TimeClusterDiag_module.cc b/TrkDiag/src/TimeClusterDiag_module.cc index 5ed50be583..788e8131a0 100644 --- a/TrkDiag/src/TimeClusterDiag_module.cc +++ b/TrkDiag/src/TimeClusterDiag_module.cc @@ -194,8 +194,7 @@ art::Ptr const& primary, art::Event const& evt); _mcmidt0 = -1000; // loop over the digis and find the ones that match for(auto mcd : *_mcdigis) { - art::Ptr sp; - TrkMCTools::simParticle(sp,mcd); + art::Ptr sp = mcd.earlyStrawGasStep()->simParticle(); if(sp.isNonnull() && sp->genParticle().isNonnull() && sp->genParticle()->generatorId().id() == _mcgen){ @@ -393,17 +392,15 @@ art::Ptr const& primary, art::Event const& evt); StrawDigiMC const& mcdigi = _mcdigis->at(shids[0]);// FIXME! StrawEnd itdc; tchi._mctime = _toff.timeWithOffsetsApplied( *mcdigi.stepPointMC(itdc)); - tchi._mcmom = mcdigi.stepPointMC(itdc)->momentum().mag(); - art::Ptr sp; - if(TrkMCTools::simParticle(sp,mcdigi) > 0){ - tchi._mcpdg = sp->pdgId(); - tchi._mcproc = sp->creationCode(); - if(sp->genParticle().isNonnull()) - tchi._mcgen = sp->genParticle()->generatorId().id(); - if(primary.isNonnull()){ - MCRelationship rel(primary,sp); - tchi._mcrel = rel.relationship(); - } + tchi._mcmom = sqrt(mcdigi.stepPointMC(itdc)->momentum().mag2()); + art::Ptr sp = mcdigi.earlyStrawGasStep()->simParticle(); + tchi._mcpdg = sp->pdgId(); + tchi._mcproc = sp->creationCode(); + if(sp->genParticle().isNonnull()) + tchi._mcgen = sp->genParticle()->generatorId().id(); + if(primary.isNonnull()){ + MCRelationship rel(primary,sp); + tchi._mcrel = rel.relationship(); } } _tchinfo.push_back(tchi); @@ -528,19 +525,17 @@ art::Ptr const& primary, art::Event const& evt); for(auto shid : shids ) { StrawDigiMC const& mcdigi = _mcdigis->at(shid); StrawEnd itdc; - art::Ptr sp; - if(TrkMCTools::simParticle(sp,mcdigi) > 0){ - bool found(false); - for(size_t isp=0;isp sp = mcdigi.earlyStrawGasStep()->simParticle(); + bool found(false); + for(size_t isp=0;isp& sp, StrawDigiMC const& mcdigi) { - int retval(-1); - if(mcdigi.wireEndTime(StrawEnd::cal) < mcdigi.wireEndTime(StrawEnd::hv)) { - sp = mcdigi.stepPointMC(StrawEnd::cal); - retval = StrawEnd::cal; - } else { - sp = mcdigi.stepPointMC(StrawEnd::hv); - retval = StrawEnd::hv; - }; - return retval; - } - bool CEDigi(StrawDigiMC const& mcdigi) { bool conversion(false); - art::Ptr spmcp; - if(stepPoint(spmcp,mcdigi) >= 0){ - art::Ptr const& spp = spmcp->simParticle(); - int gid(-1); - if(spp->genParticle().isNonnull()) - gid = spp->genParticle()->generatorId().id(); - // a conversion electron is an electron from the CE generator. The momentum requirement - // removes cases where the CE loses a catastrophic amount of energy (ie albedo backsplash - // from the calorimeter). - conversion = (spp->pdgId() == 11 && gid == 2 && spmcp->momentum().mag()>90.0); - } + auto const& spmcp = mcdigi.earlyStepPointMC(); + art::Ptr const& spp = spmcp->simParticle(); + int gid(-1); + if(spp->genParticle().isNonnull()) + gid = spp->genParticle()->generatorId().id(); + // a conversion electron is an electron from the CE generator. The momentum requirement + // removes cases where the CE loses a catastrophic amount of energy (ie albedo backsplash + // from the calorimeter). + conversion = (spp->pdgId() == 11 && gid == 2 && sqrt(spmcp->momentum().mag2())>90.0); return conversion; } @@ -56,46 +42,33 @@ namespace mu2e { for( auto hi : hits ) { StrawDigiMC const& mcdigi = mcdigis->at(hi); - art::Ptr spp; - if(simParticle(spp,mcdigi) > 0 ){ - auto ispp = spmap.find(spp); - if(ispp != spmap.end()) - ++(ispp->second); - else - spmap[spp] = 1; - } + art::Ptr spp = mcdigi.earlyStrawGasStep()->simParticle(); + auto ispp = spmap.find(spp); + if(ispp != spmap.end()) + ++(ispp->second); + else + spmap[spp] = 1; } for( auto imap : spmap ) { if(imap.second > retval){ retval = imap.second; pspp = imap.first; } - } - return retval; + } + return retval; } unsigned countDigis(art::Ptr const& pspp, const StrawDigiMCCollection* mcdigis) { unsigned retval(0); for( auto mcdigi : *mcdigis ) { - art::Ptr spp; - if(simParticle(spp,mcdigi) > 0 && spp == pspp) { + art::Ptr spp = mcdigi.earlyStrawGasStep()->simParticle(); + if(spp == pspp) { ++retval; } } return retval; } - unsigned simParticle(art::Ptr& spp, StrawDigiMC const& mcdigi) { - unsigned retval(0); - if( mcdigi.stepPointMC(StrawEnd::cal)->simParticle() == - mcdigi.stepPointMC(StrawEnd::hv)->simParticle() ) { - spp = mcdigi.stepPointMC(StrawEnd::cal)->simParticle(); - retval = 2; - } - return retval; - } - - void findMCTrk(const KalSeed& kseed,art::Ptr& spp, StrawDigiMCCollection const& mcdigis) { static art::Ptr nullvec; spp = nullvec; @@ -114,7 +87,7 @@ namespace mu2e { // loop over the hits and find the associated steppoints bool isactive = tshs.flag().hasAllProperties(active); StrawDigiMC const& mcdigi = mcdigis.at(tshs.index()); - art::Ptr spp = mcdigi.earlyStepPointMC()->simParticle(); + art::Ptr spp = mcdigi.earlyStrawGasStep()->simParticle(); // see if this particle has already been found; if so, increment, if not, add it bool found(false); for(auto& spc : sct ) { @@ -126,23 +99,6 @@ namespace mu2e { } if(!found)sct.push_back(spcount(spp,isactive)); } - if(saveall){ - // FIXME! -// // add the SimParticles that contributed non-trigger energy. These have 0 count -// for(const auto& tshs : kseed.hits()) { -// StrawDigiMC const& mcdigi = mcdigis.at(tshs.index()); -// for(auto const& spmc : mcdigi.stepPointMCs()){ -// bool found(false); -// for(auto& spc : sct ) { -// if(spc._spp == spmc->simParticle() ){ -// found = true; -// break; -// } -// } -// if(!found)sct.push_back(spcount(spmc->simParticle())); -// } -// } - } // sort by # of contributions sort(sct.begin(),sct.end(),spcountcomp()); } @@ -171,15 +127,15 @@ namespace mu2e { unsigned count(0); art::Ptr sp; for(auto sdi : indices) { - // find relation of this digi to the primary - MCRelationship prel(spp,sdmccol.at(sdi).earlyStepPointMC()->simParticle()); + // find relation of this digi to the primary + MCRelationship prel(spp,sdmccol.at(sdi).earlyStrawGasStep()->simParticle()); // count the highest relationship for these digis if(prel == mcrel && prel != MCRelationship::none) count++; else if(prel > mcrel){ mcrel = prel; count = 1; - sp = sdmccol.at(sdi).earlyStepPointMC()->simParticle(); + sp = sdmccol.at(sdi).earlyStrawGasStep()->simParticle(); } } if(count > nprimary){ diff --git a/TrkDiag/src/TrkRecoDiag_module.cc b/TrkDiag/src/TrkRecoDiag_module.cc index 3660fc040e..09c01e5cdc 100644 --- a/TrkDiag/src/TrkRecoDiag_module.cc +++ b/TrkDiag/src/TrkRecoDiag_module.cc @@ -510,9 +510,8 @@ namespace mu2e { if(tsh.flag().hasAllProperties(StrawHitFlag::active))++_kfna; if(spp.isNonnull()){ StrawDigiMC const& mcdigi = _mcdigis->at(tsh.index()); - art::Ptr spmcp; - if (TrkMCTools::stepPoint(spmcp,mcdigi) >= 0 && - spmcp->simParticle() == spp){ + auto const& spmcp = mcdigi.earlyStrawGasStep(); + if ( spmcp->simParticle() == spp){ ++_kfnp; if(!tsh.flag().hasAnyProperty(StrawHitFlag::outlier))++_kfnap; } @@ -545,9 +544,8 @@ namespace mu2e { if(tsh.flag().hasAllProperties(StrawHitFlag::active))++_ksna; if(spp.isNonnull()){ StrawDigiMC const& mcdigi = _mcdigis->at(tsh.index()); - art::Ptr spmcp; - if (TrkMCTools::stepPoint(spmcp,mcdigi) >= 0 && - spmcp->simParticle() == spp){ + auto spmcp = mcdigi.earlyStrawGasStep(); + if ( spmcp->simParticle() == spp){ ++_ksnp; if(!tsh.flag().hasAnyProperty(StrawHitFlag::outlier))++_ksnap; } @@ -573,9 +571,8 @@ namespace mu2e { if(!hhit.flag().hasAnyProperty(StrawHitFlag::outlier))_hsna += hhit.nStrawHits(); if(spp.isNonnull()){ StrawDigiMC const& mcdigi = _mcdigis->at(hhit.index()); - art::Ptr spmcp; - if (TrkMCTools::stepPoint(spmcp,mcdigi) >= 0 && - spmcp->simParticle() == spp){ + auto spmcp = mcdigi.earlyStrawGasStep(); + if ( spmcp->simParticle() == spp){ _hsnp += hhit.nStrawHits(); if(!hhit.flag().hasAnyProperty(StrawHitFlag::outlier))_hsnap += hhit.nStrawHits(); } @@ -597,9 +594,8 @@ namespace mu2e { // count matching hits for(auto tchit : tc.hits()){ StrawDigiMC const& mcdigi = _mcdigis->at(tchit); - art::Ptr spmcp; - if (TrkMCTools::stepPoint(spmcp,mcdigi) >= 0 && - spmcp->simParticle() == spp){ + auto spmcp = mcdigi.earlyStrawGasStep(); + if ( spmcp->simParticle() == spp){ ++_tcnp; } } diff --git a/TrkReco/src/TrkRecoMcUtils_tool.cc b/TrkReco/src/TrkRecoMcUtils_tool.cc index 72bc4584d5..60fb5376bc 100644 --- a/TrkReco/src/TrkRecoMcUtils_tool.cc +++ b/TrkReco/src/TrkRecoMcUtils_tool.cc @@ -22,8 +22,6 @@ #include "MCDataProducts/inc/StrawDigiMCCollection.hh" #include "MCDataProducts/inc/StepPointMC.hh" -#include "MCDataProducts/inc/StrawHitMCTruth.hh" -#include "MCDataProducts/inc/StrawHitMCTruthCollection.hh" #include "MCDataProducts/inc/StepPointMCCollection.hh" #include "Mu2eUtilities/inc/SimParticleTimeOffset.hh" @@ -73,7 +71,6 @@ namespace mu2e { int getPdgID (const SimParticle* Sim) override; float getStartMom(const SimParticle* Sim) override; - const StepPointMC* getStepPointMC(int HitIndex); }; //----------------------------------------------------------------------------- @@ -114,34 +111,12 @@ namespace mu2e { } //----------------------------------------------------------------------------- - const StepPointMC* TrkRecoMcUtils::getStepPointMC(int HitIndex) { - const StepPointMC* step(nullptr); - if (_mcdigis) { - const mu2e::StrawDigiMC* mcdigi = &_mcdigis->at(HitIndex); - - if (mcdigi->wireEndTime(mu2e::StrawEnd::cal) < mcdigi->wireEndTime(mu2e::StrawEnd::hv)) { - step = mcdigi->stepPointMC(mu2e::StrawEnd::cal).get(); - } - else { - step = mcdigi->stepPointMC(mu2e::StrawEnd::hv ).get(); - } - } - return step; - } - //----------------------------------------------------------------------------- // returns ID of the SimParticle corresponding to straw hit 'Index' //----------------------------------------------------------------------------- int TrkRecoMcUtils::strawHitSimId(const art::Event* Event, int HitIndex) { - int simId(-1); - if (Event->event() != _lastEvent) initEvent(Event); - - const StepPointMC* step = getStepPointMC(HitIndex); - - if (step) simId = step->simParticle()->id().asInt(); - - return simId; + return (*_mcdigis)[HitIndex].earlyStepPointMC()->simParticle()->id().asInt(); } //----------------------------------------------------------------------------- // find MC truth DOCA in a given straw @@ -161,13 +136,13 @@ namespace mu2e { int hitIndex = ch-&_chColl->at(0); - const StepPointMC* step = getStepPointMC(hitIndex); + auto const& step = (*_mcdigis)[hitIndex].earlyStepPointMC(); - const CLHEP::Hep3Vector* v2 = &step->position(); - HepPoint p2(v2->x(),v2->y(),v2->z()); + CLHEP::Hep3Vector v2 = step->position(); + HepPoint p2(v2.x(),v2.y(),v2.z()); TrkLineTraj trstraw(p1,straw->getDirection() ,0.,0.); - TrkLineTraj trstep (p2,step->momentum().unit(),0.,0.); + TrkLineTraj trstep (p2,Geom::Hep3Vec(step->momentum()).unit(),0.,0.); TrkPoca poca(trstep, 0., trstraw, 0.); @@ -242,13 +217,7 @@ namespace mu2e { if (Event->event() != _lastEvent) initEvent(Event); - const mu2e::StepPointMC *step = getStepPointMC(HitIndex); - - const mu2e::SimParticle* sim(nullptr); - - sim = (step != nullptr) ? step->simParticle().get() : nullptr; - - return sim; + return (*_mcdigis)[HitIndex].earlyStepPointMC()->simParticle().get(); } //----------------------------------------------------------------------------- diff --git a/Validation/inc/ValStrawDigiMC.hh b/Validation/inc/ValStrawDigiMC.hh index ed210073aa..fcbd648492 100644 --- a/Validation/inc/ValStrawDigiMC.hh +++ b/Validation/inc/ValStrawDigiMC.hh @@ -26,8 +26,6 @@ namespace mu2e { TH1D* _hN2; TH1D* _htime0; TH1D* _htime1; - TH1D* _hdrift; - TH1D* _hdriftM; TH1D* _hener; TH1D* _henerT; TH1D* _hcross; diff --git a/Validation/src/ValStrawDigiMC.cc b/Validation/src/ValStrawDigiMC.cc index 1214a50c7d..ee1b286641 100644 --- a/Validation/src/ValStrawDigiMC.cc +++ b/Validation/src/ValStrawDigiMC.cc @@ -7,8 +7,6 @@ int mu2e::ValStrawDigiMC::declare(art::TFileDirectory tfs) { _hN2 = tfs.make( "NHit2", "N Straw Hits", 100, -0.5, 9999.5); _htime0 = tfs.make( "time0", "time0", 100, 0.0, 2000.0); _htime1 = tfs.make( "time1", "time1", 100, 0.0, 2000.0); - _hdrift = tfs.make( "drift", "drift distance",50, -0.5, 1000.0); - _hdriftM = tfs.make( "driftM", "drift to Mid",50, -0.5, 1000.0); _hener = tfs.make( "ener", "energy",50, -1.0e-6, 0.01); _henerT = tfs.make( "enerT", "trigger energy",50, -1.0e-6, 0.01); _hcross = tfs.make( "cross", "cross talk flag",2, -0.5, 1.5); @@ -46,10 +44,6 @@ int mu2e::ValStrawDigiMC::fill(const mu2e::StrawDigiMCCollection & coll, if(ptrOK) { _htime0->Fill(sd.wireEndTime(StrawEnd::cal)); _htime1->Fill(sd.wireEndTime(StrawEnd::hv)); - _hdrift->Fill(sd.driftDistance(StrawEnd::cal)); - _hdrift->Fill(sd.driftDistance(StrawEnd::hv)); - _hdriftM->Fill(sd.distanceToMid(StrawEnd::cal)); - _hdriftM->Fill(sd.distanceToMid(StrawEnd::hv)); _hener->Fill(sd.energySum()); _henerT->Fill(sd.triggerEnergySum(StrawEnd::cal)); _henerT->Fill(sd.triggerEnergySum(StrawEnd::hv)); From 35b263893927aa764a968fc522b49b39750be7b2 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Mon, 11 Nov 2019 19:12:38 -0600 Subject: [PATCH 12/18] Cleanup and add diagnostics --- TrackerMC/src/MakeStrawGasSteps_module.cc | 42 ++++++++++++++--------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index bd78dc8216..f336c408fc 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -96,9 +96,8 @@ namespace mu2e { void compressDeltas(SPSMap& spsmap); void setStepType(SPMCP const& spmcptr, ParticleData const* pdata, StrawGasStep::StepType& stype); void fillStep(SPMCPV const& spmcptrs, Straw const& straw, - ParticleData const* pdata, cet::map_vector_key pid, - StrawGasStep& sgs, SPMCP & spmcptr); - void fillStepDiag(Straw const& straw, StrawGasStep const& sgs, SPMCP const& spmcptr, SPMCPV const& spmcptrs); + ParticleData const* pdata, cet::map_vector_key pid, StrawGasStep& sgs); + void fillStepDiag(Straw const& straw, StrawGasStep const& sgs, SPMCPV const& spmcptrs); XYZVec endPosition(SPMCP const& last, Straw const& straw,float charge,StrawGasStep::StepType& stype); int _debug, _diag; bool _combineDeltas, _allAssns; @@ -121,8 +120,8 @@ namespace mu2e { TH1F *_hendrad, *_hphi; TTree* _sgsdiag; Float_t _prilen, _pridist, _elen, _erad, _epri, _esec, _partP, _brot, _width, _doca; - vector _sdist; - Int_t _npri, _nsec, _partPDG; + vector _sdist, _sdot, _sp, _slen; + Int_t _npri, _nsec, _partPDG, _sion, _sshape; }; MakeStrawGasSteps::MakeStrawGasSteps(const Parameters& config ) : @@ -171,7 +170,12 @@ namespace mu2e { _sgsdiag->Branch("nsec",&_nsec,"nsec/I"); _sgsdiag->Branch("partP",&_partP,"partP/F"); _sgsdiag->Branch("partPDG",&_partPDG,"partPDG/I"); - _sgsdiag->Branch("sdist",&_sdist); + _sgsdiag->Branch("sion",&_sion,"sion/I"); + _sgsdiag->Branch("sshape",&_sshape,"sshape/I"); + _sgsdiag->Branch("sdist",&_sdist); + _sgsdiag->Branch("sdot",&_sdot); + _sgsdiag->Branch("sp",&_sp); + _sgsdiag->Branch("slen",&_slen); } } } @@ -254,8 +258,7 @@ namespace mu2e { ParticleData const* pdata(0); if(pref.isValid())pdata = &pref.ref(); StrawGasStep sgs; - SPMCP spmcptr; - fillStep(spmcptrs,straw,pdata,pid,sgs,spmcptr); + fillStep(spmcptrs,straw,pdata,pid,sgs); sgsc->push_back(sgs); auto sgsptr = art::Ptr(StrawGasStepCollectionPID,sgsc->size()-1,StrawGasStepCollectionGetter); // optionall add Assns for all StepPoints, including delta-rays @@ -263,7 +266,7 @@ namespace mu2e { for(auto const& spmcptr : spmcptrs) sgsa->addSingle(sgsptr,spmcptr); } - if(_diag > 0)fillStepDiag(straw,sgs,spmcptr,spmcptrs); + if(_diag > 0)fillStepDiag(straw,sgs,spmcptrs); if(_debug > 1){ // checks and printout cout << " SGS with " << spmcptrs.size() << " steps, StrawId = " << sgs.strawId() << " SimParticle Key = " << sgs.simParticle()->id() @@ -287,7 +290,7 @@ namespace mu2e { } // end of produce void MakeStrawGasSteps::fillStep(SPMCPV const& spmcptrs, Straw const& straw, - ParticleData const* pdata, cet::map_vector_key pid, StrawGasStep& sgs, SPMCP & spmcptr){ + ParticleData const* pdata, cet::map_vector_key pid, StrawGasStep& sgs){ // variables we accumulate for all the StepPoints in this pair double eion(0.0), pathlen(0.0); if(_diag>1){ @@ -322,7 +325,6 @@ namespace mu2e { } if(first.isNull() || last.isNull()) throw cet::exception("SIM")<<"mu2e::MakeStrawGasSteps: No first or last step" << endl; - spmcptr = first; // Define the position at entrance and exit; note the StepPointMC position is at the start of the step, so we have to extend the last XYZVec start = Geom::toXYZVec(first->position()); float charge(0.0); @@ -489,27 +491,35 @@ namespace mu2e { return retval; } - void MakeStrawGasSteps::fillStepDiag(Straw const& straw, StrawGasStep const& sgs, - SPMCP const& spmcptr, SPMCPV const& spmcptrs) { + void MakeStrawGasSteps::fillStepDiag(Straw const& straw, StrawGasStep const& sgs, SPMCPV const& spmcptrs) { _erad = sqrt((Geom::Hep3Vec(sgs.endPosition())-straw.getMidPoint()).perpPart(straw.getDirection()).mag2()); _hendrad->Fill(_erad); _hphi->Fill(_brot); if(_diag > 1){ + _sshape = sgs.stepType().shape(); + _sion = sgs.stepType().ionization(); _prilen = sgs.stepLength(); _pridist = sqrt((sgs.endPosition()-sgs.startPosition()).mag2()); - _partP = spmcptr->momentum().mag(); - _partPDG = spmcptr->simParticle()->pdgId(); - _elen = spmcptr->stepLength(); + auto const& spmc = *spmcptrs.front(); + _partP = spmc.momentum().mag(); + _partPDG = spmc.simParticle()->pdgId(); + _elen = spmc.stepLength(); _width = sgs.width(); // compute DOCA to the wire TwoLinePCA poca(Geom::Hep3Vec(sgs.startPosition()),Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()), straw.getMidPoint(),straw.getDirection()); _doca = poca.dca(); _sdist.clear(); + _sdot.clear(); + _sp.clear(); + _slen.clear(); auto sdir = Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()).unit(); for(auto const& spmcptr : spmcptrs){ auto dist = ((spmcptr->position()-Geom::Hep3Vec(sgs.startPosition())).cross(sdir)).mag(); _sdist.push_back(dist); + _sdot.push_back(sdir.dot(spmcptr->momentum().unit())); + _sp.push_back(spmcptr->momentum().mag()); + _slen.push_back(spmcptr->stepLength()); } _sgsdiag->Fill(); } From 4b8094fcea156238660c17626249f5cf81fc856f Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Tue, 12 Nov 2019 18:51:15 -0600 Subject: [PATCH 13/18] Small fixes and cleanup. Update prolog to use StrawGasStep --- JobConfig/mixing/prolog.fcl | 10 +- JobConfig/primary/prolog.fcl | 6 +- TrackerMC/fcl/prolog.fcl | 14 +- .../src/StrawDigisFromStrawGasSteps_module.cc | 126 +++++++----------- 4 files changed, 69 insertions(+), 87 deletions(-) diff --git a/JobConfig/mixing/prolog.fcl b/JobConfig/mixing/prolog.fcl index 545db582a3..4d5ae4ba52 100644 --- a/JobConfig/mixing/prolog.fcl +++ b/JobConfig/mixing/prolog.fcl @@ -81,9 +81,13 @@ Mixing : { cutMax: 11.7e7 // cut the tail at 3 times the mean } # tracker digis for primary selection + makeSGSPrimary : { + @table::makeSGS + } makeSDPrimary : { - module_type : StrawDigisFromStepPointMCs - TimeOffsets : { inputs : [ @sequence::CommonMC.TimeMapsPrimary ] } + @table::makeSD + StrawGasStepCollection : makeSGSPrimary + TimeOffsets : [ @sequence::CommonMC.TimeMapsPrimary ] } # digi compression compressDigiMCs : @local::DigiCompression.Mixing @@ -137,7 +141,7 @@ Mixing : { CreatePrimarySequence : [ @sequence::Primary.GenAndG4, @sequence::CommonMC.PrimaryDigiSim, - makeSDPrimary, DigiFilter ] + makeSGSPrimary, makeSDPrimary, DigiFilter ] # paths and output EndPath : [ @sequence::Primary.EndPath ] Output : { diff --git a/JobConfig/primary/prolog.fcl b/JobConfig/primary/prolog.fcl index 3deb043c8d..f611251c78 100644 --- a/JobConfig/primary/prolog.fcl +++ b/JobConfig/primary/prolog.fcl @@ -21,9 +21,13 @@ Primary: { @table::CaloDigiMC.producers @table::CrvDAQPackage.producers # dedicated digi maker for filter +# 2 stages now + makeSGS : { + module_type : MakeStrawGasSteps + KeepDeltasModule : "g4run" # don'e compress deltas on primary particles + } makeSD:{ @table::makeSD - TimeOffsets : { inputs : [ @sequence::CommonMC.TimeMaps ] } } compressDigiMCs : @local::DigiCompression.Primary } diff --git a/TrackerMC/fcl/prolog.fcl b/TrackerMC/fcl/prolog.fcl index d43c7597b0..24969008fb 100644 --- a/TrackerMC/fcl/prolog.fcl +++ b/TrackerMC/fcl/prolog.fcl @@ -1,17 +1,23 @@ #include "CommonMC/fcl/prolog.fcl" BEGIN_PROLOG +makeSGS : { + module_type : MakeStrawGasSteps + KeepDeltasModule : "g4run" # don'e compress deltas on primary particles +} # straw digis makeSD : { - module_type : StrawDigisFromStepPointMCs - TimeOffsets : { inputs : [ @sequence::CommonMC.TimeMaps ] } + module_type : StrawDigisFromStrawGasSteps + TimeOffsets : [ @sequence::CommonMC.TimeMaps ] + StrawGasStepCollection : makeSGS } #------------------------------------------------------------------------------ TrackerMC : { producers : { - makeSD : { @table::makeSD } + makeSGS : {@table::makeSGS } + makeSD : { @table::makeSD } } - DigiSim : [ makeSD ] + DigiSim : [ makeSGS, makeSD ] } END_PROLOG diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc index 541339159f..93af91ac45 100644 --- a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -96,7 +96,6 @@ namespace mu2e { fhicl::Atom minnxinghist{ Name("MinNXingHist"), Comment("Minimum # of crossings to histogram waveform"),1}; fhicl::Atom tstep { Name("WaveformStep"), Comment("WaveformStep (nsec)"),0.1 }; fhicl::Atom nfall{ Name("WaveformTail"), Comment("# of decay lambda past last signal to record waveform"),10.0}; - fhicl::Atom maxFullPrint{ Name("maxFullPrint"), Comment("Limit on number of events for which there will be full printout") ,2}; fhicl::Atom addXtalk{ Name("addCrossTalk"), Comment("Should we add cross talk hits?"),false }; fhicl::Atom ctMinCharge{ Name("xtalkMinimumCharge"), Comment("minimum charge to add cross talk (for performance issues)") ,0}; fhicl::Atom addNoise{ Name("addNoise"), Comment("should we add noise hits? NOT CURRENTLY IMPLEMENTED FIXME!"),false }; @@ -104,21 +103,20 @@ namespace mu2e { fhicl::Atom postampxtalk{ Name("postAmplificationCrossTalk"), Comment("Post-amplification (board) X-talk coupling") ,0.02}; fhicl::Atom minstepE{ Name("minstepE"), Comment(" minimum step energy depostion to turn into a straw signal (MeV)"),2.0e-6 }; fhicl::Atom ewMarkerTag{ Name("EventWindowMarker"), Comment("EventWindowMarker producer"),"EWMProducer" }; - fhicl::Atom StrawGasStepCollectionTag{ Name("StrawGasStepCollection"), Comment("StrawGasStepCollection producer"),"SGSMaker" }; + fhicl::Atom StrawGasStepCollectionTag{ Name("StrawGasStepCollection"), Comment("StrawGasStepCollection producer") }; fhicl::Atom steptimebuf{ Name("StrawGasStepTimeBuffer"), Comment("buffer for MC step point times (nsec) ") ,100.0 }; fhicl::Atom flashBuffer{ Name("FlashTimeBuffer"), Comment("buffer for flash blanking times (nsec) ") ,10.0 }; fhicl::Atom tdcbuf{ Name("TDCTimeBuffer"), Comment("buffer for TDC jitter (nsec) ") ,2.0 }; fhicl::Atom allStraw{ Name("AllHitsStraw"), Comment("minimum straw # to read all hits") ,90}; fhicl::Sequence allPlanes{ Name("AllHitsPlanes"), Comment("planes to read all hits"), std::vector{} }; fhicl::Atom diagpath{ Name("DiagPath"), Comment("Digitization Path for waveform diagnostics") ,0 }; - fhicl::Atom sort{ Name("SortClusterEnergy"), Comment("Sort clusters by energy before digitizing") ,false }; fhicl::Atom spinstance { Name("StrawGasStepInstance"), Comment("StrawGasStep Instance name"),""}; fhicl::Sequence SPTO { Name("TimeOffsets"), Comment("Sim Particle Time Offset Maps")}; }; typedef art::Ptr SGSPtr; - typedef art::Ptr SPMCPtr; + typedef art::Ptr SPPtr; typedef map StrawClusterMap; // clusts by straw // work with pairs of waveforms, one for each straw end typedef std::array SWFP; @@ -142,9 +140,6 @@ namespace mu2e { bool _xtalkhist; unsigned _minnxinghist; double _tstep, _nfall; - // Limit on number of events for which there will be full printout. - int _maxFullPrint; - // Parameters bool _addXtalk; double _ctMinCharge; @@ -162,7 +157,6 @@ namespace mu2e { std::vector _allPlanes; StrawElectronics::Path _diagpath; unsigned _maxnclu; - bool _sort; // sort cluster sizes before filling energy // Random number distributions art::RandomNumberGenerator::base_engine_t& _engine; CLHEP::RandGaussQ _randgauss; @@ -218,7 +212,6 @@ namespace mu2e { StrawElectronics const& strawele, Straw const& straw, SGSPtr const& sgsptr, - SPMCPtr const& spmcptr, StrawClusterSequencePair& shsp); void divideStep(StrawPhysics const& strawphys, StrawElectronics const& strawele, @@ -254,8 +247,7 @@ namespace mu2e { void waveformDiag(StrawElectronics const& strawele, SWFP const& wf, WFXPList const& xings); void digiDiag(StrawPhysics const& strawphys, SWFP const& wf, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi); - void stepDiag(StrawPhysics const& strawphys, StrawElectronics const& strawele, - StrawGasStep const& sgs, StepPointMC const& spmc); + void stepDiag(StrawPhysics const& strawphys, StrawElectronics const& strawele, StrawGasStep const& sgs); float EBAngle(XYZVec const& cpos,Straw const& straw) const; }; @@ -269,7 +261,6 @@ namespace mu2e { _minnxinghist(config().minnxinghist()), _tstep(config().tstep()), _nfall(config().nfall()), - _maxFullPrint(config().maxFullPrint()), _addXtalk(config().addXtalk()), _ctMinCharge(config().ctMinCharge()), _addNoise(config().addNoise()), @@ -283,7 +274,6 @@ namespace mu2e { _allStraw(config().allStraw()), _allPlanes(config().allPlanes()), _diagpath(static_cast(config().diagpath())), - _sort(config().sort()), // Random number distributions _engine(createEngine( art::ServiceHandle()->getSeed())), _randgauss( _engine ), @@ -298,7 +288,6 @@ namespace mu2e { { // Tell the framework what we consume. consumesMany(); - consumesMany(); consumes(_ewMarkerTag); // Tell the framework what we make. produces(); @@ -430,7 +419,7 @@ namespace mu2e { // Containers to hold the output information. unique_ptr digis(new StrawDigiCollection); unique_ptr mcdigis(new StrawDigiMCCollection); - // create the StrawCluster map and StepPointMC map + // create the StrawCluster map StrawClusterMap hmap; // fill this from the event fillClusterMap(strawphys,strawele,tracker,event,hmap); @@ -510,14 +499,6 @@ namespace mu2e { // Loop over StrawGasStep collections for ( auto const& sgsch : stepsHandles) { StrawGasStepCollection const& steps(*sgsch); - // find the associated Assns for this sgsch - art::Handle sgsah; - if(!event.getByLabel(sgsch.provenance()->moduleLabel(),sgsch.provenance()->productInstanceName(),sgsah)){ - throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: No StrawGasStepAssns found for module " - << sgsch.provenance()->moduleLabel() << " instance " - << sgsch.provenance()->productInstanceName() << endl; - } - StrawGasStepAssns const& sgsa = *sgsah; // Loop over the StrawGasSteps in this collection for(size_t isgs = 0; isgs < steps.size(); isgs++){ auto const& sgs = steps[isgs]; @@ -525,15 +506,9 @@ namespace mu2e { StrawId const & sid = sgs.strawId(); Straw const& straw = tracker.getStraw(sid); if(sgs.ionizingEdep() > _minstepE){ - // find assocated pPointMC for MC truth mapping - SGSPtr sgsptr(sgsch,isgs); - auto const& isgsa = sgsa[isgs];// these should be lock-step, but check - if(isgsa.first != sgsptr){ - throw cet::exception("SIM")<<"mu2e::StrawDigisFromStrawGasSteps: StrawGasStepAssns doesn't match StrawGasStep!" << endl; - } - auto const& spmcptr = isgsa.second; + auto sgsptr = SGSPtr(sgsch,isgs); // create a clust from this step, and add it to the clust map - addStep(strawphys,strawele,straw,sgsptr,spmcptr,hmap[sid]); + addStep(strawphys,strawele,straw,sgsptr,hmap[sid]); } } } @@ -542,7 +517,7 @@ namespace mu2e { void StrawDigisFromStrawGasSteps::addStep(StrawPhysics const& strawphys, StrawElectronics const& strawele, Straw const& straw, - SGSPtr const& sgsptr, SPMCPtr const& spmcptr, + SGSPtr const& sgsptr, StrawClusterSequencePair& shsp) { auto const& sgs = *sgsptr; StrawId sid = sgs.strawId(); @@ -576,7 +551,7 @@ namespace mu2e { addGhosts(strawele,clust,shsp.clustSequence(end)); } } - if(_diag > 0) stepDiag(strawphys, strawele, sgs, *spmcptr); + if(_diag > 0) stepDiag(strawphys, strawele, sgs); } } @@ -874,10 +849,10 @@ namespace mu2e { unsigned nc = ne.size(); while(mc < nc){ std::vector me(nc); - // fill an array of random# of electrons according to the measured distribution. These are returned sorted lowest-highest. + // fill an array of random# of electrons according to the measured distribution. fillClusterNe(strawphys,me); + // loop through these as long as there's enough energy to have at least 1 electron in each cluster. If not, re-throw the # of electrons/cluster for the remainder for(auto ie : me) { - // maximum energy for this cluster requires at least 1 electron for the rest of the cluster double emax = etot - esum - (nc -mc -1)*strawphys.ionizationEnergy((unsigned)1); double eele = strawphys.ionizationEnergy(ie); if( eele < emax){ @@ -912,7 +887,6 @@ namespace mu2e { for(size_t ie=0;ie < me.size(); ++ie){ me[ie] = strawphys.nePerIon(_randflat.fire()); } - if(_sort)std::sort(me.begin(),me.end()); } bool StrawDigisFromStrawGasSteps::readAll(StrawId const& sid) const { @@ -933,8 +907,8 @@ namespace mu2e { for(size_t iend=0;iend<2; ++iend){ ClusterList const& clusts = wfs[iend].clusts().clustList(); size_t nclust = clusts.size(); - set > steps; - set > parts; + set steps; + set parts; _nxing[iend] = 0; _txing[iend] = strawele.flashStart() + _mbbuffer; _xddist[iend] = _xwdist[iend] = _xpdist[iend] = -1.0; @@ -944,11 +918,11 @@ namespace mu2e { _xddist[iend] = ixing->at(iend)._iclust->driftDistance(); _xwdist[iend] = ixing->at(iend)._iclust->wireDistance(); // compute direction perpendicular to wire and momentum - auto const& spp = ixing->at(iend)._iclust->strawGasStep(); - if(!spp.isNull()){ - Hep3Vector pdir = straw.getDirection().cross(Geom::Hep3Vec(spp->momentum())).unit(); + auto const& sgs = ixing->at(iend)._iclust->strawGasStep(); + if(!sgs.isNull()){ + Hep3Vector pdir = straw.getDirection().cross(Geom::Hep3Vec(sgs->momentum())).unit(); // project the differences in position to get the perp distance - _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); + _xpdist[iend] = pdir.dot(sgs->position()-straw.getMidPoint()); } } if(_nxing[iend] == 0){ @@ -956,11 +930,11 @@ namespace mu2e { if(nclust > 0 ){ _xddist[iend] = clusts.front().driftDistance(); _xwdist[iend] = clusts.front().wireDistance(); - auto const& spp = clusts.front().stepPointMC(); - if(!spp.isNull()){ - Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); + auto const& sgs = clusts.front().strawGasStep(); + if(!sgs.isNull()){ + Hep3Vector pdir = straw.getDirection().cross(Geom::Hep3Vec(sgs->momentum())).unit(); // project the differences in position to get the perp distance - _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); + _xpdist[iend] = pdir.dot(sgs->position()-straw.getMidPoint()); } } } @@ -976,20 +950,20 @@ namespace mu2e { _vmax[iend] = _tvmax[iend] = 0.0; _wmcpdg[iend] = _wmcproc[iend] = 0; for(auto iclu=clusts.begin();iclu!=clusts.end();++iclu){ - if(iclu->stepPointMC().isNonnull()){ - steps.insert(iclu->stepPointMC()); - parts.insert(iclu->stepPointMC()->simParticle()); + if(iclu->strawGasStep().isNonnull()){ + steps.insert(iclu->strawGasStep()); + parts.insert(iclu->strawGasStep()->simParticle()); _hqsum[iend] += iclu->charge(); double ctime = iclu->time()+strawele.maxResponseTime(_diagpath,iclu->wireDistance()); double vout = wfs[iend].sampleWaveform(strawele,_diagpath,ctime); if(vout > _vmax[iend]){ _vmax[iend] = vout; _tvmax[iend] = ctime; - _wmcpdg[iend] = iclu->stepPointMC()->simParticle()->pdgId(); - _wmcproc[iend] = iclu->stepPointMC()->simParticle()->creationCode(); - _mce[iend] = iclu->stepPointMC()->simParticle()->startMomentum().e(); - _slen[iend] = iclu->stepPointMC()->stepLength(); - _sedep[iend] = iclu->stepPointMC()->ionizingEdep(); + _wmcpdg[iend] = iclu->strawGasStep()->simParticle()->pdgId(); + _wmcproc[iend] = iclu->strawGasStep()->simParticle()->creationCode(); + _mce[iend] = iclu->strawGasStep()->simParticle()->startMomentum().e(); + _slen[iend] = iclu->strawGasStep()->stepLength(); + _sedep[iend] = iclu->strawGasStep()->ionizingEdep(); } } } @@ -1105,28 +1079,22 @@ namespace mu2e { _mctime = _mcenergy = _mctrigenergy = _mcthreshenergy = _mcdca = -1000.0; _mcthreshpdg = _mcthreshproc = _mcnstep = 0; auto const& sgsptr = xpair[0]._iclust->strawGasStep(); - auto const& spmcptr = xpair[0]._iclust->stepPointMC(); - if(!sgsptr.isNull() && !spmcptr.isNull()){ - auto const& sgs = *sgsptr; - auto const& spmc = *spmcptr; - _mctime = sgs.time() + _toff.totalTimeOffset(sgs.simParticle()); - // compute the doca for this step - TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), - Geom::Hep3Vec(sgs.startPosition()), Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()) ); - _mcdca = pca.dca(); - _mcdcaphi = EBAngle(Geom::toXYZVec(pca.point2()),straw); - _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); - if(!spmc.simParticle().isNull()){ - auto const& sp = *spmc.simParticle(); - _dmcpdg = sp.pdgId(); - _dmcproc = sp.creationCode(); - if(sp.genParticle().isNonnull()) - _dmcgen = sp.genParticle()->generatorId().id(); - _dmcmom = spmc.momentum().mag(); - _mcthreshpdg = spmc.simParticle()->pdgId(); - _mcthreshproc = spmc.simParticle()->creationCode(); - } - } + auto const& sgs = *sgsptr; + _mctime = sgs.time() + _toff.totalTimeOffset(sgs.simParticle()); + // compute the doca for this step + TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), + Geom::Hep3Vec(sgs.startPosition()), Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()) ); + _mcdca = pca.dca(); + _mcdcaphi = EBAngle(Geom::toXYZVec(pca.point2()),straw); + _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); + _dmcmom = sqrt(sgs.momentum().mag2()); + auto const& sp = *sgs.simParticle(); + _dmcpdg = sp.pdgId(); + _dmcproc = sp.creationCode(); + if(sp.genParticle().isNonnull()) + _dmcgen = sp.genParticle()->generatorId().id(); + _mcthreshpdg = sp.pdgId(); + _mcthreshproc = sp.creationCode(); _mcenergy = mcdigi.energySum(); _mctrigenergy = mcdigi.triggerEnergySum(StrawEnd::cal); // sum the energy from the explicit trigger particle, and find it's releationship @@ -1139,13 +1107,13 @@ namespace mu2e { }//End of digiDiag void StrawDigisFromStrawGasSteps::stepDiag( StrawPhysics const& strawphys, StrawElectronics const& strawele, - StrawGasStep const& sgs, StepPointMC const& spmc) { + StrawGasStep const& sgs) { _steplen = sgs.stepLength(); _stepE = sgs.ionizingEdep(); _steptime = microbunchTime(strawele,sgs.time()+ _toff.totalTimeOffset(sgs.simParticle())); _stype = sgs.stepType()._stype; - _partP = spmc.momentum().mag(); - _partPDG = spmc.simParticle()->pdgId(); + _partP = sqrt(sgs.momentum().mag2()); + _partPDG = sgs.simParticle()->pdgId(); _nclust = (int)_clusters.size(); _netot = 0; _qsum = _esum = _eesum = 0.0; From adfc4b5918ecc4c19fa1ba7c496981afb93018e4 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Wed, 13 Nov 2019 13:53:13 -0600 Subject: [PATCH 14/18] Remove some legacy code --- TrackerMC/inc/StrawCluster.hh | 16 - TrackerMC/src/StrawCluster.cc | 14 - .../src/StrawDigisFromStepPointMCs_module.cc | 1308 ----------------- .../src/StrawDigisFromStrawGasSteps_module.cc | 4 +- 4 files changed, 2 insertions(+), 1340 deletions(-) delete mode 100644 TrackerMC/src/StrawDigisFromStepPointMCs_module.cc diff --git a/TrackerMC/inc/StrawCluster.hh b/TrackerMC/inc/StrawCluster.hh index b8ab3bbc48..6fb90fd95f 100644 --- a/TrackerMC/inc/StrawCluster.hh +++ b/TrackerMC/inc/StrawCluster.hh @@ -16,7 +16,6 @@ // Mu2e includes #include "DataProducts/inc/StrawId.hh" #include "DataProducts/inc/StrawEnd.hh" -#include "MCDataProducts/inc/StepPointMC.hh" #include "MCDataProducts/inc/StrawGasStep.hh" // toolkit includes #include "canvas/Persistency/Common/Ptr.h" @@ -44,19 +43,6 @@ namespace mu2e { float proptime, art::Ptr const& sgs, XYZVec const& cpos, float ctime); - - // legacy constructor - explicit StrawCluster(ClusterType type,StrawId sid, - StrawEnd end, - double time, - float charge, - float ddist, - float phi, - float wdist, - float drifttime, - float proptime, - art::Ptr const& stepmc, - CLHEP::HepLorentzVector const& cpos); // use compiler version of copy, assignment // Accessors ClusterType type() const { return _type; } @@ -72,7 +58,6 @@ namespace mu2e { art::Ptr const& strawGasStep() const { return _sgsptr; } float cluTime() const { return _ctime; } XYZVec const& cluPos() const { return _cpos; } - art::Ptr const& stepPointMC() const { return _spmcptr; } // Legacy function FIXME CLHEP::HepLorentzVector clusterPosition() const { return CLHEP::HepLorentzVector(Geom::Hep3Vec(_cpos),_ctime); } // legacy function FIXME // Print contents of the object. void print( std::ostream& ost = std::cout, bool doEndl = true ) const; @@ -88,7 +73,6 @@ namespace mu2e { float _drifttime; // drift time to the wire float _proptime; // propagation time to the wire end art::Ptr _sgsptr; - art::Ptr _spmcptr; // legacy ref to StepPointMC should be removed after testing FIXME! XYZVec _cpos; float _ctime; }; diff --git a/TrackerMC/src/StrawCluster.cc b/TrackerMC/src/StrawCluster.cc index b8d8bbed97..93a8bd6974 100644 --- a/TrackerMC/src/StrawCluster.cc +++ b/TrackerMC/src/StrawCluster.cc @@ -26,20 +26,6 @@ namespace mu2e { XYZVec const& cpos, float ctime) : _type(type), _strawId(sid), _end(end), _time(time), _charge(charge), _ddist(ddist), _phi(phi),_wdist(wdist), _drifttime(drifttime), _proptime(proptime), _sgsptr(sgsptr), _cpos(cpos), _ctime(ctime) {} - StrawCluster::StrawCluster(ClusterType type,StrawId sid, - StrawEnd end, - double time, - float charge, - float ddist, - float phi, - float wdist, - float drifttime, - float proptime, - art::Ptr const& stepmc, - CLHEP::HepLorentzVector const& cpos) : _type(type), _strawId(sid), _end(end), _time(time), - _charge(charge), _ddist(ddist), _phi(phi),_wdist(wdist), _drifttime(drifttime), _proptime(proptime), _spmcptr(stepmc), _cpos(cpos) - {} - // delegating constructors in C++11! StrawCluster::StrawCluster(const StrawCluster& primary, StrawId const& id, float xfactor) : StrawCluster(primary) { diff --git a/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc b/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc deleted file mode 100644 index 747d50c4ef..0000000000 --- a/TrackerMC/src/StrawDigisFromStepPointMCs_module.cc +++ /dev/null @@ -1,1308 +0,0 @@ -// -// module to convert G4 steps into straw digis. -// It also builds the truth match -// -// Original author David Brown, LBNL -// -// framework -#include "art/Framework/Principal/Event.h" -#include "fhiclcpp/ParameterSet.h" -#include "art/Framework/Principal/Handle.h" -#include "GeometryService/inc/GeomHandle.hh" -#include "art/Framework/Core/EDProducer.h" -#include "GeometryService/inc/DetectorSystem.hh" -#include "art/Framework/Core/ModuleMacros.h" -#include "art_root_io/TFileService.h" -#include "SeedService/inc/SeedService.hh" -#include "cetlib_except/exception.h" -// conditions -#include "ProditionsService/inc/ProditionsHandle.hh" -#include "ConditionsService/inc/ConditionsHandle.hh" -#include "ConditionsService/inc/AcceleratorParams.hh" -#include "TrackerGeom/inc/Tracker.hh" -#include "ConfigTools/inc/ConfigFileLookupPolicy.hh" -#include "TrackerConditions/inc/DeadStraw.hh" -#include "TrackerConditions/inc/StrawElectronics.hh" -#include "TrackerConditions/inc/StrawPhysics.hh" -#include "GeometryService/inc/DetectorSystem.hh" -#include "BFieldGeom/inc/BFieldManager.hh" -#include "BTrk/BField/BField.hh" -#include "GlobalConstantsService/inc/GlobalConstantsHandle.hh" -#include "GlobalConstantsService/inc/ParticleDataTable.hh" -// utiliities -#include "Mu2eUtilities/inc/TwoLinePCA.hh" -#include "Mu2eUtilities/inc/SimParticleTimeOffset.hh" -#include "DataProducts/inc/TrkTypes.hh" -// data -#include "DataProducts/inc/EventWindowMarker.hh" -#include "DataProducts/inc/StrawId.hh" -#include "RecoDataProducts/inc/StrawDigiCollection.hh" -#include "MCDataProducts/inc/StepPointMCCollection.hh" -#include "MCDataProducts/inc/PtrStepPointMCVectorCollection.hh" -#include "MCDataProducts/inc/StrawDigiMCCollection.hh" -#include "MCDataProducts/inc/StrawGasStep.hh" -// MC structures -#include "TrackerMC/inc/StrawClusterSequencePair.hh" -#include "TrackerMC/inc/StrawWaveform.hh" -#include "TrackerMC/inc/IonCluster.hh" -//CLHEP -#include "CLHEP/Random/RandGaussQ.h" -#include "CLHEP/Random/RandFlat.h" -#include "CLHEP/Random/RandExponential.h" -#include "CLHEP/Random/RandPoisson.h" -#include "CLHEP/Vector/LorentzVector.h" -// root -#include "TMath.h" -#include "TH1F.h" -#include "TH2F.h" -#include "TGraph.h" -#include "TMarker.h" -#include "TTree.h" -// C++ -#include -#include -#include -#include -#include -using namespace std; -using CLHEP::Hep3Vector; -namespace mu2e { - namespace TrackerMC { - using namespace TrkTypes; - - struct WireCharge { // charge at the wire after drift - double _charge; // charge at the wire, in units of pC - double _time; // relative time at the wire, relative to ionzation time (ns) - double _dd; // transverse distance drifted to the wrie - double _phi; //JB: angle between E and B at ionization event - double _wpos; // position long the wire, WRT the wire center, signed by the wire direction - - }; - - struct WireEndCharge { // charge at one end of the wire after propagation - double _charge; // charge at the wire, in units of pC - double _time; // time at the wire end, relative to the time the charge reached the wire (ns) - double _wdist; // propagation distance from the point of collection to the end - }; - - class StrawDigisFromStepPointMCs : public art::EDProducer { - - public: - typedef map StrawClusterMap; // clusts by straw - typedef vector > StrawSPMCPV; // vector of associated StepPointMCs for a single straw/particle - // work with pairs of waveforms, one for each straw end - typedef std::array SWFP; - typedef std::array WFXP; - typedef list WFXPList; - typedef WFXPList::const_iterator WFXPI; - - explicit StrawDigisFromStepPointMCs(fhicl::ParameterSet const& pset); - // Accept compiler written d'tor. - - private: - - void beginJob() override; - void beginRun(art::Run& run) override; - void produce(art::Event& e) override; - - // Diagnostics level. - int _debug, _diag, _printLevel; - unsigned _maxhist; - bool _xtalkhist; - unsigned _minnxinghist; - double _tstep, _nfall; - // Limit on number of events for which there will be full printout. - int _maxFullPrint; - - // Parameters - bool _addXtalk; // should we add cross talk hits? - double _ctMinCharge; // minimum charge to add cross talk (for performance issues) - bool _addNoise; // should we add noise hits? - double _preampxtalk, _postampxtalk; // x-talk parameters; these should come from conditions, FIXME!! - double _bgcut; // cut dividing 'min-ion' particles from highly-ionizing - double _minstepE; // minimum step energy to simulate - art::InputTag _ewMarkerTag; // name of the module that makes eventwindowmarkers - double _mbtime; // period of 1 microbunch - double _mbbuffer; // buffer on that for ghost clusts (for waveform) - double _adcbuffer; // time buffer for ADC - double _steptimebuf; // buffer for MC step point times - double _tdcbuf; // buffer for TDC jitter - uint16_t _allStraw; // minimum straw # to read all hits - std::vector _allPlanes; // planes in which to read all hits - // models of straw response to stimuli - ProditionsHandle _strawphys_h; - ProditionsHandle _strawele_h; - SimParticleTimeOffset _toff; - StrawElectronics::Path _diagpath; // electronics path for waveform diagnostics - // Random number distributions - art::RandomNumberGenerator::base_engine_t& _engine; - CLHEP::RandGaussQ _randgauss; - CLHEP::RandFlat _randflat; - CLHEP::RandExponential _randexp; - CLHEP::RandPoisson _randP; - // A category for the error logger. - const string _messageCategory; - // Give some informationation messages only on the first event. - bool _firstEvent; - // record the BField direction at the tracker center - Hep3Vector _bdir; - // minimum pt (perp to bfield) to assume straight trajectory in a starw - double _ptmin, _ptfac; - // max # clusters for modeling non-minion steps - unsigned _maxnclu; - bool _sort; // sort cluster sizes before filling energy - // List of dead straws as a parameter set; needed at beginRun time. - ProditionsHandle _deadStraw_h; - // StepPointMC selector - // This selector will select only data products with the given instance name. - // optionally exclude modules: this is a fix - art::Selector _selector; - - // diagnostics - TTree* _swdiag; - Int_t _swplane, _swpanel, _swlayer, _swstraw, _ndigi; - Float_t _hqsum[2], _vmax[2], _tvmax[2], _sesum[2]; - Int_t _wmcpdg[2], _wmcproc[2], _nxing[2], _nclu[2]; - Int_t _nsteppoint[2], _npart[2]; - Float_t _mce[2], _slen[2], _sedep[2]; - Float_t _tmin[2], _tmax[2], _txing[2], _xddist[2], _xwdist[2], _xpdist[2]; - TTree* _sddiag; - Int_t _sdplane, _sdpanel, _sdlayer, _sdstraw; - Int_t _ncludd[2], _iclust[2]; - Int_t _nstep; - Float_t _ectime[2], _ecddist[2], _ecdtime[2], _ecptime[2]; - Float_t _xtime[2], _tctime[2], _charge[2], _ddist[2], _dtime[2], _ptime[2]; - Float_t _wdist[2], _vstart[2], _vcross[2]; - Float_t _phi[2]; //JB - Float_t _mcenergy, _mctrigenergy, _mcthreshenergy; - Double_t _mctime; - Int_t _mcthreshpdg, _mcthreshproc, _mcnstep; - Float_t _mcdca, _mcdcaphi, _mcdcadtime; - Int_t _dmcpdg, _dmcproc, _dmcgen; - Float_t _dmcmom; - Bool_t _xtalk; - vector _adc; - Int_t _tdc[2], _tot[2]; - TTree* _sdiag; - Float_t _steplen, _stepE, _qsum, _esum, _eesum, _qe, _partP, _steptime; - Int_t _nclust, _netot, _partPDG; - vector _clusters; - Float_t _ewMarkerOffset; - array _ewMarkerROCdt; - - // helper functions - void fillClusterMap(art::Event const& event, StrawClusterMap & hmap); - void addStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - art::Ptr const& spmcptr, - Straw const& straw, StrawClusterSequencePair& shsp); - void divideStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StepPointMC const& step, vector& clusters); - void driftCluster(StrawPhysics const& strawphys, Straw const& straw, - IonCluster const& cluster, WireCharge& wireq); - void propagateCharge(StrawPhysics const& strawphys, Straw const& straw, - WireCharge const& wireq, StrawEnd end, WireEndCharge& weq); - double microbunchTime(StrawElectronics const& strawele, double globaltime) const; - void addGhosts(StrawElectronics const& strawele, StrawCluster const& clust,StrawClusterSequence& shs); - void addNoise(StrawClusterMap& hmap); - void findThresholdCrossings(StrawElectronics const& strawele, SWFP const& swfp, WFXPList& xings); - void createDigis(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StrawClusterSequencePair const& hsp, - XTalk const& xtalk, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStepPointMCVectorCollection* mcptrs ); - void fillDigis(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - WFXPList const& xings,SWFP const& swfp , StrawId sid, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStepPointMCVectorCollection* mcptrs ); - bool createDigi(StrawElectronics const& strawele,WFXP const& xpair, SWFP const& wf, StrawId sid, StrawDigiCollection* digis); - void findCrossTalkStraws(Straw const& straw,vector& xtalk); - void fillClusterNe(StrawPhysics const& strawphys,std::vector& me); - void fillClusterPositions(Straw const& straw, StepPointMC const& step, std::vector& cpos); - void fillClusterMinion(StrawPhysics const& strawphys, StepPointMC const& step, std::vector& me, std::vector& cen); - bool readAll(StrawId const& sid) const; - // diagnostic functions - void waveformHist(StrawElectronics const& strawele, - SWFP const& wf, WFXPList const& xings); - void waveformDiag(StrawElectronics const& strawele, - SWFP const& wf, WFXPList const& xings); - void digiDiag(StrawPhysics const& strawphys, SWFP const& wf, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi); - }; - - StrawDigisFromStepPointMCs::StrawDigisFromStepPointMCs(fhicl::ParameterSet const& pset) : - EDProducer{pset}, - // diagnostic parameters - _debug(pset.get("debugLevel",0)), - _diag(pset.get("diagLevel",0)), - _printLevel(pset.get("printLevel",0)), - _maxhist(pset.get("MaxHist",100)), - _xtalkhist(pset.get("CrossTalkHist",false)), - _minnxinghist(pset.get("MinNXingHist",1)), // minimum # of crossings to histogram waveform - _tstep(pset.get("WaveformStep",0.1)), // ns - _nfall(pset.get("WaveformTail",10.0)), // # of decay lambda past last signal to record waveform - // Parameters - _maxFullPrint(pset.get("maxFullPrint",2)), - _addXtalk(pset.get("addCrossTalk",false)), - _ctMinCharge(pset.get("xtalkMinimumCharge",0)), - _addNoise(pset.get("addNoise",false)), - _preampxtalk(pset.get("preAmplificationCrossTalk",0.0)), - _postampxtalk(pset.get("postAmplificationCrossTalk",0.02)), // dimensionless relative coupling - _bgcut(pset.get("BetaGammaCut",0.5)), // treat particles with beta-gamma above this as minimum-ionizing - _minstepE(pset.get("minstepE",2.0e-6)), // minimum step energy depostion to turn into a straw signal (MeV) - _ewMarkerTag(pset.get("EventWindowMarkerLabel","EWMProducer")), - _steptimebuf(pset.get("StepPointMCTimeBuffer",100.0)), // nsec - _tdcbuf(pset.get("TDCTimeBuffer",2.0)), // nsec - _allStraw(pset.get("AllHitsStraw",90)), - _allPlanes(pset.get>("AllHitsPlanes",std::vector{})), // planes to read all hits - _toff(pset.get("TimeOffsets", {})), - _diagpath(static_cast(pset.get("WaveformDiagPath",StrawElectronics::thresh))), - // Random number distributions - _engine(createEngine( art::ServiceHandle()->getSeed())), - _randgauss( _engine ), - _randflat( _engine ), - _randexp( _engine), - _randP( _engine), - _messageCategory("HITS"), - _firstEvent(true), // Control some information messages. - _ptfac(pset.get("PtFactor", 2.0)), // factor for defining curling in a straw - _maxnclu(pset.get("MaxNClusters", 10)), // max # of clusters for low-PT steps - _sort(pset.get("SortClusterEnergy",false)), - _selector{art::ProductInstanceNameSelector(pset.get("trackerStepPoints","tracker")) && - !art::ModuleLabelSelector(pset.get("SkipTheseStepPoints","")) } { - // Tell the framework what we consume. - consumesMany(); - consumes(_ewMarkerTag); - // Since SimParticleTimeOffset calls getValidHandle, we have to - // declare the consumes statements here. - auto const& toffInputs = pset.get>("TimeOffsets.inputs", {}); - for (auto const& tag : toffInputs) { - consumes(tag); - } - // Tell the framework what we make. - produces(); - produces(); - produces(); - } - - void StrawDigisFromStepPointMCs::beginJob(){ - - if(_diag > 0){ - - art::ServiceHandle tfs; - _sdiag =tfs->make("sdiag","Step diagnostics"); - _sdiag->Branch("steplen",&_steplen,"steplen/F"); - _sdiag->Branch("stepE",&_stepE,"stepE/F"); - _sdiag->Branch("partP",&_partP,"partP/F"); - _sdiag->Branch("qsum",&_qsum,"qsum/F"); - _sdiag->Branch("esum",&_esum,"esum/F"); - _sdiag->Branch("eesum",&_eesum,"eesum/F"); - _sdiag->Branch("qe",&_qe,"qe/F"); - _sdiag->Branch("steptime",&_steptime,"steptime/F"); - _sdiag->Branch("nclust",&_nclust,"nclust/I"); - _sdiag->Branch("netot",&_netot,"netot/I"); - _sdiag->Branch("partPDG",&_partPDG,"partPDG/I"); - _sdiag->Branch("clusters",&_clusters); - - _swdiag =tfs->make("swdiag","StrawWaveform diagnostics"); - _swdiag->Branch("plane",&_swplane,"plane/I"); - _swdiag->Branch("panel",&_swpanel,"panel/I"); - _swdiag->Branch("layer",&_swlayer,"layer/I"); - _swdiag->Branch("straw",&_swstraw,"straw/I"); - _swdiag->Branch("ndigi",&_ndigi,"ndigi/I"); - _swdiag->Branch("hqsum",&_hqsum,"hqsumcal/F:hqsumhv/F"); - _swdiag->Branch("vmax",&_vmax,"vmaxcal/F:vmaxhv/F"); - _swdiag->Branch("tvmax",&_tvmax,"tvmaxcal/F:tvmaxhv/F"); - _swdiag->Branch("mcpdg",&_wmcpdg,"mcpdgcal/I:mcpdghv/I"); - _swdiag->Branch("mcproc",&_wmcproc,"mcproccal/I:mcprochv/I"); - _swdiag->Branch("mce",&_mce,"mcecal/F:mcehv/F"); - _swdiag->Branch("slen",&_slen,"slencal/F:slenhv/F"); - _swdiag->Branch("sedep",&_sedep,"sedepcal/F:sedephv/F"); - _swdiag->Branch("nxing",&_nxing,"nxingcal/I:nxinghv/I"); - _swdiag->Branch("nclust",&_nclu,"nclucal/I:ncluhv/I"); - _swdiag->Branch("nstep",&_nsteppoint,"nscal/I:nshv/I"); - _swdiag->Branch("sesum",&_sesum,"sesumcal/F:sesumhv/F"); - _swdiag->Branch("npart",&_npart,"npart/I"); - _swdiag->Branch("tmin",&_tmin,"tmincal/F:tminhv/F"); - _swdiag->Branch("tmax",&_tmax,"tmaxcal/F:tmaxhv/F"); - _swdiag->Branch("txing",&_txing,"txcal/F:txhv/F"); - _swdiag->Branch("xddist",&_xddist,"xdcal/F:xdhv/F"); - _swdiag->Branch("xwdist",&_xwdist,"xwdcal/F:xwdhv/F"); - _swdiag->Branch("xpdist",&_xpdist,"xpdcal/F:xpdhv/F"); - - - if(_diag > 1){ - _sddiag =tfs->make("sddiag","StrawDigi diagnostics"); - _sddiag->Branch("plane",&_sdplane,"plane/I"); - _sddiag->Branch("panel",&_sdpanel,"panel/I"); - _sddiag->Branch("layer",&_sdlayer,"layer/I"); - _sddiag->Branch("straw",&_sdstraw,"straw/I"); - _sddiag->Branch("nstep",&_nstep,"nstep/I"); - _sddiag->Branch("xtime",&_xtime,"xtimecal/F:xtimehv/F"); - _sddiag->Branch("tctime",&_tctime,"tctimecal/F:tctimehv/F"); - _sddiag->Branch("ectime",&_ectime,"ectimecal/F:ectimehv/F"); - _sddiag->Branch("ecdtime",&_ecdtime,"ecdtimecal/F:ecdtimehv/F"); - _sddiag->Branch("ecptime",&_ecptime,"ecptimecal/F:ecptimehv/F"); - _sddiag->Branch("charge",&_charge,"chargecal/F:chargehv/F"); - _sddiag->Branch("wdist",&_wdist,"wdistcal/F:wdisthv/F"); - _sddiag->Branch("phi",&_phi,"phical/F:phihv/F");//JB - _sddiag->Branch("ecddist",&_ecddist,"ecddistcal/F:ecddisthv/F"); - _sddiag->Branch("vstart",&_vstart,"vstartcal/F:vstarthv/F"); - _sddiag->Branch("vcross",&_vcross,"vcrosscal/F:vcrosshv/F"); - _sddiag->Branch("ddist",&_ddist,"ddistcal/F:ddisthv/F"); - _sddiag->Branch("dtime",&_dtime,"dtimecal/F:dtimehv/F"); - _sddiag->Branch("ptime",&_ptime,"ptimecal/F:ptimehv/F"); - _sddiag->Branch("nclust",&_ncludd,"nclustcal/I:nclusthv/I"); - _sddiag->Branch("iclust",&_iclust,"iclustcal/I:iclusthv/I"); - _sddiag->Branch("tdc",&_tdc,"tdccal/I:tdchv/I"); - _sddiag->Branch("tot",&_tot,"totcal/I:tothv/I"); - _sddiag->Branch("adc",&_adc); - _sddiag->Branch("mctime",&_mctime,"mctime/D"); - _sddiag->Branch("mcenergy",&_mcenergy,"mcenergy/F"); - _sddiag->Branch("mctrigenergy",&_mctrigenergy,"mctrigenergy/F"); - _sddiag->Branch("mcthreshenergy",&_mcthreshenergy,"mcthreshenergy/F"); - _sddiag->Branch("mcthreshpdg",&_mcthreshpdg,"mcthreshpdg/I"); - _sddiag->Branch("mcthreshproc",&_mcthreshproc,"mcthreshproc/I"); - _sddiag->Branch("mcnstep",&_mcnstep,"mcnstep/I"); - _sddiag->Branch("mcdca",&_mcdca,"mcdca/F"); - _sddiag->Branch("mcdcaphi",&_mcdcaphi,"mcdcaphi/F"); - _sddiag->Branch("mcdcadtime",&_mcdcadtime,"mcdcadtime/F"); - _sddiag->Branch("mcpdg",&_dmcpdg,"mcpdg/I"); - _sddiag->Branch("mcproc",&_dmcproc,"mcproc/I"); - _sddiag->Branch("mcgen",&_dmcgen,"mcgen/I"); - _sddiag->Branch("mcmom",&_dmcmom,"mcmom/F"); - _sddiag->Branch("xtalk",&_xtalk,"xtalk/B"); - - } - } - } - - void StrawDigisFromStepPointMCs::beginRun( art::Run& run ){ - // get field at the center of the tracker - GeomHandle bfmgr; - GeomHandle det; - Hep3Vector vpoint_mu2e = det->toMu2e(Hep3Vector(0.0,0.0,0.0)); - Hep3Vector b0 = bfmgr->getBField(vpoint_mu2e); - // if the field is too small, don't perform any curvature-based analysis - if ( b0.mag() < 1.0e-4 ){ - _bdir = Hep3Vector(0.0,0.0,1.0); - _ptmin = -1.0; - } else { - _bdir = b0.unit(); - //compute the transverse momentum for which a particle will curl up in a straw - const Tracker& tracker = *GeomHandle(); - const Straw& straw = tracker.getStraw(StrawId(0,0,0)); - double rstraw = straw.getRadius(); - _ptmin = _ptfac*BField::mmTeslaToMeVc*b0.mag()*rstraw; - } - if ( _printLevel > 0 ) { - auto const& strawphys = _strawphys_h.get(run.id()); - strawphys.print(cout); - } - } - - void StrawDigisFromStepPointMCs::produce(art::Event& event) { - if ( _printLevel > 1 ) cout << "StrawDigisFromStepPointMCs: produce() begin; event " << event.id().event() << endl; - static int ncalls(0); - ++ncalls; - // update conditions caches. - ConditionsHandle accPar("ignored"); - _mbtime = accPar->deBuncherPeriod; - _toff.updateMap(event); - StrawElectronics const& strawele = _strawele_h.get(event.id()); - StrawPhysics const& strawphys = _strawphys_h.get(event.id()); - art::Handle ewMarkerHandle; - event.getByLabel(_ewMarkerTag, ewMarkerHandle); - const EventWindowMarker& ewMarker(*ewMarkerHandle); - _ewMarkerOffset = ewMarker.timeOffset(); - // calculate event window marker jitter for this microbunch for each panel - for (size_t i=0;i(); - // make the microbunch buffer long enough to get the full waveform - _mbbuffer = (strawele.nADCSamples() - strawele.nADCPreSamples())*strawele.adcPeriod(); - _adcbuffer = 0.01*strawele.adcPeriod(); - // Containers to hold the output information. - unique_ptr digis(new StrawDigiCollection); - unique_ptr mcdigis(new StrawDigiMCCollection); - unique_ptr mcptrs(new PtrStepPointMCVectorCollection); - // create the StrawCluster map - StrawClusterMap hmap; - // fill this from the event - fillClusterMap(event,hmap); - // add noise clusts - if(_addNoise)addNoise(hmap); - // loop over the clust sequences - for(auto ihsp=hmap.begin();ihsp!= hmap.end();++ihsp){ - StrawClusterSequencePair const& hsp = ihsp->second; - // create primary digis from this clust sequence - XTalk self(hsp.strawId()); // this object represents the straws coupling to itself, ie 100% - createDigis(strawphys,strawele,hsp,self,digis.get(),mcdigis.get(),mcptrs.get()); - // if we're applying x-talk, look for nearby coupled straws - if(_addXtalk) { - // only apply if the charge is above a threshold - double totalCharge = 0; - for(auto ih=hsp.clustSequence(StrawEnd::cal).clustList().begin();ih!= hsp.clustSequence(StrawEnd::cal).clustList().end();++ih){ - totalCharge += ih->charge(); - } - if( totalCharge > _ctMinCharge){ - vector xtalk; - Straw const& straw = tracker.getStraw(hsp.strawId()); - findCrossTalkStraws(straw,xtalk); - for(auto ixtalk=xtalk.begin();ixtalk!=xtalk.end();++ixtalk){ - createDigis(strawphys,strawele,hsp,*ixtalk,digis.get(),mcdigis.get(),mcptrs.get()); - } - } - } - } - // store the digis in the event - event.put(move(digis)); - // store MC truth match - event.put(move(mcdigis)); - event.put(move(mcptrs)); - if ( _printLevel > 1 ) cout << "StrawDigisFromStepPointMCs: produce() end" << endl; - // Done with the first event; disable some messages. - _firstEvent = false; - } // end produce - - void StrawDigisFromStepPointMCs::createDigis( - StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StrawClusterSequencePair const& hsp, XTalk const& xtalk, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStepPointMCVectorCollection* mcptrs ) { - // instantiate waveforms for both ends of this straw - SWFP waveforms ={ StrawWaveform(hsp.clustSequence(StrawEnd::cal),xtalk), - StrawWaveform(hsp.clustSequence(StrawEnd::hv),xtalk) }; - // find the threshold crossing points for these waveforms - WFXPList xings; - // find the threshold crossings - findThresholdCrossings(strawele,waveforms,xings); - // convert the crossing points into digis, and add them to the event data - fillDigis(strawphys,strawele,xings,waveforms,xtalk._dest,digis,mcdigis,mcptrs); - // waveform diagnostics - if (_diag >1 && ( - waveforms[0].clusts().clustList().size() > 0 || - waveforms[1].clusts().clustList().size() > 0 ) ) { - // waveform xing diagnostics - _ndigi = digis->size(); - waveformDiag(strawele,waveforms,xings); - // waveform histograms - if(_diag > 2 )waveformHist(strawele,waveforms,xings); - } - } - - void StrawDigisFromStepPointMCs::fillClusterMap(art::Event const& event, StrawClusterMap & hmap){ - // get conditions - DeadStraw const& deadStraw = _deadStraw_h.get(event.id()); - StrawPhysics const& strawphys = _strawphys_h.get(event.id()); - StrawElectronics const& strawele = _strawele_h.get(event.id()); - const Tracker& tracker = *GeomHandle(); - // Get all of the tracker StepPointMC collections from the event: - typedef vector< art::Handle > HandleVector; - HandleVector stepsHandles; - event.getMany( _selector, stepsHandles); - // Informational message on the first event. - if ( _firstEvent ) { - mf::LogInfo log(_messageCategory); - log << "StrawDigisFromStepPointMCs::fillHitMap will use StepPointMCs from: \n"; - for ( HandleVector::const_iterator i=stepsHandles.begin(), e=stepsHandles.end(); - i != e; ++i ){ - art::Provenance const& prov(*(i->provenance())); - log << " " << prov.branchName() << "\n"; - } - } - if(stepsHandles.empty()){ - throw cet::exception("SIM")<<"mu2e::StrawDigisFromStepPointMCs: No StepPointMC collections found for tracker" << endl; - } - // Loop over StepPointMC collections - for ( HandleVector::const_iterator ispmcc=stepsHandles.begin(), espmcc=stepsHandles.end();ispmcc != espmcc; ++ispmcc ){ - art::Handle const& handle(*ispmcc); - StepPointMCCollection const& steps(*handle); - // Loop over the StepPointMCs in this collection - for (size_t ispmc =0; ispmc _minstepE){ - // create ptr to MC truth, used for references - art::Ptr spmcptr(handle,ispmc); - // create a clust from this step, and add it to the clust map - addStep(strawphys,strawele,spmcptr,straw,hmap[sid]); - } - } - } - } - } - - void StrawDigisFromStepPointMCs::addStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - art::Ptr const& spmcptr, - Straw const& straw, StrawClusterSequencePair& shsp) { - StepPointMC const& step = *spmcptr; - StrawId sid = straw.id(); - // get time offset for this step - double tstep = _toff.timeWithOffsetsApplied(step); - // test if this step point is roughly in the digitization window - double mbtime = microbunchTime(strawele,tstep); - if( (mbtime > strawele.flashEnd() - _steptimebuf - && mbtime < strawele.flashStart()) - || readAll(sid)) { - // Subdivide the StepPointMC into ionization clusters - _clusters.clear(); - divideStep(strawphys,strawele,step,_clusters); - // check - if(_debug > 1){ - double ec(0.0); - double ee(0.0); - double eq(0.0); - for (auto const& cluster : _clusters) { - ec += cluster._eion; - ee += strawphys.ionizationEnergy(cluster._ne); - eq += strawphys.ionizationEnergy(cluster._charge); - } - cout << "step with ionization edep = " << step.ionizingEdep() - << " creates " << _clusters.size() - << " clusters with total cluster energy = " << ec - << " electron count energy = " << ee - << " charge energy = " << eq << endl; - } - // drift these clusters to the wire, and record the charge at the wire - for(auto iclu = _clusters.begin(); iclu != _clusters.end(); ++iclu){ - WireCharge wireq; - driftCluster(strawphys,straw,*iclu,wireq); - // propagate this charge to each end of the wire - for(size_t iend=0;iend<2;++iend){ - StrawEnd end(static_cast(iend)); - // compute the longitudinal propagation effects - WireEndCharge weq; - propagateCharge(strawphys,straw,wireq,end,weq); - // compute the total time, modulo the microbunch - double gtime = tstep + wireq._time + weq._time; - // convert from - double ctime = microbunchTime(strawele,gtime); - // create the clust - StrawCluster clust(StrawCluster::primary,sid,end,ctime, - weq._charge,wireq._dd,wireq._phi,weq._wdist,wireq._time,weq._time, - spmcptr,CLHEP::HepLorentzVector(Geom::Hep3Vec(iclu->_pos),mbtime)); - - // add the clusts to the appropriate sequence. - shsp.clustSequence(end).insert(clust); - // if required, add a 'ghost' copy of this clust - addGhosts(strawele,clust,shsp.clustSequence(end)); - } - } - } - } - - void StrawDigisFromStepPointMCs::divideStep(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - StepPointMC const& step, vector& clusters) { - // get particle charge - double charge(0.0); - GlobalConstantsHandle pdt; - if(pdt->particle(step.simParticle()->pdgId()).isValid()){ - charge = pdt->particle(step.simParticle()->pdgId()).ref().charge(); - } - - // get tracker information - const Tracker& tracker = *GeomHandle(); - const Straw& straw = tracker.getStraw(step.strawId()); - // if the step length is small compared to the mean free path, or this is an - // uncharged particle, put all the energy in a single cluster - if (charge == 0.0 || step.stepLength() < strawphys.meanFreePath()){ - double cen = step.ionizingEdep(); - double fne = cen/strawphys.meanElectronEnergy(); - unsigned ne = std::max( static_cast(_randP(fne)),(unsigned)1); - - Hep3Vector cdir = (step.position()-straw.getMidPoint()); - cdir -= straw.getDirection()*(cdir.dot(straw.getDirection())); - double phi = cdir.theta(); - for (size_t i=0;iparticle(step.simParticle()->pdgId()).isValid()){ - double mass = pdt->particle(step.simParticle()->pdgId()).ref().mass(); - double mom = step.momentum().mag(); - // approximate pt - double apt = 0.; - if ( _bdir.mag() > 0 ) apt = step.momentum().perpPart(_bdir).mag(); - double bg = mom/mass; // beta x gamma - minion = bg > _bgcut && apt > _ptmin; - } - - - // compute the number of clusters for this step from the mean free path - double fnc = step.stepLength()/strawphys.meanFreePath(); - // use a truncated Poisson distribution; this keeps both the mean and variance physical - unsigned nc = std::max(static_cast(_randP.fire(fnc)),(unsigned)1); - if(!minion)nc = std::min(nc,_maxnclu); - // require clusters not exceed the energy sum required for single-electron clusters - nc = std::min(nc,static_cast(floor(step.ionizingEdep()/strawphys.ionizationEnergy((unsigned)1)))); - // generate random positions for the clusters - std::vector cpos(nc); - fillClusterPositions(straw,step,cpos); - // generate electron counts and energies for these clusters: minion model is more detailed - std::vector ne(nc); - std::vector cen(nc); - if(minion){ - fillClusterMinion(strawphys,step,ne,cen); - } else { - // get Poisson distribution of # of electrons for the average energy - double fne = step.ionizingEdep()/(nc*strawphys.meanElectronEnergy()); // average # of electrons/cluster for non-minion clusters - for(unsigned ic=0;ic(std::max(_randP.fire(fne),(long)1)); - cen[ic] = ne[ic]*strawphys.meanElectronEnergy(); // average energy per electron, works for large numbers of electrons - } - } - // create the cluster objects - for(unsigned ic=0;ic 0){ - _steplen = step.stepLength(); - _stepE = step.ionizingEdep(); - _steptime = microbunchTime(strawele,_toff.timeWithOffsetsApplied(step)); - _partP = step.momentum().mag(); - _partPDG = step.simParticle()->pdgId(); - _nclust = (int)clusters.size(); - _netot = 0; - _qsum = _esum = _eesum = 0.0; - for(auto iclust=clusters.begin();iclust != clusters.end();++iclust){ - _netot += iclust->_ne; - _qsum += iclust->_charge; - _esum += iclust->_eion; - _eesum += strawphys.meanElectronEnergy()*iclust->_ne; - } - _qe = strawphys.ionizationEnergy(_qsum); - _sdiag->Fill(); - } - } - - void StrawDigisFromStepPointMCs::driftCluster( - StrawPhysics const& strawphys,Straw const& straw, - IonCluster const& cluster, WireCharge& wireq ) { - // Compute the vector from the cluster to the wire - Hep3Vector cpos = Geom::Hep3Vec(cluster._pos)-straw.getMidPoint(); - // drift distance perp to wire, and angle WRT magnetic field (for Lorentz effect) - double dd = min(cpos.perp(straw.getDirection()),straw.innerRadius()); - // sample the gain for this cluster - double gain = strawphys.clusterGain(_randgauss, _randflat, cluster._ne); - wireq._charge = cluster._charge*(gain); - // compute drift time for this cluster - double dt = strawphys.driftDistanceToTime(dd,cluster._phi); //JB: this is now from the lorentz corrected r-component of the drift - wireq._phi = cluster._phi; //JB - wireq._time = _randgauss.fire(dt,strawphys.driftTimeSpread(dd)); - wireq._dd = dd; - // position along wire - wireq._wpos = cpos.dot(straw.getDirection()); - - } - - void StrawDigisFromStepPointMCs::propagateCharge( - StrawPhysics const& strawphys, Straw const& straw, - WireCharge const& wireq, StrawEnd end, WireEndCharge& weq) { - // compute distance to the appropriate end - double wlen = straw.halfLength(); // use the full length, not the active length - // NB: the following assumes the straw direction points in increasing azimuth. FIXME! - if(end == StrawEnd::hv) - weq._wdist = wlen - wireq._wpos; - else - weq._wdist = wlen + wireq._wpos; - // split the charge - weq._charge = 0.5*wireq._charge; - weq._time = strawphys.propagationTime(weq._wdist); - } - - double StrawDigisFromStepPointMCs::microbunchTime(StrawElectronics const& strawele, double globaltime) const { - // converts time from proton beam time (StepPointMC time) to event window marker time - // fold time relative to MB frequency - double mbtime = fmod(globaltime - _ewMarkerOffset,_mbtime); - // keep the microbunch time contiguous - if(mbtime < strawele.flashStart()-_mbtime ) mbtime += _mbtime; - return mbtime; - } - - void StrawDigisFromStepPointMCs::addGhosts(StrawElectronics const& strawele,StrawCluster const& clust,StrawClusterSequence& shs) { - // add enough buffer to cover both the flash blanking and the ADC waveform - if(clust.time() < strawele.flashStart() - _mbtime + _mbbuffer) - shs.insert(StrawCluster(clust,_mbtime)); - if(clust.time() > _mbtime - _mbbuffer) shs.insert(StrawCluster(clust,-_mbtime)); - } - - void StrawDigisFromStepPointMCs::findThresholdCrossings(StrawElectronics const& strawele, SWFP const& swfp, WFXPList& xings){ - //randomize the threshold to account for electronics noise; this includes parts that are coherent - // for both ends (coming from the straw itself) - // Keep track of crossings on each end to keep them in sequence - double strawnoise = _randgauss.fire(0,strawele.strawNoise()); - // add specifics for each end - double thresh[2] = {_randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(0))+strawnoise,strawele.analogNoise(StrawElectronics::thresh)), - _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(1))+strawnoise,strawele.analogNoise(StrawElectronics::thresh))}; - // Initialize search when the electronics becomes enabled: - double tstart =strawele.flashEnd() - 10.0; // this buffer should be a parameter FIXME! - // for reading all hits, make sure we start looking for clusters at the minimum possible cluster time - // this accounts for deadtime effects from previous microbunches - if(readAll(swfp[0].strawId()))tstart = -strawele.deadTimeAnalog(); - WFXP wfx = {WFX(swfp[0],tstart),WFX(swfp[1],tstart)}; - // search for coherent crossings on both ends - bool crosses[2]; - for(size_t iend=0;iend<2;++iend){ - crosses[iend] = swfp[iend].crossesThreshold(strawele,thresh[iend],wfx[iend]); - } - // loop until we hit the end of the waveforms. Require both in time. Buffer to account for eventual TDC jitter - // this is a loose pre-selection, final selection is done at digitization - while( crosses[0] && crosses[1] && std::max(wfx[0]._time,wfx[1]._time) - < strawele.flashStart() + strawele.electronicsTimeDelay() + _tdcbuf){ - // see if the crossings match - if(strawele.combineEnds(wfx[0]._time,wfx[1]._time)){ - // put the pair of crossings in the crosing list - // make sure the time is positive in case this was a hit from the 'previous' microbunch - if(std::min(wfx[0]._time,wfx[1]._time) > 0.0 )xings.push_back(wfx); - // search for next crossing: - // update threshold for straw noise - strawnoise = _randgauss.fire(0,strawele.strawNoise()); - for(unsigned iend=0;iend<2;++iend){ - // insure a minimum time buffer between crossings - wfx[iend]._time += strawele.deadTimeAnalog(); - // skip to the next clust - ++(wfx[iend]._iclust); - // update threshold for incoherent noise - thresh[iend] = _randgauss.fire(strawele.threshold(swfp[0].strawId(),static_cast(iend)),strawele.analogNoise(StrawElectronics::thresh)); - // find next crossing - crosses[iend] = swfp[iend].crossesThreshold(strawele,thresh[iend],wfx[iend]); - } - } else { - // skip to the next crossing on the earlier waveform - unsigned iearly = wfx[0]._time < wfx[1]._time ? 0 : 1; - ++(wfx[iearly]._iclust); - wfx[iearly]._time += strawele.deadTimeAnalog(); - crosses[iearly] = swfp[iearly].crossesThreshold(strawele,thresh[iearly],wfx[iearly]); - } - } - } - - void StrawDigisFromStepPointMCs::fillDigis(StrawPhysics const& strawphys, - StrawElectronics const& strawele, - WFXPList const& xings, SWFP const& wf, - StrawId sid, - StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis, - PtrStepPointMCVectorCollection* mcptrs ){ - // loop over crossings - for(auto xpair : xings) { - // create a digi from this pair. This also performs a finial test - // on whether the pair should make a digi - if(createDigi(strawele,xpair,wf,sid,digis)){ - // fill associated MC truth matching. Only count the same step once - set > xmcsp; - double wetime[2] = {-100.,-100.}; - CLHEP::HepLorentzVector cpos[2]; - art::Ptr stepMC[2]; - set > spmcs; - for (size_t iend=0;iend<2;++iend){ - StrawCluster const& sc = *(xpair[iend]._iclust); - xmcsp.insert(sc.stepPointMC()); - wetime[iend] = sc.time(); - cpos[iend] = sc.clusterPosition(); - stepMC[iend] = sc.stepPointMC(); - // make sure the trigter StepPoints also go in the StrawDigiMC - spmcs.insert(sc.stepPointMC()); - } - // choose the minimum time from either end, as the ADC sums both - double ptime = 1.0e10; - for (size_t iend=0;iend<2;++iend){ - ptime = std::min(ptime,wetime[iend]); - } - // subtract a small buffer - ptime -= _adcbuffer; - // pickup all StepPointMCs associated with clusts inside the time window of the ADC digitizations (after the threshold) - for (auto ih=wf[0].clusts().clustList().begin();ih!=wf[0].clusts().clustList().end();++ih){ - if (ih->time() >= ptime && ih->time() < ptime + - ( strawele.nADCSamples()-strawele.nADCPreSamples())*strawele.adcPeriod()) - spmcs.insert(ih->stepPointMC()); - } - vector > stepMCs; - stepMCs.reserve(spmcs.size()); - for(auto ispmc=spmcs.begin(); ispmc!= spmcs.end(); ++ispmc){ - stepMCs.push_back(*ispmc); - } - PtrStepPointMCVector mcptr; - for(auto ixmcsp=xmcsp.begin();ixmcsp!=xmcsp.end();++ixmcsp) - mcptr.push_back(*ixmcsp); - mcptrs->push_back(mcptr); - mcdigis->push_back(StrawDigiMC(sid,wetime,cpos,stepMC,stepMCs)); - // diagnostics - if(_diag > 1)digiDiag(strawphys,wf,xpair,digis->back(),mcdigis->back()); - } - } - } - - bool StrawDigisFromStepPointMCs::createDigi(StrawElectronics const& strawele, WFXP const& xpair, SWFP const& waveform, - StrawId sid, StrawDigiCollection* digis){ - // initialize the float variables that we later digitize - TDCTimes xtimes = {0.0,0.0}; - TrkTypes::TOTValues tot; - // get the ADC sample times from the electroincs. Use the cal side time to randomize - // the phase, this doesn't really matter - TrkTypes::ADCTimes adctimes; - strawele.adcTimes(xpair[0]._time,adctimes); - // sums voltages from both waveforms for ADC - ADCVoltages wf[2]; - // add the jitter in the EventWindowMarker time for this Panel (constant for a whole microbunch, same for both sides) - double dt = _ewMarkerROCdt[sid.getPanel()]; - // loop over the associated crossings - for(size_t iend = 0;iend<2; ++iend){ - WFX const& wfx = xpair[iend]; - // record the crossing time for this end, including clock jitter These already include noise effects - // add noise for TDC on each side - double tdc_jitter = _randgauss.fire(0.0,strawele.TDCResolution()); - xtimes[iend] = wfx._time+dt+tdc_jitter; - // randomize threshold using the incoherent noise - double threshold = _randgauss.fire(wfx._vcross,strawele.analogNoise(StrawElectronics::thresh)); - // find TOT - tot[iend] = waveform[iend].digitizeTOT(strawele,threshold,wfx._time + dt); - // sample ADC - waveform[iend].sampleADCWaveform(strawele,adctimes,wf[iend]); - } - // uncalibrate - strawele.uncalibrateTimes(xtimes,sid); - // add ends and add noise - ADCVoltages wfsum; wfsum.reserve(adctimes.size()); - for(unsigned isamp=0;isamppush_back(StrawDigi(sid,tdcs,tot,adc)); - } - return digitize; - } - - // find straws which couple to the given one, and record them and their couplings in XTalk objects. - // For now, this is just a fixed number for adjacent straws, - // the couplings and straw identities should eventually come from a database, FIXME!!! - void StrawDigisFromStepPointMCs::findCrossTalkStraws(Straw const& straw, vector& xtalk) { - StrawId selfid = straw.id(); - xtalk.clear(); - // find straws sensitive to straw-to-straw cross talk - vector const& strawNeighbors = straw.nearestNeighboursById(); - // find straws sensitive to electronics cross talk - vector const& preampNeighbors = straw.preampNeighboursById(); - // convert these to cross-talk - for(auto isid=strawNeighbors.begin();isid!=strawNeighbors.end();++isid){ - xtalk.push_back(XTalk(selfid,*isid,_preampxtalk,0)); - } - for(auto isid=preampNeighbors.begin();isid!=preampNeighbors.end();++isid){ - xtalk.push_back(XTalk(selfid,*isid,0,_postampxtalk)); - } - } - - // functions that need implementing:: FIXME!!!!!! - // Could also fold in beam-off random trigger hits from real data - void StrawDigisFromStepPointMCs::addNoise(StrawClusterMap& hmap){ - // create random noise clusts and add them to the sequences of random straws. - } - // diagnostic functions - void StrawDigisFromStepPointMCs::waveformHist(StrawElectronics const& strawele, SWFP const& wfs, WFXPList const& xings) { - // histogram individual waveforms - static unsigned nhist(0);// maximum number of histograms per job! - for(size_t iend=0;iend<2;++iend){ - // step to the 1st cluster past the blanking time to avoid double-counting - ClusterList const& clist = wfs[iend].clusts().clustList(); - auto icl = clist.begin(); - while(icl->time() < strawele.flashEnd()) - icl++; - if(icl != clist.end() && nhist < _maxhist && xings.size() >= _minnxinghist && - ( ((!_xtalkhist) && wfs[iend].xtalk().self()) || (_xtalkhist && !wfs[iend].xtalk().self()) ) ) { - double tstart = icl->time()-_tstep; - double tfall = strawele.fallTime(_diagpath); - double tend = clist.rbegin()->time() + _nfall*tfall; - ADCTimes times; - ADCVoltages volts; - times.reserve(size_t(ceil(tend-tstart)/_tstep)); - volts.reserve(size_t(ceil(tend-tstart)/_tstep)); - double t = tstart; - while(t tfs; - char name[60]; - char title[100]; - snprintf(name,60,"SWF%i_%i",wfs[iend].clusts().strawId().asUint16(),nhist); - snprintf(title,100,"Electronic output for straw %i end %i path %i;time (nSec);Waveform (mVolts)",wfs[iend].clusts().strawId().asUint16(),(int)iend,_diagpath); - TH1F* wfh = tfs->make(name,title,volts.size(),times.front(),times.back()); - for(size_t ibin=0;ibinSetBinContent(ibin+1,volts[ibin]); - TList* flist = wfh->GetListOfFunctions(); - for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ - TMarker* smark = new TMarker(ixing->at(iend)._time,ixing->at(iend)._vcross,8); - smark->SetMarkerColor(kGreen); - smark->SetMarkerSize(2); - flist->Add(smark); - } - } - } - } - - void StrawDigisFromStepPointMCs::waveformDiag( - StrawElectronics const& strawele, - SWFP const& wfs, WFXPList const& xings) { - const Tracker& tracker = *GeomHandle(); - const Straw& straw = tracker.getStraw( wfs[0].clusts().strawId() ); - _swplane = straw.id().getPlane(); - _swpanel = straw.id().getPanel(); - _swlayer = straw.id().getLayer(); - _swstraw = straw.id().getStraw(); - for(size_t iend=0;iend<2; ++iend){ - ClusterList const& clusts = wfs[iend].clusts().clustList(); - size_t nclust = clusts.size(); - set > steps; - set > parts; - _nxing[iend] = 0; - _txing[iend] = strawele.flashStart() + _mbbuffer; - _xddist[iend] = _xwdist[iend] = _xpdist[iend] = -1.0; - for(auto ixing=xings.begin();ixing!=xings.end();++ixing){ - ++_nxing[iend]; - _txing[iend] = min(_txing[iend],static_cast(ixing->at(iend)._time)); - _xddist[iend] = ixing->at(iend)._iclust->driftDistance(); - _xwdist[iend] = ixing->at(iend)._iclust->wireDistance(); - // compute direction perpendicular to wire and momentum - art::Ptr const& spp = ixing->at(iend)._iclust->stepPointMC(); - if(!spp.isNull()){ - Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); - // project the differences in position to get the perp distance - _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); - } - } - if(_nxing[iend] == 0){ - // no xings: just take the 1st clust - if(nclust > 0 ){ - _xddist[iend] = clusts.front().driftDistance(); - _xwdist[iend] = clusts.front().wireDistance(); - art::Ptr const& spp = clusts.front().stepPointMC(); - if(!spp.isNull()){ - Hep3Vector pdir = straw.getDirection().cross(spp->momentum()).unit(); - // project the differences in position to get the perp distance - _xpdist[iend] = pdir.dot(spp->position()-straw.getMidPoint()); - } - } - } - if(nclust > 0){ - _tmin[iend] = clusts.begin()->time(); - _tmax[iend] = clusts.rbegin()->time(); - } else { - _tmin[iend] = _mbtime+_mbbuffer; - _tmax[iend] = -100.0; - } - - _hqsum[iend] = 0.0; - _vmax[iend] = _tvmax[iend] = 0.0; - _wmcpdg[iend] = _wmcproc[iend] = 0; - for(auto iclu=clusts.begin();iclu!=clusts.end();++iclu){ - if(iclu->stepPointMC().isNonnull()){ - steps.insert(iclu->stepPointMC()); - parts.insert(iclu->stepPointMC()->simParticle()); - _hqsum[iend] += iclu->charge(); - double ctime = iclu->time()+strawele.maxResponseTime(_diagpath,iclu->wireDistance()); - double vout = wfs[iend].sampleWaveform(strawele,_diagpath,ctime); - if(vout > _vmax[iend]){ - _vmax[iend] = vout; - _tvmax[iend] = ctime; - _wmcpdg[iend] = iclu->stepPointMC()->simParticle()->pdgId(); - _wmcproc[iend] = iclu->stepPointMC()->simParticle()->creationCode(); - _mce[iend] = iclu->stepPointMC()->simParticle()->startMomentum().e(); - _slen[iend] = iclu->stepPointMC()->stepLength(); - _sedep[iend] = iclu->stepPointMC()->ionizingEdep(); - } - } - } - _nsteppoint[iend] = steps.size(); - _npart[iend] = parts.size(); - _sesum[iend] = 0.0; - for(auto istep=steps.begin();istep!=steps.end();++istep) - _sesum [iend]+= (*istep)->ionizingEdep(); - } - _swdiag->Fill(); - } - - void StrawDigisFromStepPointMCs::digiDiag(StrawPhysics const& strawphys, SWFP const& wfs, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi) { - const Tracker& tracker = *GeomHandle(); - const Straw& straw = tracker.getStraw( digi.strawId() ); - _sdplane = straw.id().getPlane(); - _sdpanel = straw.id().getPanel(); - _sdlayer = straw.id().getLayer(); - _sdstraw = straw.id().getStraw(); - - for(size_t iend=0;iend<2;++iend){ - _xtime[iend] = xpair[iend]._time; - _tctime[iend] = xpair[iend]._iclust->time(); - _charge[iend] = xpair[iend]._iclust->charge(); - _ddist[iend] = xpair[iend]._iclust->driftDistance(); - _dtime[iend] = xpair[iend]._iclust->driftTime(); - _ptime[iend] = xpair[iend]._iclust->propTime(); - _phi[iend] = xpair[iend]._iclust->phi(); //JB - _wdist[iend] = xpair[iend]._iclust->wireDistance(); - _vstart[iend] = xpair[iend]._vstart; - _vcross[iend] = xpair[iend]._vcross; - _tdc[iend] = digi.TDC(xpair[iend]._iclust->strawEnd()); - _tot[iend] = digi.TOT(xpair[iend]._iclust->strawEnd()); - ClusterList const& clist = wfs[iend].clusts().clustList(); - auto ctrig = xpair[iend]._iclust; - _ncludd[iend] = clist.size(); - // find the earliest cluster from the same particle that triggered the crossing - auto iclu = clist.begin(); - while( iclu != clist.end() && ctrig->stepPointMC()->simParticle() != iclu->stepPointMC()->simParticle() ){ - ++iclu; - } - if(iclu != clist.end() ){ - _ectime[iend] = iclu->time(); - _ecddist[iend] = iclu->driftDistance(); - _ecdtime[iend] = iclu->driftTime(); - _ecptime[iend] = iclu->propTime(); - // count how many clusters till we get to the trigger cluster - size_t iclust(0); - while( iclu != clist.end() && iclu != ctrig){ - ++iclu; - ++iclust; - } - _iclust[iend] = iclust; - } - } - if(xpair[0]._iclust->stepPointMC() == xpair[1]._iclust->stepPointMC()) - _nstep = 1; - else - _nstep = 2; - _adc.clear(); - for(auto iadc=digi.adcWaveform().begin();iadc!=digi.adcWaveform().end();++iadc){ - _adc.push_back(*iadc); - } - // mc truth information - _dmcpdg = _dmcproc = _dmcgen = 0; - _dmcmom = -1.0; - _mctime = _mcenergy = _mctrigenergy = _mcthreshenergy = _mcdca = -1000.0; - _mcthreshpdg = _mcthreshproc = _mcnstep = 0; - art::Ptr const& spmc = xpair[0]._iclust->stepPointMC(); - if(!spmc.isNull()){ - _mctime = _toff.timeWithOffsetsApplied(*spmc); - // compute the doca for this step - TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), - spmc->position(), spmc->momentum().unit() ); - _mcdca = pca.dca(); - - Hep3Vector mccdir = (pca.point2()-straw.getMidPoint()); - mccdir -= straw.getDirection()*(mccdir.dot(straw.getDirection())); - _mcdcaphi = mccdir.theta(); - _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); //JB: this is now from the lorentz corrected r-component of the drift - - if(!spmc->simParticle().isNull()){ - _dmcpdg = spmc->simParticle()->pdgId(); - _dmcproc = spmc->simParticle()->creationCode(); - if(spmc->simParticle()->genParticle().isNonnull()) - _dmcgen = spmc->simParticle()->genParticle()->generatorId().id(); - _dmcmom = spmc->momentum().mag(); - } - } - _mcenergy = mcdigi.energySum(); - _mctrigenergy = mcdigi.triggerEnergySum(StrawEnd::cal); - // sum the energy from the explicit trigger particle, and find it's releationship - _mcthreshenergy = 0.0; - _mcnstep = mcdigi.stepPointMCs().size(); - auto threshpart = mcdigi.stepPointMC(StrawEnd::cal); - if(threshpart.isNull()) threshpart = mcdigi.stepPointMC(StrawEnd::hv); - for(auto imcs = mcdigi.stepPointMCs().begin(); imcs!= mcdigi.stepPointMCs().end(); ++ imcs){ - // if the SimParticle for this step is the same as the one which fired the discrim, add the energy - if( (*imcs)->simParticle() == threshpart->simParticle() ) - _mcthreshenergy += (*imcs)->eDep(); - } - _mcthreshpdg = threshpart->simParticle()->pdgId(); - _mcthreshproc = threshpart->simParticle()->creationCode(); - - _xtalk = digi.strawId() != spmc->strawId(); - // fill the tree entry - _sddiag->Fill(); - }//End of digiDiag - - - - - void StrawDigisFromStepPointMCs::fillClusterPositions(Straw const& straw, StepPointMC const& step, std::vector& cpos) { - // basic info - double charge(0.0); - GlobalConstantsHandle pdt; - if(pdt->particle(step.simParticle()->pdgId()).isValid()){ - charge = pdt->particle(step.simParticle()->pdgId()).ref().charge(); - } - static const double r2 = straw.innerRadius()*straw.innerRadius(); - // decide how we step; straight or helix, depending on the Pt - Hep3Vector const& mom = step.momentum(); - Hep3Vector mdir = mom.unit(); - // approximate pt - double apt = step.momentum().perpPart(_bdir).mag(); - if( apt > _ptmin) { // use linear approximation - double slen = step.stepLength(); - // make sure this linear approximation doesn't extend past the physical straw - Hep3Vector dperp = (step.position() -straw.getMidPoint()).perpPart(straw.getDirection()); - Hep3Vector mperp = mdir.perpPart(straw.getDirection()); - double dm = dperp.dot(mperp); - double m2 = mperp.mag2(); - double dp2 = dperp.mag2(); - double sarg = dm*dm + m2*(r2 - dp2); - // some glancing cases fail the linear math - if(sarg > 0.0 && m2 > 0.0){ - double smax = (-dm + sqrt(sarg))/m2; - slen = std::min(smax,slen); - } - // generate random cluster positions - for(unsigned ic=0;ic < cpos.size();++ic){ - // - cpos[ic] = step.position() +_randflat.fire(slen) *mdir; - } - } else { - // Use a helix to model particles which curl on the scale of the straws - GeomHandle bfmgr; - GeomHandle det; - // find the local field vector at this step - Hep3Vector vpoint_mu2e = det->toMu2e(step.position()); - Hep3Vector bf = bfmgr->getBField(vpoint_mu2e); - // compute transverse radius of particle - double rcurl = fabs(charge*(mom.perpPart(bf).mag())/BField::mmTeslaToMeVc*bf.mag()); - // basis using local Bfield direction - Hep3Vector bfdir = bf.unit(); - Hep3Vector qmdir = (charge*mom).unit(); // charge-signed momentum direction - Hep3Vector rdir = qmdir.cross(bfdir).unit(); // points along magnetic force, ie towards center - Hep3Vector pdir = bfdir.cross(rdir).unit(); // perp to this and field - // find the center of the helix at the start of this step - Hep3Vector hcent = step.position() + rcurl*rdir; - // find helix parameters. By definition, z0 = phi0 = 0 - double omega = qmdir.dot(pdir)/(rcurl*qmdir.dot(bfdir)); - // compute how far this step goes along the field direction. This includes sign information - double zlen = step.stepLength()*mdir.dot(bfdir); - // loop until we've found enough valid samples, or have given up trying - unsigned iclu(0); - unsigned ntries(0); - unsigned nclus = cpos.size(); - while(iclu < nclus && ntries < 10*nclus){ - double zclu = _randflat.fire(zlen); - double phi = zclu*omega; - // build cluster position from these - Hep3Vector cp = hcent + rcurl*(-rdir*cos(phi) + pdir*sin(phi)) + zclu*bfdir; - // test - double rd2 = (cp-straw.getMidPoint()).perpPart(straw.getDirection()).mag2(); - if(rd2 - r2 < 1.0e-3){ - cpos[iclu] = cp; - ++iclu; - } else if (_debug > 0) { - cout << "cluster outside straw: helix " << sqrt(rd2) << endl; - } - ++ntries; - } - if(iclu != nclus){ - // failed to find valid steps. put any remining energy at the step - if(_debug > 0)cout << "mu2e::StrawDigisFromStepPointMCs: Couldn't create enough clusters : "<< iclu << " wanted " << nclus << endl; - while(iclu < nclus){ - cpos[iclu] = step.position(); - ++iclu; - } - } - } - } - - void StrawDigisFromStepPointMCs::fillClusterMinion(StrawPhysics const& strawphys, StepPointMC const& step, std::vector& ne, std::vector& cen) { - // Loop until we've assigned energy + electrons to every cluster - unsigned mc(0); - double esum(0.0); - double etot = step.ionizingEdep(); - unsigned nc = ne.size(); - while(mc < nc){ - std::vector me(nc); - // fill an array of random# of electrons according to the measured distribution. These are returned sorted lowest-highest. - fillClusterNe(strawphys,me); - for(auto ie : me) { - // maximum energy for this cluster requires at least 1 electron for the rest of the cluster - double emax = etot - esum - (nc -mc -1)*strawphys.ionizationEnergy((unsigned)1); - double eele = strawphys.ionizationEnergy(ie); - if( eele < emax){ - ne[mc] = ie; - cen[mc] = eele; - ++mc; - esum += eele; - } else { - break; - } - } - } - // distribute any residual energy randomly to these clusters. This models delta rays - unsigned ns; - do{ - unsigned me = strawphys.nePerIon(_randflat.fire()); - double emax = etot - esum; - double eele = strawphys.ionizationEnergy(me); - if(eele < emax){ - // choose a random cluster to assign this energy to - unsigned mc = std::min(nc-1,static_cast(floor(_randflat.fire(nc)))); - ne[mc] += me; - cen[mc] += eele; - esum += eele; - } - // maximum energy for this cluster requires at least 1 electron for the rest of the cluster - ns = static_cast(floor((etot-esum)/strawphys.ionizationEnergy((unsigned)1))); - } while(ns > 0); - } - - void StrawDigisFromStepPointMCs::fillClusterNe(StrawPhysics const& strawphys,std::vector& me) { - for(size_t ie=0;ie < me.size(); ++ie){ - me[ie] = strawphys.nePerIon(_randflat.fire()); - } - if(_sort)std::sort(me.begin(),me.end()); - } - - bool StrawDigisFromStepPointMCs::readAll(StrawId const& sid) const { - - return sid.straw() >= _allStraw && - (std::find(_allPlanes.begin(),_allPlanes.end(),sid.plane()) != _allPlanes.end()); - } - - } // end namespace trackermc -} // end namespace mu2e - -using mu2e::TrackerMC::StrawDigisFromStepPointMCs; -DEFINE_ART_MODULE(StrawDigisFromStepPointMCs); diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc index 93af91ac45..5af53e18bc 100644 --- a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -1048,7 +1048,7 @@ namespace mu2e { _ncludd[iend] = clist.size(); // find the earliest cluster from the same particle that triggered the crossing auto iclu = clist.begin(); - while( iclu != clist.end() && ctrig->stepPointMC()->simParticle() != iclu->stepPointMC()->simParticle() ){ + while( iclu != clist.end() && ctrig->strawGasStep()->simParticle() != iclu->strawGasStep()->simParticle() ){ ++iclu; } if(iclu != clist.end() ){ @@ -1065,7 +1065,7 @@ namespace mu2e { _iclust[iend] = iclust; } } - if(xpair[0]._iclust->stepPointMC() == xpair[1]._iclust->stepPointMC()) + if(xpair[0]._iclust->strawGasStep() == xpair[1]._iclust->strawGasStep()) _nstep = 1; else _nstep = 2; From 78d17cf22fd8119ff1d45a9d27d19e1cc4635b56 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Fri, 15 Nov 2019 00:20:12 -0600 Subject: [PATCH 15/18] Remove legacy functions. Convert IonCluster to work in cylindrical coordinates --- Analyses/src/TrackSummaryTruthMaker_module.cc | 4 +- CalPatRec/src/DeltaFinderAna_module.cc | 4 +- CalPatRec/src/ObjectDumpUtils.cc | 4 +- CommonMC/src/SelectRecoMC_module.cc | 4 +- CosmicReco/src/CosmicAnalyzer_module.cc | 4 +- CosmicReco/src/CosmicMuonInfo_module.cc | 8 +- Filters/src/CompressDigiMCsCheck_module.cc | 12 +- Filters/src/CompressDigiMCs_module.cc | 2 +- Filters/src/StepPointsInDigis_module.cc | 2 +- Filters/src/StrawDigiMCFilter_module.cc | 2 +- Filters/src/TrkPatRecFilter_module.cc | 4 +- MCDataProducts/inc/StrawDigiMC.hh | 8 +- MCDataProducts/src/MCRelationship.cc | 4 +- MCDataProducts/src/StrawDigiMC.cc | 12 +- Print/src/StrawDigiMCPrinter.cc | 8 +- TrackerMC/inc/IonCluster.hh | 23 ++-- TrackerMC/inc/StrawCluster.hh | 22 ++-- TrackerMC/inc/StrawPosition.hh | 9 ++ TrackerMC/src/MakeStrawGasSteps_module.cc | 14 ++- TrackerMC/src/StrawCluster.cc | 16 ++- .../src/StrawDigisFromStrawGasSteps_module.cc | 118 +++++++++++------- TrackerMC/src/classes_def.xml | 4 +- Trigger/src/ReadTriggerInfo_module.cc | 8 +- TrkDiag/src/BkgDiag_module.cc | 2 +- TrkDiag/src/ComboHitDiag_module.cc | 2 +- TrkDiag/src/HelixDiag_module.cc | 2 +- TrkDiag/src/KalDiag.cc | 12 +- TrkDiag/src/StrawHitDiag_module.cc | 2 +- TrkDiag/src/TimeClusterDiag_module.cc | 4 +- TrkDiag/src/TrkMCTools.cc | 2 +- TrkDiag/src/TrkRecoDiag_module.cc | 4 +- TrkReco/src/TrkRecoMcUtils_tool.cc | 6 +- Validation/src/ValStrawDigiMC.cc | 8 +- 33 files changed, 178 insertions(+), 162 deletions(-) create mode 100644 TrackerMC/inc/StrawPosition.hh diff --git a/Analyses/src/TrackSummaryTruthMaker_module.cc b/Analyses/src/TrackSummaryTruthMaker_module.cc index da45738bbd..c5a08a8112 100644 --- a/Analyses/src/TrackSummaryTruthMaker_module.cc +++ b/Analyses/src/TrackSummaryTruthMaker_module.cc @@ -80,10 +80,10 @@ namespace mu2e { } if(hit->isActive()) { - ++nPrincipal[particleEnteringG4Volume(*dmc.stepPointMC(end))]; + ++nPrincipal[particleEnteringG4Volume(*dmc.strawGasStep(end))]; // Aggregate all the steps, so that each particle is counted no more than once per hit std::set > parts; - parts.insert(particleEnteringG4Volume(*dmc.stepPointMC(end))); + parts.insert(particleEnteringG4Volume(*dmc.strawGasStep(end))); for(const auto& p: parts) { ++nAll[p]; } diff --git a/CalPatRec/src/DeltaFinderAna_module.cc b/CalPatRec/src/DeltaFinderAna_module.cc index 2ddbf532a0..5722f5e77e 100644 --- a/CalPatRec/src/DeltaFinderAna_module.cc +++ b/CalPatRec/src/DeltaFinderAna_module.cc @@ -585,10 +585,10 @@ namespace mu2e { const mu2e::StrawGasStep *stmc; if (mcdigi->wireEndTime(mu2e::StrawEnd::cal) < mcdigi->wireEndTime(mu2e::StrawEnd::hv)) { - stmc = mcdigi->stepPointMC(mu2e::StrawEnd::cal).get(); + stmc = mcdigi->strawGasStep(mu2e::StrawEnd::cal).get(); } else { - stmc = mcdigi->stepPointMC(mu2e::StrawEnd::hv ).get(); + stmc = mcdigi->strawGasStep(mu2e::StrawEnd::hv ).get(); } const mu2e::SimParticle* sim = &(*stmc->simParticle()); diff --git a/CalPatRec/src/ObjectDumpUtils.cc b/CalPatRec/src/ObjectDumpUtils.cc index e6579cb393..46eba55d0d 100644 --- a/CalPatRec/src/ObjectDumpUtils.cc +++ b/CalPatRec/src/ObjectDumpUtils.cc @@ -308,10 +308,10 @@ void ObjectDumpUtils::printKalRep(const KalRep* Krep, const char* Opt, const cha const mu2e::StrawGasStep *step; if (mcdigi->wireEndTime(mu2e::StrawEnd::cal) < mcdigi->wireEndTime(mu2e::StrawEnd::hv)) { - step = mcdigi->stepPointMC(mu2e::StrawEnd::cal).get(); + step = mcdigi->strawGasStep(mu2e::StrawEnd::cal).get(); } else { - step = mcdigi->stepPointMC(mu2e::StrawEnd::hv ).get(); + step = mcdigi->strawGasStep(mu2e::StrawEnd::hv ).get(); } // vol_id = step->volumeId(); diff --git a/CommonMC/src/SelectRecoMC_module.cc b/CommonMC/src/SelectRecoMC_module.cc index ba234f59b3..fe7231656c 100644 --- a/CommonMC/src/SelectRecoMC_module.cc +++ b/CommonMC/src/SelectRecoMC_module.cc @@ -274,7 +274,7 @@ namespace mu2e { auto const& sdmc = sdmcc.at(hit.index()); // bounds-check for security; for(size_t isp=0;isp < spcc.size(); isp++){ auto const& spc = spcc[isp]; - if(sdmc.earlyStepPointMC()->simParticle() == spc._spp){ + if(sdmc.earlyStrawGasStep()->simParticle() == spc._spp){ spref = isp; break; } @@ -283,7 +283,7 @@ namespace mu2e { tshmc._spindex = spref; // fill other info directly from the StrawDigiMC tshmc._energySum = sdmc.triggerEnergySum(sdmc.earlyEnd()); - const auto& mcstep = *(sdmc.earlyStepPointMC()); + const auto& mcstep = *(sdmc.earlyStrawGasStep()); tshmc._cpos = Geom::toXYZVec(sdmc.clusterPosition(sdmc.earlyEnd())); tshmc._mom = mcstep.momentum(); tshmc._time = fmod(mcstep.time(),_mbtime); diff --git a/CosmicReco/src/CosmicAnalyzer_module.cc b/CosmicReco/src/CosmicAnalyzer_module.cc index c35b43f603..21070be916 100644 --- a/CosmicReco/src/CosmicAnalyzer_module.cc +++ b/CosmicReco/src/CosmicAnalyzer_module.cc @@ -836,7 +836,7 @@ CosmicTrackMCInfo CosmicAnalyzer::FitMC(const StrawDigiMCCollection*& _mcdigis){ StrawDigiMC first = (*_mcdigis)[0]; //Get StepPointMC: - auto const& spmcp0= first.stepPointMC(StrawEnd::cal); + auto const& spmcp0= first.strawGasStep(StrawEnd::cal); XYZVec pos0(spmcp0->position().x(), spmcp0->position().y(), spmcp0->position().z()); XYZVec dir0(spmcp0->momentum().x(), spmcp0->momentum().y(), spmcp0->momentum().z()); @@ -844,7 +844,7 @@ CosmicTrackMCInfo CosmicAnalyzer::FitMC(const StrawDigiMCCollection*& _mcdigis){ hitP1 = (*_mcdigis)[ich]; //Get StepPointMC: - auto const& spmcp = hitP1.stepPointMC(StrawEnd::cal); + auto const& spmcp = hitP1.strawGasStep(StrawEnd::cal); XYZVec posN(spmcp->position().x(), spmcp->position().y(), spmcp->position().z()); //Use Step Point MC direction as the True Axes: diff --git a/CosmicReco/src/CosmicMuonInfo_module.cc b/CosmicReco/src/CosmicMuonInfo_module.cc index 6586ea65ab..eff8afbe14 100644 --- a/CosmicReco/src/CosmicMuonInfo_module.cc +++ b/CosmicReco/src/CosmicMuonInfo_module.cc @@ -143,11 +143,11 @@ namespace { int n{-1}; for ( auto const& digimc : digimcs ){ - auto const& sim_cal = digimc.stepPointMC(mu2e::StrawEnd::cal)->simParticle(); - auto const& sim_hv = digimc.stepPointMC(mu2e::StrawEnd::cal)->simParticle(); + auto const& sim_cal = digimc.strawGasStep(mu2e::StrawEnd::cal)->simParticle(); + auto const& sim_hv = digimc.strawGasStep(mu2e::StrawEnd::cal)->simParticle(); if ( sim_cal == sim_hv ){ - double p = sqrt(digimc.stepPointMC(mu2e::StrawEnd::cal)->momentum().mag2()); - _bySim[digimc.stepPointMC(mu2e::StrawEnd::cal)->simParticle()].addIndex(++n,p); + double p = sqrt(digimc.strawGasStep(mu2e::StrawEnd::cal)->momentum().mag2()); + _bySim[digimc.strawGasStep(mu2e::StrawEnd::cal)->simParticle()].addIndex(++n,p); ++_sum; }else{ ++_nbad; diff --git a/Filters/src/CompressDigiMCsCheck_module.cc b/Filters/src/CompressDigiMCsCheck_module.cc index a267a3419d..61355a58fa 100644 --- a/Filters/src/CompressDigiMCsCheck_module.cc +++ b/Filters/src/CompressDigiMCsCheck_module.cc @@ -105,11 +105,11 @@ namespace mu2e { } const auto& i_newStrawDigiMC = newStrawDigiMCs.at(i_new_digi_mc); - const auto& i_oldStepPointMC = i_oldStrawDigiMC.stepPointMC(StrawEnd::hv); + const auto& i_oldStepPointMC = i_oldStrawDigiMC.strawGasStep(StrawEnd::hv); if (!i_oldStepPointMC.isAvailable()) { continue; // this is a null step point } - const auto& i_newStepPointMC = i_newStrawDigiMC.stepPointMC(StrawEnd::hv); + const auto& i_newStepPointMC = i_newStrawDigiMC.strawGasStep(StrawEnd::hv); const auto& i_old_digi_mc_strawId = i_oldStrawDigiMC.strawId(); const auto& i_new_digi_mc_strawId = i_newStrawDigiMC.strawId(); @@ -144,10 +144,10 @@ namespace mu2e { // If we only access steps through digis then you will get the correct information // You cannot loop over the StepPointMCCollection however // Here we check that the HV and Cal StepPtrs also exist in the WaveformStepPtrs -// const auto& i_newStepPointMCCal = i_newStrawDigiMC.stepPointMC(StrawEnd::cal); +// const auto& i_newStepPointMCCal = i_newStrawDigiMC.strawGasStep(StrawEnd::cal); // bool identical_cal_ptr = false; // bool identical_hv_ptr = false; -// for (const auto& i_triggerStepPointPtr : i_newStrawDigiMC.stepPointMCs()) { +// for (const auto& i_triggerStepPointPtr : i_newStrawDigiMC.strawGasSteps()) { // if (i_triggerStepPointPtr == i_newStepPointMC) { // identical_hv_ptr = true; // } @@ -166,8 +166,8 @@ namespace mu2e { // // StrawDigiMC: HVStepPtr-->A', CalStepPtr-->A'', WaveformStepPtrs-->A, B, C, D, E, A', A'' // // This will not trigger the exception in Case 1 // // Here we check that there are no identical waveform steps -// for (const auto& i_stepPointPtr : i_newStrawDigiMC.stepPointMCs()) { -// for (const auto& j_stepPointPtr : i_newStrawDigiMC.stepPointMCs()) { +// for (const auto& i_stepPointPtr : i_newStrawDigiMC.strawGasSteps()) { +// for (const auto& j_stepPointPtr : i_newStrawDigiMC.strawGasSteps()) { // if (i_stepPointPtr == j_stepPointPtr) { // continue; // these will obviously match // } diff --git a/Filters/src/CompressDigiMCs_module.cc b/Filters/src/CompressDigiMCs_module.cc index 467fcbcf2a..b1c180293f 100644 --- a/Filters/src/CompressDigiMCs_module.cc +++ b/Filters/src/CompressDigiMCs_module.cc @@ -661,7 +661,7 @@ void mu2e::CompressDigiMCs::copyStrawDigiMC(const mu2e::StrawDigiMC& old_straw_d for(int i_end=0;i_end(i_end); - const auto& old_step_point = old_straw_digi_mc.stepPointMC(end); + const auto& old_step_point = old_straw_digi_mc.strawGasStep(end); const auto& newStepPtrIter = step_remap.find(old_step_point); if (newStepPtrIter == step_remap.end()) { if (old_step_point.isAvailable()) { diff --git a/Filters/src/StepPointsInDigis_module.cc b/Filters/src/StepPointsInDigis_module.cc index f237399504..649da20c28 100644 --- a/Filters/src/StepPointsInDigis_module.cc +++ b/Filters/src/StepPointsInDigis_module.cc @@ -120,7 +120,7 @@ void mu2e::StepPointsInDigis::analyze(art::Event const& event) for(int i_end=0;i_end(i_end); - auto const& old_step_point = i_strawDigiMC.stepPointMC(end); + auto const& old_step_point = i_strawDigiMC.strawGasStep(end); if (old_step_point.isAvailable()) { fillTree( *old_step_point ); } diff --git a/Filters/src/StrawDigiMCFilter_module.cc b/Filters/src/StrawDigiMCFilter_module.cc index d141fa7acd..d49d7ceae6 100644 --- a/Filters/src/StrawDigiMCFilter_module.cc +++ b/Filters/src/StrawDigiMCFilter_module.cc @@ -67,7 +67,7 @@ namespace mu2e { for(auto const& mcdigi : *mcdigis) { // look at the early end StrawEnd fend = mcdigi.earlyEnd(); - auto const& step = mcdigi.stepPointMC(fend); + auto const& step = mcdigi.strawGasStep(fend); art::Ptr const& sp = step->simParticle(); auto const& mom = step->momentum(); // cast to 3-vector if(debug_ > 0)std::cout <<"SimParticle PDG = " << sp->pdgId() << " Mom = " << sqrt(mom.mag2()) << std::endl; diff --git a/Filters/src/TrkPatRecFilter_module.cc b/Filters/src/TrkPatRecFilter_module.cc index 61dc190a9a..a5877bbf7d 100644 --- a/Filters/src/TrkPatRecFilter_module.cc +++ b/Filters/src/TrkPatRecFilter_module.cc @@ -88,8 +88,8 @@ namespace mu2e const StrawDigiMCCollection* mcdigis = mcdigisHandle.product(); for(auto imcdigi = mcdigis->begin(); imcdigi != mcdigis->end(); ++imcdigi){ if( imcdigi->wireEndTime(StrawEnd::cal) > _minCETime ) { - if(imcdigi->stepPointMC(StrawEnd::cal)->simParticle()->genParticle().isNonnull() && - imcdigi->stepPointMC(StrawEnd::cal)->simParticle()->genParticle()->generatorId().isConversion()) ++ncehits; + if(imcdigi->strawGasStep(StrawEnd::cal)->simParticle()->genParticle().isNonnull() && + imcdigi->strawGasStep(StrawEnd::cal)->simParticle()->genParticle()->generatorId().isConversion()) ++ncehits; } } } diff --git a/MCDataProducts/inc/StrawDigiMC.hh b/MCDataProducts/inc/StrawDigiMC.hh index a21c20aeab..e1b97c00d2 100644 --- a/MCDataProducts/inc/StrawDigiMC.hh +++ b/MCDataProducts/inc/StrawDigiMC.hh @@ -36,9 +36,6 @@ namespace mu2e { StrawDigiMC(); // construct from hitlets StrawDigiMC(StrawId sid, PA cpos, FA ctime, FA wetime, SGSPA sgs); - // temporary legacy construtctor fot testing FIXME! - StrawDigiMC(StrawId sid, double wetime[2], - CLHEP::HepLorentzVector cpos[2], art::Ptr stepMC[2], std::vector > const& stepmcs); // use compuater copy construcors StrawDigiMC(const StrawDigiMC& rhs, SGSPA sgsp ); // update the Ptrs @@ -63,9 +60,6 @@ namespace mu2e { void print( std::ostream& ost = std::cout, bool doEndl = true ) const; // legacy functions - SGSP const& stepPointMC(StrawEnd strawend) const { return _sgspa[strawend]; } - SGSPA const& stepPointMCs() const { return _sgspa; } - SGSP const& earlyStepPointMC() const { return stepPointMC(earlyEnd()); } CLHEP::HepLorentzVector clusterPosition(StrawEnd strawend) const { return CLHEP::HepLorentzVector(Geom::Hep3Vec(_cpos[strawend]),_ctime[strawend]); } private: @@ -73,7 +67,7 @@ namespace mu2e { PA _cpos; // Positions of the trigger clusters FA _ctime; // times of the trigger clusters FA _wtime; // times at the wire ends of the signals which fired the TDC. - SGSPA _sgspa; // StrawGasStep collection that triggered each end + SGSPA _sgspa; // StrawGasStep that triggered each end }; inline std::ostream& operator<<( std::ostream& ost, diff --git a/MCDataProducts/src/MCRelationship.cc b/MCDataProducts/src/MCRelationship.cc index 1df7adc561..8c4a66cba7 100644 --- a/MCDataProducts/src/MCRelationship.cc +++ b/MCDataProducts/src/MCRelationship.cc @@ -9,11 +9,11 @@ namespace mu2e using std::vector; MCRelationship::MCRelationship(StrawDigiMC const& mcd1, StrawDigiMC const& mcd2) : - MCRelationship(mcd1.earlyStepPointMC()->simParticle(),mcd2.earlyStepPointMC()->simParticle()) + MCRelationship(mcd1.earlyStrawGasStep()->simParticle(),mcd2.earlyStrawGasStep()->simParticle()) {} MCRelationship::MCRelationship(StrawDigiMC const& mcd, SPPtr const& spp) : - MCRelationship(mcd.earlyStepPointMC()->simParticle(),spp) + MCRelationship(mcd.earlyStrawGasStep()->simParticle(),spp) {} MCRelationship::MCRelationship(SPPtr const& sppi,SPPtr const& sppj) : _rel(none), _rem(-1) { diff --git a/MCDataProducts/src/StrawDigiMC.cc b/MCDataProducts/src/StrawDigiMC.cc index f6000b8528..601851307c 100644 --- a/MCDataProducts/src/StrawDigiMC.cc +++ b/MCDataProducts/src/StrawDigiMC.cc @@ -25,18 +25,8 @@ namespace mu2e { _strawid(sid), _cpos(cpos), _ctime(ctime), _wtime(wetime), _sgspa(sgs) {} -// legacy constructor: StrawGasSteps will be empty! - StrawDigiMC::StrawDigiMC(StrawId sid, double wetime[2], - CLHEP::HepLorentzVector cpos[2], art::Ptr stepMC[2], std::vector > const& stepmcs) :_strawid(sid) - { - for(size_t strawend=0;strawend<2;++strawend){ - _wtime[strawend] = wetime[strawend]; - _cpos[strawend] = cpos[strawend]; - } - } - StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs, SGSPA sgspa ) : StrawDigiMC(rhs) { - _sgspa = sgspa; // can't initialize after delecated construtor + _sgspa = sgspa; } bool StrawDigiMC::isCrossTalk(StrawEnd strawend) const { diff --git a/Print/src/StrawDigiMCPrinter.cc b/Print/src/StrawDigiMCPrinter.cc index a49460f04d..685ca76323 100644 --- a/Print/src/StrawDigiMCPrinter.cc +++ b/Print/src/StrawDigiMCPrinter.cc @@ -70,8 +70,8 @@ mu2e::StrawDigiMCPrinter::Print(const mu2e::StrawDigiMC& obj, int ind, std::ostr // energy accessor is not protected against bad Ptr double energy = 0.0, tenergy0 = 0.0, tenergy1 = 0.0; bool eOK = true; - if(!obj.stepPointMC(StrawEnd::cal).isAvailable() || - !obj.stepPointMC(StrawEnd::hv).isAvailable() || + if(!obj.strawGasStep(StrawEnd::cal).isAvailable() || + !obj.strawGasStep(StrawEnd::hv).isAvailable() || !obj.strawGasStep(StrawEnd::cal).isAvailable() || !obj.strawGasStep(StrawEnd::hv).isAvailable() ) eOK = false; if(eOK) { @@ -81,8 +81,8 @@ mu2e::StrawDigiMCPrinter::Print(const mu2e::StrawDigiMC& obj, int ind, std::ostr } // now check if the basic StepPointMC's are also available - auto const& a0 = obj.stepPointMC(StrawEnd::cal); - auto const& a1 = obj.stepPointMC(StrawEnd::hv); + auto const& a0 = obj.strawGasStep(StrawEnd::cal); + auto const& a1 = obj.strawGasStep(StrawEnd::hv); if(!(a0.isAvailable() && a1.isAvailable()) ) { // give up at this point since basically no accessors work diff --git a/TrackerMC/inc/IonCluster.hh b/TrackerMC/inc/IonCluster.hh index fa8ca8e1df..51dad927b9 100644 --- a/TrackerMC/inc/IonCluster.hh +++ b/TrackerMC/inc/IonCluster.hh @@ -1,17 +1,20 @@ #ifndef TrackerMC_IonCluster_hh #define TrackerMC_IonCluster_hh #include "DataProducts/inc/XYZVec.hh" +#include "TrackerMC/inc/StrawPosition.hh" #include "Rtypes.h" namespace mu2e { - struct IonCluster { // ion charge cluster before drift or amplification - XYZVec _pos; // position of this cluster - Float_t _phi; // initial angle of the cluster WRT the wire and the BField - Float_t _charge; // charge of this cluster, in pC. Note: this is pre-gain!!! - Float_t _eion; // ionization energy of this cluster, in MeV - UInt_t _ne; // number of electrons in this cluster - IonCluster(XYZVec const& pos, double phi, double charge, double eion, unsigned ne): - _pos(pos), _phi(phi),_charge(charge),_eion(eion),_ne(ne) {} - IonCluster() : _charge(0.0), _eion(0.0), _ne(0) {} - }; + namespace TrackerMC { + struct IonCluster { // ion charge cluster before drift or amplification + StrawPosition _pos; // position in straw coordinates + // Float_t _phi; // initial angle of the cluster WRT the wire and the BField + Float_t _charge; // charge of this cluster, in pC. Note: this is pre-gain!!! + Float_t _eion; // ionization energy of this cluster, in MeV + UInt_t _ne; // number of electrons in this cluster + IonCluster(StrawPosition const& pos, double charge, double eion, unsigned ne): + _pos(pos), _charge(charge),_eion(eion),_ne(ne) {} + IonCluster() : _charge(0.0), _eion(0.0), _ne(0) {} + }; + } } #endif diff --git a/TrackerMC/inc/StrawCluster.hh b/TrackerMC/inc/StrawCluster.hh index 6fb90fd95f..fabc8e3d5d 100644 --- a/TrackerMC/inc/StrawCluster.hh +++ b/TrackerMC/inc/StrawCluster.hh @@ -16,10 +16,10 @@ // Mu2e includes #include "DataProducts/inc/StrawId.hh" #include "DataProducts/inc/StrawEnd.hh" +#include "TrackerMC/inc/StrawPosition.hh" #include "MCDataProducts/inc/StrawGasStep.hh" // toolkit includes #include "canvas/Persistency/Common/Ptr.h" -#include "CLHEP/Vector/LorentzVector.h" namespace mu2e { namespace TrackerMC { @@ -36,13 +36,11 @@ namespace mu2e { StrawEnd end, float time, float charge, - float ddist, - float phi, - float wdist, + StrawPosition const& pos, float drifttime, float proptime, art::Ptr const& sgs, - XYZVec const& cpos, float ctime); + float ctime); // use compiler version of copy, assignment // Accessors ClusterType type() const { return _type; } @@ -50,15 +48,14 @@ namespace mu2e { StrawEnd strawEnd() const { return _end; } double time() const { return _time;} float charge() const { return _charge; } - float driftDistance() const { return _ddist; } - float phi() const { return _phi; } //JB: added - float wireDistance() const { return _wdist; } + StrawPosition const& pos() const { return _pos; } + float wireDistance() const { return _pos.Z(); } + float driftDistance() const { return _pos.Rho(); } + float driftPhi() const { return _pos.Phi(); } float driftTime() const { return _drifttime; } float propTime() const { return _proptime; } art::Ptr const& strawGasStep() const { return _sgsptr; } float cluTime() const { return _ctime; } - XYZVec const& cluPos() const { return _cpos; } - CLHEP::HepLorentzVector clusterPosition() const { return CLHEP::HepLorentzVector(Geom::Hep3Vec(_cpos),_ctime); } // legacy function FIXME // Print contents of the object. void print( std::ostream& ost = std::cout, bool doEndl = true ) const; private: @@ -67,13 +64,10 @@ namespace mu2e { StrawEnd _end; // which end of the straw float _time; // microbunch time at the wire end, in ns since EventWindowMarker, offsets and wrapping applied float _charge; // charge at the wire end, in units of pC - float _ddist; // drift distance charge traveled to the wire - float _phi; // angle between E and B at ionization event - float _wdist; // distance along the wire the charge has traveled, used to calculate dispersion + StrawPosition _pos; // cluster position WRT the straw float _drifttime; // drift time to the wire float _proptime; // propagation time to the wire end art::Ptr _sgsptr; - XYZVec _cpos; float _ctime; }; } // namespace TrackerMC diff --git a/TrackerMC/inc/StrawPosition.hh b/TrackerMC/inc/StrawPosition.hh new file mode 100644 index 0000000000..89835133b3 --- /dev/null +++ b/TrackerMC/inc/StrawPosition.hh @@ -0,0 +1,9 @@ +#ifndef TrackerMC_StrawPosition_hh +#define TrackerMC_StrawPosition_hh +#include "Math/Vector3D.h" +namespace mu2e { + namespace TrackerMC { + typedef ROOT::Math::Cylindrical3D StrawPosition; // position WRT the straw. + } +} +#endif diff --git a/TrackerMC/src/MakeStrawGasSteps_module.cc b/TrackerMC/src/MakeStrawGasSteps_module.cc index f336c408fc..43484fcfeb 100644 --- a/TrackerMC/src/MakeStrawGasSteps_module.cc +++ b/TrackerMC/src/MakeStrawGasSteps_module.cc @@ -60,11 +60,13 @@ namespace mu2e { fhicl::Atom curlRotation{ Name("curlRotation"), Comment("Minimum bending rotation to use curl end estimation (radians)"),2.0}; fhicl::Atom minionBG{ Name("minionBetaGamma"), - Comment("Minimum beta x gamma value to consider a particle minimmum-ionizing"),0.5}; + Comment("Minimum beta*gamma to consider a particle minimmum-ionizing"),0.5}; + fhicl::Atom minionKE{ Name("minionKineticEnergy"), + Comment("Minimum kinetic energy to consider a particle minimmum-ionizing (MeV)"),20.0}; fhicl::Atom curlRatio{ Name("CurlRatio"), Comment("Maximum bend radius to straw radius ratio to consider a particle a curler"),1.0}; fhicl::Atom lineRatio{ Name("LineRatio"), - Comment("Minimum bend radius to straw radius ratio to consider a particle path a line"),10.0}; + Comment("Minimum bend radius to straw radius ratio to consider a particle path a line (mm)"),10.0}; fhicl::Atom csize{ Name("OutputCollectionSize"), Comment("Estimated size of output collection"), 2000}; fhicl::Atom trackerSteps { Name("trackerStepPoints"), @@ -102,7 +104,7 @@ namespace mu2e { int _debug, _diag; bool _combineDeltas, _allAssns; float _maxDeltaLen, _radtol, _parrot, _curlrot; - float _minionBG; + float _minionBG, _minionKE; float _curlfac, _linefac; float _curlmom, _linemom; unsigned _csize, _ssize; @@ -135,6 +137,7 @@ namespace mu2e { _parrot(config().parabolicRotation()), _curlrot(config().curlRotation()), _minionBG(config().minionBG()), + _minionKE(config().minionKE()), _curlfac(config().curlRatio()), _linefac(config().lineRatio()), _csize(config().csize()), @@ -540,8 +543,9 @@ namespace mu2e { else shape = StrawGasStep::StepType::line; double mass = pdata->mass(); - double bg = mom/mass; // beta x gamma - if(bg > _minionBG) + double bg = mom/mass; // betagamma + double ke = sqrt(mom*mom + mass*mass)-mass; // kinetic energy + if(bg > _minionBG && ke > _minionKE) itype =StrawGasStep::StepType::minion; else itype =StrawGasStep::StepType::highion; diff --git a/TrackerMC/src/StrawCluster.cc b/TrackerMC/src/StrawCluster.cc index 93a8bd6974..fe7a0bd34d 100644 --- a/TrackerMC/src/StrawCluster.cc +++ b/TrackerMC/src/StrawCluster.cc @@ -10,21 +10,19 @@ using namespace std; namespace mu2e { namespace TrackerMC { - StrawCluster::StrawCluster() : _type(unknown), _strawId(0), _end(StrawEnd::cal), _time(0.0), _charge(0.0), _ddist(0.0),_phi(0.0), _wdist(0.0), _drifttime(0.0), _proptime(0.0) + StrawCluster::StrawCluster() : _type(unknown), _strawId(0), _end(StrawEnd::cal), _time(0.0), _charge(0.0), _drifttime(0.0), _proptime(0.0) {} StrawCluster::StrawCluster(ClusterType type,StrawId sid, StrawEnd end, float time, float charge, - float ddist, - float phi, - float wdist, + StrawPosition const& pos, float drifttime, float proptime, art::Ptr const& sgsptr, - XYZVec const& cpos, float ctime) : _type(type), _strawId(sid), _end(end), _time(time), - _charge(charge), _ddist(ddist), _phi(phi),_wdist(wdist), _drifttime(drifttime), _proptime(proptime), _sgsptr(sgsptr), _cpos(cpos), _ctime(ctime) {} + float ctime) : _type(type), _strawId(sid), _end(end), _time(time), + _charge(charge), _pos(pos), _drifttime(drifttime), _proptime(proptime), _sgsptr(sgsptr), _ctime(ctime) {} // delegating constructors in C++11! StrawCluster::StrawCluster(const StrawCluster& primary, StrawId const& id, float xfactor) : @@ -44,9 +42,9 @@ namespace mu2e { << " end " << _end << " time " << _time << " charge " << _charge - << " drift distance " << _ddist - << " phi " << _phi - << " wire propagation distance " << _wdist + << " drift distance " << _pos.Rho() + << " phi " << _pos.Phi() + << " wire propagation distance " << _pos.Z() << *_sgsptr << std::endl; } } diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc index 5af53e18bc..8cd2e3eb1a 100644 --- a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -42,6 +42,7 @@ #include "TrackerMC/inc/StrawClusterSequencePair.hh" #include "TrackerMC/inc/StrawWaveform.hh" #include "TrackerMC/inc/IonCluster.hh" +#include "TrackerMC/inc/StrawPosition.hh" //CLHEP #include "CLHEP/Random/RandGaussQ.h" #include "CLHEP/Random/RandFlat.h" @@ -70,10 +71,7 @@ namespace mu2e { struct WireCharge { // charge at the wire after drift float _charge; // charge at the wire, in units of pC float _time; // relative time at the wire, relative to ionzation time (ns) - float _dd; // transverse distance drifted to the wrie - float _phi; // angle between E and B at ionization event - float _wpos; // position long the wire, WRT the wire center, signed by the wire direction - + StrawPosition _pos; // cylindrical coordinates WRT straw }; struct WireEndCharge { // charge at one end of the wire after propagation @@ -96,7 +94,9 @@ namespace mu2e { fhicl::Atom minnxinghist{ Name("MinNXingHist"), Comment("Minimum # of crossings to histogram waveform"),1}; fhicl::Atom tstep { Name("WaveformStep"), Comment("WaveformStep (nsec)"),0.1 }; fhicl::Atom nfall{ Name("WaveformTail"), Comment("# of decay lambda past last signal to record waveform"),10.0}; + fhicl::Atom maxnclu{ Name("MaxNClusters"), Comment("Maximum number of clusters for non-minion steps"), 10}; fhicl::Atom addXtalk{ Name("addCrossTalk"), Comment("Should we add cross talk hits?"),false }; + fhicl::Atom drift1e{ Name("DriftSingleElectrons"), Comment("Always drift single electrons"),false }; fhicl::Atom ctMinCharge{ Name("xtalkMinimumCharge"), Comment("minimum charge to add cross talk (for performance issues)") ,0}; fhicl::Atom addNoise{ Name("addNoise"), Comment("should we add noise hits? NOT CURRENTLY IMPLEMENTED FIXME!"),false }; fhicl::Atom preampxtalk{ Name("preAmplificationCrossTalk"), Comment("Pre-amplification (straw) X-talk coupling"), 0.0 }; @@ -141,7 +141,7 @@ namespace mu2e { unsigned _minnxinghist; double _tstep, _nfall; // Parameters - bool _addXtalk; + bool _addXtalk, _drift1e; double _ctMinCharge; bool _addNoise; double _preampxtalk, _postampxtalk;// these should come from conditions, FIXME!! @@ -155,8 +155,8 @@ namespace mu2e { double _tdcbuf; uint16_t _allStraw; std::vector _allPlanes; - StrawElectronics::Path _diagpath; unsigned _maxnclu; + StrawElectronics::Path _diagpath; // Random number distributions art::RandomNumberGenerator::base_engine_t& _engine; CLHEP::RandGaussQ _randgauss; @@ -177,7 +177,7 @@ namespace mu2e { Int_t _swplane, _swpanel, _swlayer, _swstraw, _ndigi; Float_t _hqsum[2], _vmax[2], _tvmax[2], _sesum[2]; Int_t _wmcpdg[2], _wmcproc[2], _nxing[2], _nclu[2]; - Int_t _nsteppoint[2], _npart[2]; + Int_t _ngasstep[2], _npart[2]; Float_t _mce[2], _slen[2], _sedep[2]; Float_t _tmin[2], _tmax[2], _txing[2], _xddist[2], _xwdist[2], _xpdist[2]; TTree* _sddiag; @@ -228,17 +228,19 @@ namespace mu2e { void findThresholdCrossings(StrawElectronics const& strawele, SWFP const& swfp, WFXPList& xings); void createDigis(StrawPhysics const& strawphys, StrawElectronics const& strawele, + Tracker const& tracker, StrawClusterSequencePair const& hsp, XTalk const& xtalk, StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis); void fillDigis(StrawPhysics const& strawphys, StrawElectronics const& strawele, + Tracker const& tracker, WFXPList const& xings,SWFP const& swfp , StrawId sid, StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis); bool createDigi(StrawElectronics const& strawele,WFXP const& xpair, SWFP const& wf, StrawId sid, StrawDigiCollection* digis); void findCrossTalkStraws(Straw const& straw,vector& xtalk); void fillClusterNe(StrawPhysics const& strawphys,std::vector& me); - void fillClusterPositions(StrawGasStep const& step, std::vector& cpos); + void fillClusterPositions(StrawGasStep const& step, Straw const& straw, std::vector& cpos); void fillClusterMinion(StrawPhysics const& strawphys, StrawGasStep const& step, std::vector& me, std::vector& cen); bool readAll(StrawId const& sid) const; // diagnostic functions @@ -248,7 +250,8 @@ namespace mu2e { SWFP const& wf, WFXPList const& xings); void digiDiag(StrawPhysics const& strawphys, SWFP const& wf, WFXP const& xpair, StrawDigi const& digi,StrawDigiMC const& mcdigi); void stepDiag(StrawPhysics const& strawphys, StrawElectronics const& strawele, StrawGasStep const& sgs); - float EBAngle(XYZVec const& cpos,Straw const& straw) const; + StrawPosition strawPosition( XYZVec const& cpos,Straw const& straw) const; + XYZVec strawPosition( StrawPosition const& cpos, Straw const& straw) const; }; StrawDigisFromStrawGasSteps::StrawDigisFromStrawGasSteps(const Parameters& config) : @@ -262,6 +265,7 @@ namespace mu2e { _tstep(config().tstep()), _nfall(config().nfall()), _addXtalk(config().addXtalk()), + _drift1e(config().drift1e()), _ctMinCharge(config().ctMinCharge()), _addNoise(config().addNoise()), _preampxtalk(config().preampxtalk()), @@ -273,6 +277,7 @@ namespace mu2e { _tdcbuf(config().tdcbuf()), _allStraw(config().allStraw()), _allPlanes(config().allPlanes()), + _maxnclu(config().maxnclu()), _diagpath(static_cast(config().diagpath())), // Random number distributions _engine(createEngine( art::ServiceHandle()->getSeed())), @@ -330,7 +335,7 @@ namespace mu2e { _swdiag->Branch("sedep",&_sedep,"sedepcal/F:sedephv/F"); _swdiag->Branch("nxing",&_nxing,"nxingcal/I:nxinghv/I"); _swdiag->Branch("nclust",&_nclu,"nclucal/I:ncluhv/I"); - _swdiag->Branch("nstep",&_nsteppoint,"nscal/I:nshv/I"); + _swdiag->Branch("nstep",&_ngasstep,"nscal/I:nshv/I"); _swdiag->Branch("sesum",&_sesum,"sesumcal/F:sesumhv/F"); _swdiag->Branch("npart",&_npart,"npart/I"); _swdiag->Branch("tmin",&_tmin,"tmincal/F:tminhv/F"); @@ -430,7 +435,7 @@ namespace mu2e { StrawClusterSequencePair const& hsp = ihsp->second; // create primary digis from this clust sequence XTalk self(hsp.strawId()); // this object represents the straws coupling to itself, ie 100% - createDigis(strawphys,strawele,hsp,self,digis.get(),mcdigis.get()); + createDigis(strawphys,strawele,tracker,hsp,self,digis.get(),mcdigis.get()); // if we're applying x-talk, look for nearby coupled straws if(_addXtalk) { // only apply if the charge is above a threshold @@ -443,7 +448,7 @@ namespace mu2e { Straw const& straw = tracker.getStraw(hsp.strawId()); findCrossTalkStraws(straw,xtalk); for(auto ixtalk=xtalk.begin();ixtalk!=xtalk.end();++ixtalk){ - createDigis(strawphys,strawele,hsp,*ixtalk,digis.get(),mcdigis.get()); + createDigis(strawphys,strawele,tracker,hsp,*ixtalk,digis.get(),mcdigis.get()); } } } @@ -461,6 +466,7 @@ namespace mu2e { void StrawDigisFromStrawGasSteps::createDigis( StrawPhysics const& strawphys, StrawElectronics const& strawele, + Tracker const& tracker, StrawClusterSequencePair const& hsp, XTalk const& xtalk, StrawDigiCollection* digis, StrawDigiMCCollection* mcdigis) { @@ -472,7 +478,7 @@ namespace mu2e { // find the threshold crossings findThresholdCrossings(strawele,waveforms,xings); // convert the crossing points into digis, and add them to the event data - fillDigis(strawphys,strawele,xings,waveforms,xtalk._dest,digis,mcdigis); + fillDigis(strawphys,strawele,tracker,xings,waveforms,xtalk._dest,digis,mcdigis); } void StrawDigisFromStrawGasSteps::fillClusterMap(StrawPhysics const& strawphys, @@ -544,7 +550,7 @@ namespace mu2e { // compute the time the signal arrives at the wire end double gtime = ctime + wireq._time + weq._time; // create the clust - StrawCluster clust(StrawCluster::primary,sid,end,(float)gtime,weq._charge,wireq._dd,wireq._phi,weq._wdist,(float)wireq._time,(float)weq._time,sgsptr,iclu->_pos,(float)ctime); + StrawCluster clust(StrawCluster::primary,sid,end,(float)gtime,weq._charge,wireq._pos,(float)wireq._time,(float)weq._time,sgsptr,(float)ctime); // add the clusts to the appropriate sequence. shsp.clustSequence(end).insert(clust); // if required, add a 'ghost' copy of this clust @@ -565,12 +571,16 @@ namespace mu2e { float cen = sgs.ionizingEdep(); float fne = cen/strawphys.meanElectronEnergy(); unsigned ne = std::max( static_cast(_randP(fne)),(unsigned)1); - float phi = EBAngle(sgs.startPosition(),straw); - for (size_t i=0;i(floor(sgs.ionizingEdep()/strawphys.ionizationEnergy((unsigned)1)))); // generate random positions for the clusters - std::vector cposv(nc); - fillClusterPositions(sgs,cposv); + std::vector cposv(nc); + fillClusterPositions(sgs,straw,cposv); // generate electron counts and energies for these clusters: minion model is more detailed std::vector ne(nc); std::vector cen(nc); @@ -600,11 +610,15 @@ namespace mu2e { // create the cluster objects for(unsigned ic=0;ic& cposv) { + void StrawDigisFromStrawGasSteps::fillClusterPositions(StrawGasStep const& sgs, Straw const& straw, std::vector& cposv) { // generate a random position between the start and end points. Also smear perp to the path by the width XYZVec path = sgs.endPosition() - sgs.startPosition(); for(auto& cpos : cposv) { // add width effects FIXME! - cpos = Geom::Hep3Vec(sgs.startPosition() + _randflat.fire(1.0)*path); + cpos = strawPosition(sgs.startPosition() + _randflat.fire(1.0)*path,straw); } } @@ -967,7 +976,7 @@ namespace mu2e { } } } - _nsteppoint[iend] = steps.size(); + _ngasstep[iend] = steps.size(); _npart[iend] = parts.size(); _sesum[iend] = 0.0; for(auto istep=steps.begin();istep!=steps.end();++istep) @@ -1037,7 +1046,7 @@ namespace mu2e { _ddist[iend] = xpair[iend]._iclust->driftDistance(); _dtime[iend] = xpair[iend]._iclust->driftTime(); _ptime[iend] = xpair[iend]._iclust->propTime(); - _phi[iend] = xpair[iend]._iclust->phi(); + _phi[iend] = xpair[iend]._iclust->driftPhi(); _wdist[iend] = xpair[iend]._iclust->wireDistance(); _vstart[iend] = xpair[iend]._vstart; _vcross[iend] = xpair[iend]._vcross; @@ -1085,7 +1094,8 @@ namespace mu2e { TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), Geom::Hep3Vec(sgs.startPosition()), Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()) ); _mcdca = pca.dca(); - _mcdcaphi = EBAngle(Geom::toXYZVec(pca.point2()),straw); + auto spos = strawPosition(Geom::toXYZVec(pca.point2()),straw); + _mcdcaphi = spos.Phi(); _mcdcadtime = strawphys.driftDistanceToTime(_mcdca,_mcdcaphi); _dmcmom = sqrt(sgs.momentum().mag2()); auto const& sp = *sgs.simParticle(); @@ -1127,13 +1137,27 @@ namespace mu2e { _sdiag->Fill(); } - float StrawDigisFromStrawGasSteps::EBAngle(XYZVec const& cpos,Straw const& straw) const { - // this assumes E points along the radial direction and B along Z FIXME! + StrawPosition StrawDigisFromStrawGasSteps::strawPosition( XYZVec const& cpos,Straw const& straw) const { + // first calculate the angle XYZVec smid = Geom::toXYZVec(straw.getMidPoint()); XYZVec sdir = Geom::toXYZVec(straw.getDirection()); XYZVec cdir = cpos - smid; - cdir -= sdir*(cdir.Dot(sdir)); - return cdir.theta(); + float dw = cdir.Dot(sdir); + cdir -= sdir*dw; + float phi = cdir.theta(); + float rho = min(sqrt(cdir.mag2()),(float)straw.innerRadius()); + return StrawPosition(rho,dw,phi); + } + + XYZVec StrawDigisFromStrawGasSteps::strawPosition( StrawPosition const& cpos, Straw const& straw) const { + static XYZVec zdir(0.0,0.0,1.0); + XYZVec smid = Geom::toXYZVec(straw.getMidPoint()); + XYZVec sdir = Geom::toXYZVec(straw.getDirection()); + XYZVec pdir = sdir.Cross(zdir); + if(pdir.Dot(smid) < 0.0)pdir *= -1.0; // sign radially outwards + XYZVec cdir = cos(cpos.Phi())*zdir + sin(cpos.Phi())*pdir; + XYZVec retval = smid + cpos.Z()*sdir + cpos.Rho()*cdir; + return retval; } } // end namespace trackermc diff --git a/TrackerMC/src/classes_def.xml b/TrackerMC/src/classes_def.xml index 931119d603..175d7c6543 100644 --- a/TrackerMC/src/classes_def.xml +++ b/TrackerMC/src/classes_def.xml @@ -1,4 +1,4 @@ - - + + diff --git a/Trigger/src/ReadTriggerInfo_module.cc b/Trigger/src/ReadTriggerInfo_module.cc index 4157eb7f55..c888398efb 100644 --- a/Trigger/src/ReadTriggerInfo_module.cc +++ b/Trigger/src/ReadTriggerInfo_module.cc @@ -908,10 +908,10 @@ namespace mu2e { const mu2e::StrawGasStep* step(0); const mu2e::StrawDigiMC* sdmc = &_mcdigis->at(loc); if (sdmc->wireEndTime(mu2e::StrawEnd::cal) < sdmc->wireEndTime(mu2e::StrawEnd::hv)) { - step = sdmc->stepPointMC(mu2e::StrawEnd::cal).get(); + step = sdmc->strawGasStep(mu2e::StrawEnd::cal).get(); } else { - step = sdmc->stepPointMC(mu2e::StrawEnd::hv ).get(); + step = sdmc->strawGasStep(mu2e::StrawEnd::hv ).get(); } if (step) { @@ -1027,7 +1027,7 @@ namespace mu2e { for (size_t k=0; kat(shids[k]); - auto const& spmcp = sdmc->earlyStepPointMC(); + auto const& spmcp = sdmc->earlyStrawGasStep(); art::Ptr const& simptr = spmcp->simParticle(); int sim_id = simptr->id().asInt(); float dz = spmcp->position().z();// - trackerZ0; @@ -1055,7 +1055,7 @@ namespace mu2e { //finally, get the info of the first StrawDigi const mu2e::StrawDigiMC* sdmc = &_mcdigis->at(mostvalueindex); - auto const& spmcp = sdmc->earlyStepPointMC(); + auto const& spmcp = sdmc->earlyStrawGasStep(); art::Ptr const& simptr = spmcp->simParticle(); int pdg = simptr->pdgId(); art::Ptr mother = simptr; diff --git a/TrkDiag/src/BkgDiag_module.cc b/TrkDiag/src/BkgDiag_module.cc index fe971c237d..c0dd531a20 100644 --- a/TrkDiag/src/BkgDiag_module.cc +++ b/TrkDiag/src/BkgDiag_module.cc @@ -464,7 +464,7 @@ namespace mu2e for(auto id : dids) { StrawDigiMC const& mcdigi = _mcdigis->at(id); // use TDC channel 0 to define the MC match - auto const& spmcp = mcdigi.earlyStepPointMC(); + auto const& spmcp = mcdigi.earlyStrawGasStep(); art::Ptr const& spp = spmcp->simParticle(); if(spp == pptr){ diff --git a/TrkDiag/src/ComboHitDiag_module.cc b/TrkDiag/src/ComboHitDiag_module.cc index 417c8ac889..8f428d1953 100644 --- a/TrkDiag/src/ComboHitDiag_module.cc +++ b/TrkDiag/src/ComboHitDiag_module.cc @@ -236,7 +236,7 @@ namespace mu2e throw cet::exception("DIAG")<<"mu2e::ComboHitDiag: invalid ComboHit" << std::endl; // use the 1st hit to define the MC match; this is arbitrary should be an average FIXME! StrawDigiMC const& mcd1 = _mcdigis->at(shids[0]); - auto const& spmcp = mcd1.stepPointMC(StrawEnd::cal); + auto const& spmcp = mcd1.strawGasStep(StrawEnd::cal); art::Ptr spp = spmcp->simParticle(); _mctime = _toff.timeWithOffsetsApplied(*spmcp); _mcpdg = spp->pdgId(); diff --git a/TrkDiag/src/HelixDiag_module.cc b/TrkDiag/src/HelixDiag_module.cc index ea54d416ac..41dbcacf3f 100644 --- a/TrkDiag/src/HelixDiag_module.cc +++ b/TrkDiag/src/HelixDiag_module.cc @@ -786,7 +786,7 @@ namespace mu2e { } else { // no vd steps: try to fill from the tracker StepPoints for(auto imcd = _mcdigis->begin();imcd != _mcdigis->end(); ++imcd){ - auto const& stepptr = imcd->stepPointMC(imcd->earlyEnd()); + auto const& stepptr = imcd->strawGasStep(imcd->earlyEnd()); if(stepptr->simParticle() == pspp){ mom = Geom::Hep3Vec(stepptr->momentum()); pos = stepptr->position(); diff --git a/TrkDiag/src/KalDiag.cc b/TrkDiag/src/KalDiag.cc index 3b225a9f02..b2e4e9022a 100644 --- a/TrkDiag/src/KalDiag.cc +++ b/TrkDiag/src/KalDiag.cc @@ -322,7 +322,7 @@ namespace mu2e // loop over the hits and find the associated steppoints if(tsh != 0 && tsh->isActive()){ StrawDigiMC const& mcdigi = _mcdata._mcdigis->at(tsh->index()); - art::Ptr spp = mcdigi.earlyStepPointMC()->simParticle(); + art::Ptr spp = mcdigi.earlyStrawGasStep()->simParticle(); // see if this particle has already been found; if so, increment, if not, add it bool found(false); for(size_t isp=0;isp const& pspp, StrawDigiMC const& mcdigi,Straw const& straw, TrkStrawHitInfoMC& tshinfomc) const { - auto const& spmcp = mcdigi.earlyStepPointMC(); + auto const& spmcp = mcdigi.earlyStrawGasStep(); art::Ptr const& spp = spmcp->simParticle(); // create MC info and fill tshinfomc._t0 = _toff.timeWithOffsetsApplied(*spmcp); @@ -517,7 +517,7 @@ namespace mu2e const TrkStrawHit* tsh = *ihit; if(tsh != 0){ StrawDigiMC const& mcdigi = _mcdata._mcdigis->at(tsh->index()); - auto const& spmcp = mcdigi.earlyStepPointMC(); + auto const& spmcp = mcdigi.earlyStrawGasStep(); if(spp == spmcp->simParticle()){ ++mcinfo._nhits; // easiest way to get MC ambiguity is through info object @@ -536,9 +536,9 @@ namespace mu2e // count the # of tracker hits (digis) generated by this particle mcinfo._ndigi = mcinfo._ndigigood = 0; for(auto imcd = _mcdata._mcdigis->begin(); imcd !=_mcdata._mcdigis->end();++imcd){ - if( imcd->stepPointMC(StrawEnd::cal)->simParticle() == spp){ + if( imcd->strawGasStep(StrawEnd::cal)->simParticle() == spp){ mcinfo._ndigi++; - if(sqrt(imcd->stepPointMC(StrawEnd::cal)->momentum().mag2())/mcmom > _mingood) + if(sqrt(imcd->strawGasStep(StrawEnd::cal)->momentum().mag2())/mcmom > _mingood) mcinfo._ndigigood++; } } @@ -719,7 +719,7 @@ namespace mu2e unsigned nstrs = mcData()._mcdigis->size(); for(unsigned istr=0; istrat(istr); - auto const& spmcp = mcdigi.earlyStepPointMC(); + auto const& spmcp = mcdigi.earlyStrawGasStep(); art::Ptr const& spp = spmcp->simParticle(); bool conversion = (spp->genParticle().isNonnull() && spp->genParticle()->generatorId().isConversion() && sqrt(spmcp->momentum().mag2())>90.0); if(conversion){ diff --git a/TrkDiag/src/StrawHitDiag_module.cc b/TrkDiag/src/StrawHitDiag_module.cc index b3f4e72a11..23dab02978 100644 --- a/TrkDiag/src/StrawHitDiag_module.cc +++ b/TrkDiag/src/StrawHitDiag_module.cc @@ -302,7 +302,7 @@ namespace mu2e StrawDigiMC const& mcdigi = _mcdigis->at(istr); // use TDC channel 0 to define the MC match StrawEnd itdc; - auto const& spmcp = mcdigi.stepPointMC(itdc); + auto const& spmcp = mcdigi.strawGasStep(itdc); art::Ptr const& spp = spmcp->simParticle(); SimParticle const& osp = spp->originParticle(); Hep3Vector dprod = spmcp->position()-det->toDetector(osp.startPosition()); diff --git a/TrkDiag/src/TimeClusterDiag_module.cc b/TrkDiag/src/TimeClusterDiag_module.cc index 788e8131a0..d400eac956 100644 --- a/TrkDiag/src/TimeClusterDiag_module.cc +++ b/TrkDiag/src/TimeClusterDiag_module.cc @@ -391,8 +391,8 @@ art::Ptr const& primary, art::Event const& evt); _chcol->fillStrawDigiIndices(event,ich,shids); StrawDigiMC const& mcdigi = _mcdigis->at(shids[0]);// FIXME! StrawEnd itdc; - tchi._mctime = _toff.timeWithOffsetsApplied( *mcdigi.stepPointMC(itdc)); - tchi._mcmom = sqrt(mcdigi.stepPointMC(itdc)->momentum().mag2()); + tchi._mctime = _toff.timeWithOffsetsApplied( *mcdigi.strawGasStep(itdc)); + tchi._mcmom = sqrt(mcdigi.strawGasStep(itdc)->momentum().mag2()); art::Ptr sp = mcdigi.earlyStrawGasStep()->simParticle(); tchi._mcpdg = sp->pdgId(); tchi._mcproc = sp->creationCode(); diff --git a/TrkDiag/src/TrkMCTools.cc b/TrkDiag/src/TrkMCTools.cc index d24eaf9b7e..30220366a4 100644 --- a/TrkDiag/src/TrkMCTools.cc +++ b/TrkDiag/src/TrkMCTools.cc @@ -24,7 +24,7 @@ namespace mu2e { bool CEDigi(StrawDigiMC const& mcdigi) { bool conversion(false); - auto const& spmcp = mcdigi.earlyStepPointMC(); + auto const& spmcp = mcdigi.earlyStrawGasStep(); art::Ptr const& spp = spmcp->simParticle(); int gid(-1); if(spp->genParticle().isNonnull()) diff --git a/TrkDiag/src/TrkRecoDiag_module.cc b/TrkDiag/src/TrkRecoDiag_module.cc index 09c01e5cdc..c2c1dbd26c 100644 --- a/TrkDiag/src/TrkRecoDiag_module.cc +++ b/TrkDiag/src/TrkRecoDiag_module.cc @@ -612,13 +612,13 @@ namespace mu2e { MCRelationship mcrel; SPP sp; for(auto mcd : *_mcdigis) { - MCRelationship prel(psp,mcd.earlyStepPointMC()->simParticle()); + MCRelationship prel(psp,mcd.earlyStrawGasStep()->simParticle()); if(prel == mcrel) count++; else if(prel > mcrel){ mcrel = prel; count = 1; - sp = mcd.earlyStepPointMC()->simParticle(); + sp = mcd.earlyStrawGasStep()->simParticle(); } } if(count > nprimary){ diff --git a/TrkReco/src/TrkRecoMcUtils_tool.cc b/TrkReco/src/TrkRecoMcUtils_tool.cc index 60fb5376bc..220ab09a61 100644 --- a/TrkReco/src/TrkRecoMcUtils_tool.cc +++ b/TrkReco/src/TrkRecoMcUtils_tool.cc @@ -116,7 +116,7 @@ namespace mu2e { //----------------------------------------------------------------------------- int TrkRecoMcUtils::strawHitSimId(const art::Event* Event, int HitIndex) { if (Event->event() != _lastEvent) initEvent(Event); - return (*_mcdigis)[HitIndex].earlyStepPointMC()->simParticle()->id().asInt(); + return (*_mcdigis)[HitIndex].earlyStrawGasStep()->simParticle()->id().asInt(); } //----------------------------------------------------------------------------- // find MC truth DOCA in a given straw @@ -136,7 +136,7 @@ namespace mu2e { int hitIndex = ch-&_chColl->at(0); - auto const& step = (*_mcdigis)[hitIndex].earlyStepPointMC(); + auto const& step = (*_mcdigis)[hitIndex].earlyStrawGasStep(); CLHEP::Hep3Vector v2 = step->position(); HepPoint p2(v2.x(),v2.y(),v2.z()); @@ -217,7 +217,7 @@ namespace mu2e { if (Event->event() != _lastEvent) initEvent(Event); - return (*_mcdigis)[HitIndex].earlyStepPointMC()->simParticle().get(); + return (*_mcdigis)[HitIndex].earlyStrawGasStep()->simParticle().get(); } //----------------------------------------------------------------------------- diff --git a/Validation/src/ValStrawDigiMC.cc b/Validation/src/ValStrawDigiMC.cc index ee1b286641..0c1944856c 100644 --- a/Validation/src/ValStrawDigiMC.cc +++ b/Validation/src/ValStrawDigiMC.cc @@ -31,14 +31,14 @@ int mu2e::ValStrawDigiMC::fill(const mu2e::StrawDigiMCCollection & coll, // check the Ptr's. If the products are not there, the accessors can crash bool ptrOK = true; - auto const& a0 = sd.stepPointMC(StrawEnd::cal); - auto const& a1 = sd.stepPointMC(StrawEnd::hv); + auto const& a0 = sd.strawGasStep(StrawEnd::cal); + auto const& a1 = sd.strawGasStep(StrawEnd::hv); if(!(a0.isAvailable() && a1.isAvailable()) ) ptrOK = false; double ns = 0.0; - if(sd.stepPointMC(StrawEnd::cal).isAvailable()) ns++; - if(sd.stepPointMC(StrawEnd::hv).isAvailable()) ns++; + if(sd.strawGasStep(StrawEnd::cal).isAvailable()) ns++; + if(sd.strawGasStep(StrawEnd::hv).isAvailable()) ns++; _hgStep->Fill(ns); if(ptrOK) { From 534affb05f0f92b5be2c1bda0d6539647b74b21e Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Fri, 15 Nov 2019 18:32:32 -0600 Subject: [PATCH 16/18] Smear cluster position by width. Other small fixes --- MCDataProducts/src/classes_def.xml | 1 + TrackerMC/inc/StrawCluster.hh | 6 +- TrackerMC/inc/StrawClusterSequence.hh | 8 +-- TrackerMC/inc/StrawWaveform.hh | 4 +- TrackerMC/src/StrawCluster.cc | 7 ++- TrackerMC/src/StrawClusterSequence.cc | 6 +- .../src/StrawDigisFromStrawGasSteps_module.cc | 56 +++++++++++++------ TrackerMC/src/StrawWaveform.cc | 4 +- 8 files changed, 58 insertions(+), 34 deletions(-) diff --git a/MCDataProducts/src/classes_def.xml b/MCDataProducts/src/classes_def.xml index 4be737baa4..1e3a596be2 100644 --- a/MCDataProducts/src/classes_def.xml +++ b/MCDataProducts/src/classes_def.xml @@ -203,6 +203,7 @@ + diff --git a/TrackerMC/inc/StrawCluster.hh b/TrackerMC/inc/StrawCluster.hh index fabc8e3d5d..c068a346d0 100644 --- a/TrackerMC/inc/StrawCluster.hh +++ b/TrackerMC/inc/StrawCluster.hh @@ -36,6 +36,7 @@ namespace mu2e { StrawEnd end, float time, float charge, + float wdist, StrawPosition const& pos, float drifttime, float proptime, @@ -48,8 +49,8 @@ namespace mu2e { StrawEnd strawEnd() const { return _end; } double time() const { return _time;} float charge() const { return _charge; } - StrawPosition const& pos() const { return _pos; } - float wireDistance() const { return _pos.Z(); } + StrawPosition const& cluPos() const { return _pos; } + float wireDistance() const { return _wdist; } float driftDistance() const { return _pos.Rho(); } float driftPhi() const { return _pos.Phi(); } float driftTime() const { return _drifttime; } @@ -64,6 +65,7 @@ namespace mu2e { StrawEnd _end; // which end of the straw float _time; // microbunch time at the wire end, in ns since EventWindowMarker, offsets and wrapping applied float _charge; // charge at the wire end, in units of pC + float _wdist; // propagation distance from cluster to the wire end StrawPosition _pos; // cluster position WRT the straw float _drifttime; // drift time to the wire float _proptime; // propagation time to the wire end diff --git a/TrackerMC/inc/StrawClusterSequence.hh b/TrackerMC/inc/StrawClusterSequence.hh index 473527f776..1390785f42 100644 --- a/TrackerMC/inc/StrawClusterSequence.hh +++ b/TrackerMC/inc/StrawClusterSequence.hh @@ -15,7 +15,7 @@ namespace mu2e { namespace TrackerMC { - typedef std::list ClusterList; + typedef std::list StrawClusterList; class StrawClusterSequence { public: // constructors @@ -25,15 +25,15 @@ namespace mu2e { StrawClusterSequence(StrawClusterSequence const& other); StrawClusterSequence& operator =(StrawClusterSequence const& other); // accessors: just hand over the list! - ClusterList const& clustList() const { return _clist; } + StrawClusterList const& clustList() const { return _clist; } // insert a new clust, in time order. - ClusterList::iterator insert(StrawCluster const& clust); + StrawClusterList::iterator insert(StrawCluster const& clust); StrawId const& strawId() const { return _strawId; } StrawEnd const& strawEnd() const { return _end; } private: StrawId _strawId; StrawEnd _end; - ClusterList _clist; // time-ordered sequence of clusts + StrawClusterList _clist; // time-ordered sequence of clusts }; } } diff --git a/TrackerMC/inc/StrawWaveform.hh b/TrackerMC/inc/StrawWaveform.hh index cd0c37e1a7..5d0e67d168 100644 --- a/TrackerMC/inc/StrawWaveform.hh +++ b/TrackerMC/inc/StrawWaveform.hh @@ -68,14 +68,14 @@ namespace mu2e { void returnCrossing(StrawElectronics const& strawele, double threshold, WFX& wfx) const; bool roughCrossing(StrawElectronics const& strawele, double threshold, WFX& wfx) const; bool fineCrossing(StrawElectronics const& strawele, double threshold, double vmax, WFX& wfx) const; - double maxLinearResponse(StrawElectronics const& strawele,ClusterList::const_iterator const& iclust) const; + double maxLinearResponse(StrawElectronics const& strawele,StrawClusterList::const_iterator const& iclust) const; }; struct WFX { // waveform crossing double _time; // time waveform crossed threhold. Note this includes noise effects double _vstart; // starting voltage, at time 0 of the referenced clust double _vcross; // crossing voltage - ClusterList::const_iterator _iclust; // iterator to clust associated with this crossing + StrawClusterList::const_iterator _iclust; // iterator to clust associated with this crossing WFX() = delete; // disallow WFX(StrawWaveform const& wf, double time) : _time(time), _vstart(0.0), _vcross(0.0), _iclust(wf.clusts().clustList().begin()) {} diff --git a/TrackerMC/src/StrawCluster.cc b/TrackerMC/src/StrawCluster.cc index fe7a0bd34d..67b0d349f1 100644 --- a/TrackerMC/src/StrawCluster.cc +++ b/TrackerMC/src/StrawCluster.cc @@ -17,12 +17,13 @@ namespace mu2e { StrawEnd end, float time, float charge, + float wdist, StrawPosition const& pos, float drifttime, float proptime, art::Ptr const& sgsptr, float ctime) : _type(type), _strawId(sid), _end(end), _time(time), - _charge(charge), _pos(pos), _drifttime(drifttime), _proptime(proptime), _sgsptr(sgsptr), _ctime(ctime) {} + _charge(charge), _wdist(wdist), _pos(pos), _drifttime(drifttime), _proptime(proptime), _sgsptr(sgsptr), _ctime(ctime) {} // delegating constructors in C++11! StrawCluster::StrawCluster(const StrawCluster& primary, StrawId const& id, float xfactor) : @@ -44,8 +45,8 @@ namespace mu2e { << " charge " << _charge << " drift distance " << _pos.Rho() << " phi " << _pos.Phi() - << " wire propagation distance " << _pos.Z() - << *_sgsptr << std::endl; + << " wire propagation distance " << _wdist + << " " << *_sgsptr << std::endl; } } } diff --git a/TrackerMC/src/StrawClusterSequence.cc b/TrackerMC/src/StrawClusterSequence.cc index 158a0703d8..db78ec51df 100644 --- a/TrackerMC/src/StrawClusterSequence.cc +++ b/TrackerMC/src/StrawClusterSequence.cc @@ -36,8 +36,8 @@ namespace mu2e { return *this; } // insert a new clust. This is the only non-trivial function - ClusterList::iterator StrawClusterSequence::insert(StrawCluster const& clust) { - ClusterList::iterator retval = _clist.end(); + StrawClusterList::iterator StrawClusterSequence::insert(StrawCluster const& clust) { + StrawClusterList::iterator retval = _clist.end(); if(clust.type() == StrawCluster::unknown){ throw cet::exception("SIM") << "mu2e::StrawClusterSequence: tried to add unknown clust type" @@ -59,7 +59,7 @@ namespace mu2e { retval = _clist.begin(); } else { // loop over the contents and insert in the correct place - ClusterList::iterator ibefore = _clist.begin(); + StrawClusterList::iterator ibefore = _clist.begin(); while(ibefore != _clist.end() && ibefore->time() < clust.time()) ++ibefore; retval = _clist.insert(ibefore,clust); diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc index 8cd2e3eb1a..ec7c6e7c1a 100644 --- a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -94,9 +94,10 @@ namespace mu2e { fhicl::Atom minnxinghist{ Name("MinNXingHist"), Comment("Minimum # of crossings to histogram waveform"),1}; fhicl::Atom tstep { Name("WaveformStep"), Comment("WaveformStep (nsec)"),0.1 }; fhicl::Atom nfall{ Name("WaveformTail"), Comment("# of decay lambda past last signal to record waveform"),10.0}; - fhicl::Atom maxnclu{ Name("MaxNClusters"), Comment("Maximum number of clusters for non-minion steps"), 10}; + fhicl::Atom maxnclu{ Name("MaxNClusters"), Comment("Maximum number of clusters for non-minion steps"), 20}; fhicl::Atom addXtalk{ Name("addCrossTalk"), Comment("Should we add cross talk hits?"),false }; fhicl::Atom drift1e{ Name("DriftSingleElectrons"), Comment("Always drift single electrons"),false }; + fhicl::Atom randrad{ Name("RandomizeRadius"), Comment("Randomize the drift by step width effects"),true }; fhicl::Atom ctMinCharge{ Name("xtalkMinimumCharge"), Comment("minimum charge to add cross talk (for performance issues)") ,0}; fhicl::Atom addNoise{ Name("addNoise"), Comment("should we add noise hits? NOT CURRENTLY IMPLEMENTED FIXME!"),false }; fhicl::Atom preampxtalk{ Name("preAmplificationCrossTalk"), Comment("Pre-amplification (straw) X-talk coupling"), 0.0 }; @@ -141,7 +142,7 @@ namespace mu2e { unsigned _minnxinghist; double _tstep, _nfall; // Parameters - bool _addXtalk, _drift1e; + bool _addXtalk, _drift1e, _randrad; double _ctMinCharge; bool _addNoise; double _preampxtalk, _postampxtalk;// these should come from conditions, FIXME!! @@ -197,7 +198,9 @@ namespace mu2e { Bool_t _xtalk; vector _adc; Int_t _tdc[2], _tot[2]; + Int_t _sdtype; TTree* _sdiag; + Float_t _sdwidth, _sdlen; Float_t _steplen, _stepE, _qsum, _esum, _eesum, _qe, _partP, _steptime; Int_t _nclust, _netot, _partPDG, _stype; vector _clusters; @@ -266,6 +269,7 @@ namespace mu2e { _nfall(config().nfall()), _addXtalk(config().addXtalk()), _drift1e(config().drift1e()), + _randrad(config().randrad()), _ctMinCharge(config().ctMinCharge()), _addNoise(config().addNoise()), _preampxtalk(config().preampxtalk()), @@ -371,6 +375,9 @@ namespace mu2e { _sddiag->Branch("iclust",&_iclust,"iclustcal/I:iclusthv/I"); _sddiag->Branch("tdc",&_tdc,"tdccal/I:tdchv/I"); _sddiag->Branch("tot",&_tot,"totcal/I:tothv/I"); + _sddiag->Branch("sdtype",&_sdtype,"sdtype/I"); + _sddiag->Branch("sdwidth",&_sdwidth,"sdwidth/F"); + _sddiag->Branch("sdlen",&_sdlen,"sdlen/F"); _sddiag->Branch("adc",&_adc); _sddiag->Branch("mctime",&_mctime,"mctime/D"); _sddiag->Branch("mcenergy",&_mcenergy,"mcenergy/F"); @@ -550,7 +557,7 @@ namespace mu2e { // compute the time the signal arrives at the wire end double gtime = ctime + wireq._time + weq._time; // create the clust - StrawCluster clust(StrawCluster::primary,sid,end,(float)gtime,weq._charge,wireq._pos,(float)wireq._time,(float)weq._time,sgsptr,(float)ctime); + StrawCluster clust(StrawCluster::primary,sid,end,(float)gtime,weq._charge,weq._wdist,wireq._pos,(float)wireq._time,(float)weq._time,sgsptr,(float)ctime); // add the clusts to the appropriate sequence. shsp.clustSequence(end).insert(clust); // if required, add a 'ghost' copy of this clust @@ -740,7 +747,7 @@ namespace mu2e { StrawCluster const& sc = *(xpair[iend]._iclust); wetime[iend] = sc.time(); ctime[iend] = sc.cluTime(); - cpos[iend] = strawPosition(sc.pos(),straw); + cpos[iend] = strawPosition(sc.cluPos(),straw); sgspa[iend] = sc.strawGasStep(); } // choose the minimum time from either end, as the ADC sums both @@ -842,11 +849,19 @@ namespace mu2e { } void StrawDigisFromStrawGasSteps::fillClusterPositions(StrawGasStep const& sgs, Straw const& straw, std::vector& cposv) { - // generate a random position between the start and end points. Also smear perp to the path by the width + // generate a random position between the start and end points. XYZVec path = sgs.endPosition() - sgs.startPosition(); for(auto& cpos : cposv) { - // add width effects FIXME! - cpos = strawPosition(sgs.startPosition() + _randflat.fire(1.0)*path,straw); + XYZVec pos = sgs.startPosition() + _randflat.fire(1.0)*path; + // randomize the position by width. This needs to be 2-d to avoid problems at the origin + if(_randrad){ + XYZVec sdir = Geom::toXYZVec(straw.getDirection()); + XYZVec p1 = path.Cross(sdir).Unit(); + XYZVec p2 = path.Cross(p1).Unit(); + pos += p1*_randgauss.fire()*sgs.width(); + pos += p2*_randgauss.fire()*sgs.width(); + } + cpos = strawPosition(pos,straw); } } @@ -914,7 +929,7 @@ namespace mu2e { _swlayer = straw.id().getLayer(); _swstraw = straw.id().getStraw(); for(size_t iend=0;iend<2; ++iend){ - ClusterList const& clusts = wfs[iend].clusts().clustList(); + StrawClusterList const& clusts = wfs[iend].clusts().clustList(); size_t nclust = clusts.size(); set steps; set parts; @@ -992,7 +1007,7 @@ namespace mu2e { static unsigned nhist(0);// maximum number of histograms per job! for(size_t iend=0;iend<2;++iend){ // step to the 1st cluster past the blanking time to avoid double-counting - ClusterList const& clist = wfs[iend].clusts().clustList(); + StrawClusterList const& clist = wfs[iend].clusts().clustList(); auto icl = clist.begin(); while(icl->time() < strawele.flashEnd()) icl++; @@ -1052,7 +1067,7 @@ namespace mu2e { _vcross[iend] = xpair[iend]._vcross; _tdc[iend] = digi.TDC(xpair[iend]._iclust->strawEnd()); _tot[iend] = digi.TOT(xpair[iend]._iclust->strawEnd()); - ClusterList const& clist = wfs[iend].clusts().clustList(); + StrawClusterList const& clist = wfs[iend].clusts().clustList(); auto ctrig = xpair[iend]._iclust; _ncludd[iend] = clist.size(); // find the earliest cluster from the same particle that triggered the crossing @@ -1087,7 +1102,7 @@ namespace mu2e { _dmcmom = -1.0; _mctime = _mcenergy = _mctrigenergy = _mcthreshenergy = _mcdca = -1000.0; _mcthreshpdg = _mcthreshproc = _mcnstep = 0; - auto const& sgsptr = xpair[0]._iclust->strawGasStep(); + auto const& sgsptr = mcdigi.earlyStrawGasStep(); auto const& sgs = *sgsptr; _mctime = sgs.time() + _toff.totalTimeOffset(sgs.simParticle()); // compute the doca for this step @@ -1105,6 +1120,9 @@ namespace mu2e { _dmcgen = sp.genParticle()->generatorId().id(); _mcthreshpdg = sp.pdgId(); _mcthreshproc = sp.creationCode(); + _sdtype= sgs.stepType()._stype; + _sdwidth= sgs.width(); + _sdlen= sgs.stepLength(); _mcenergy = mcdigi.energySum(); _mctrigenergy = mcdigi.triggerEnergySum(StrawEnd::cal); // sum the energy from the explicit trigger particle, and find it's releationship @@ -1138,14 +1156,16 @@ namespace mu2e { } StrawPosition StrawDigisFromStrawGasSteps::strawPosition( XYZVec const& cpos,Straw const& straw) const { - // first calculate the angle + static XYZVec zdir(0.0,0.0,1.0); XYZVec smid = Geom::toXYZVec(straw.getMidPoint()); + XYZVec delta = cpos - smid; // cluster position WRT straw middle XYZVec sdir = Geom::toXYZVec(straw.getDirection()); - XYZVec cdir = cpos - smid; - float dw = cdir.Dot(sdir); - cdir -= sdir*dw; - float phi = cdir.theta(); - float rho = min(sqrt(cdir.mag2()),(float)straw.innerRadius()); + XYZVec pdir = sdir.Cross(zdir); // radial direction + if(pdir.Dot(smid) < 0.0)pdir *= -1.0; // sign radially outwards + float dw = delta.Dot(sdir); + XYZVec cperp = delta - dw*sdir; // just perp part + float phi = atan2(cperp.Dot(pdir),cperp.Dot(zdir));// angle around wire WRT Z axis in range -pi,pi + float rho = min(sqrt(cperp.mag2()),(float)straw.innerRadius()); // truncate! return StrawPosition(rho,dw,phi); } @@ -1155,7 +1175,7 @@ namespace mu2e { XYZVec sdir = Geom::toXYZVec(straw.getDirection()); XYZVec pdir = sdir.Cross(zdir); if(pdir.Dot(smid) < 0.0)pdir *= -1.0; // sign radially outwards - XYZVec cdir = cos(cpos.Phi())*zdir + sin(cpos.Phi())*pdir; + XYZVec cdir = cos(cpos.Phi())*zdir + sin(cpos.Phi())*pdir; // cluster direction perp to wire XYZVec retval = smid + cpos.Z()*sdir + cpos.Rho()*cdir; return retval; } diff --git a/TrackerMC/src/StrawWaveform.cc b/TrackerMC/src/StrawWaveform.cc index 8e7fc40856..3ab8edff6a 100644 --- a/TrackerMC/src/StrawWaveform.cc +++ b/TrackerMC/src/StrawWaveform.cc @@ -139,7 +139,7 @@ namespace mu2e { return dt < timestep; } - double StrawWaveform::maxLinearResponse(StrawElectronics const& strawele,ClusterList::const_iterator const& iclust) const { + double StrawWaveform::maxLinearResponse(StrawElectronics const& strawele,StrawClusterList::const_iterator const& iclust) const { // ignore saturation effects double linresp = strawele.maxLinearResponse(_sid,StrawElectronics::thresh,iclust->wireDistance(),iclust->charge()); linresp *= (_xtalk._preamp + _xtalk._postamp); @@ -148,7 +148,7 @@ namespace mu2e { double StrawWaveform::sampleWaveform(StrawElectronics const& strawele,StrawElectronics::Path ipath,double time) const { // loop over all clusts and add their response at this time - ClusterList const& hlist = _cseq.clustList(); + StrawClusterList const& hlist = _cseq.clustList(); double linresp(0.0); auto iclust = hlist.begin(); while(iclust != hlist.end() && iclust->time()-strawele.clusterLookbackTime() < time){ From 74dc0e38672aa9bee375c41ac8223b42ea584a41 Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Sun, 17 Nov 2019 10:10:20 -0600 Subject: [PATCH 17/18] Fix bug --- Filters/src/CompressDigiMCs_module.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Filters/src/CompressDigiMCs_module.cc b/Filters/src/CompressDigiMCs_module.cc index b1c180293f..92d1241e29 100644 --- a/Filters/src/CompressDigiMCs_module.cc +++ b/Filters/src/CompressDigiMCs_module.cc @@ -271,6 +271,9 @@ void mu2e::CompressDigiMCs::produce(art::Event & event) _newStepPointMCsPID[i_instance] = event.getProductID(i_instance); _newStepPointMCGetter[i_instance] = event.productGetter(_newStepPointMCsPID[i_instance]); } + _newStrawGasSteps = std::unique_ptr(new StrawGasStepCollection); + _newStrawGasStepsPID = event.getProductID(); + _newStrawGasStepGetter = event.productGetter(_newStrawGasStepsPID); _newSimParticles = std::unique_ptr(new SimParticleCollection); _newSimParticlesPID = event.getProductID(); @@ -617,6 +620,7 @@ void mu2e::CompressDigiMCs::produce(art::Event & event) event.put(std::move(_newStepPointMCs.at(i_instance)), i_instance); } event.put(std::move(_newStrawDigiMCs)); + event.put(std::move(_newStrawGasSteps)); event.put(std::move(_newCrvDigiMCs)); event.put(std::move(_newSimParticles)); From ceac5626f9b646c5a920e9d1aa540e0284ac532d Mon Sep 17 00:00:00 2001 From: David Nathan Brown Date: Mon, 18 Nov 2019 17:17:27 -0600 Subject: [PATCH 18/18] Add missing eventmarker time in MC comparison. Fix compression --- Filters/src/CompressDigiMCs_module.cc | 8 +++++++- MCDataProducts/inc/StrawGasStep.hh | 1 + TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Filters/src/CompressDigiMCs_module.cc b/Filters/src/CompressDigiMCs_module.cc index 92d1241e29..ff7b805bb1 100644 --- a/Filters/src/CompressDigiMCs_module.cc +++ b/Filters/src/CompressDigiMCs_module.cc @@ -543,13 +543,19 @@ void mu2e::CompressDigiMCs::produce(art::Event & event) } } - // Update the StepPointMCs + // Update the StepPointMCs for (const auto& i_instance : _newStepPointMCInstances) { for (auto& i_stepPointMC : *_newStepPointMCs.at(i_instance)) { art::Ptr newSimPtr = remap.at(i_stepPointMC.simParticle()); i_stepPointMC.simParticle() = newSimPtr; } } + + // Update the StrawGasSteps + for (auto& i_strawGasStep : *_newStrawGasSteps) { + art::Ptr newSimPtr = remap.at(i_strawGasStep.simParticle()); + i_strawGasStep.simParticle() = newSimPtr; + } if (_caloClusterMCTag == "") { // Update the CaloShowerSteps diff --git a/MCDataProducts/inc/StrawGasStep.hh b/MCDataProducts/inc/StrawGasStep.hh index a414b31926..bb088ff975 100644 --- a/MCDataProducts/inc/StrawGasStep.hh +++ b/MCDataProducts/inc/StrawGasStep.hh @@ -54,6 +54,7 @@ namespace mu2e { XYZVec const& endPosition() const { return _endpos; } XYZVec const& momentum() const { return _mom; } art::Ptr const& simParticle() const { return _simp; } + art::Ptr& simParticle() { return _simp; } // legacy accessors, for compatibility with StepPointMC consumers CLHEP::Hep3Vector position() const { return Geom::Hep3Vec(_startpos); } diff --git a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc index ec7c6e7c1a..0d2f772174 100644 --- a/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc +++ b/TrackerMC/src/StrawDigisFromStrawGasSteps_module.cc @@ -1104,7 +1104,7 @@ namespace mu2e { _mcthreshpdg = _mcthreshproc = _mcnstep = 0; auto const& sgsptr = mcdigi.earlyStrawGasStep(); auto const& sgs = *sgsptr; - _mctime = sgs.time() + _toff.totalTimeOffset(sgs.simParticle()); + _mctime = sgs.time() + _toff.totalTimeOffset(sgs.simParticle()) -_ewMarkerOffset; // compute the doca for this step TwoLinePCA pca( straw.getMidPoint(), straw.getDirection(), Geom::Hep3Vec(sgs.startPosition()), Geom::Hep3Vec(sgs.endPosition()-sgs.startPosition()) );