9#include <beast/microtpc/modules/TpcDigitizerModule.h>
10#include <beast/microtpc/dataobjects/MicrotpcSimHit.h>
12#include <mdst/dataobjects/MCParticle.h>
13#include <framework/logging/Logger.h>
14#include <framework/gearbox/GearDir.h>
15#include <framework/gearbox/Const.h>
16#include <framework/core/RandomNumbers.h>
17#include <framework/geometry/B2Vector3.h>
21#include <boost/foreach.hpp>
25using namespace microtpc;
47TpcDigitizerModule::~TpcDigitizerModule()
53 B2INFO(
"TpcDigitizer: Initializing");
60 fctToT_Calib1 =
new TF1(
"fctToT_Calib1",
"[0]*(x/[3]+[1])/(x/[3]+[2])", 0., 100000.);
63 fctToT_Calib2 =
new TF1(
"fctToT_Calib2",
"[0]*(x/[3]+[1])/(x/[3]+[2])", 0., 100000.);
94 std::vector<double> T0(
m_nTPC,
98 for (
const auto& microtpcSimHit : microtpcSimHits) {
99 const int detNb = microtpcSimHit.getdetNb();
100 const ROOT::Math::XYZVector simHitPosition = microtpcSimHit.gettkPos();
102 simHitPosition.X() / 100. -
m_TPCCenter[detNb].X(),
103 simHitPosition.Y() / 100. -
m_TPCCenter[detNb].Y(),
108 const double T = chipPosition.
Z() +
m_z_DG / 2.;
114 for (
auto& val : T0) {
124 for (
const auto& microtpcSimHit : microtpcSimHits) {
126 const int PDGid = microtpcSimHit.gettkPDG();
128 if (PDGid != 1000020040 && PDGid != 1000060120 && PDGid != 1000080160 && PDGid !=
Const::proton.getPDGCode()) {
133 const int detNb = microtpcSimHit.getdetNb();
134 const double edep = microtpcSimHit.getEnergyDep();
135 const double niel = microtpcSimHit.getEnergyNiel();
136 const int pdg = microtpcSimHit.gettkPDG();
137 const int trkID = microtpcSimHit.gettkID();
139 const ROOT::Math::XYZVector simHitPosition = microtpcSimHit.gettkPos();
141 simHitPosition.X() / 100. -
m_TPCCenter[detNb].X(),
142 simHitPosition.Y() / 100. -
m_TPCCenter[detNb].Y(),
148 ROOT::Math::XYZVector ChipPosition(0, 0, 0);
150 if (detNb == 0 || detNb == 3) {
151 ChipPosition.SetX(-chipPosition.
Y());
152 ChipPosition.SetY(-chipPosition.
X());
153 ChipPosition.SetZ(chipPosition.
Z() +
m_z_DG / 2.);
155 if (detNb == 1 || detNb == 2) {
156 ChipPosition.SetX(chipPosition.
Y());
157 ChipPosition.SetY(chipPosition.
X());
158 ChipPosition.SetZ(chipPosition.
Z() +
m_z_DG / 2.);
162 ChipPosition.SetX(chipPosition.
Y());
163 ChipPosition.SetY(chipPosition.
X());
164 ChipPosition.SetZ(chipPosition.
Z() +
m_z_DG / 2);
183 (0. < ChipPosition.Z() && ChipPosition.Z() <
m_z_DG) &&
188 const double ionEn = (edep - niel) * 1e3;
198 const double meanEl = ionEn * 1e3 /
m_Workfct;
200 const int NbEle = (int)gRandom->Gaus(meanEl, sigma);
201 const double NbEle_real = NbEle - NbEle *
m_GasAbs * chipPosition.
Z();
204 for (
int ie = 0; ie < (int)NbEle_real; ie++) {
207 double x_DG, y_DG, z_DG, t_DG;
208 Drift(ChipPosition.X(),
221 for (
int ig1 = 0; ig1 < (int)GEM_gain1; ig1++) {
224 const ROOT::Math::XYVector GEM1(
GEMGeo1(x_DG, y_DG));
226 double x_TG, y_TG, z_TG, t_TG;
231 for (
int ig2 = 0; ig2 < (int)GEM_gain2; ig2++) {
234 const ROOT::Math::XYVector GEM2(
GEMGeo2(x_TG, y_TG));
236 double x_CG, y_CG, z_CG, t_CG;
243 int quT = gRandom->Uniform(-1, 1);
244 int bci = (int)((t_DG + t_TG + t_CG - T0[detNb]) / (double)
m_PixelTimeBin) + quT;
251 (0 <= bci && bci < MAXtSIZE)) {
298 double sl,
double vd)
303 x2 = x1 + gRandom->Gaus(0.,
sqrt(z1) * st);
305 y2 = y1 + gRandom->Gaus(0.,
sqrt(z1) * st);
307 z2 = z1 + gRandom->Gaus(0.,
sqrt(z1) * sl);
311 x2 = -1000; y2 = -1000; z2 = -1000; t2 = -1000;
316 static const double sqrt3o4 = std::sqrt(3. / 4.);
319 int yint = (int)(y1 / (sqrt3o4 *
m_GEMpitch) + 0.5);
326 return ROOT::Math::XYVector(x2, y2);
331 static const double sqrt3o4 = std::sqrt(3. / 4.);
334 int yint = (int)(x1 / (sqrt3o4 *
m_GEMpitch) + 0.5);
341 return ROOT::Math::XYVector(x2, y2);
352 std::vector<int> col;
353 std::vector<int> row;
354 std::vector<int> ToT;
355 std::vector<int> bci;
364 const auto& key = keyValuePair.first;
366 int i = std::get<0>(key);
368 int j = std::get<1>(key);
370 if (
m_dchip_map[std::tuple<int, int>(i, j)] == 1) {
373 const int quE = gRandom->Uniform(0, 2);
377 for (
auto& keyValuePair2 :
m_dchip) {
378 const auto& key2 = keyValuePair2.first;
379 int k = std::get<2>(key2);
380 if (
m_dchip[std::tuple<int, int, int>(i, j, k)] > thresEl) {
391 for (
auto& keyValuePair2 :
m_dchip) {
392 const auto& key2 = keyValuePair2.first;
393 int k = std::get<2>(key2);
396 NbOfEl +=
m_dchip[std::tuple<int, int, int>(i, j, k)];
400 if (NbOfEl > thresEl && NbOfEl <= 45.*
m_TOTQ1) {
404 }
else if (NbOfEl > 800.*
m_TOTQ1) {
426 if (NbOfEl > thresEl && NbOfEl <= 45.*
m_TOTQ1) {
430 }
else if (NbOfEl > 800.*
m_TOTQ1) {
452 if (bci.size() > 0) {
456 sort(t0.begin(), t0.end());
459 for (
int j = 0; j < (int)bci.size(); j++) {
662 GearDir content =
GearDir(
"/Detector/DetectorComponent[@name=\"MICROTPC\"]/Content/");
665 BOOST_FOREACH(
const GearDir & activeParams, content.getNodes(
"Active")) {
675 m_phase = content.getDouble(
"Phase");
692 m_TOTA1 = content.getDouble(
"TOTA1");
693 m_TOTB1 = content.getDouble(
"TOTB1");
694 m_TOTC1 = content.getDouble(
"TOTC1");
695 m_TOTQ1 = content.getDouble(
"TOTQ1");
696 m_TOTA2 = content.getDouble(
"TOTA2");
697 m_TOTB2 = content.getDouble(
"TOTB2");
698 m_TOTC2 = content.getDouble(
"TOTC2");
699 m_TOTQ2 = content.getDouble(
"TOTQ2");
700 m_z_DG = content.getDouble(
"z_DG");
701 m_z_TG = content.getDouble(
"z_TG");
702 m_z_CG = content.getDouble(
"z_CG");
703 m_Dl_DG = content.getDouble(
"Dl_DG");
704 m_Dl_TG = content.getDouble(
"Dl_TG");
705 m_Dl_CG = content.getDouble(
"Dl_CG");
706 m_Dt_DG = content.getDouble(
"Dt_DG");
707 m_Dt_TG = content.getDouble(
"Dt_TG");
708 m_Dt_CG = content.getDouble(
"Dt_CG");
709 m_v_DG = content.getDouble(
"v_DG");
710 m_v_TG = content.getDouble(
"v_TG");
711 m_v_CG = content.getDouble(
"v_CG");
712 m_Workfct = content.getDouble(
"Workfct");
713 m_Fanofac = content.getDouble(
"Fanofac");
714 m_GasAbs = content.getDouble(
"GasAbs");
716 B2INFO(
"TpcDigitizer: Aquired tpc locations and gas parameters");
717 B2INFO(
" from MICROTPC.xml. There are " <<
m_nTPC <<
" TPCs implemented");
DataType Z() const
access variable Z (= .at(2) without boundary check)
DataType X() const
access variable X (= .at(0) without boundary check)
DataType Y() const
access variable Y (= .at(1) without boundary check)
void RotateX(DataType angle)
Rotates the B2Vector3 around the x-axis.
void RotateZ(DataType angle)
Rotates the B2Vector3 around the z-axis.
static const ChargedStable proton
proton particle
GearDir is the basic class used for accessing the parameter store.
ClassMicrotpcHit - digitization simulated hit for the Microtpc detector.
void setDescription(const std::string &description)
Sets the description of the module.
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
double m_GEMGainRMS2
GEM 2 RMS.
double m_TOTC1
TOT factor C1.
double m_lowerTimingCut
Lower timing cut.
double m_ChipRowY
Chip row y dimension.
std::map< std::tuple< int, int >, int > m_dchip_pdg_map
chip pdg map arrays
double m_GEMGain1
GEM 1 gain.
int m_LookAtRec
Flag 0/1 only look at nuclear recoils.
double m_Dl_CG
Longitudinal diffusion in collection gap.
double m_TOTA1
TOT factor A1.
double m_Dl_DG
Longitudinal diffusion in drift gap.
std::map< std::tuple< int, int >, int > m_dchip_trkID_map
chip track ID map arrays
double m_PixelTimeBin
Pixel time bin.
ROOT::Math::XYVector GEMGeo1(double x1, double y1)
GEMazition of GEM1.
double m_z_TG
z transfer gap
virtual void initialize() override
Initialize the Module.
TF1 * fctToT_Calib1
Define ToT calib 1.
virtual void event() override
This method is the core of the module.
double m_TOTB1
TOT factor B1.
double m_v_DG
Drift velocity in drift gap.
double m_GEMGain2
GEM 2 gain.
virtual void endRun() override
This method is called if the current run ends.
double m_ChipColumnX
Chip column x dimension.
void getXMLData()
reads data from MICROTPC.xml: tube location, drift data filename, sigma of impulse response function
double m_ScaleGain2
Scale GEM 2 gain.
TpcDigitizerModule()
Constructor: Sets the description, the properties and the parameters of the module.
virtual void terminate() override
This method is called at the end of the event processing.
double m_TOTQ2
TOT factor Q2.
double m_upperTimingCut
Upper timing cut.
std::map< std::tuple< int, int, int >, int > m_dchip
chip store arrays
int m_nTPC
number of detectors.
TF1 * fctToT_Calib2
Define ToT calib 2.
std::map< std::tuple< int, int >, int > m_dchip_detNb_map
chip Nb map arrays
virtual void beginRun() override
Called when entering a new run.
double m_TOTC2
TOT factor C2.
double m_Dt_CG
Transverse diffusion in collection gap.
std::vector< float > m_TPCAngleZ
TPC angle Z.
double m_z_CG
z collection gap
int m_ChipRowNb
Chip row number.
std::map< std::tuple< int, int >, int > m_dchip_map
chip map arrays
double m_GEMGainRMS1
GEM 1 RMS.
double m_Dt_TG
Transverse diffusion in transfer gap.
std::vector< float > m_TPCAngleX
TPC angle X.
int m_PixelTimeBinNb
Pixel time number of bin.
int olddetNb
Old detector counter.
std::vector< ROOT::Math::XYZVector > m_TPCCenter
TPC coordinate.
int m_ChipColumnNb
Chip column number.
double m_Dt_DG
Transverse diffusion in drift gap.
void Pixelization()
Produces the pixelization.
double m_Workfct
Work function.
ROOT::Math::XYVector GEMGeo2(double x1, double y1)
GEMazition of GEM2.
StoreArray< MicrotpcHit > m_microtpcHit
Array for MicrotpcHit.
double m_ScaleGain1
Scale GEM 1 gain.
double m_TOTA2
TOT factor A2.
int m_PixelThresholdRMS
Pixel threshold RMS.
int m_PixelThreshold
Pixel threshold.
double m_v_CG
Drift velocity in collection gap.
double m_GasAbs
Absorption in gas.
virtual void Drift(double, double, double, double &, double &, double &, double &, double, double, double)
Drift ionization Make the ionization drifting from (x,y,z) to GEM1 top plane.
int oldtrkID
Old track ID.
double m_Dl_TG
Longitudinal diffusion in transfer gap.
double m_Fanofac
Fano factor.
double m_GEMpitch
GEM pitch.
double m_v_TG
Drift velocity in transfer gap.
double m_TOTB2
TOT factor B2.
double m_TOTQ1
TOT factor Q1.
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
Abstract base class for different kinds of events.