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>
49 PXDBackgroundModule::PXDBackgroundModule() :
50 Module(), m_outputDirectoryName(
""),
51 m_doseReportingLevel(c_reportNTuple),
52 m_nfluxReportingLevel(c_reportNTuple),
53 m_occupancyReportingLevel(c_reportNTuple),
54 m_componentName(
""), m_componentTime(0), m_integrationTime(20),
55 m_nielNeutrons(new
TNiel(c_niel_neutronFile)),
56 m_nielProtons(new
TNiel(c_niel_protonFile)),
57 m_nielPions(new
TNiel(c_niel_pionFile)),
58 m_nielElectrons(new
TNiel(c_niel_electronFile))
77 static ROOT::Math::XYZVector result(0, 0, 0);
80 result = info.pointToGlobal(local);
86 static ROOT::Math::XYZVector result(0, 0, 0);
89 result = info.vectorToGlobal(local);
108 RelationArray relDigitsMCParticles(storeDigits, storeMCParticles);
110 RelationArray relMCParticlesTrueHits(storeMCParticles, storeTrueHits);
111 RelationArray relTrueHitsSimHits(storeTrueHits, storeSimHits);
166 double currentComponentTime = storeBgMetaData->getRealTime();
168 B2FATAL(
"Mismatch in component times:\n"
170 <<
"Background file: " << currentComponentTime);
172 VxdID currentSensorID(0);
173 double currentSensorThickness(0);
174 double currentSensorArea(0);
178 B2DEBUG(100,
"Expo and dose");
179 currentSensorID.
setID(0);
180 double currentSensorMass(0);
181 for (
const PXDSimHit& hit : storeSimHits) {
183 VxdID sensorID = hit.getSensorID();
184 if (sensorID != currentSensorID) {
185 currentSensorID = sensorID;
193 (hitEnergy /
Unit::J) / (currentSensorMass / 1000) * (
c_smy / currentComponentTime);
195 m_sensorData[currentSensorID].m_expo += hitEnergy / currentSensorArea / (currentComponentTime /
Unit::s);
197 const ROOT::Math::XYZVector localPos = hit.getPosIn();
198 const ROOT::Math::XYZVector globalPos =
pointToGlobal(currentSensorID, localPos);
199 float globalPosXYZ[3];
200 globalPos.GetCoordinates(globalPosXYZ);
203 hit.getPDGcode(), hit.getGlobalTime(),
204 localPos.X(), localPos.Y(), globalPosXYZ, hitEnergy,
205 (hitEnergy /
Unit::J) / (currentSensorMass / 1000) / (currentComponentTime /
Unit::s),
206 (hitEnergy /
Unit::J) / currentSensorArea / (currentComponentTime /
Unit::s)
214 B2DEBUG(100,
"Neutron flux");
215 currentSensorID.
setID(0);
217 VxdID sensorID = hit.getSensorID();
219 if (sensorID != currentSensorID) {
220 currentSensorID = sensorID;
225 ROOT::Math::XYZVector entryPos(hit.getEntryU(), hit.getEntryV(), hit.getEntryW());
226 ROOT::Math::XYZVector exitPos(hit.getExitU(), hit.getExitV(), hit.getExitW());
227 double stepLength = (exitPos - entryPos).
R();
233 double minDistance = 1.0e10;
234 for (
const PXDSimHit& related : storeSimHits) {
235 double distance = (entryPos - related.getPosIn()).
R();
236 if (distance < minDistance) {
237 minDistance = distance;
243 B2WARNING(
"No related PXDSimHit found");
250 ROOT::Math::XYZVector hitMomentum(hit.getMomentum());
251 hitMomentum.SetX(std::isfinite(hitMomentum.X()) ? hitMomentum.X() : 0.0);
252 hitMomentum.SetY(std::isfinite(hitMomentum.Y()) ? hitMomentum.Y() : 0.0);
253 hitMomentum.SetZ(std::isfinite(hitMomentum.Z()) ? hitMomentum.Z() : 0.0);
255 double kineticEnergy(0.0);
256 double nielWeight(0.0);
259 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
264 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
269 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
274 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
279 kineticEnergy =
sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
283 nielWeight = std::isfinite(nielWeight) ? nielWeight : 0.0;
284 m_sensorData[currentSensorID].m_neutronFlux += nielWeight * stepLength / currentSensorThickness / currentSensorArea /
285 currentComponentTime *
c_smy;
289 ROOT::Math::XYZVector localPos(hit.getU(), hit.getV(), hit.getW());
290 const ROOT::Math::XYZVector globalPos =
pointToGlobal(currentSensorID, localPos);
291 float globalPosXYZ[3];
292 globalPos.GetCoordinates(globalPosXYZ);
293 ROOT::Math::XYZVector localMom = hit.getMomentum();
294 const ROOT::Math::XYZVector globalMom =
vectorToGlobal(currentSensorID, localMom);
295 float globalMomXYZ[3];
296 globalMom.GetCoordinates(globalMomXYZ);
300 hit.getU(), hit.getV(), globalPosXYZ, globalMomXYZ, kineticEnergy,
301 stepLength, nielWeight,
302 stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime /
Unit::s),
303 nielWeight * stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime /
Unit::s)
311 B2DEBUG(100,
"Fired pixels");
312 currentSensorID.
setID(0);
313 double currentSensorCut = 0;
315 std::map<VxdID, std::vector<float> > firedPixels;
316 for (
const PXDDigit& storeDigit : storeDigits) {
319 VxdID sensorID = storeDigit.getSensorID();
320 if (sensorID != currentSensorID) {
321 currentSensorID = sensorID;
323 currentSensorCut = info.getChargeThreshold();
325 B2DEBUG(30,
"Digit charge: " << storeDigit.getCharge() <<
" threshold: " << currentSensorCut);
326 if (storeDigit.getCharge() < currentSensorCut)
continue;
327 B2DEBUG(30,
"Passed.");
328 firedPixels[sensorID].push_back(storeDigit.getCharge());
331 for (
auto idAndSet : firedPixels) {
332 VxdID sensorID = idAndSet.first;
334 int nFired = idAndSet.second.size();
335 double fired = nFired / (currentComponentTime /
Unit::s) / sensorArea;
339 B2DEBUG(100,
"Occupancy");
340 currentSensorID.
setID(0);
342 for (
auto cluster : storeClsuters) {
343 VxdID sensorID = cluster.getSensorID();
344 if (currentSensorID != sensorID) {
345 currentSensorID = sensorID;
347 nPixels = info.getUCells() * info.getVCells();
351 double occupancy = 1.0 / nPixels * cluster.getSize();
352 m_sensorData[sensorID].m_occupancy += w_acceptance * occupancy;
358 cluster.getU(), cluster.getV(), cluster.getSize(),
359 cluster.getCharge(), occupancy
376 outfile.open(outfileName.c_str(), ios::out | ios::trunc);
377 outfile <<
"component_name\t"
378 <<
"component_time\t"
391 << componentTime <<
"\t"
392 << vxdSensor.first.getLayerNumber() <<
"\t"
393 << vxdSensor.first.getLadderNumber() <<
"\t"
394 << vxdSensor.first.getSensorNumber() <<
"\t"
395 << vxdSensor.second.m_dose <<
"\t"
396 << vxdSensor.second.m_expo <<
"\t"
397 << vxdSensor.second.m_neutronFlux <<
"\t"
398 << vxdSensor.second.m_fired <<
"\t"
399 << 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.
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.
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.