From b1a62e21eb447a43d736782d5d34df2219d2928a Mon Sep 17 00:00:00 2001
From: "guofangyi@ihep.ac.cn" <guofangyi@ihep.ac.cn>
Date: Mon, 6 May 2024 03:09:47 +0000
Subject: [PATCH] Beam background simulation

---
 Examples/options/beambkgsim.py               | 127 +++++++++++++++++++
 Generator/CMakeLists.txt                     |   2 +
 Generator/src/BeamBackgroundFileParserV0.h   |   6 +-
 Generator/src/BeamBackgroundFileParserV1.cpp |  80 ++++++++++++
 Generator/src/BeamBackgroundFileParserV1.h   |  29 +++++
 Generator/src/BeamBackgroundFileParserV2.cpp |  74 +++++++++++
 Generator/src/BeamBackgroundFileParserV2.h   |  29 +++++
 Generator/src/GtBeamBackgroundTool.cpp       |  82 ++++++++----
 Generator/src/GtBeamBackgroundTool.h         |  12 +-
 Generator/src/GuineaPigPairsFileParser.h     |   2 +
 Generator/src/HepMCRdr.cpp                   |   2 +-
 Generator/src/IBeamBackgroundFileParser.h    |   6 +-
 12 files changed, 416 insertions(+), 35 deletions(-)
 create mode 100644 Examples/options/beambkgsim.py
 create mode 100644 Generator/src/BeamBackgroundFileParserV1.cpp
 create mode 100644 Generator/src/BeamBackgroundFileParserV1.h
 create mode 100644 Generator/src/BeamBackgroundFileParserV2.cpp
 create mode 100644 Generator/src/BeamBackgroundFileParserV2.h

diff --git a/Examples/options/beambkgsim.py b/Examples/options/beambkgsim.py
new file mode 100644
index 00000000..a786b3c7
--- /dev/null
+++ b/Examples/options/beambkgsim.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+#Author: Zhan Li <lizhan@ihep.ac.cn>
+#Created [2024-03-07 Thu 14:53]
+
+import os
+import sys
+
+import Gaudi.Configuration
+from Configurables import RndmGenSvc, HepRndm__Engine_CLHEP__RanluxEngine_, k4DataSvc, GeomSvc
+from Configurables import TimeProjectionChamberSensDetTool
+from Configurables import GenAlgo
+from Configurables import GtGunTool
+from Configurables import StdHepRdr
+from Configurables import SLCIORdr
+from Configurables import HepMCRdr
+from Configurables import GenPrinter
+from Configurables import GtBeamBackgroundTool
+from Configurables import DetSimSvc
+from Configurables import DetSimAlg
+from Configurables import AnExampleDetElemTool
+from Configurables import PodioOutput
+from Configurables import ApplicationMgr
+
+seed = [42]
+
+rndmengine = Gaudi.Configuration.HepRndm__Engine_CLHEP__HepJamesRandom_("RndmGenSvc.Engine")
+rndmengine.SetSingleton = True
+rndmengine.Seeds = seed
+
+rndmgensvc = RndmGenSvc("RndmGenSvc")
+rndmgensvc.Engine = rndmengine.name()
+
+
+dsvc = k4DataSvc("EventDataSvc")
+#geometry_option = "CepC_v4-onlyVXD.xml"
+#geometry_option = "CepC_v4_onlyTracker.xml"
+geometry_option = "CepC_v4.xml"
+
+geometry_path = os.path.join(os.getenv("DETCEPCV4ROOT"), "compact", geometry_option)
+geosvc = GeomSvc("GeomSvc")
+geosvc.compact = geometry_path
+
+#Previously I do not have these 2 lines
+tpc_sensdettool = TimeProjectionChamberSensDetTool("TimeProjectionChamberSensDetTool")
+tpc_sensdettool.TypeOption = 1
+
+
+# Physics Generator
+# ------------------ WARNING ------------------
+# Files for code test only. 
+# Contact @Haoyu Shi (shihy@ihep.ac.cn) for reliable simulation samples and rates. 
+# ---------------------------------------------
+bg = GtBeamBackgroundTool("GtBeamBackgroundTool")
+bg.InputFileMap = {
+  "BGB":"/cefs/higgs/guofy/CEPCSW_BeamBkgSim/run/BGB_Higgs.root",
+  "BGC":"/cefs/higgs/guofy/CEPCSW_BeamBkgSim/run/BGC_Higgs.root",
+  "BTH":"/cefs/higgs/guofy/CEPCSW_BeamBkgSim/run/BTH_Higgs.root",
+#  "TSC":"",
+#  "Pair":"",
+  "SR":"/cefs/higgs/guofy/CEPCSW_BeamBkgSim/run/SRBkg/"
+}
+bg.InputFormatMap = {
+  "BGB":"BeamBackgroundFileParserV1",
+  "BGC":"BeamBackgroundFileParserV1",
+  "BTH":"BeamBackgroundFileParserV1",
+#  "TSC":"BeamBackgroundFileParserV1",
+#  "Pair":"BeamBackgroundFileParserV1",
+  "SR":"BeamBackgroundFileParserV2"
+}
+bg.InputRateMap = {  # in Hz
+  "BGB":1e7, 
+  "BGC":5e6,
+  "BTH":5e5,
+#  "TSC":"5e5",
+#  "Pair":"",
+  "SR":1
+}
+bg.TimeWindow = 1e-6
+bg.InputBeamEnergy = 120.
+bg.RotationAlongYMap = {
+  "BGB":16.5e-3,
+  "BGC":16.5e-3,
+  "BTH":16.5e-3,
+#  "TSC":"16.5e-3",
+#  "Pair":"",
+  "SR":0
+}
+
+gun = GtGunTool("GtGunTool")
+gun.Particles = ["gamma"]
+gun.EnergyMins = [10]
+gun.EnergyMaxs = [10]
+gun.ThetaMins = [90]
+gun.ThetaMaxs = [90]
+gun.PhiMins = [0]
+gun.PhiMaxs = [0]
+
+genprinter = GenPrinter("GenPrinter")
+
+genalg = GenAlgo("GenAlgo")
+genalg.GenTools = ["GtBeamBackgroundTool", "GtGunTool"]
+
+detsimsvc = DetSimSvc("DetSimSvc")
+
+detsimalg = DetSimAlg("DetSimAlg")
+detsimalg.RandomSeeds = seed
+
+
+detsimalg.RunCmds = []
+detsimalg.AnaElems = [
+    "Edm4hepWriterAnaElemTool"
+]
+detsimalg.RootDetElem = "WorldDetElemTool"
+
+example_dettool = AnExampleDetElemTool("AnExampleDetElemTool")
+
+
+# POD I/O
+out = PodioOutput("outputalg")
+out.filename = "beam-SETv0.root"
+out.outputCommands = ["keep *"]
+
+ApplicationMgr( TopAlg = [genalg, detsimalg, out],
+                EvtSel = 'NONE',
+                EvtMax = 3,
+                ExtSvc = [rndmengine, rndmgensvc, dsvc, geosvc],
+)
diff --git a/Generator/CMakeLists.txt b/Generator/CMakeLists.txt
index e3f20777..c227254a 100644
--- a/Generator/CMakeLists.txt
+++ b/Generator/CMakeLists.txt
@@ -18,6 +18,8 @@ gaudi_add_module(GenAlgo
                          # ------- Beam Background -------
                          src/GtBeamBackgroundTool.cpp
                          src/BeamBackgroundFileParserV0.cpp
+                         src/BeamBackgroundFileParserV1.cpp
+                         src/BeamBackgroundFileParserV2.cpp
                          src/GuineaPigPairsFileParser.cpp
                  LINK ${ROOT_LIBRARIES}
                       k4FWCore::k4FWCore 
diff --git a/Generator/src/BeamBackgroundFileParserV0.h b/Generator/src/BeamBackgroundFileParserV0.h
index 3f3037f2..e93d1c8e 100644
--- a/Generator/src/BeamBackgroundFileParserV0.h
+++ b/Generator/src/BeamBackgroundFileParserV0.h
@@ -9,7 +9,11 @@ class BeamBackgroundFileParserV0: public IBeamBackgroundFileParser {
 public:
     BeamBackgroundFileParserV0(const std::string& filename, int pdgid, double beam_energy);
 
-    bool load(IBeamBackgroundFileParser::BeamBackgroundData&);
+    bool load(IBeamBackgroundFileParser::BeamBackgroundData& _data);
+    bool load(IBeamBackgroundFileParser::BeamBackgroundData& _data, int iEntry) { return load(_data); }
+    bool SampleParticleNum(int&, int&) { return true; }
+    //int totalEnteries() { return 0; }
+
 private:
     std::ifstream m_input;
 
diff --git a/Generator/src/BeamBackgroundFileParserV1.cpp b/Generator/src/BeamBackgroundFileParserV1.cpp
new file mode 100644
index 00000000..107be097
--- /dev/null
+++ b/Generator/src/BeamBackgroundFileParserV1.cpp
@@ -0,0 +1,80 @@
+
+#include "BeamBackgroundFileParserV1.h"
+#include "CLHEP/Random/RandPoisson.h"
+#include "CLHEP/Random/RandFlat.h"
+#include <iostream>
+#include <sstream>
+#include <cmath>
+
+BeamBackgroundFileParserV1::BeamBackgroundFileParserV1(const std::string& filename,
+                                                       const std::string& treename,
+                                                       double beam_energy, 
+                                                       double rate,
+                                                       double timewindow ) {
+
+
+    m_inputFile.reset(TFile::Open(filename.c_str(), "read"));
+    std::cout << "BeamBackgroundFileParserV1: readin file name "<<filename<<" / "<<m_inputFile->GetName()<<", status " << m_inputFile->IsOpen() << std::endl;
+
+    m_readTree = (TTree*)m_inputFile->Get(treename.c_str());
+    std::cout << "  Get Tree: entries " << m_readTree->GetEntries() << std::endl;
+    m_beam_energy = beam_energy;
+
+    m_readTree->SetBranchAddress("x", &x);
+    m_readTree->SetBranchAddress("y", &y);
+    m_readTree->SetBranchAddress("z", &z);
+    m_readTree->SetBranchAddress("cosx", &cosx);
+    m_readTree->SetBranchAddress("cosy", &cosy);
+    m_readTree->SetBranchAddress("dp", &dp);
+    m_readTree->SetBranchAddress("dz", &dz);
+
+    m_rate = rate;
+    m_timewindow = timewindow;
+}
+
+bool BeamBackgroundFileParserV1::load(IBeamBackgroundFileParser::BeamBackgroundData& result, int iEntry) {
+
+    if (not m_inputFile->IsOpen()) {
+        return false;
+    }
+
+    if(m_readTree && m_readTree->GetEntries()>=0){
+        if(iEntry>=m_readTree->GetEntries()) iEntry = m_readTree->GetEntries()-1;
+        m_readTree->GetEntry(iEntry);
+
+        double p = m_beam_energy*(1+dp);
+
+        // Now, we get a almost valid data
+        const double m2mm = 1e3; // convert from m to mm
+        result.pdgid = 11;
+        result.x     = x * m2mm;
+        result.y     = y * m2mm;
+        result.z     = (z+dz) * m2mm;
+
+        result.px    = p * cosx;
+        result.py    = p * cosy;
+        result.pz    = p * std::sqrt(1-cosx*cosx-cosy*cosy);
+
+        result.mass  = 0.000511; // assume e-/e+, mass is 0.511 MeV
+
+        return true;
+
+    }
+
+    return false;
+}
+
+bool BeamBackgroundFileParserV1::SampleParticleNum(int& npart, int& start ){
+
+  npart = int(m_rate * m_timewindow);
+  npart = CLHEP::RandPoisson::shoot(npart);
+
+  int nTotPartInFile = m_readTree->GetEntries();
+  if(npart>nTotPartInFile){
+    start = 0;
+    npart = nTotPartInFile;
+  }
+  else start = CLHEP::RandFlat::shoot(0., (double)nTotPartInFile-npart);
+
+  return true;
+}
diff --git a/Generator/src/BeamBackgroundFileParserV1.h b/Generator/src/BeamBackgroundFileParserV1.h
new file mode 100644
index 00000000..ad80f225
--- /dev/null
+++ b/Generator/src/BeamBackgroundFileParserV1.h
@@ -0,0 +1,29 @@
+#ifndef BeamBackgroundFileParserV1_h
+#define BeamBackgroundFileParserV1_h
+
+#include "IBeamBackgroundFileParser.h"
+#include "TFile.h"
+#include "TTree.h"
+#include <fstream>
+
+class BeamBackgroundFileParserV1: public IBeamBackgroundFileParser {
+public:
+    BeamBackgroundFileParserV1(const std::string& filename, const std::string& treename, double beam_energy, double rate, double timewindow);
+
+    bool load(IBeamBackgroundFileParser::BeamBackgroundData&) { return 0; }
+    bool load(IBeamBackgroundFileParser::BeamBackgroundData&, int iEntry);
+    bool SampleParticleNum(int&, int&);
+    //int totalEnteries() { return m_readTree->GetEntries(); }
+
+private:
+    std::unique_ptr<TFile> m_inputFile;
+    TTree* m_readTree;
+    double m_beam_energy;
+    double m_rate;
+    double m_timewindow; 
+
+    double x, y, z, cosx, cosy, dz, dp;
+
+};
+
+#endif
diff --git a/Generator/src/BeamBackgroundFileParserV2.cpp b/Generator/src/BeamBackgroundFileParserV2.cpp
new file mode 100644
index 00000000..748ed9b8
--- /dev/null
+++ b/Generator/src/BeamBackgroundFileParserV2.cpp
@@ -0,0 +1,74 @@
+
+#include "BeamBackgroundFileParserV2.h"
+#include "CLHEP/Random/RandFlat.h"
+#include <sstream>
+#include <cmath>
+
+BeamBackgroundFileParserV2::BeamBackgroundFileParserV2(const std::string& dirpath,
+                                                       const std::string& treename,
+                                                       double beam_energy) {
+
+    //Choose one root file from the dir
+    std::vector<std::string> rootFiles;
+    for (const auto& entry : std::filesystem::directory_iterator(dirpath)) {
+        if (entry.path().extension() == ".root") {
+            rootFiles.push_back(entry.path().string());
+        }
+    }
+    std::cout << "BeamBackgroundFileParserV2: In Dir " << dirpath << ": file size "<<rootFiles.size()<<std::endl;
+
+    int randomIndex = CLHEP::RandFlat::shoot(0., rootFiles.size()-1.);
+    std::cout << "  Chosen file index "<<randomIndex<<", file name "<<rootFiles[randomIndex]<<std::endl;
+    m_inputFile.reset(TFile::Open(rootFiles[randomIndex].c_str(), "read"));
+    std::cout << "BeamBackgroundFileParserV1: readin file name "<<m_inputFile->GetName()<<", status " << m_inputFile->IsOpen() << std::endl;
+    m_readTree = (TTree*)m_inputFile->Get(treename.c_str());
+    std::cout << "  Get Tree: entries " << m_readTree->GetEntries() << std::endl;
+    m_beam_energy = beam_energy;
+
+    m_readTree->SetBranchAddress("X", &x);
+    m_readTree->SetBranchAddress("Y", &y);
+    m_readTree->SetBranchAddress("Z", &z);
+    m_readTree->SetBranchAddress("PX", &px);
+    m_readTree->SetBranchAddress("PY", &py);
+    m_readTree->SetBranchAddress("DP", &dp);
+    m_readTree->SetBranchAddress("PID", &pid);
+
+}
+
+bool BeamBackgroundFileParserV2::load(IBeamBackgroundFileParser::BeamBackgroundData& result, int iEntry) {
+
+    if (not m_inputFile->IsOpen()) {
+        return false;
+    }
+
+    if(m_readTree && m_readTree->GetEntries()>=0){
+        if(iEntry>=m_readTree->GetEntries()) iEntry = m_readTree->GetEntries()-1;
+        m_readTree->GetEntry(iEntry);
+
+        double p = m_beam_energy*(1+dp);
+        const double m2mm = 1e3; // convert from m to mm
+        result.pdgid = (int)pid;
+        result.x     = x * m2mm;
+        result.y     = y * m2mm;
+        result.z     = z * m2mm;
+
+        result.px    = px;
+        result.py    = py;
+        result.pz    = sqrt(p*p - px*px - py*py);
+
+        if(pid==22) result.mass  = 0.;
+        else result.mass  = 0.000511; // assume e-/e+, mass is 0.511 MeV
+
+        return true;
+
+    }
+
+    return false;
+}
+
+bool BeamBackgroundFileParserV2::SampleParticleNum(int& npart, int& start ){
+  npart = m_readTree->GetEntries();
+  start = 0;
+
+  return true;
+}
diff --git a/Generator/src/BeamBackgroundFileParserV2.h b/Generator/src/BeamBackgroundFileParserV2.h
new file mode 100644
index 00000000..0f9cb260
--- /dev/null
+++ b/Generator/src/BeamBackgroundFileParserV2.h
@@ -0,0 +1,29 @@
+#ifndef BeamBackgroundFileParserV2_h
+#define BeamBackgroundFileParserV2_h
+
+#include "IBeamBackgroundFileParser.h"
+#include "TFile.h"
+#include "TTree.h"
+#include <fstream>
+#include <filesystem>
+#include <random>
+
+class BeamBackgroundFileParserV2: public IBeamBackgroundFileParser {
+public:
+    BeamBackgroundFileParserV2(const std::string& dirname, const std::string& treename, double beam_energy);
+
+    bool load(IBeamBackgroundFileParser::BeamBackgroundData&) { return 0; }
+    bool load(IBeamBackgroundFileParser::BeamBackgroundData&, int iEntry);
+    bool SampleParticleNum(int&, int&);
+    //int totalEnteries() { return m_readTree->GetEntries(); }
+
+private:
+    std::unique_ptr<TFile> m_inputFile;
+    TTree* m_readTree;
+    double m_beam_energy;
+
+    float x, y, z, px, py, dp, pid;
+
+};
+
+#endif
diff --git a/Generator/src/GtBeamBackgroundTool.cpp b/Generator/src/GtBeamBackgroundTool.cpp
index c21a1291..82847a23 100644
--- a/Generator/src/GtBeamBackgroundTool.cpp
+++ b/Generator/src/GtBeamBackgroundTool.cpp
@@ -2,9 +2,12 @@
 #include "IBeamBackgroundFileParser.h"
 
 #include "BeamBackgroundFileParserV0.h"
+#include "BeamBackgroundFileParserV1.h"
+#include "BeamBackgroundFileParserV2.h"
 #include "GuineaPigPairsFileParser.h"
 
 #include "CLHEP/Random/RandPoisson.h"
+#include "CLHEP/Random/RandFlat.h"
 
 #include "TVector3.h" // for rotation
 DECLARE_COMPONENT(GtBeamBackgroundTool)
@@ -24,9 +27,17 @@ StatusCode GtBeamBackgroundTool::initialize() {
 
         if (format == "BeamBackgroundFileParserV0") {
             init_BeamBackgroundFileParserV0(label, inputfn);
-        } else if (format == "GuineaPigPairsFileParser") {
+        } 
+        else if (format == "GuineaPigPairsFileParser") {
             init_GuineaPigPairsFileParser(label, inputfn);
-        } else {
+        }
+        else if(format == "BeamBackgroundFileParserV1"){
+            init_BeamBackgroundFileParserV1(label, inputfn);
+        }
+        else if(format == "BeamBackgroundFileParserV2"){
+            init_BeamBackgroundFileParserV2(label, inputfn);
+        } 
+        else {
             init_BeamBackgroundFileParserV0(label, inputfn);
         }
         
@@ -50,38 +61,33 @@ bool GtBeamBackgroundTool::mutate(MyHepMC::GenEvent& event) {
     if (m_beaminputs.empty()) {
         return false;
     }
-    // TODO: should sample according to the rates
-    // dummy: get one and stop to generate
-    for (auto& [label, parser]: m_beaminputs) {
-        int nparticles = 1; // by default, only one particle
-
-        if (auto itRate = m_ratemaps.find(label); itRate != m_ratemaps.end()) {
-            nparticles = itRate->second * m_timewindow;
 
-            // now sampling the number of particles
-            nparticles = CLHEP::RandPoisson::shoot(nparticles);
-        }
+    for (auto& [label, parser]: m_beaminputs) {
 
-        for (auto iparticle = 0; iparticle < nparticles; ++iparticle) {
+        int nparticles = 0;
+        int startNo = 0;
+        parser->SampleParticleNum(nparticles, startNo);
+        for(auto ipart = 0; ipart < nparticles; ++ipart){
             IBeamBackgroundFileParser::BeamBackgroundData beamdata;
-            auto isok = parser->load(beamdata);
+            auto isok = parser->load(beamdata, ipart+startNo);
             if (not isok) {
                 error() << "Failed to load beam background data from the parser " << label << endmsg;
                 return false;
             }
-            // fill the value
-            float charge = beamdata.pdgid == 11 ? -1: 1;
+
+            float charge = beamdata.charge;
 
             TVector3 pos(beamdata.x,beamdata.y,beamdata.z);
             TVector3 mom(beamdata.px,beamdata.py,beamdata.pz);
 
-            auto itrot = m_rotYmaps.find(label);
-            if (itrot  != m_rotYmaps.end() ) {
-                info() << "Apply rotation along Y " << itrot->second << endmsg;
+
+            auto itrot = m_rotYMap.find(label);
+            if (itrot  != m_rotYMap.end() ) {
+                //info() << "Apply rotation along Y " << itrot->second << endmsg;
 
                 pos.RotateY(itrot->second);
                 mom.RotateY(itrot->second);
-            }
+            }            
 
             // create the MC particle
             auto mcp = event.m_mc_vec.create();
@@ -91,9 +97,11 @@ bool GtBeamBackgroundTool::mutate(MyHepMC::GenEvent& event) {
             mcp.setCharge(static_cast<float>(charge));
             mcp.setTime(beamdata.t);
             mcp.setMass(beamdata.mass);
-            mcp.setVertex(edm4hep::Vector3d(pos.X(), pos.Y(), pos.Z())); 
+            mcp.setVertex(edm4hep::Vector3d(pos.X(), pos.Y(), pos.Z()));
             mcp.setMomentum(edm4hep::Vector3f(mom.X(), mom.Y(), mom.Z()));
+
         }
+
     }
     
     return true;
@@ -110,17 +118,35 @@ bool GtBeamBackgroundTool::configure_gentool() {
 
 bool GtBeamBackgroundTool::init_BeamBackgroundFileParserV0(const std::string& label,
                                                            const std::string& inputfn) {
-    double beamE = 120.;
-    auto itBeamE = m_Ebeammaps.find(label);
-    if (itBeamE != m_Ebeammaps.end()) {
-        beamE = itBeamE->second;
-    }
     info() << "Initializing beam background ... "
            << label << " "
-           << beamE << " "
+           << m_Ebeam << " "
            << inputfn
            << endmsg;
-    m_beaminputs[label] = std::make_shared<BeamBackgroundFileParserV0>(inputfn, 11, beamE);
+    m_beaminputs[label] = std::make_shared<BeamBackgroundFileParserV0>(inputfn, 11, m_Ebeam);
+
+    return true;
+}
+
+bool GtBeamBackgroundTool::init_BeamBackgroundFileParserV1(const std::string& label,
+                                                           const std::string& inputfn) {
+    info() << "Initializing beam background ... " << label << inputfn <<endmsg;
+    auto itRate = m_ratemaps.find(label);
+    if(itRate == m_ratemaps.end()){ 
+      error() << "Did not find the beam process rate for: " << label << endmsg;
+      return false;
+    }
+
+    m_beaminputs[label] = std::make_shared<BeamBackgroundFileParserV1>(inputfn, "BeamTree", m_Ebeam, itRate->second, m_timewindow);
+
+    return true;
+}
+
+bool GtBeamBackgroundTool::init_BeamBackgroundFileParserV2(const std::string& label,
+                                                           const std::string& inputfn) {
+
+    info() << "Initializing beam background ... " << label << inputfn <<endmsg;
+    m_beaminputs[label] = std::make_shared<BeamBackgroundFileParserV2>(inputfn, "RBBG", m_Ebeam);
 
     return true;
 }
diff --git a/Generator/src/GtBeamBackgroundTool.h b/Generator/src/GtBeamBackgroundTool.h
index b3f22548..6affcb85 100644
--- a/Generator/src/GtBeamBackgroundTool.h
+++ b/Generator/src/GtBeamBackgroundTool.h
@@ -49,19 +49,23 @@ public:
 
 private:
     bool init_BeamBackgroundFileParserV0(const std::string& label, const std::string& inputfn);
+    bool init_BeamBackgroundFileParserV1(const std::string& label, const std::string& inputfn);
+    bool init_BeamBackgroundFileParserV2(const std::string& label, const std::string& inputfn);
     bool init_GuineaPigPairsFileParser(const std::string& label, const std::string& inputfn);
 
 private:
     Gaudi::Property<std::map<std::string, std::string>> m_inputmaps{this, "InputFileMap"};
     Gaudi::Property<std::map<std::string, std::string>> m_formatmaps{this, "InputFormatMap"};
     Gaudi::Property<std::map<std::string, double>>      m_ratemaps {this, "InputRateMap"}; // unit: Hz
-    Gaudi::Property<double> m_timewindow{this, "TimeWindow", 1e-6}; // unit: s
+
+    // Detector time window. Should be different for different sub-Det. Unit: s
+    Gaudi::Property<double>      m_timewindow{this, "TimeWindow"}; 
 
     // unit of beam energy: GeV
-    Gaudi::Property<std::map<std::string, double>>      m_Ebeammaps{this, "InputBeamEnergyMap"};
+    Gaudi::Property<double>      m_Ebeam{this, "InputBeamEnergy"};
 
-    // unit of the rotation along Y: rad
-    Gaudi::Property<std::map<std::string, double>>      m_rotYmaps {this, "RotationAlongYMap"};
+    // Rotation along Y for single beam background. Unit: rad
+    Gaudi::Property<std::map<std::string, double>>      m_rotYMap {this, "RotationAlongYMap"};
 
 private:
     std::map<std::string, std::shared_ptr<IBeamBackgroundFileParser>> m_beaminputs;
diff --git a/Generator/src/GuineaPigPairsFileParser.h b/Generator/src/GuineaPigPairsFileParser.h
index 078a38a0..71e2b0a0 100644
--- a/Generator/src/GuineaPigPairsFileParser.h
+++ b/Generator/src/GuineaPigPairsFileParser.h
@@ -24,6 +24,8 @@ public:
     GuineaPigPairsFileParser(const std::string& filename);
 
     bool load(IBeamBackgroundFileParser::BeamBackgroundData&);
+    bool load(IBeamBackgroundFileParser::BeamBackgroundData&, int) { return 0; }
+    bool SampleParticleNum(int&, int&) { return true; }
 
 private:
     std::ifstream m_input;
diff --git a/Generator/src/HepMCRdr.cpp b/Generator/src/HepMCRdr.cpp
index c89a6190..0ba5577a 100644
--- a/Generator/src/HepMCRdr.cpp
+++ b/Generator/src/HepMCRdr.cpp
@@ -20,7 +20,7 @@
 
 
 using namespace edm4hep;
-using namespace std;
+//using namespace std;
 
 DECLARE_COMPONENT(HepMCRdr)
 
diff --git a/Generator/src/IBeamBackgroundFileParser.h b/Generator/src/IBeamBackgroundFileParser.h
index fedc6fab..dcc8f3ac 100644
--- a/Generator/src/IBeamBackgroundFileParser.h
+++ b/Generator/src/IBeamBackgroundFileParser.h
@@ -20,6 +20,7 @@ public:
     // Internal used Data
     struct BeamBackgroundData {
         int pdgid;
+        int charge;
 
         double x; // unit: mm
         double y; // unit: mm
@@ -32,13 +33,16 @@ public:
         double mass; // unit: GeV
 
         BeamBackgroundData() 
-          : pdgid(11), x(0), y(0), z(0), t(0), 
+          : pdgid(11), charge(-1), x(0), y(0), z(0), t(0), 
             px(0), py(0), pz(0), mass(0) {}
         
     };
 
     // return false if failed to load the data
     virtual bool load(BeamBackgroundData&) = 0;
+    virtual bool load(BeamBackgroundData&, int) = 0;
+    virtual bool SampleParticleNum(int&, int&) = 0;
+    //virtual int totalEnteries() = 0;
 };
 
 #endif
-- 
GitLab