1 #include "StFstFastSimMaker.h"
3 #include "St_base/StMessMgr.h"
5 #include "StEvent/StEvent.h"
6 #include "StEvent/StRnDHit.h"
7 #include "StEvent/StFstHit.h"
8 #include "StEvent/StFstHitCollection.h"
9 #include "StEvent/StRnDHitCollection.h"
11 #include "tables/St_g2t_fts_hit_Table.h"
12 #include "tables/St_g2t_track_Table.h"
14 #include "StarClassLibrary/StThreeVectorF.hh"
15 #include "StarGenerator/UTIL/StarRandom.h"
27 #define _USE_MATH_DEFINES
38 constexpr
float SQRT12 = sqrt(12.0);
42 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};
43 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};
46 float RSegment[] = {5., 7.875, 10.75, 13.625, 16.5, 19.375, 22.25, 25.125, 28.};
49 const bool verbose =
false;
52 typedef std::tuple<int, int, int> FstKeyTriple;
57 StFstFastSimMaker::StFstFastSimMaker(
const Char_t *name)
64 mGEANTPassthrough{
false},
80 h3GlobalDeltaXYDisk(0),
81 h3GlobalDeltaXYR(0) { }
83 int StFstFastSimMaker::Init() {
86 fOut =
new TFile(mQAFileName.Data(),
"RECREATE");
87 AddHist(hTrutHitYXDisk =
new TH3F(
"hTrutHitYXDisk",
"Global hits before segmentation", 151, -75.5, 75.5, 151, -75.5, 75.5, 10, 0, 10));
88 AddHist(hTrutHitRDisk =
new TH2F(
"hTrutHitRDisk",
"Global hits before segmentation", 400, 0, 40, 10, 0, 10));
89 AddHist(hTrutHitRShower[0] =
new TH2F(
"hTrutHitRShower_4",
"Global hits before segmentation", 400, 0, 40, 20, -10, 10));
90 AddHist(hTrutHitRShower[1] =
new TH2F(
"hTrutHitRShower_5",
"Global hits before segmentation", 400, 0, 40, 20, -10, 10));
91 AddHist(hTrutHitRShower[2] =
new TH2F(
"hTrutHitRShower_6",
"Global hits before segmentation", 400, 0, 40, 20, -10, 10));
92 AddHist(hTrutHitPhiDisk =
new TH2F(
"hTrutHitPhiDisk",
"Global hits before segmentation", 360, 0, 360, 10, 0, 10));
93 AddHist(hTrutHitPhiZ =
new TH2F(
"hTrutHitPhiZ",
"Global hits before segmentation", 360, 0, 360, 6000, 0, 600));
94 AddHist(hRecoHitYXDisk =
new TH3F(
"hRecoHitYXDisk",
"Global hits after segmentation", 151, -75.5, 75.5, 151, -75.5, 75.5, 10, 0, 10));
95 AddHist(hRecoHitRDisk =
new TH2F(
"hRecoHitRDisk",
"Global hits after segmentation", 400, 0, 40, 10, 0, 10));
96 AddHist(hRecoHitPhiDisk =
new TH2F(
"hRecoHitPhiDisk",
"Global hits after segmentation", 360, 0, 360, 10, 0, 10));
97 AddHist(hRecoHitPhiZ =
new TH2F(
"hRecoHitPhiZ",
"Global hits after segmentation", 360, 0, 360, 6000, 0, 600));
98 AddHist(hGlobalDRDisk =
new TH2F(
"hGlobalDRDisk",
"; Reco. r - MC r [cm]; Events;", 1000, -50, 50, 10, 0, 10));
99 AddHist(hGlobalZ =
new TH1F(
"hGlobalZ",
"; Z [cm]; Events;", 6000, 0, 600));
100 AddHist(h3GlobalDeltaXYR =
new TH3F(
"h3GlobalDeltaXYR",
";globalDeltaX; globalDeltaY; R", 300, -0.3, 0.3, 300, -3, 3, 100, 0, 30));
101 AddHist(h2GlobalXY =
new TH2F(
"h2GlobalXY",
";globalX; globalY", 1510, -75.5, 75.5, 1510, -75.5, 75.5));
102 AddHist(h2GlobalSmearedXY =
new TH2F(
"h2GlobalSmearedXY",
";globalSmearedX; globalSmearedY", 1510, -75.5, 75.5, 1510, -75.5, 75.5));
103 AddHist(h2GlobalDeltaXY =
new TH2F(
"h2GlobalDeltaXY",
";globalDeltaX; globalDeltaY", 151, -75.5, 75.5, 151, -75.5, 75.5));
104 AddHist(h3GlobalDeltaXYDisk =
new TH3F(
"h3GlobalDeltaXYDisk",
";globalDeltaX; globalDeltaY; Disk", 151, -75.5, 75.5, 151, -75.5, 75.5, 10, 0, 10));
106 return StMaker::Init();
110 FstGlobal::RMIN[i] = rmn;
111 FstGlobal::RMAX[i] = rmx;
115 LOG_DEBUG <<
"StFstFastSimMaker::Make" << endm;
122 LOG_DEBUG <<
"Creating StEvent" << endm;
125 if (0 == event->rndHitCollection()) {
127 LOG_DEBUG <<
"Creating StRnDHitCollection for FTS" << endm;
133 if (!fstHitCollection) {
135 event->setFstHitCollection(fstHitCollection);
136 LOG_DEBUG <<
"Make() - Added new StFstHitCollection to this StEvent" << endm;
149 void StFstFastSimMaker::FillSilicon(
StEvent *event) {
153 const int MAXR = mNumR;
154 const int MAXPHI = mNumPHI * mNumSEC;
156 if ( mGEANTPassthrough ){
157 LOG_INFO <<
"FST Hits using GEANT xyz directly (no raster etc.)" << endm;
161 std::map< FstGlobal::FstKeyTriple, StRnDHit* > hitMap;
162 std::map< FstGlobal::FstKeyTriple, double > energySum;
163 std::map< FstGlobal::FstKeyTriple, double > energyMax;
166 St_g2t_fts_hit *hitTable =
static_cast<St_g2t_fts_hit *
>(GetDataSet(
"g2t_fsi_hit"));
168 LOG_INFO <<
"g2t_fsi_hit table is empty" << endm;
172 const Int_t nHits = hitTable->GetNRows();
173 LOG_DEBUG <<
"g2t_fsi_hit table has " << nHits <<
" hits" << endm;
174 const g2t_fts_hit_st *
hit = hitTable->GetTable();
179 St_g2t_track *trkTable =
static_cast<St_g2t_track *
>(GetDataSet(
"g2t_track"));
181 LOG_INFO <<
"g2t_track table is empty" << endm;
185 const Int_t nTrks = trkTable->GetNRows();
187 LOG_DEBUG <<
"g2t_track table has " << nTrks <<
" tracks" << endm;
189 const g2t_track_st *trk = trkTable->GetTable();
193 for (Int_t i = 0; i < nHits; ++i) {
195 hit = (g2t_fts_hit_st *)hitTable->At(i);
202 int volume_id = hit->volume_id;
203 LOG_DEBUG <<
"volume_id = " << volume_id << endm;
204 int disk = volume_id / 1000;
205 int wedge = (volume_id % 1000) / 10;
206 int sensor = volume_id % 10;
209 size_t disk_index = disk - 1;
211 LOG_DEBUG <<
"disk = " << disk <<
", wedge = " << wedge <<
", sensor = " << sensor << endm;
214 if ( disk > 6 )
continue;
217 double energy = hit->de;
218 int track = hit->track_p;
220 trk = (g2t_track_st *)trkTable->At(track);
221 int isShower =
false;
223 isShower = trk->is_shower;
227 const double z_delta = 1.755;
229 double x = hit->x[0];
230 double y = hit->x[1];
231 double z = hit->x[2] + z_delta;
236 double r = sqrt(x * x + y * y);
237 double p = atan2(y, x);
240 auto wrapAngle = [&](
double angle ) {
241 angle = fmod( angle, 2.0 * M_PI );
249 LOG_DEBUG <<
"r = " << r <<
" p=" << p << endm;
250 LOG_DEBUG <<
"RMIN = " << FstGlobal::RMIN[disk_index] <<
" RMAX= " << FstGlobal::RMAX[disk_index] << endm;
253 if (r < FstGlobal::RMIN[disk_index] || r > FstGlobal::RMAX[disk_index])
257 int r_index = floor(MAXR * (r - FstGlobal::RMIN[disk_index]) / (FstGlobal::RMAX[disk_index] - FstGlobal::RMIN[disk_index]));
258 for (
int ii = 0; ii < MAXR; ii++)
259 if (r > FstGlobal::RSegment[ii] && r <= FstGlobal::RSegment[ii + 1])
263 int phi_index = int(MAXPHI * p / 2.0 / M_PI);
269 assert(r_index < MAXR);
271 assert(phi_index < MAXPHI);
276 auto threeKey = std::tie( disk_index, r_index, phi_index );
278 if (hitMap.count( threeKey ) == 0) {
280 if (FstGlobal::verbose){
281 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",
282 disk, x, y, z, r, p, r_index, phi_index, energy * 1000.0, track)
288 fsihit->setDetectorId(kFtsId);
289 fsihit->setLayer(disk);
290 fsihit->setLadder(wedge);
291 fsihit->setWafer(sensor);
295 double p0 = (phi_index + 0.5) * 2.0 * M_PI / double(MAXPHI);
296 double dp = 2.0 * M_PI / double(MAXPHI) / FstGlobal::SQRT12;
299 double r0 = (FstGlobal::RSegment[r_index] + FstGlobal::RSegment[r_index + 1]) * 0.5;
300 double dr = FstGlobal::RSegment[r_index + 1] - FstGlobal::RSegment[r_index];
302 double x0 = r0 * cos(p0);
303 double y0 = r0 * sin(p0);
304 assert(TMath::Abs(x0) + TMath::Abs(y0) > 0);
305 double dz = 0.03 / FstGlobal::SQRT12;
306 double er = dr / FstGlobal::SQRT12;
309 if ( mGEANTPassthrough ){
315 fsihit->setErrorMatrix(&FstGlobal::Hack1to6(fsihit)[0][0]);
317 fsihit->setCharge(energy);
318 fsihit->setIdTruth(track, 100);
319 hits.push_back(fsihit);
321 hitMap[ threeKey ] = fsihit;
322 energySum[ threeKey ] = energy;
323 energyMax[ threeKey ] = energy;
325 if (FstGlobal::verbose){
326 LOG_INFO << Form(
"NEW d=%1d xyz=%8.4f %8.4f %8.4f ", disk, x, y, z) << endm;
327 LOG_INFO << Form(
"smeared xyz=%8.4f %8.4f %8.4f ", fsihit->position().x(), fsihit->position().y(), fsihit->position().z()) << endm;
331 TVector2 hitpos_mc(x, y);
332 TVector2 hitpos_rc(fsihit->position().x(), fsihit->position().y());
334 hTrutHitYXDisk->Fill(x, y, disk);
335 hTrutHitRDisk->Fill(hitpos_mc.Mod(), disk);
338 hTrutHitRShower[0]->Fill(hitpos_mc.Mod(), isShower);
340 hTrutHitRShower[1]->Fill(hitpos_mc.Mod(), isShower);
342 hTrutHitRShower[2]->Fill(hitpos_mc.Mod(), isShower);
344 hTrutHitPhiDisk->Fill(hitpos_mc.Phi() * 180.0 / TMath::Pi(), disk);
345 hTrutHitPhiZ->Fill(hitpos_mc.Phi() * 180.0 / TMath::Pi(), z);
346 hRecoHitYXDisk->Fill(fsihit->position().x(), fsihit->position().y(), disk);
347 hRecoHitRDisk->Fill(hitpos_rc.Mod(), disk);
348 hRecoHitPhiDisk->Fill(hitpos_rc.Phi() * 180.0 / TMath::Pi(), disk);
349 hRecoHitPhiZ->Fill(hitpos_rc.Phi() * 180.0 / TMath::Pi(), z);
350 hGlobalDRDisk->Fill(hitpos_rc.Mod() - hitpos_mc.Mod(), disk);
351 hGlobalZ->Fill(fsihit->position().z());
354 h2GlobalXY->Fill(x, y);
355 h2GlobalSmearedXY->Fill(fsihit->position().x(), fsihit->position().y());
356 h2GlobalDeltaXY->Fill(fsihit->position().x() - x, fsihit->position().y() - y);
357 h3GlobalDeltaXYDisk->Fill(fsihit->position().x() - x, fsihit->position().y() - y, disk);
359 h3GlobalDeltaXYR->Fill(fsihit->position().x() - x, fsihit->position().y() - y, sqrt(pow(fsihit->position().x(), 2) + pow(fsihit->position().y(), 2)));
364 fsihit = hitMap[ threeKey ] ;
365 fsihit->setCharge(fsihit->charge() + energy);
368 energySum[ threeKey ] = energySum[ threeKey ] + energy;
370 if (energy> energyMax[ threeKey ])
371 energyMax[ threeKey ] = energy;
374 track = fsihit->idTruth();
376 fsihit->setIdTruth(track, 100 * (energyMax[ threeKey ] / energySum[ threeKey ]));
379 int nfsihit = hits.size();
382 LOG_INFO <<
"FST Fast simulator is using mInEff = " << mInEff << endm;
384 for (
int i = 0; i < nfsihit; i++) {
385 double rnd_save = rand.
flat();
386 if (rnd_save > mInEff || mGEANTPassthrough){
387 fsicollection->addHit(hits[i]);
389 StFstHit *fHit =
new StFstHit(hits[i]->position(), hits[i]->positionError(), 0, hits[i]->charge(), 0);
390 fHit->setIdTruth(hits[i]->idTruth());
391 float r = sqrt(hits[i]->position().x() * hits[i]->position().x() + hits[i]->position().y() * hits[i]->position().y());
392 float phi = atan2(hits[i]->position().y(), hits[i]->position().x());
393 fHit->setLocalPosition( r, phi, hits[i]->position().z() );
394 fHit->setDiskWedgeSensor(hits[i]->layer(), hits[i]->ladder(), hits[i]->wafer());
395 event->fstHitCollection()->addHit(fHit);
399 if (FstGlobal::verbose) {
400 LOG_DEBUG << Form(
"Found %d/%d g2t hits in %d cells, created %d hits with ADC>0 and put %d into StFstHitCollection", count, nHits, nfsihit, fsicollection->numberOfHits(),
event->fstHitCollection()->numberOfHits()) << endm;
409 hTrutHitYXDisk->Write();
410 hTrutHitRDisk->Write();
411 hTrutHitRShower[0]->Write();
412 hTrutHitRShower[1]->Write();
413 hTrutHitRShower[2]->Write();
414 hTrutHitPhiDisk->Write();
415 hTrutHitPhiZ->Write();
416 hRecoHitYXDisk->Write();
417 hRecoHitRDisk->Write();
418 hRecoHitPhiDisk->Write();
419 hRecoHitPhiZ->Write();
420 hGlobalDRDisk->Write();
422 h3GlobalDeltaXYR->Write();
424 h2GlobalSmearedXY->Write();
425 h2GlobalDeltaXY->Write();
426 h3GlobalDeltaXYDisk->Write();
439 auto hiPos = stHit->position();
440 auto hiErr = stHit->positionError();
441 double Rxy = sqrt(hiPos[0] * hiPos[0] + hiPos[1] * hiPos[1]);
442 double cosFi = hiPos[0] / Rxy;
443 double sinFi = hiPos[1] / Rxy;
444 double T[3][3] = {{cosFi, -Rxy * sinFi, 0}, {sinFi, Rxy * cosFi, 0}, {0, 0, 1}};
445 double Ginp[6] = {hiErr[0] * hiErr[0], 0, hiErr[1] * hiErr[1], 0, 0, hiErr[2] * hiErr[2]};
451 for (
int i = 0, li = 0; i < 3; li += ++i) {
452 for (
int j = 0; j <= i; j++) {
453 mtxF[i][j] = Gout[li + j];
454 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.