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>
48 Module(), m_outputDirectoryName(
""),
49 m_doseReportingLevel(c_reportNTuple),
50 m_nfluxReportingLevel(c_reportNTuple),
51 m_occupancyReportingLevel(c_reportNTuple),
52 m_componentName(
""), m_componentTime(0), m_integrationTime(20),
53 m_nielNeutrons(new
TNiel(c_niel_neutronFile)),
54 m_nielProtons(new
TNiel(c_niel_protonFile)),
55 m_nielPions(new
TNiel(c_niel_pionFile)),
56 m_nielElectrons(new
TNiel(c_niel_electronFile))
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);
164 double currentComponentTime = storeBgMetaData->getRealTime();
166 B2FATAL(
"Mismatch in component times:\n"
168 <<
"Background file: " << currentComponentTime);
170 VxdID currentSensorID(0);
171 double currentSensorThickness(0);
172 double currentSensorArea(0);
176 B2DEBUG(100,
"Expo and dose");
177 currentSensorID.
setID(0);
178 double currentSensorMass(0);
179 for (
const PXDSimHit& hit : storeSimHits) {
181 VxdID sensorID = hit.getSensorID();
182 if (sensorID != currentSensorID) {
183 currentSensorID = sensorID;
191 (hitEnergy /
Unit::J) / (currentSensorMass / 1000) * (
c_smy / currentComponentTime);
193 m_sensorData[currentSensorID].m_expo += hitEnergy / currentSensorArea / (currentComponentTime /
Unit::s);
195 const ROOT::Math::XYZVector localPos = hit.getPosIn();
196 const ROOT::Math::XYZVector globalPos =
pointToGlobal(currentSensorID, localPos);
197 float globalPosXYZ[3];
198 globalPos.GetCoordinates(globalPosXYZ);
201 hit.getPDGcode(), hit.getGlobalTime(),
202 localPos.X(), localPos.Y(), globalPosXYZ, hitEnergy,
203 (hitEnergy /
Unit::J) / (currentSensorMass / 1000) / (currentComponentTime /
Unit::s),
204 (hitEnergy /
Unit::J) / currentSensorArea / (currentComponentTime /
Unit::s)
212 B2DEBUG(100,
"Neutron flux");
213 currentSensorID.
setID(0);
215 VxdID sensorID = hit.getSensorID();
217 if (sensorID != currentSensorID) {
218 currentSensorID = sensorID;
223 ROOT::Math::XYZVector entryPos(hit.getEntryU(), hit.getEntryV(), hit.getEntryW());
224 ROOT::Math::XYZVector exitPos(hit.getExitU(), hit.getExitV(), hit.getExitW());
225 double stepLength = (exitPos - entryPos).
R();
231 double minDistance = 1.0e10;
232 for (
const PXDSimHit& related : storeSimHits) {
233 double distance = (entryPos - related.getPosIn()).
R();
234 if (distance < minDistance) {
235 minDistance = distance;
241 B2WARNING(
"No related PXDSimHit found");
248 ROOT::Math::XYZVector hitMomentum(hit.getMomentum());
249 hitMomentum.SetX(std::isfinite(hitMomentum.X()) ? hitMomentum.X() : 0.0);
250 hitMomentum.SetY(std::isfinite(hitMomentum.Y()) ? hitMomentum.Y() : 0.0);
251 hitMomentum.SetZ(std::isfinite(hitMomentum.Z()) ? hitMomentum.Z() : 0.0);
253 double kineticEnergy(0.0);
254 double nielWeight(0.0);
257 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
262 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
267 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
272 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
277 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
281 nielWeight = std::isfinite(nielWeight) ? nielWeight : 0.0;
282 m_sensorData[currentSensorID].m_neutronFlux += nielWeight * stepLength / currentSensorThickness / currentSensorArea /
283 currentComponentTime *
c_smy;
287 ROOT::Math::XYZVector localPos(hit.getU(), hit.getV(), hit.getW());
288 const ROOT::Math::XYZVector globalPos =
pointToGlobal(currentSensorID, localPos);
289 float globalPosXYZ[3];
290 globalPos.GetCoordinates(globalPosXYZ);
291 ROOT::Math::XYZVector localMom = hit.getMomentum();
292 const ROOT::Math::XYZVector globalMom =
vectorToGlobal(currentSensorID, localMom);
293 float globalMomXYZ[3];
294 globalMom.GetCoordinates(globalMomXYZ);
298 hit.getU(), hit.getV(), globalPosXYZ, globalMomXYZ, kineticEnergy,
299 stepLength, nielWeight,
300 stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime /
Unit::s),
301 nielWeight * stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime /
Unit::s)
309 B2DEBUG(100,
"Fired pixels");
310 currentSensorID.
setID(0);
311 double currentSensorCut = 0;
313 std::map<VxdID, std::vector<float> > firedPixels;
314 for (
const PXDDigit& storeDigit : storeDigits) {
317 VxdID sensorID = storeDigit.getSensorID();
318 if (sensorID != currentSensorID) {
319 currentSensorID = sensorID;
321 currentSensorCut = info.getChargeThreshold();
323 B2DEBUG(30,
"Digit charge: " << storeDigit.getCharge() <<
" threshold: " << currentSensorCut);
324 if (storeDigit.getCharge() < currentSensorCut)
continue;
325 B2DEBUG(30,
"Passed.");
326 firedPixels[sensorID].push_back(storeDigit.getCharge());
329 for (
auto idAndSet : firedPixels) {
330 VxdID sensorID = idAndSet.first;
332 int nFired = idAndSet.second.size();
333 double fired = nFired / (currentComponentTime /
Unit::s) / sensorArea;
337 B2DEBUG(100,
"Occupancy");
338 currentSensorID.
setID(0);
340 for (
auto cluster : storeClsuters) {
341 VxdID sensorID = cluster.getSensorID();
342 if (currentSensorID != sensorID) {
343 currentSensorID = sensorID;
345 nPixels = info.getUCells() * info.getVCells();
349 double occupancy = 1.0 / nPixels * cluster.getSize();
350 m_sensorData[sensorID].m_occupancy += w_acceptance * occupancy;
356 cluster.getU(), cluster.getV(), cluster.getSize(),
357 cluster.getCharge(), occupancy
374 outfile.open(outfileName.c_str(), ios::out | ios::trunc);
375 outfile <<
"component_name\t"
376 <<
"component_time\t"
389 << componentTime <<
"\t"
390 << vxdSensor.first.getLayerNumber() <<
"\t"
391 << vxdSensor.first.getLadderNumber() <<
"\t"
392 << vxdSensor.first.getSensorNumber() <<
"\t"
393 << vxdSensor.second.m_dose <<
"\t"
394 << vxdSensor.second.m_expo <<
"\t"
395 << vxdSensor.second.m_neutronFlux <<
"\t"
396 << vxdSensor.second.m_fired <<
"\t"
397 << 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
const ROOT::Math::XYZVector & vectorToGlobal(VxdID sensorID, const ROOT::Math::XYZVector &local)
Convert local vector coordinates to global.
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.
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.
virtual void endRun() override
End-of-run tasks.
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.
double getSensorThickness(VxdID sensorID) const
Return thickness of the sensor with the given sensor ID.
const PXD::SensorInfo & getInfo(VxdID sensorID) const
This is a shortcut to getting PXD::SensorInfo from the GeoCache.
std::unique_ptr< TNiel > m_nielPions
Pointer to Niel table for pions.
virtual void beginRun() override
Start-of-run initializations.
std::string m_storeBgMetaDataName
Name of the persistent BackgroundMetaDta object.
PXDBackgroundModule()
Constructor.
double getSensorArea(VxdID sensorID) const
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.
std::unique_ptr< TNiel > m_nielElectrons
Pointer to Niel table for electrons.
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.
virtual ~PXDBackgroundModule()
Destructor.
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Low-level class to create/modify relations between StoreArrays.
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.