72 #include "nurandom/RandomUtils/NuRandomService.h" 75 #include "CLHEP/Random/RandGauss.h" 150 ,
fRecombA{pset.get<
double>(
"RecombA", 0.800)}
151 ,
fRecombk{pset.get<
double>(
"Recombk", 0.0486)}
152 ,
fModBoxA{pset.get<
double>(
"ModBoxA", 0.930)}
153 ,
fModBoxB{pset.get<
double>(
"ModBoxB", 0.212)}
171 for (
int i = 0; i < 3; ++i) {
172 double driftVelocity =
173 detProp.DriftVelocity(detProp.Efield(i),
174 detProp.Temperature()) *
181 <<
"\n Temperature (K): " << detProp.Temperature()
204 energyDepositHandle_t energyDepositHandle;
211 std::unique_ptr<std::vector<sim::SimDriftedElectronCluster>>
212 SimDriftedElectronClusterCollection(
new std::vector<sim::SimDriftedElectronCluster>);
217 auto const& energyDeposits = *energyDepositHandle;
218 auto energyDepositsSize = energyDeposits.size();
223 for (
size_t edIndex = 0; edIndex < energyDepositsSize; ++edIndex) {
224 auto const& energyDeposit = energyDeposits[edIndex];
229 auto const mp = energyDeposit.MidPoint();
230 double const xyz[3] = {mp.X(), mp.Y(), mp.Z()};
235 unsigned int cryostat = 0;
236 unsigned int tpc = 0;
252 int transversecoordinate1 = 0;
253 int transversecoordinate2 = 0;
254 if (driftcoordinate == 0) {
255 transversecoordinate1 = 1;
256 transversecoordinate2 = 2;
258 else if (driftcoordinate == 1) {
259 transversecoordinate1 = 0;
260 transversecoordinate2 = 2;
262 else if (driftcoordinate == 2) {
263 transversecoordinate1 = 0;
264 transversecoordinate2 = 1;
267 if (transversecoordinate1 == transversecoordinate2)
277 if (driftsign == 1 && tpcGeo.
PlaneLocation(0)[driftcoordinate] < xyz[driftcoordinate])
279 if (driftsign == -1 && tpcGeo.
PlaneLocation(0)[driftcoordinate] > xyz[driftcoordinate])
284 double DriftDistance =
290 double posOffsetxyz[3] = {
292 auto const* SCE = lar::providerFrom<spacecharge::SpaceChargeService>();
293 if (SCE->EnableSimSpatialSCE() ==
true) {
294 posOffsets = SCE->GetPosOffsets(mp);
296 posOffsetxyz[0] = posOffsets.X();
297 posOffsetxyz[1] = posOffsets.Y();
298 posOffsetxyz[2] = posOffsets.Z();
301 double avegagetransversePos1 = 0.;
302 double avegagetransversePos2 = 0.;
304 DriftDistance += -1. * posOffsetxyz[driftcoordinate];
305 avegagetransversePos1 = xyz[transversecoordinate1] + posOffsetxyz[transversecoordinate1];
306 avegagetransversePos2 = xyz[transversecoordinate2] + posOffsetxyz[transversecoordinate2];
312 if (DriftDistance < 0.) DriftDistance = 0.;
321 TDrift = ((DriftDistance - tpcGeo.
PlanePitch(0, 1)) * fRecipDriftVel[0] +
324 const int nIonizedElectrons =
328 const double energy = energyDeposit.Energy();
332 if (nIonizedElectrons <= 0) {
335 <<
"No electrons drifted to readout, " << energy <<
" MeV lost.";
340 const double nElectrons = nIonizedElectrons * lifetimecorrection;
343 double SqrtT = std::sqrt(TDrift);
349 int nClus = (
int)std::ceil(nElectrons / electronclsize);
352 if (electronclsize < 1.0) { electronclsize = 1.0; }
353 nClus = (
int)std::ceil(nElectrons / electronclsize);
365 fnElDiff.resize(nClus, electronclsize);
369 fnElDiff.back() = nElectrons - (nClus - 1) * electronclsize;
371 for (
size_t xx = 0; xx <
fnElDiff.size(); ++xx) {
384 if (TDiffSig > 0.0) {
395 for (
size_t p = 0;
p < tpcGeo.
Nplanes(); ++
p) {
400 for (
int k = 0;
k < nClus; ++
k) {
403 double TDiff = TDrift +
fLongDiff[
k] * fRecipDriftVel[0];
407 for (
size_t ip = 0; ip <
p; ++ip) {
411 fRecipDriftVel[(tpcGeo.
Nplanes() == 2 && driftcoordinate == 0) ? ip + 2 : ip + 1];
416 auto const simTime = energyDeposit.Time();
418 SimDriftedElectronClusterCollection->emplace_back(
424 fDriftClusterPos[2]},
426 LDiffSig, TDiffSig, TDiffSig},
428 energyDeposit.TrackID());
double PlanePitch(unsigned int p1=0, unsigned int p2=1) const
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.
EDProducer(fhicl::ParameterSet const &pset)
Geometry information for a single TPC.
Detector simulation of raw signals on wires.
double fLifetimeCorr_const
std::vector< double > fTransDiff1
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
art framework interface to geometry description
std::vector< size_t > fNTPCs
double fElectronClusterSize
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
bool fStoreDriftedElectronClusters
double fLongitudinalDiffusion
double fDriftClusterPos[3]
#define DEFINE_ART_MODULE(klass)
CLHEP::RandGauss fRandGauss
Utility function for testing if Space Charge offsets are out of bounds.
Data CalculateIonizationAndScintillation(detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) const
std::vector< double > fnEnDiff
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
double fTransverseDiffusion
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
void produce(art::Event &evt) override
ISCalculationSeparate fISAlg
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
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
int fMinNumberOfElCluster
const double * PlaneLocation(unsigned int p) const
Event finding and building.
std::vector< double > fLongDiff