12 #include "art/Framework/Core/EDProducer.h"
13 #include "art/Framework/Core/ModuleMacros.h"
14 #include "art/Framework/Principal/Event.h"
15 #include "art/Framework/Principal/Handle.h"
16 #include "art/Framework/Principal/Run.h"
17 #include "art/Framework/Principal/SubRun.h"
18 #include "art_root_io/TFileService.h"
22 #include "fhiclcpp/ParameterSet.h"
54 void produce(art::Event &
e)
override;
55 void beginRun(art::Run& run)
override;
94 produces< std::vector<sim::SimChannel> >();
95 produces< std::vector<sim::SimEnergyDeposit> >();
96 produces< std::vector<raw::Trigger> >();
97 produces< sumdata::RunData, art::InRun >();
99 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
100 fTriggerTime = clockData.TriggerTime();
103 fSimTime_v =
p.get< std::vector<double> >(
"SimTimeArray_us");
104 fY_v =
p.get< std::vector<double> >(
"YArray_cm");
105 fZ_v =
p.get< std::vector<double> >(
"ZArray_cm");
106 fNumElectrons_v =
p.get< std::vector<double> >(
"NumElectronsArray");
107 fVerbose =
p.get<
bool> (
"Verbose",
false);
109 assert( fSimTime_v.size() == fY_v.size() &&
110 fSimTime_v.size() == fZ_v.size() &&
111 fSimTime_v.size() == fNumElectrons_v.size() );
116 art::ServiceHandle<art::TFileService>
tfs;
118 fTupleTree = tfs->make<TTree>(
"simTestPulse",
"Tree by SimTestPulse_module");
125 fTupleTree->Branch(
"y_v",
"std::vector<double>",&fY_v);
126 fTupleTree->Branch(
"z_v",
"std::vector<double>",&fZ_v);
127 fTupleTree->Branch(
"e_v",
"std::vector<double>",&fNumElectrons_v);
146 art::ServiceHandle<geo::Geometry> geo;
148 std::unique_ptr<sumdata::RunData> runData(
new sumdata::RunData(geo->DetectorName()));
150 run.put(std::move(runData));
157 std::unique_ptr<std::vector<raw::Trigger> > trigger_v(
new std::vector<raw::Trigger> );
160 std::unique_ptr<std::vector<sim::SimChannel> > simch_v(
new std::vector<sim::SimChannel> );
162 std::unique_ptr<std::vector<sim::SimEnergyDeposit>> simDep_v(
new std::vector<sim::SimEnergyDeposit>);
166 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
167 art::ServiceHandle<geo::Geometry> geo;
169 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clockData);
182 for(
size_t index=0; index <
fSimTime_v.size(); ++index) {
184 int tdc =
fSimTime_v[index] / clockData.TPCClock().TickPeriod();
185 fTick_v.push_back(clockData.TPCTDC2Tick(tdc));
188 std::cout <<
"[BUFFOON!] Charge injection id " << index <<
" @ TDC=" << tdc
189 <<
" @ Y=" << fY_v[index] <<
" @ Z=" << fZ_v[index]
190 <<
" with " << fNumElectrons_v[index] <<
" electrons " << std::endl;
194 <<
" as it results in negative TDC (invalid)" << std::endl;
200 TVector3 planeCoords = planeGeo.
GetCenter();
204 chargeDepCoords =
geo::Point_t(planeCoords[0] + 1. * planeNormal[0],fY_v[index],fZ_v[index]);
207 pulse_record.
tdc = tdc;
209 pulse_record.
tick = clockData.TPCTDC2Tick(tdc);
211 double nElecADC =
detProp.ElectronsToADC() * fNumElectrons_v[index];
212 double eDeposit = 23.6 * fNumElectrons_v[index] / 1000.;
214 std::cout <<
"==> x position of plane 0: " << planeCoords[0] <<
", normal: " << planeNormal[0] <<
", nElec: " << fNumElectrons_v[index] <<
", nElecADC: " << nElecADC <<
", edep: " << eDeposit << std::endl;
215 std::cout <<
" x position of charge deposit: " << chargeDepCoords.X() << std::endl;
217 simDep_v->emplace_back(0,
218 fNumElectrons_v[index],
221 geo::Point_t(chargeDepCoords.X(),chargeDepCoords.Y()+0.001,chargeDepCoords.Z()+0.001),
222 geo::Point_t(chargeDepCoords.X(),chargeDepCoords.Y()-0.001,chargeDepCoords.Z()-0.001));
226 for(
size_t plane=0; plane<3; ++plane) {
228 double xyz[3] = {chargeDepCoords.X(),chargeDepCoords.Y(),chargeDepCoords.Z()};
230 std::cout <<
"++ Searching for nearest wire id for planeID: " << planeID <<
", xyz: " << xyz[0] <<
"," << xyz[1] <<
"," << xyz[2] << std::endl;
231 geo::WireID nearestID = geo->NearestWireID(xyz,plane);
232 std::cout <<
" WireID: " << nearestID << std::endl;
233 std::cout <<
"** Searching for nearest channel with plane: " << plane <<
", xyz: " << xyz[0] <<
"," << xyz[1] <<
"," << xyz[2] << std::endl;
234 auto channel = geo->NearestChannel(xyz,plane);
235 std::cout <<
" Returned with channel: " << channel << std::endl;
236 auto wire = geo->ChannelToWire(channel).front().Wire;
237 std::cout <<
" which gives wire: " << wire << std::endl;
238 if(fVerbose)
std::cout <<
"[BUFFOON!] plane " << plane <<
" channel "
239 << channel <<
" ... wire " << wire << std::endl;
246 std::cerr <<
"[BUFFOON!] unexpected plane! " << plane << std::endl;
247 throw std::exception();
250 unsigned planeTDC = clockData.TPCTick2TDC(pulse_record.
tick +
detProp.GetXTicksOffset(planeID) -
detProp.GetXTicksOffset(collectionPlaneID));
252 (
unsigned int)planeTDC,
253 fNumElectrons_v[index],
256 simch_v->emplace_back(std::move(sch));
258 pholder.Register(std::move(pulse_record));
266 e.put(std::move(simch_v));
267 e.put(std::move(simDep_v));
268 e.put(std::move(trigger_v));
std::vector< int > fPlane1Channel_v
Resulting plane 1 channel number where charge is deposited.
static ParamHolder & get()
Energy deposited on a readout channel by simulated tracks.
BEGIN_PROLOG could also be cerr
SimTestPulse(fhicl::ParameterSet const &p)
SimTestPulse & operator=(SimTestPulse const &)=delete
TTree * fTupleTree
output analysis tree
std::vector< double > fSimTime_v
Charge timing in electronics clock [us].
The data type to uniquely identify a Plane.
void produce(art::Event &e) override
std::vector< double > fNumElectrons_v
Charge amount in electron count.
std::vector< int > fPlane2Wire_v
Resulting plane 2 wire number where charge is deposited.
Vector GetNormalDirection() const
Returns the direction normal to the plane.
Access the description of detector geometry.
std::vector< int > fPlane0Channel_v
Resulting plane 0 channel number where charge is deposited.
std::vector< int > fPlane2Channel_v
Resulting plane 2 channel number where charge is deposited.
Point GetCenter() const
Returns the centre of the wire plane in world coordinates [cm].
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
std::vector< int > fPlane0Wire_v
Resulting plane 0 wire number where charge is deposited.
std::vector< int > fTick_v
Corresponding tick.
std::array< int, 3 > channel_list
double fTriggerTime
Trigger timing in electronics clock [us].
void beginRun(art::Run &run) override
contains information for a single step in the detector simulation
std::vector< double > fY_v
Charge Y position in detector coordinate [cm].
object containing MC truth information necessary for making RawDigits and doing back tracking ...
std::vector< int > fPlane1Wire_v
Resulting plane 1 wire number where charge is deposited.
art::ServiceHandle< art::TFileService > tfs
void AddIonizationElectrons(TrackID_t trackID, TDC_t tdc, double numberElectrons, double const *xyz, double energy, TrackID_t origTrackID=util::kBogusI)
Add ionization electrons and energy to this channel.
std::vector< double > fZ_v
Charge Z position in detector coordinate [cm].
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
art framework interface to geometry description
BEGIN_PROLOG could also be cout