66 #include "art/Framework/Core/EDProducer.h"
67 #include "art/Framework/Core/ModuleMacros.h"
68 #include "art/Framework/Principal/Event.h"
69 #include "art/Framework/Principal/Handle.h"
70 #include "art/Framework/Services/Registry/ServiceHandle.h"
71 #include "fhiclcpp/ParameterSet.h"
72 #include "messagefacility/MessageLogger/MessageLogger.h"
73 #include "nurandom/RandomUtils/NuRandomService.h"
76 #include "CLHEP/Random/RandGauss.h"
144 : art::EDProducer{pset}
145 , fSimModuleLabel{pset.get<art::InputTag>(
"SimulationLabel")}
149 , fRandGauss{art::ServiceHandle<rndm::NuRandomService>{}->createEngine(*
this, pset,
"Seed")}
173 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
177 for (
int i = 0; i < 3; ++i) {
178 double driftVelocity =
185 MF_LOG_DEBUG(
"DriftElectronstoPlane")
187 <<
"\n Temperature (K): " <<
detProp.Temperature()
209 typedef art::Handle<std::vector<sim::SimEnergyDeposit>> energyDepositHandle_t;
210 energyDepositHandle_t energyDepositHandle;
217 std::unique_ptr<std::vector<sim::SimDriftedElectronCluster>>
218 SimDriftedElectronClusterCollection(
new std::vector<sim::SimDriftedElectronCluster>);
223 auto const& energyDeposits = *energyDepositHandle;
224 auto energyDepositsSize = energyDeposits.size();
227 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event);
229 for (
size_t edIndex = 0; edIndex < energyDepositsSize; ++edIndex) {
230 auto const& energyDeposit = energyDeposits[edIndex];
235 auto const mp = energyDeposit.MidPoint();
236 double const xyz[3] = {mp.X(), mp.Y(), mp.Z()};
241 unsigned int cryostat = 0;
242 unsigned int tpc = 0;
258 int transversecoordinate1 = 0;
259 int transversecoordinate2 = 0;
260 if (driftcoordinate == 0) {
261 transversecoordinate1 = 1;
262 transversecoordinate2 = 2;
264 else if (driftcoordinate == 1) {
265 transversecoordinate1 = 0;
266 transversecoordinate2 = 2;
268 else if (driftcoordinate == 2) {
269 transversecoordinate1 = 0;
270 transversecoordinate2 = 1;
273 if (transversecoordinate1 == transversecoordinate2)
283 if (driftsign == 1 && tpcGeo.
PlaneLocation(0)[driftcoordinate] < xyz[driftcoordinate])
285 if (driftsign == -1 && tpcGeo.
PlaneLocation(0)[driftcoordinate] > xyz[driftcoordinate])
290 double DriftDistance =
296 double posOffsetxyz[3] = {
298 auto const* SCE = lar::providerFrom<spacecharge::SpaceChargeService>();
299 if (SCE->EnableSimSpatialSCE() ==
true) {
300 posOffsets = SCE->GetPosOffsets(mp);
302 posOffsetxyz[0] = posOffsets.X();
303 posOffsetxyz[1] = posOffsets.Y();
304 posOffsetxyz[2] = posOffsets.Z();
307 double avegagetransversePos1 = 0.;
308 double avegagetransversePos2 = 0.;
310 DriftDistance += -1. * posOffsetxyz[driftcoordinate];
311 avegagetransversePos1 = xyz[transversecoordinate1] + posOffsetxyz[transversecoordinate1];
312 avegagetransversePos2 = xyz[transversecoordinate2] + posOffsetxyz[transversecoordinate2];
318 if (DriftDistance < 0.) DriftDistance = 0.;
327 TDrift = ((DriftDistance - tpcGeo.
PlanePitch(0, 1)) * fRecipDriftVel[0] +
330 const int nIonizedElectrons =
334 const double energy = energyDeposit.Energy();
338 if (nIonizedElectrons <= 0) {
339 MF_LOG_DEBUG(
"DriftElectronstoPlane")
341 <<
"No electrons drifted to readout, " << energy <<
" MeV lost.";
346 const double nElectrons = nIonizedElectrons * lifetimecorrection;
349 double SqrtT = std::sqrt(TDrift);
355 int nClus = (int)std::ceil(nElectrons / electronclsize);
358 if (electronclsize < 1.0) { electronclsize = 1.0; }
359 nClus = (int)std::ceil(nElectrons / electronclsize);
371 fnElDiff.resize(nClus, electronclsize);
375 fnElDiff.back() = nElectrons - (nClus - 1) * electronclsize;
377 for (
size_t xx = 0; xx <
fnElDiff.size(); ++xx) {
390 if (TDiffSig > 0.0) {
401 for (
size_t p = 0;
p < tpcGeo.
Nplanes(); ++
p) {
406 for (
int k = 0;
k < nClus; ++
k) {
409 double TDiff = TDrift +
fLongDiff[
k] * fRecipDriftVel[0];
413 for (
size_t ip = 0; ip <
p; ++ip) {
417 fRecipDriftVel[(tpcGeo.
Nplanes() == 2 && driftcoordinate == 0) ? ip + 2 : ip + 1];
422 auto const simTime = energyDeposit.Time();
424 SimDriftedElectronClusterCollection->emplace_back(
430 fDriftClusterPos[2]},
432 LDiffSig, TDiffSig, TDiffSig},
434 energyDeposit.TrackID());
createEngine fTransverseDiffusion
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
double PlanePitch(unsigned int p1=0, unsigned int p2=1) const
Utilities related to art service access.
contains objects relating to SimDriftedElectronCluster
std::vector< double > fnElDiff
bool out_of_bounds(geo::Vector_t const &offset)
unsigned int Nplanes() const
Number of planes in this tpc.
art::ServiceHandle< geo::Geometry const > fGeometry
Handle to the Geometry service.
Geometry information for a single TPC.
double fLifetimeCorr_const
std::vector< double > fTransDiff1
createEngine fElectronClusterSize
std::vector< size_t > fNTPCs
double fElectronClusterSize
bool fStoreDriftedElectronClusters
double fLongitudinalDiffusion
double fDriftClusterPos[3]
createEngine fStoreDriftedElectronClusters
CLHEP::RandGauss fRandGauss
createEngine fLongitudinalDiffusion
Utility function for testing if Space Charge offsets are out of bounds.
Data CalculateIonizationAndScintillation(detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) const
createEngine fGeVToElectrons
std::vector< double > fnEnDiff
double fTransverseDiffusion
void produce(art::Event &evt) override
ISCalculationSeparate fISAlg
createEngine fMinNumberOfElCluster
art::InputTag fSimModuleLabel
short int DetectDriftDirection() const
Returns the expected drift direction based on geometry.
contains information for a single step in the detector simulation
DriftElectronstoPlane(fhicl::ParameterSet const &pset)
std::vector< double > fTransDiff2
createEngine fUseModBoxRecomb
int fMinNumberOfElCluster
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
const double * PlaneLocation(unsigned int p) const
art framework interface to geometry description
std::vector< double > fLongDiff