Skip to content

Commit

Permalink
implement first-pass digi mixing for the tracker:
Browse files Browse the repository at this point in the history
  - extend Mu2eProductMixer to include digital data products
  - implement module for exclusively mixing in such products
  - propagate those products through to simulated StrawDigi creation
  - define structure for resolving situations where simulated digis overlap with preexisting digis in time (for now, just choosing the earliest)
  • Loading branch information
edcallaghan committed Apr 25, 2024
1 parent 15c45d3 commit 13d5837
Show file tree
Hide file tree
Showing 12 changed files with 759 additions and 7 deletions.
52 changes: 52 additions & 0 deletions CommonMC/src/ProtonBunchTimeMCFromProtonBunchTime_module.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Convert proton bunch time marker from data to MC data product
// To be used for mixing simulated signal into real data from detector
//
// Ed Callaghan, 2024

// art
#include <art/Framework/Core/EDProducer.h>
#include <art/Framework/Principal/Event.h>

// canvas
#include <canvas/Utilities/InputTag.h>

// fhiclcpp
#include <fhiclcpp/types/Atom.h>

// mu2e
#include <Offline/MCDataProducts/inc/ProtonBunchTimeMC.hh>
#include <Offline/RecoDataProducts/inc/ProtonBunchTime.hh>

namespace mu2e{
class ProtonBunchTimeMCFromProtonBunchTime: public art::EDProducer{
public:
struct Config{
fhicl::Atom<art::InputTag> pbttag{
fhicl::Name("PBTTag"),
fhicl::Comment("ProtonBunchTime provenance"),
"" // default, eventually to specify "from data"
};
};

using Parameters = art::EDProducer::Table<Config>;
explicit ProtonBunchTimeMCFromProtonBunchTime(Parameters const& config);
protected:
/**/
private:
void produce(art::Event& event) override;
art::InputTag pbttag_;
};

ProtonBunchTimeMCFromProtonBunchTime::ProtonBunchTimeMCFromProtonBunchTime(Parameters const& config): EDProducer(config), pbttag_(config().pbttag()){
this->produces<ProtonBunchTimeMC>();
}

void ProtonBunchTimeMCFromProtonBunchTime::produce(art::Event& event){
auto pbt = event.getHandle<ProtonBunchTime>(pbttag_);
std::unique_ptr<ProtonBunchTimeMC> pbtmc(new ProtonBunchTimeMC);
pbtmc->pbtime_ = pbt->pbtime_;
event.put(std::move(pbtmc));
}
}

DEFINE_ART_MODULE(mu2e::ProtonBunchTimeMCFromProtonBunchTime);
25 changes: 24 additions & 1 deletion EventMixing/inc/Mu2eProductMixer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
#include "Offline/MCDataProducts/inc/CosmicLivetime.hh"
#include "Offline/MCDataProducts/inc/SimTimeOffset.hh"
#include "Offline/MCDataProducts/inc/PhysicalVolumeInfoMultiCollection.hh"

#include "Offline/RecoDataProducts/inc/StrawDigi.hh"
#include "Offline/MCDataProducts/inc/StrawDigiMC.hh"
#include "Offline/DataProducts/inc/EventWindowMarker.hh"


//================================================================
Expand Down Expand Up @@ -102,6 +104,10 @@ namespace mu2e {
fhicl::Table<CollectionMixerConfig> crvStepMixer { fhicl::Name("crvStepMixer") };
fhicl::Table<CollectionMixerConfig> extMonSimHitMixer { fhicl::Name("extMonSimHitMixer") };
fhicl::Table<CollectionMixerConfig> eventIDMixer { fhicl::Name("eventIDMixer") };
fhicl::Table<CollectionMixerConfig> strawDigiMixer { fhicl::Name("strawDigiMixer") };
fhicl::Table<CollectionMixerConfig> strawDigiADCWaveformMixer { fhicl::Name("strawDigiADCWaveformMixer") };
fhicl::Table<CollectionMixerConfig> strawDigiMCMixer { fhicl::Name("strawDigiMCMixer") };
fhicl::Table<CollectionMixerConfig> eventWindowMarkerMixer { fhicl::Name("eventWindowMarkerMixer") };
fhicl::OptionalTable<CosmicLivetimeMixerConfig> cosmicLivetimeMixer { fhicl::Name("cosmicLivetimeMixer") };
fhicl::OptionalTable<VolumeInfoMixerConfig> volumeInfoMixer { fhicl::Name("volumeInfoMixer") };
fhicl::OptionalAtom<art::InputTag> simTimeOffset { fhicl::Name("simTimeOffset"), fhicl::Comment("Simulation time offset to apply (optional)") };
Expand Down Expand Up @@ -148,6 +154,23 @@ namespace mu2e {
ExtMonFNALSimHitCollection& out,
art::PtrRemapper const& remap);

bool mixStrawDigis(std::vector<StrawDigiCollection const*> const& in,
StrawDigiCollection& out,
art::PtrRemapper const& remap);

bool mixStrawDigiADCWaveforms(std::vector<StrawDigiADCWaveformCollection const*> const& in,
StrawDigiADCWaveformCollection& out,
art::PtrRemapper const& remap);

bool mixStrawDigiMCs(std::vector<StrawDigiMCCollection const*> const& in,
StrawDigiMCCollection& out,
art::PtrRemapper const& remap);

bool mixEventWindowMarkers(std::vector<EventWindowMarker const*> const& in,
EventWindowMarker& out,
art::PtrRemapper const& remap);


bool mixEventIDs(std::vector<art::EventIDSequence const*> const &in,
art::EventIDSequence& out,
art::PtrRemapper const& remap);
Expand Down
113 changes: 113 additions & 0 deletions EventMixing/src/MixDigis_module.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Mix digi-level data products, as opposed to simulation-level data products,
// into art events
//
// Ed Callaghan, 2023

// stl

// art
#include "art/Framework/Principal/Event.h"
#include "art/Framework/Principal/SubRun.h"
#include "art/Framework/IO/ProductMix/MixHelper.h"
#include "art/Framework/Modules/MixFilter.h"
#include "art_root_io/RootIOPolicy.h"
#include "fhiclcpp/types/Atom.h"
#include "fhiclcpp/types/Comment.h"
#include "fhiclcpp/types/Name.h"
#include "fhiclcpp/types/Sequence.h"
#include "fhiclcpp/types/Table.h"
#include "fhiclcpp/types/TupleAs.h"

// cetlib_except
#include "cetlib_except/exception.h"

// mu2e
#include "Offline/EventMixing/inc/Mu2eProductMixer.hh"

namespace mu2e{
// detail class for art::MixFilter<>
class MixDigisDetail{
public:
struct Mu2eConfig{
// configuration is simple --- which data products to mix in
fhicl::Table<Mu2eProductMixer::Config> products{
fhicl::Name("products"),
fhicl::Comment("Products to be mixed, as form of a mixingMap, i.e. tuples of InputTags to output instance names.")

};
};

struct Config{
fhicl::Table<Mu2eConfig> mu2e{ fhicl::Name("mu2e") };
};

using Parameters = art::MixFilterTable<Config>;
explicit MixDigisDetail(const Parameters& parameters,
art::MixHelper& helper);
size_t nSecondaries();

void processEventIDs(const art::EventIDSequence& seq);
void beginSubRun(const art::SubRun& subrun);
void endSubRun(art::SubRun& subrun);
void startEvent(const art::Event& event);
void finalizeEvent(art::Event& event);

protected:
/**/

private:
Mu2eProductMixer mixer;
art::EventIDSequence evids;
};

// implementation
MixDigisDetail::MixDigisDetail(const Parameters& parameters,
art::MixHelper& helper)
: mixer{parameters().mu2e().products(), helper}{
helper.produces<art::EventIDSequence>();
}

// always overlay simulated event onto one event window
size_t MixDigisDetail::nSecondaries(){
size_t rv = 1;
return rv;
}

// always keep track of secondary EventIDs
void MixDigisDetail::processEventIDs(const art::EventIDSequence& seq){
// intent is to overlay signals onto a nominally-complete event,
// so we should only mix in one event
if (seq.size() != 1){
throw cet::exception("MIX") << "mu2e::DixDigisDetail: mixing more than one digi frame" << std::endl;
}
mixer.processEventIDs(seq);
evids = seq;
}

// forward beginSubRun
void MixDigisDetail::beginSubRun(const art::SubRun& subrun){
mixer.beginSubRun(subrun);
}

// forward endSubRun
void MixDigisDetail::endSubRun(art::SubRun& subrun){
mixer.endSubRun(subrun);
}

// forward startEvent
void MixDigisDetail::startEvent(const art::Event& event){
mixer.startEvent(event);
}

void MixDigisDetail::finalizeEvent(art::Event& event){
// "manually" mix in EventIDs, as these do not preexist as data products
auto seq = std::make_unique<art::EventIDSequence>();
seq->swap(evids);
event.put(std::move(seq));
}

// define the module
typedef art::MixFilter<MixDigisDetail,art::RootIOPolicy> MixDigis;
}

DEFINE_ART_MODULE(mu2e::MixDigis);
58 changes: 58 additions & 0 deletions EventMixing/src/Mu2eProductMixer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <algorithm>
#include <iterator>
#include <iostream>
#include <string>

#include "cetlib_except/exception.h"

Expand Down Expand Up @@ -96,6 +97,26 @@ namespace mu2e {
(e.inTag, e.resolvedInstanceName(), &Mu2eProductMixer::mixEventIDs, *this);
}

for(const auto& e: conf.strawDigiMixer().mixingMap()) {
helper.declareMixOp
(e.inTag, e.resolvedInstanceName(), &Mu2eProductMixer::mixStrawDigis, *this);
}

for(const auto& e: conf.strawDigiADCWaveformMixer().mixingMap()) {
helper.declareMixOp
(e.inTag, e.resolvedInstanceName(), &Mu2eProductMixer::mixStrawDigiADCWaveforms, *this);
}

for(const auto& e: conf.strawDigiMCMixer().mixingMap()) {
helper.declareMixOp
(e.inTag, e.resolvedInstanceName(), &Mu2eProductMixer::mixStrawDigiMCs, *this);
}

for(const auto& e: conf.eventWindowMarkerMixer().mixingMap()) {
helper.declareMixOp
(e.inTag, e.resolvedInstanceName(), &Mu2eProductMixer::mixEventWindowMarkers, *this);
}

//----------------------------------------------------------------
// VolumeInfo handling

Expand Down Expand Up @@ -397,6 +418,43 @@ namespace mu2e {
return true;
}

bool Mu2eProductMixer::mixStrawDigis(std::vector<StrawDigiCollection const*> const& in,
StrawDigiCollection& out,
art::PtrRemapper const& remap)
{
art::flattenCollections(in, out);
return true;
}

bool Mu2eProductMixer::mixStrawDigiADCWaveforms(std::vector<StrawDigiADCWaveformCollection const*> const& in,
StrawDigiADCWaveformCollection& out,
art::PtrRemapper const& remap)
{
art::flattenCollections(in, out);
return true;
}

bool Mu2eProductMixer::mixStrawDigiMCs(std::vector<StrawDigiMCCollection const*> const& in,
StrawDigiMCCollection& out,
art::PtrRemapper const& remap)
{
art::flattenCollections(in, out);
return true;
}

bool Mu2eProductMixer::mixEventWindowMarkers(std::vector<EventWindowMarker const*> const& in,
EventWindowMarker& out,
art::PtrRemapper const& remap){
// assert that only one EventWindowMarker be present
if (in.size() != 1){
std::string msg = "attempting to mix more than 1 EventWindowMarker: ";
msg += std::to_string(in.size()) + " present";
throw cet::exception("BADINPUT") << msg << std::endl;
}
out = *in[0];
return true;
}

//----------------------------------------------------------------
bool Mu2eProductMixer::mixEventIDs(std::vector<art::EventIDSequence const*> const &in,
art::EventIDSequence& out,
Expand Down
8 changes: 7 additions & 1 deletion MCDataProducts/inc/StrawDigiMC.hh
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,21 @@ namespace mu2e {
typedef std::array<SGSP,StrawEnd::nends> SGSPA;
typedef std::array<XYZVectorF,StrawEnd::nends> PA;
typedef std::array<float,StrawEnd::nends> FA;
enum Validity {Valid, PartiallyValid, Invalid};

StrawDigiMC();
// construct from hitlets
StrawDigiMC(StrawId sid, PA cpos, FA ctime, FA wetime, SGSPA sgs);
StrawDigiMC(StrawId sid, PA cpos, FA ctime, FA wetime, SGSPA sgs, Validity=Valid);

// use compuater copy construcors
StrawDigiMC(const StrawDigiMC& rhs, SGSPA sgsp ); // update the Ptrs
StrawDigiMC(const StrawDigiMC& rhs, Validity validity ); // update validity

// Accessors
StrawId strawId() const { return _strawid; }

Validity validity() const { return _validity; }

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; }
Expand All @@ -68,6 +73,7 @@ namespace mu2e {
FA _ctime; // times of the trigger clusters
FA _wtime; // times at the wire ends of the signals which fired the TDC.
SGSPA _sgspa; // StrawGasStep that triggered each end
Validity _validity; // level of association with any true MC events
};

inline std::ostream& operator<<( std::ostream& ost,
Expand Down
8 changes: 7 additions & 1 deletion MCDataProducts/src/StrawDigiMC.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,22 @@ namespace mu2e {
// Default constructor is required for persistable classes
StrawDigiMC::StrawDigiMC()
: _strawid(StrawId::_invalid)
, _validity(Invalid)
{}

StrawDigiMC::StrawDigiMC(StrawId sid, PA cpos, FA ctime, FA wetime, SGSPA sgs):
StrawDigiMC::StrawDigiMC(StrawId sid, PA cpos, FA ctime, FA wetime, SGSPA sgs, Validity validity):
_strawid(sid), _cpos(cpos), _ctime(ctime), _wtime(wetime), _sgspa(sgs)
, _validity(validity)
{}

StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs, SGSPA sgspa ) : StrawDigiMC(rhs) {
_sgspa = sgspa;
}

StrawDigiMC::StrawDigiMC(const StrawDigiMC& rhs, Validity validity): StrawDigiMC(rhs){
_validity = validity;
}

bool StrawDigiMC::isCrossTalk(StrawEnd strawend) const {
bool retval(false);
if(!_sgspa[strawend].isNull()){
Expand Down
35 changes: 35 additions & 0 deletions TrackerMC/inc/StrawDigiBundle.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Bundle together references to various StrawDigi products, to circumvent
// triplicated-loops which pop up when iterating over digis
//
// Ed Callaghan, 2023

#ifndef TrackerMC_StrawDigiBundle_hh
#define TrackerMC_StrawDigiBundle_hh

// mu2e
#include <Offline/RecoDataProducts/inc/StrawDigi.hh>
#include <Offline/MCDataProducts/inc/StrawDigiMC.hh>

namespace mu2e{
class StrawDigiBundle{
public:
StrawDigiBundle(const StrawDigi digi, const StrawDigiADCWaveform adcs, const StrawDigiMC mc);
StrawDigiBundle(const StrawDigi digi, const StrawDigiADCWaveform adcs);
StrawDigiBundle(const StrawDigiBundle& bundle);

const StrawDigi GetStrawDigi() const;
const StrawDigiADCWaveform GetStrawDigiADCWaveform() const;
const StrawDigiMC GetStrawDigiMC() const;

// interface for sorting into buckets of overlapping digitization windows
const double time() const;
protected:
const StrawDigi digi;
const StrawDigiADCWaveform adcs;
const StrawDigiMC mc;
private:
/**/
};
}

#endif
Loading

0 comments on commit 13d5837

Please sign in to comment.