10#include <background/modules/BeamBkgMixer/BeamBkgMixerModule.h>
13#include <framework/datastore/DataStore.h>
14#include <framework/datastore/StoreArray.h>
15#include <framework/datastore/StoreObjPtr.h>
18#include <framework/core/ModuleParam.templateDetails.h>
19#include <framework/logging/Logger.h>
22#include <pxd/dataobjects/PXDSimHit.h>
23#include <svd/dataobjects/SVDSimHit.h>
24#include <cdc/dataobjects/CDCSimHit.h>
25#include <top/dataobjects/TOPSimHit.h>
26#include <arich/dataobjects/ARICHSimHit.h>
27#include <ecl/dataobjects/ECLHit.h>
28#include <klm/dataobjects/KLMSimHit.h>
29#include <simulation/dataobjects/BeamBackHit.h>
32#include <framework/dataobjects/BackgroundInfo.h>
57 setDescription(
"Beam background mixer at SimHit level that uses beam background"
58 " simulation output directly (collision files) and not ROF files. "
59 "Each background event is shifted in time randomly within "
60 "a time window specified with minTime and maxTime.");
64 "List of background (collision) files (wildcards not allowed - "
65 "use python glob.glob() to expand to list of files)");
67 "Time window lower edge in nano seconds", -1000.0);
69 "Time window upper edge in nano seconds", 800.0);
71 "Overall factor to scale rates of backgrounds", 1.0);
73 "Factors to scale rates of backgrounds. "
74 "Possible tag names: " +
m_bgTypes.getBGTypes(),
77 "Detector components to be included, empty list means all components",
80 "if true wrap around events passing time window upper edge",
true);
82 "Time window lower edge for ECL in nano seconds", -17600.0);
84 "Time window upper edge for ECL in nano seconds", 8500.0);
86 "Time window lower edge for PXD in nano seconds", -10000.0);
88 "Time window upper edge for PXD in nano seconds", 10000.0);
91 "If true also add the BeamBackHits collection for the selected "
92 "subdetectors to the output file",
false);
95 "maximal deposited energy of ECLHit to accept BG event for mixing"
96 "(0 means accept all events)", 1.0);
99 "file cache size in Mbytes. If negative, use root default", 0);
132 if (!components.empty()) {
134 for (
unsigned i = 0; i < components.size(); ++i) str = str +
" " + components[i];
135 B2WARNING(
"Unknown components:" << str);
143 if (TString(file.c_str()).Contains(
"*")) {
144 B2ERROR(file <<
": wildcards are not allowed");
149 TFile* f = TFile::Open(file.c_str(),
"READ");
151 B2ERROR(file <<
": file not found");
155 B2ERROR(file <<
": can't open file");
160 TChain persistent(
"persistent");
161 int nFiles = persistent.Add(file.c_str());
163 B2ERROR(file <<
": no such files");
166 if (persistent.GetEntries() == 0) {
167 B2ERROR(file <<
": tree 'persistent' has no entries");
171 TObject* bkgMetaData = 0;
172 TBranch* branchBMD = persistent.GetBranch(
"BackgroundMetaData");
174 B2ERROR(file <<
": branch 'BackgroundMetaData' not found");
177 branchBMD->SetAddress(&bkgMetaData);
179 std::vector<BackgroundMetaData::BG_TAG> tags;
180 std::vector<std::string> types;
181 std::vector<BackgroundMetaData::EFileType> fileTypes;
183 for (
unsigned k = 0; k < persistent.GetEntries(); k++) {
184 persistent.GetEntry(k);
192 B2ERROR(file <<
": invalid realTime: " << realTime);
195 for (
unsigned i = 1; i < tags.size(); ++i) {
196 if (tags[i] != tags[0]) {
197 B2ERROR(file <<
": files with mixed background types not supported");
201 for (
unsigned i = 1; i < fileTypes.size(); ++i) {
202 if (fileTypes[i] != fileTypes[0]) {
203 B2ERROR(file <<
": files with mixed file types not supported");
208 appendSample(tags[0], types[0], file, realTime, fileTypes[0]);
216 std::string type = std::get<0>(scaleFactor);
218 B2ERROR(
"Unknown beam background type found in 'scaleFactors': " << type <<
"\n"
219 "Possible are: " +
m_bgTypes.getBGTypes());
222 bkg.scaleFactor *= std::get<1>(scaleFactor);
231 bkg.tree.reset(
new TChain(
"tree"));
232 for (
unsigned i = 0; i < bkg.fileNames.size(); ++i) {
233 bkg.numFiles += bkg.tree->Add(bkg.fileNames[i].c_str());
236 bkg.numEvents = bkg.tree->GetEntries();
237 bkg.rate = bkg.numEvents / bkg.realTime * bkg.scaleFactor;
241 if (
m_PXD and bkg.tree->GetBranch(
"PXDSimHits"))
242 bkg.tree->SetBranchAddress(
"PXDSimHits", &
m_simHits.PXD);
243 if (
m_SVD and bkg.tree->GetBranch(
"SVDSimHits"))
244 bkg.tree->SetBranchAddress(
"SVDSimHits", &
m_simHits.SVD);
245 if (
m_CDC and bkg.tree->GetBranch(
"CDCSimHits"))
246 bkg.tree->SetBranchAddress(
"CDCSimHits", &
m_simHits.CDC);
247 if (
m_TOP and bkg.tree->GetBranch(
"TOPSimHits"))
248 bkg.tree->SetBranchAddress(
"TOPSimHits", &
m_simHits.TOP);
249 if (
m_ARICH and bkg.tree->GetBranch(
"ARICHSimHits"))
250 bkg.tree->SetBranchAddress(
"ARICHSimHits", &
m_simHits.ARICH);
251 if (
m_ECL and bkg.tree->GetBranch(
"ECLHits"))
252 bkg.tree->SetBranchAddress(
"ECLHits", &
m_simHits.ECL);
253 if (
m_KLM and bkg.tree->GetBranch(
"KLMSimHits"))
254 bkg.tree->SetBranchAddress(
"KLMSimHits", &
m_simHits.KLM);
257 bkg.tree->SetBranchAddress(
"BeamBackHits", &
m_simHits.BeamBackHits);
260 std::string unit(
" ns");
261 double realTime = bkg.realTime;
262 if (realTime >= 1000.0) {realTime /= 1000.0; unit =
" us";}
263 if (realTime >= 1000.0) {realTime /= 1000.0; unit =
" ms";}
264 if (realTime >= 1000.0) {realTime /= 1000.0; unit =
" s";}
266 B2INFO(
"BeamBkgMixer: " << bkg.type <<
267 " tag=" << bkg.tag <<
268 " files=" << bkg.numFiles <<
269 " events=" << bkg.numEvents <<
270 " realTime=" << realTime << unit <<
271 " scaleFactor=" << bkg.scaleFactor <<
272 " rate=" << bkg.rate * 1000 <<
" MHz");
321 descr.type = bkg.type;
322 descr.fileType = bkg.fileType;
323 descr.fileNames = bkg.fileNames;
324 descr.realTime = bkg.realTime;
325 descr.numEvents = bkg.numEvents;
326 descr.scaleFactor = bkg.scaleFactor;
327 descr.rate = bkg.rate;
329 bkgInfo->appendBackgroundDescr(descr);
351 int nev = gRandom->Poisson(mean);
353 for (
int iev = 0; iev < nev; iev++) {
355 bkg.tree->GetEntry(bkg.eventCount);
369 std::string message =
"BeamBkgMixer: event " + to_string(bkg.eventCount)
370 +
" of " + bkg.type +
" rejected due to large energy deposit in ECL";
374 B2INFO(
"BeamBkgMixer: event rejected due to large energy deposit in ECL");
376 B2INFO(
"BeamBkgMixer: event rejected due to large energy deposit in ECL "
377 <<
"(message will be suppressed now)");
382 if (bkg.eventCount >= bkg.numEvents) {
384 std::string message =
"BeamBkgMixer: events of " + bkg.type +
" will be reused";
386 if (
m_reused[message] == 1) B2INFO(message);
387 bkgInfo->incrementReusedCounter(bkg.index);
398 int nev = gRandom->Poisson(mean);
400 for (
int iev = 0; iev < nev; iev++) {
403 bkg.tree->GetEntry(bkg.eventCount);
416 std::string message =
"BeamBkgMixer: event " + to_string(bkg.eventCount)
417 +
" of " + bkg.type +
" rejected due to large energy deposit in ECL";
421 B2INFO(
"BeamBkgMixer: event rejected due to large energy deposit in ECL");
423 B2INFO(
"BeamBkgMixer: event rejected due to large energy deposit in ECL "
424 <<
"(message will be suppressed now)");
429 if (bkg.eventCount >= bkg.numEvents) {
431 std::string message =
"BeamBkgMixer: events of " + bkg.type +
" will be reused";
433 if (
m_reused[message] == 1) B2INFO(message);
434 bkgInfo->incrementReusedCounter(bkg.index);
446 int nev = gRandom->Poisson(mean);
448 for (
int iev = 0; iev < nev; iev++) {
451 bkg.tree->GetEntry(bkg.eventCount);
463 if (bkg.eventCount >= bkg.numEvents) {
465 std::string message =
"BeamBkgMixer: events of " + bkg.type +
" will be reused";
467 if (
m_reused[message] == 1) B2INFO(message);
468 bkgInfo->incrementReusedCounter(bkg.index);
480 B2INFO(
"BeamBkgMixer - reused samples:");
481 for (
const auto& message :
m_reused) {
482 B2INFO(message.first <<
"(occurred " << message.second <<
" times)");
484 B2INFO(
"BeamBkgMixer - rejected events:");
486 B2INFO(message.first <<
"(occurred " << message.second <<
" times)");
497 const std::string& component)
500 auto iterator = std::find(components.begin(), components.end(), component);
501 if (iterator != components.end()) {
502 components.erase(iterator);
510 const std::string& type,
511 const std::string& fileName,
516 if (tag == bkg.tag and fileType == bkg.fileType) {
517 bkg.fileNames.push_back(fileName);
518 bkg.realTime += realTime;
522 std::string ftype = type;
533 if (!cloneArrayECL)
return true;
536 int numEntries = cloneArrayECL->GetEntriesFast();
537 for (
int i = 0; i < numEntries; i++) {
538 const ECLHit* simHit =
static_cast<ECLHit*
>(cloneArrayECL->AddrAt(i));
std::map< std::string, int > m_reused
messages: rejused events
double m_maxEdepECL
maximal allowed deposited energy in ECL
std::vector< BkgFiles > m_backgrounds
container for background samples
double m_maxTimeECL
maximal time shift of background event for ECL
std::map< std::string, int > m_rejected
messages: rejected events
bool isComponentIncluded(std::vector< std::string > &components, const std::string &component)
Returns true if a component is found in components or the list is empty.
bool m_ECL
true if found in m_components
std::vector< std::string > m_components
detector components
void addBeamBackHits(StoreArray< HIT > &hits, TClonesArray *cloneArray, double timeShift, double minTime, double maxTime)
functions that add BeamBackHits to those in the DataStore
double m_minTimePXD
minimal time shift of background event for PXD
bool m_PXD
true if found in m_components
void addSimHits(StoreArray< SIMHIT > &simHits, TClonesArray *cloneArray, double timeShift, double minTime, double maxTime)
functions that add background SimHits to those in the DataStore
background::BeamBGTypes m_bgTypes
defined BG types
std::vector< std::string > m_backgroundFiles
names of beam background files
virtual void initialize() override
Initialize the Module.
bool m_CDC
true if found in m_components
double m_maxTime
maximal time shift of background event
virtual void event() override
Event processor.
double m_minTime
minimal time shift of background event
bool m_wrapAround
if true wrap around events in the tail after maxTime
double m_maxTimePXD
maximal time shift of background event for PXD
int m_rejectedCount
counter for suppressing "rejected event" messages
virtual void terminate() override
Termination action.
BkgHits m_simHits
input event buffer
int m_cacheSize
file cache size in Mbytes
bool m_BeamBackHits
if true add also background hits
bool m_ARICH
true if found in m_components
double m_overallScaleFactor
overall scale factor
BeamBkgMixerModule()
Constructor.
void appendSample(BackgroundMetaData::BG_TAG bkgTag, const std::string &bkgType, const std::string &fileName, double realTime, BackgroundMetaData::EFileType fileTyp)
appends background sample to m_backgrounds
bool acceptEvent(TClonesArray *cloneArrayECL)
Checks for deposited energy of ECLHits and returns true if Edep < m_maxEdepECL.
double m_minTimeECL
minimal time shift of background event for ECL
std::vector< std::tuple< std::string, double > > m_scaleFactors
scale factors
bool m_KLM
true if found in m_components
bool m_SVD
true if found in m_components
bool m_TOP
true if found in m_components
@ c_Persistent
Object is available during entire execution time.
Class to store simulated hits which equate to average of ECLSImHit on crystals input for digitization...
double getEnergyDep() const
Get deposit energy.
void setDescription(const std::string &description)
Sets the description of the module.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
Accessor to arrays stored in the data store.
Type-safe access to single objects in the data store.
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.
Abstract base class for different kinds of events.
Structure for background description.
structure to hold samples of a particular background type