8#include <pxd/modules/pxdBackground/PXDBackgroundModule.h>
10#include <framework/datastore/DataStore.h>
11#include <framework/datastore/StoreObjPtr.h>
12#include <framework/datastore/StoreArray.h>
13#include <framework/datastore/RelationArray.h>
15#include <framework/dataobjects/FileMetaData.h>
16#include <framework/dataobjects/BackgroundMetaData.h>
17#include <framework/gearbox/Const.h>
18#include <mdst/dataobjects/MCParticle.h>
19#include <pxd/dataobjects/PXDSimHit.h>
20#include <pxd/dataobjects/PXDTrueHit.h>
21#include <pxd/dataobjects/PXDDigit.h>
22#include <pxd/dataobjects/PXDCluster.h>
23#include <pxd/dataobjects/PXDEnergyDepositionEvent.h>
24#include <pxd/dataobjects/PXDNeutronFluxEvent.h>
25#include <pxd/dataobjects/PXDOccupancyEvent.h>
28#include <boost/format.hpp>
75 static ROOT::Math::XYZVector result(0, 0, 0);
78 result = info.pointToGlobal(local);
84 static ROOT::Math::XYZVector result(0, 0, 0);
87 result = info.vectorToGlobal(local);
106 RelationArray relDigitsMCParticles(storeDigits, storeMCParticles);
108 RelationArray relMCParticlesTrueHits(storeMCParticles, storeTrueHits);
109 RelationArray relTrueHitsSimHits(storeTrueHits, storeSimHits);
160 double currentComponentTime = storeBgMetaData->getRealTime();
162 B2FATAL(
"Mismatch in component times:\n"
164 <<
"Background file: " << currentComponentTime);
166 VxdID currentSensorID(0);
167 double currentSensorThickness(0);
168 double currentSensorArea(0);
172 B2DEBUG(100,
"Expo and dose");
173 currentSensorID.
setID(0);
174 double currentSensorMass(0);
175 for (
const PXDSimHit& hit : storeSimHits) {
177 VxdID sensorID = hit.getSensorID();
178 if (sensorID != currentSensorID) {
179 currentSensorID = sensorID;
187 (hitEnergy /
Unit::J) / (currentSensorMass / 1000) * (
c_smy / currentComponentTime);
189 m_sensorData[currentSensorID].m_expo += hitEnergy / currentSensorArea / (currentComponentTime /
Unit::s);
191 const ROOT::Math::XYZVector localPos = hit.getPosIn();
192 const ROOT::Math::XYZVector globalPos =
pointToGlobal(currentSensorID, localPos);
193 float globalPosXYZ[3];
194 globalPos.GetCoordinates(globalPosXYZ);
197 hit.getPDGcode(), hit.getGlobalTime(),
198 localPos.X(), localPos.Y(), globalPosXYZ, hitEnergy,
199 (hitEnergy /
Unit::J) / (currentSensorMass / 1000) / (currentComponentTime /
Unit::s),
200 (hitEnergy /
Unit::J) / currentSensorArea / (currentComponentTime /
Unit::s)
208 B2DEBUG(100,
"Neutron flux");
209 currentSensorID.
setID(0);
211 VxdID sensorID = hit.getSensorID();
213 if (sensorID != currentSensorID) {
214 currentSensorID = sensorID;
219 ROOT::Math::XYZVector entryPos(hit.getEntryU(), hit.getEntryV(), hit.getEntryW());
220 ROOT::Math::XYZVector exitPos(hit.getExitU(), hit.getExitV(), hit.getExitW());
221 double stepLength = (exitPos - entryPos).
R();
227 double minDistance = 1.0e10;
228 for (
const PXDSimHit& related : storeSimHits) {
229 double distance = (entryPos - related.getPosIn()).R();
230 if (distance < minDistance) {
231 minDistance = distance;
237 B2WARNING(
"No related PXDSimHit found");
244 ROOT::Math::XYZVector hitMomentum(hit.getMomentum());
245 hitMomentum.SetX(std::isfinite(hitMomentum.X()) ? hitMomentum.X() : 0.0);
246 hitMomentum.SetY(std::isfinite(hitMomentum.Y()) ? hitMomentum.Y() : 0.0);
247 hitMomentum.SetZ(std::isfinite(hitMomentum.Z()) ? hitMomentum.Z() : 0.0);
249 double kineticEnergy(0.0);
250 double nielWeight(0.0);
253 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
258 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
263 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
268 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
273 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
277 nielWeight = std::isfinite(nielWeight) ? nielWeight : 0.0;
278 m_sensorData[currentSensorID].m_neutronFlux += nielWeight * stepLength / currentSensorThickness / currentSensorArea /
279 currentComponentTime *
c_smy;
283 ROOT::Math::XYZVector localPos(hit.getU(), hit.getV(), hit.getW());
284 const ROOT::Math::XYZVector globalPos =
pointToGlobal(currentSensorID, localPos);
285 float globalPosXYZ[3];
286 globalPos.GetCoordinates(globalPosXYZ);
287 ROOT::Math::XYZVector localMom = hit.getMomentum();
288 const ROOT::Math::XYZVector globalMom =
vectorToGlobal(currentSensorID, localMom);
289 float globalMomXYZ[3];
290 globalMom.GetCoordinates(globalMomXYZ);
294 hit.getU(), hit.getV(), globalPosXYZ, globalMomXYZ, kineticEnergy,
295 stepLength, nielWeight,
296 stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime /
Unit::s),
297 nielWeight * stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime /
Unit::s)
305 B2DEBUG(100,
"Fired pixels");
306 currentSensorID.
setID(0);
307 double currentSensorCut = 0;
309 std::map<VxdID, std::vector<float> > firedPixels;
310 for (
const PXDDigit& storeDigit : storeDigits) {
313 VxdID sensorID = storeDigit.getSensorID();
314 if (sensorID != currentSensorID) {
315 currentSensorID = sensorID;
317 currentSensorCut = info.getChargeThreshold();
319 B2DEBUG(30,
"Digit charge: " << storeDigit.getCharge() <<
" threshold: " << currentSensorCut);
320 if (storeDigit.getCharge() < currentSensorCut)
continue;
321 B2DEBUG(30,
"Passed.");
322 firedPixels[sensorID].push_back(storeDigit.getCharge());
325 for (
auto idAndSet : firedPixels) {
326 VxdID sensorID = idAndSet.first;
328 int nFired = idAndSet.second.size();
329 double fired = nFired / (currentComponentTime /
Unit::s) / sensorArea;
333 B2DEBUG(100,
"Occupancy");
334 currentSensorID.
setID(0);
336 for (
auto cluster : storeClsuters) {
337 VxdID sensorID = cluster.getSensorID();
338 if (currentSensorID != sensorID) {
339 currentSensorID = sensorID;
341 nPixels = info.getUCells() * info.getVCells();
345 double occupancy = 1.0 / nPixels * cluster.getSize();
346 m_sensorData[sensorID].m_occupancy += w_acceptance * occupancy;
352 cluster.getU(), cluster.getV(), cluster.getSize(),
353 cluster.getCharge(), occupancy
366 outfile.open(outfileName.c_str(), ios::out | ios::trunc);
367 outfile <<
"component_name\t"
368 <<
"component_time\t"
381 << componentTime <<
"\t"
382 << vxdSensor.first.getLayerNumber() <<
"\t"
383 << vxdSensor.first.getLadderNumber() <<
"\t"
384 << vxdSensor.first.getSensorNumber() <<
"\t"
385 << vxdSensor.second.m_dose <<
"\t"
386 << vxdSensor.second.m_expo <<
"\t"
387 << vxdSensor.second.m_neutronFlux <<
"\t"
388 << vxdSensor.second.m_fired <<
"\t"
389 << vxdSensor.second.m_occupancy
static const ParticleType neutron
neutron particle
static const ParticleType pi0
neutral pion particle
static const ChargedStable pion
charged pion particle
static const double electronMass
electron mass
static const double neutronMass
neutron mass
static const ChargedStable proton
proton particle
static const double ehEnergy
Energy needed to create an electron-hole pair in Si at std.
static const double protonMass
proton mass
static const ParticleType photon
photon particle
static const double pi0Mass
neutral pion mass
static const ChargedStable electron
electron particle
@ c_Persistent
Object is available during entire execution time.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Class PXDSimHit - Geant4 simulated hit for the PXD.
Class PXDTrueHit - Records of tracks that either enter or leave the sensitive volume.
static const unsigned short c_reportNTuple
Summary and NTuple.
std::string m_storeFileMetaDataName
Name of the persistent FileMetaData object.
unsigned short m_nfluxReportingLevel
0 - no data, 1 - summary only, 2 - ntuple
static const ROOT::Math::XYZVector & vectorToGlobal(VxdID sensorID, const ROOT::Math::XYZVector &local)
Convert local vector coordinates to global.
static const ROOT::Math::XYZVector & pointToGlobal(VxdID sensorID, const ROOT::Math::XYZVector &local)
Convert local sensor coordinates to global.
std::string m_storeEnergyDepositsName
PXDEnergyDepositEvents StoreArray name.
const double c_smy
Seconds in snowmass year.
unsigned short m_doseReportingLevel
0 - no data, 1 - summary only, 2 - ntuple
std::string m_storeOccupancyEventsName
PXDOccupancyEvents StoreArray name.
std::map< VxdID, SensorData > m_sensorData
Struct to hold sensor-wise background data.
virtual void initialize() override
Initialize module.
std::string m_relTrueHitsSimHitsName
PXDTrueHitsToPXDSimHits RelationArray name.
double m_integrationTime
Integration time of PXD.
std::string m_relDigitsMCParticlesName
StoreArray name of PXDDigits to MCParticles relation.
const std::string c_niel_neutronFile
NIEL-correction file for neutrons.
virtual void event() override
Event processing.
double getSensorMass(VxdID sensorID) const
Return mass of the sensor with the given sensor ID.
static const unsigned short c_reportNone
No reporting.
static const PXD::SensorInfo & getInfo(const VxdID &sensorID)
This is a shortcut to getting PXD::SensorInfo from the GeoCache.
std::string m_storeNeutronFluxesName
PXDNeutronFluxEvents StoreArray name.
std::string m_storeTrueHitsName
PXDTrueHits StoreArray name.
virtual void terminate() override
Final summary and cleanup.
std::unique_ptr< TNiel > m_nielNeutrons
Pointer to Niel table for neutrons.
std::string m_storeMCParticlesName
MCParticles StoreArray name.
std::unique_ptr< TNiel > m_nielProtons
Pointer to Niel table for protons.
std::unique_ptr< TNiel > m_nielPions
Pointer to Niel table for pions.
const std::string c_niel_electronFile
NIEL-correction file for electrons.
std::string m_storeBgMetaDataName
Name of the persistent BackgroundMetaDta object.
PXDBackgroundModule()
Constructor.
static double getSensorArea(VxdID sensorID)
Return area of the sensor with the given sensor ID.
std::string m_outputDirectoryName
Path to directory where output data will be stored.
std::string m_storeDigitsName
PXDDigits StoreArray name.
std::string m_storeClustersName
PXDClusters StoreArray name.
static double getSensorThickness(VxdID sensorID)
Return thickness of the sensor with the given sensor ID.
std::unique_ptr< TNiel > m_nielElectrons
Pointer to Niel table for electrons.
const std::string c_niel_protonFile
NIEL-correction file for protons.
virtual ~PXDBackgroundModule() override
Destructor.
const std::string c_niel_pionFile
NIEL-correction file for pions.
std::string m_relParticlesTrueHitsName
MCParticlesToPXDTrueHits RelationArray name.
std::string m_componentName
Name of the current bg component.
double m_componentTime
Time of current component.
unsigned short m_occupancyReportingLevel
0 - no data, 1 - summary only, 2 - ntuple
std::string m_storeSimHitsName
PXDSimHits StoreArray name.
std::string m_relDigitsTrueHitsName
StoreArray name of PXDDigits to PXDTrueHits relation.
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Low-level class to create/modify relations between StoreArrays.
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
Type-safe access to single objects in the data store.
static const double us
[microsecond]
static const double J
[joule]
static const double MeV
[megaelectronvolt]
static const double s
[second]
float getGlobalTime() const override
Return the time of the electron deposition.
int getPDGcode() const
Return the PDG code of the particle causing the electron deposition.
Class to uniquely identify a any structure of the PXD and SVD.
baseType getSensorNumber() const
Get the sensor id.
void setID(baseType id)
Set the unique id.
baseType getLadderNumber() const
Get the ladder id.
baseType getLayerNumber() const
Get the layer id.
TNiel - the class providing values for NIEL factors.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
Abstract base class for different kinds of events.