79 #include "CLHEP/Random/RandGauss.h" 183 produces< std::vector<sim::SimChannel> >();
209 std::string
label= p.
get< std::string >(
"SimulationLabel");
221 fTimeService = lar::providerFrom<detinfo::DetectorClocksService>();
226 CLHEP::HepRandomEngine& engine = rng->
getEngine();
227 fRandGauss = std::unique_ptr<CLHEP::RandGauss>(
new CLHEP::RandGauss(engine));
231 auto const * detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
233 for (
int i = 0; i<3; ++i) {
234 double driftVelocity = detprop->DriftVelocity(detprop->Efield(i),
235 detprop->Temperature())*1.
e-3;
248 LOG_DEBUG(
"SimDriftElectrons") <<
" e lifetime (ns): " << fElectronLifetime
249 <<
"\n Temperature (K): " << detprop->Temperature()
269 lar::providerFrom<spacecharge::SpaceChargeService>());
285 energyDepositHandle_t energyDepositHandle;
295 std::unique_ptr< std::vector<sim::SimChannel> > channels(
new std::vector<sim::SimChannel>);
297 std::unique_ptr< std::vector<sim::SimDriftedElectronCluster> > SimDriftedElectronClusterCollection(
new std::vector<sim::SimDriftedElectronCluster>);
304 cryoData.resize(
fNTPCs[cryo++]);
305 for (
auto& channelsMap: cryoData) channelsMap.clear();
311 auto const& energyDeposits = *energyDepositHandle;
312 auto energyDepositsSize = energyDeposits.size();
315 for (
size_t edIndex = 0; edIndex < energyDepositsSize; ++edIndex )
317 auto const& energyDeposit = energyDeposits[edIndex];
322 auto const mp = energyDeposit.MidPoint();
323 double const xyz[3] = { mp.X(), mp.Y(), mp.Z() };
328 unsigned int cryostat = 0;
334 <<
"cannot be found in a cryostat\n" 339 unsigned int tpc = 0;
345 <<
"cannot be found in a TPC\n" 363 double XDrift = std::abs(xyz[0] - tpcGeo.
PlaneLocation(0)[0]);
370 if(XDrift < 0.)
continue;
375 auto const* SCE = lar::providerFrom<spacecharge::SpaceChargeService>();
376 if (SCE->EnableSimSpatialSCE() ==
true)
378 posOffsets = SCE->GetPosOffsets(mp);
380 XDrift += -1.*posOffsets.X();
386 if (XDrift < 0.) XDrift = 0.;
391 TDrift = ((XDrift - tpcGeo.
PlanePitch(0,1)) * fRecipDriftVel[0]
392 + tpcGeo.
PlanePitch(0,1) * fRecipDriftVel[1]);
401 const double energy = energyDeposit.Energy();
405 if (nIonizedElectrons <= 0) {
408 <<
"No electrons drifted to readout, " << energy <<
" MeV lost.";
413 const double nElectrons = nIonizedElectrons * lifetimecorrection;
417 double SqrtT = std::sqrt(TDrift);
423 int nClus = (int) std::ceil(nElectrons / electronclsize);
427 if (electronclsize < 1.0)
429 electronclsize = 1.0;
431 nClus = (int) std::ceil(nElectrons / electronclsize);
443 fnElDiff.resize(nClus, electronclsize);
447 fnElDiff.back() = nElectrons - (nClus-1)*electronclsize;
456 double const avegageYtransversePos
457 = xyz[1] + posOffsets.Y();
458 double const avegageZtransversePos
459 = xyz[2] + posOffsets.Z();
465 fXDiff.assign(nClus, 0.0);
467 if (TDiffSig > 0.0) {
473 fYDiff.assign(nClus, avegageYtransversePos);
474 fZDiff.assign(nClus, avegageZtransversePos);
480 for(
size_t p = 0; p < tpcGeo.
Nplanes(); ++p){
492 for(
int k = 0; k < nClus; ++k){
499 double TDiff = TDrift +
fXDiff[k] * fRecipDriftVel[0];
502 for (
size_t ip = 0; ip<p; ++ip){
503 TDiff += tpcGeo.
PlanePitch(ip,ip+1) * fRecipDriftVel[tpcGeo.
Nplanes()==3?ip+1:ip+2];
536 auto const simTime = energyDeposit.Time();
540 ChannelMap_t& channelDataMap = fChannelMaps[cryostat][tpc];
541 auto search = channelDataMap.find(channel);
546 size_t channelIndex=0;
550 if (search == channelDataMap.end())
561 channels->emplace_back( channel );
571 bookKeeping.
stepList.push_back( edIndex );
574 channelDataMap[channel] = bookKeeping;
582 auto& bookKeeping = search->second;
587 auto& stepList = bookKeeping.stepList;
588 auto stepSearch = std::find(stepList.begin(), stepList.end(), edIndex );
589 if ( stepSearch == stepList.end() ) {
591 stepList.push_back( edIndex );
617 {mp.X(),mp.Y(),mp.Z()},
619 {LDiffSig,TDiffSig,TDiffSig},
621 energyDeposit.TrackID()) );
627 mf::LogWarning(
"SimDriftElectrons") <<
"unable to drift electrons from point (" 628 << xyz[0] <<
"," << xyz[1] <<
"," << xyz[2]
629 <<
") with exception " <<
e;
671 event.put(std::move(channels));
Store parameters for running LArG4.
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
Returns the center of the TPC volume in world coordinates [cm].
std::vector< double > fYDiff
std::vector< double > fnEnDiff
double fElectronClusterSize
virtual const ::detinfo::ElecClock & TPCClock() const =0
Lends a constant TPC clock with time set to trigger time.
Energy deposited on a readout channel by simulated tracks.
contains objects relating to SimDriftedElectronCluster
CryostatGeo const & PositionToCryostat(geo::Point_t const &point) const
Returns the cryostat at specified location.
unsigned int Nplanes() const
Number of planes in this tpc.
larg4::ISCalculationSeparate fISAlg
Geometry information for a single TPC.
std::vector< std::vector< ChannelMap_t > > fChannelMaps
Detector simulation of raw signals on wires.
art::ServiceHandle< geo::Geometry > fGeometry
Handle to the Geometry service.
int Ticks() const
Current clock tick (that is, the number of tick Time() falls in).
Drift towards negative X values.
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::vector< size_t > fNTPCs
std::vector< double > fXDiff
geo::TPCGeo const & PositionToTPC(geo::Point_t const &point) const
Returns the TPC at specified location.
double fLongitudinalDiffusion
base_engine_t & getEngine() const
double NumberIonizationElectrons() const
double TransverseDiffusion() const
base_engine_t & createEngine(seed_t seed)
#define DEFINE_ART_MODULE(klass)
std::vector< double > fnElDiff
double ElectronClusterSize() const
const detinfo::DetectorClocks * fTimeService
T get(std::string const &key) const
void CalculateIonizationAndScintillation(sim::SimEnergyDeposit const &edep)
std::vector< double > fZDiff
double Plane0Pitch(unsigned int p) const
Returns the center of the TPC volume in world coordinates [cm].
virtual double G4ToElecTime(double g4_time) const =0
Given a simulation time [ns], converts it into electronics time [µs].
DriftDirection_t DriftDirection() const
Returns an enumerator value describing the drift direction.
An art service to assist in the distribution of guaranteed unique seeds to all engines within an art ...
double fTransverseDiffusion
art::InputTag fSimModuleLabel
Conversion of times between different formats and references.
double fLifetimeCorr_const
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
void AddIonizationElectrons(TrackID_t trackID, TDC_t tdc, double numberElectrons, double const *xyz, double energy)
Add ionization electrons and energy to this channel.
std::map< raw::ChannelID_t, ChannelBookKeeping_t > ChannelMap_t
void produce(art::Event &evt)
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
double fDriftClusterPos[3]
Utility object to perform functions of association.
Drift towards positive X values.
int MinNumberOfElCluster() const
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
virtual ~SimDriftElectrons()
::detinfo::ElecClock fClock
TPC electronics clock.
contains information for a single step in the detector simulation
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
object containing MC truth information necessary for making RawDigits and doing back tracking ...
std::vector< size_t > stepList
std::unique_ptr< CLHEP::RandGauss > fRandGauss
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
double LongitudinalDiffusion() const
Class representing the time measured by an electronics clock.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
bool fStoreDriftedElectronClusters
raw::ChannelID_t NearestChannel(geo::Point_t const &worldLoc, geo::PlaneID const &planeid) const
Returns the ID of the channel nearest to the specified position.
void reconfigure(fhicl::ParameterSet const &p)
int fMinNumberOfElCluster
const double * PlaneLocation(unsigned int p) const
Returns the coordinates of the center of the specified plane [cm].
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
SimDriftElectrons(fhicl::ParameterSet const &pset)
Event finding and building.
void Initialize(const detinfo::LArProperties *larp, const detinfo::DetectorProperties *detp, const sim::LArG4Parameters *lgp, const spacecharge::SpaceCharge *sce)