1 #include "StFstFastSimMaker.h"
3 #include "St_base/StMessMgr.h"
5 #include "StEvent/StEvent.h"
6 #include "StEvent/StRnDHit.h"
7 #include "StEvent/StRnDHitCollection.h"
9 #include "tables/St_g2t_fts_hit_Table.h"
10 #include "tables/St_g2t_track_Table.h"
12 #include "StarClassLibrary/StThreeVectorF.hh"
13 #include "StarGenerator/UTIL/StarRandom.h"
25 #define _USE_MATH_DEFINES
36 constexpr
float SQRT12 = sqrt(12.0);
40 float RMIN[] = {0.95 * 4.3, 0.95 * 4.3, 0.95 * 4.3, 0.95 * 5.0, 0.95 * 5.0, 0.95 * 5.0};
41 float RMAX[] = {1.05 * 15.0, 1.05 * 25.0, 1.05 * 25.0, 1.05 * 28.0, 1.05 * 28.0, 1.05 * 28.0};
44 float RSegment[] = {5., 7.875, 10.75, 13.625, 16.5, 19.375, 22.25, 25.125, 28.};
47 const bool verbose =
false;
50 typedef std::tuple<int, int, int> FstKeyTriple;
55 StFstFastSimMaker::StFstFastSimMaker(
const Char_t *name)
78 h3GlobalDeltaXYDisk(0),
79 h3GlobalDeltaXYR(0) { }
81 int StFstFastSimMaker::Init() {
84 fOut =
new TFile(mQAFileName.Data(),
"RECREATE");
85 AddHist(hTrutHitYXDisk =
new TH3F(
"hTrutHitYXDisk",
"Global hits before segmentation", 151, -75.5, 75.5, 151, -75.5, 75.5, 10, 0, 10));
86 AddHist(hTrutHitRDisk =
new TH2F(
"hTrutHitRDisk",
"Global hits before segmentation", 400, 0, 40, 10, 0, 10));
87 AddHist(hTrutHitRShower[0] =
new TH2F(
"hTrutHitRShower_4",
"Global hits before segmentation", 400, 0, 40, 20, -10, 10));
88 AddHist(hTrutHitRShower[1] =
new TH2F(
"hTrutHitRShower_5",
"Global hits before segmentation", 400, 0, 40, 20, -10, 10));
89 AddHist(hTrutHitRShower[2] =
new TH2F(
"hTrutHitRShower_6",
"Global hits before segmentation", 400, 0, 40, 20, -10, 10));
90 AddHist(hTrutHitPhiDisk =
new TH2F(
"hTrutHitPhiDisk",
"Global hits before segmentation", 360, 0, 360, 10, 0, 10));
91 AddHist(hTrutHitPhiZ =
new TH2F(
"hTrutHitPhiZ",
"Global hits before segmentation", 360, 0, 360, 6000, 0, 600));
92 AddHist(hRecoHitYXDisk =
new TH3F(
"hRecoHitYXDisk",
"Global hits after segmentation", 151, -75.5, 75.5, 151, -75.5, 75.5, 10, 0, 10));
93 AddHist(hRecoHitRDisk =
new TH2F(
"hRecoHitRDisk",
"Global hits after segmentation", 400, 0, 40, 10, 0, 10));
94 AddHist(hRecoHitPhiDisk =
new TH2F(
"hRecoHitPhiDisk",
"Global hits after segmentation", 360, 0, 360, 10, 0, 10));
95 AddHist(hRecoHitPhiZ =
new TH2F(
"hRecoHitPhiZ",
"Global hits after segmentation", 360, 0, 360, 6000, 0, 600));
96 AddHist(hGlobalDRDisk =
new TH2F(
"hGlobalDRDisk",
"; Reco. r - MC r [cm]; Events;", 1000, -50, 50, 10, 0, 10));
97 AddHist(hGlobalZ =
new TH1F(
"hGlobalZ",
"; Z [cm]; Events;", 6000, 0, 600));
98 AddHist(h3GlobalDeltaXYR =
new TH3F(
"h3GlobalDeltaXYR",
";globalDeltaX; globalDeltaY; R", 300, -0.3, 0.3, 300, -3, 3, 100, 0, 30));
99 AddHist(h2GlobalXY =
new TH2F(
"h2GlobalXY",
";globalX; globalY", 1510, -75.5, 75.5, 1510, -75.5, 75.5));
100 AddHist(h2GlobalSmearedXY =
new TH2F(
"h2GlobalSmearedXY",
";globalSmearedX; globalSmearedY", 1510, -75.5, 75.5, 1510, -75.5, 75.5));
101 AddHist(h2GlobalDeltaXY =
new TH2F(
"h2GlobalDeltaXY",
";globalDeltaX; globalDeltaY", 151, -75.5, 75.5, 151, -75.5, 75.5));
102 AddHist(h3GlobalDeltaXYDisk =
new TH3F(
"h3GlobalDeltaXYDisk",
";globalDeltaX; globalDeltaY; Disk", 151, -75.5, 75.5, 151, -75.5, 75.5, 10, 0, 10));
104 return StMaker::Init();
108 FstGlobal::RMIN[i] = rmn;
109 FstGlobal::RMAX[i] = rmx;
113 LOG_DEBUG <<
"StFstFastSimMaker::Make" << endm;
120 LOG_DEBUG <<
"Creating StEvent" << endm;
123 if (0 == event->rndHitCollection()) {
125 LOG_DEBUG <<
"Creating StRnDHitCollection for FTS" << endm;
138 void StFstFastSimMaker::FillSilicon(
StEvent *event) {
142 const int MAXR = mNumR;
143 const int MAXPHI = mNumPHI * mNumSEC;
145 float X0[] = {0, 0, 0, 0, 0, 0};
146 float Y0[] = {0, 0, 0, 0, 0, 0};
149 for (
int i = 0; i < 6; i++) {
150 X0[i] = mRaster * TMath::Cos(i * 60 * TMath::DegToRad());
151 Y0[i] = mRaster * TMath::Sin(i * 60 * TMath::DegToRad());
156 std::map< FstGlobal::FstKeyTriple, StRnDHit* > hitMap;
157 std::map< FstGlobal::FstKeyTriple, double > energySum;
158 std::map< FstGlobal::FstKeyTriple, double > energyMax;
161 St_g2t_fts_hit *hitTable =
static_cast<St_g2t_fts_hit *
>(GetDataSet(
"g2t_fsi_hit"));
163 LOG_INFO <<
"g2t_fsi_hit table is empty" << endm;
167 const Int_t nHits = hitTable->GetNRows();
168 LOG_DEBUG <<
"g2t_fsi_hit table has " << nHits <<
" hits" << endm;
169 const g2t_fts_hit_st *
hit = hitTable->GetTable();
174 St_g2t_track *trkTable =
static_cast<St_g2t_track *
>(GetDataSet(
"g2t_track"));
176 LOG_INFO <<
"g2t_track table is empty" << endm;
180 const Int_t nTrks = trkTable->GetNRows();
182 LOG_DEBUG <<
"g2t_track table has " << nTrks <<
" tracks" << endm;
184 const g2t_track_st *trk = trkTable->GetTable();
188 for (Int_t i = 0; i < nHits; ++i) {
190 hit = (g2t_fts_hit_st *)hitTable->At(i);
197 int volume_id = hit->volume_id;
198 LOG_DEBUG <<
"volume_id = " << volume_id << endm;
199 int disk = volume_id / 1000;
200 int wedge = (volume_id % 1000) / 10;
201 int sensor = volume_id % 10;
204 size_t disk_index = disk - 1;
206 LOG_DEBUG <<
"disk = " << disk <<
", wedge = " << wedge <<
", sensor = " << sensor << endm;
209 if ( disk > 6 )
continue;
212 double energy = hit->de;
213 int track = hit->track_p;
215 trk = (g2t_track_st *)trkTable->At(track);
216 int isShower =
false;
218 isShower = trk->is_shower;
221 double xc = X0[disk_index];
222 double yc = Y0[disk_index];
225 double x = hit->x[0];
226 double y = hit->x[1];
227 double z = hit->x[2];
233 double rastered_x = x - xc;
234 double rastered_y = y - yc;
236 double r = sqrt(x * x + y * y);
237 double p = atan2(y, x);
240 double rr = sqrt(rastered_x * rastered_x + rastered_y * rastered_y);
241 double pp = atan2(rastered_y, rastered_x);
245 auto wrapAngle = [&](
double angle ) {
246 angle = fmod( angle, 2.0 * M_PI );
253 pp = wrapAngle( pp );
255 LOG_DEBUG <<
"rr = " << rr <<
" pp=" << pp << endm;
256 LOG_DEBUG <<
"RMIN = " << FstGlobal::RMIN[disk_index] <<
" RMAX= " << FstGlobal::RMAX[disk_index] << endm;
259 if (rr < FstGlobal::RMIN[disk_index] || rr > FstGlobal::RMAX[disk_index])
262 LOG_DEBUG <<
"rr = " << rr << endm;
265 int r_index = floor(MAXR * (rr - FstGlobal::RMIN[disk_index]) / (FstGlobal::RMAX[disk_index] - FstGlobal::RMIN[disk_index]));
268 for (
int ii = 0; ii < MAXR; ii++)
269 if (rr > FstGlobal::RSegment[ii] && rr <= FstGlobal::RSegment[ii + 1])
273 int phi_index = int(MAXPHI * pp / 2.0 / M_PI);
279 assert(r_index < MAXR);
281 assert(phi_index < MAXPHI);
286 auto threeKey = std::tie( disk_index, r_index, phi_index );
288 if (hitMap.count( threeKey ) == 0) {
290 if (FstGlobal::verbose){
291 LOG_INFO << Form(
"NEW d=%1d xyz=%8.4f %8.4f %8.4f r=%8.4f phi=%8.4f iR=%2d iPhi=%4d dE=%8.4f[MeV] truth=%d",
292 disk, x, y, z, r, p, r_index, phi_index, energy * 1000.0, track)
298 fsihit->setDetectorId(kFtsId);
299 fsihit->setLayer(disk);
304 double p0 = (phi_index + 0.5) * 2.0 * M_PI / double(MAXPHI);
305 double dp = 2.0 * M_PI / double(MAXPHI) / FstGlobal::SQRT12;
308 double r0 = (FstGlobal::RSegment[r_index] + FstGlobal::RSegment[r_index + 1]) * 0.5;
309 double dr = FstGlobal::RSegment[r_index + 1] - FstGlobal::RSegment[r_index];
311 double x0 = r0 * cos(p0) + xc;
312 double y0 = r0 * sin(p0) + yc;
313 assert(TMath::Abs(x0) + TMath::Abs(y0) > 0);
314 double dz = 0.03 / FstGlobal::SQRT12;
315 double er = dr / FstGlobal::SQRT12;
320 fsihit->setErrorMatrix(&FstGlobal::Hack1to6(fsihit)[0][0]);
322 fsihit->setCharge(energy);
323 fsihit->setIdTruth(track, 100);
324 hits.push_back(fsihit);
326 hitMap[ threeKey ] = fsihit;
327 energySum[ threeKey ] = energy;
328 energyMax[ threeKey ] = energy;
330 if (FstGlobal::verbose){
331 LOG_INFO << Form(
"NEW d=%1d xyz=%8.4f %8.4f %8.4f ", disk, x, y, z) << endm;
332 LOG_INFO << Form(
"smeared xyz=%8.4f %8.4f %8.4f ", fsihit->position().x(), fsihit->position().y(), fsihit->position().z()) << endm;
336 TVector2 hitpos_mc(x, y);
337 TVector2 hitpos_rc(fsihit->position().x(), fsihit->position().y());
339 hTrutHitYXDisk->Fill(x, y, disk);
340 hTrutHitRDisk->Fill(hitpos_mc.Mod(), disk);
343 hTrutHitRShower[0]->Fill(hitpos_mc.Mod(), isShower);
345 hTrutHitRShower[1]->Fill(hitpos_mc.Mod(), isShower);
347 hTrutHitRShower[2]->Fill(hitpos_mc.Mod(), isShower);
349 hTrutHitPhiDisk->Fill(hitpos_mc.Phi() * 180.0 / TMath::Pi(), disk);
350 hTrutHitPhiZ->Fill(hitpos_mc.Phi() * 180.0 / TMath::Pi(), z);
351 hRecoHitYXDisk->Fill(fsihit->position().x(), fsihit->position().y(), disk);
352 hRecoHitRDisk->Fill(hitpos_rc.Mod(), disk);
353 hRecoHitPhiDisk->Fill(hitpos_rc.Phi() * 180.0 / TMath::Pi(), disk);
354 hRecoHitPhiZ->Fill(hitpos_rc.Phi() * 180.0 / TMath::Pi(), z);
355 hGlobalDRDisk->Fill(hitpos_rc.Mod() - hitpos_mc.Mod(), disk);
356 hGlobalZ->Fill(fsihit->position().z());
359 h2GlobalXY->Fill(x, y);
360 h2GlobalSmearedXY->Fill(fsihit->position().x(), fsihit->position().y());
361 h2GlobalDeltaXY->Fill(fsihit->position().x() - x, fsihit->position().y() - y);
362 h3GlobalDeltaXYDisk->Fill(fsihit->position().x() - x, fsihit->position().y() - y, disk);
364 h3GlobalDeltaXYR->Fill(fsihit->position().x() - x, fsihit->position().y() - y, sqrt(pow(fsihit->position().x(), 2) + pow(fsihit->position().y(), 2)));
369 fsihit = hitMap[ threeKey ] ;
370 fsihit->setCharge(fsihit->charge() + energy);
373 energySum[ threeKey ] = energySum[ threeKey ] + energy;
375 if (energy> energyMax[ threeKey ])
376 energyMax[ threeKey ] = energy;
379 track = fsihit->idTruth();
381 fsihit->setIdTruth(track, 100 * (energyMax[ threeKey ] / energySum[ threeKey ]));
384 int nfsihit = hits.size();
389 for (
int i = 0; i < nfsihit; i++) {
390 double rnd_save = rand.
flat();
391 if (rnd_save > mInEff){
392 fsicollection->addHit(hits[i]);
395 if (FstGlobal::verbose) {
396 LOG_DEBUG << Form(
"Found %d/%d g2t hits in %d cells, created %d hits with ADC>0", count, nHits, nfsihit, fsicollection->numberOfHits()) << endm;
405 hTrutHitYXDisk->Write();
406 hTrutHitRDisk->Write();
407 hTrutHitRShower[0]->Write();
408 hTrutHitRShower[1]->Write();
409 hTrutHitRShower[2]->Write();
410 hTrutHitPhiDisk->Write();
411 hTrutHitPhiZ->Write();
412 hRecoHitYXDisk->Write();
413 hRecoHitRDisk->Write();
414 hRecoHitPhiDisk->Write();
415 hRecoHitPhiZ->Write();
416 hGlobalDRDisk->Write();
418 h3GlobalDeltaXYR->Write();
420 h2GlobalSmearedXY->Write();
421 h2GlobalDeltaXY->Write();
422 h3GlobalDeltaXYDisk->Write();
435 auto hiPos = stHit->position();
436 auto hiErr = stHit->positionError();
437 double Rxy = sqrt(hiPos[0] * hiPos[0] + hiPos[1] * hiPos[1]);
438 double cosFi = hiPos[0] / Rxy;
439 double sinFi = hiPos[1] / Rxy;
440 double T[3][3] = {{cosFi, -Rxy * sinFi, 0}, {sinFi, Rxy * cosFi, 0}, {0, 0, 1}};
441 double Ginp[6] = {hiErr[0] * hiErr[0], 0, hiErr[1] * hiErr[1], 0, 0, hiErr[2] * hiErr[2]};
447 for (
int i = 0, li = 0; i < 3; li += ++i) {
448 for (
int j = 0; j <= i; j++) {
449 mtxF[i][j] = Gout[li + j];
450 mtxF[j][i] = mtxF[i][j];
static StarRandom & Instance()
Obtain the single instance of the random number generator.
virtual void AddData(TDataSet *data, const char *dir=".data")
User methods.
A class for providing random number generation.
Double_t flat() const
Return a random number uniformly distributed between 0 and 1.
static float * trasat(const float *a, const float *s, float *r, int m, int n)
void SetDisk(const int i, const float rmn, const float rmx)
Set min/max active radii for each disk.