49 #include "St_base/StMessMgr.h"
50 #include "StEvent/StEvent.h"
51 #include "StEvent/StFmsCollection.h"
52 #include "StEvent/StFmsHit.h"
53 #include "StFmsDbMaker/StFmsDbMaker.h"
54 #include "tables/St_g2t_emc_hit_Table.h"
55 #include "tables/St_fpdm_fmcg_Table.h"
62 StMaker(name),mFpsDEPerMIP(0.0016),mFpsNPhotonPerMIP(100.0) { }
66 LOG_DEBUG <<
"StFmsFastSimulatorMaker::Make" << endm;
68 if (!GetMaker(
"fmsDb")) {
69 LOG_ERROR <<
"No StFmsDbMaker. StFmsDbMaker library not loaded?" << endm;
77 LOG_DEBUG <<
"Creating StEvent" << endm;
80 if (!event->fmsCollection()) {
82 LOG_DEBUG <<
"Creating StFmsCollection" << endm;
87 St_fpdm_fmcg* FMCG = (St_fpdm_fmcg*) GetChain()->
Find(
"bfc/.make/geant/.const/geom/fpdm_fmcg");
90 fpdm_fmcg_st* fmcg = (fpdm_fmcg_st*)FMCG->At(0);
93 mAttenuation = fmcg->atten;
94 LOG_DEBUG <<
"Found St_fpdm_fmcg* at bfc/.make/geant/.const/geom/fpdm_fmcg and atten="<<mAttenuation<<endm;
96 LOG_INFO <<
"Fail to get fpdm_fmcg_st" << endm;
99 LOG_INFO <<
"Fail to find St_fpdm_fmcg* at bfc/.make/geant/.const/geom/fpdm_fmcg" << endm;
104 if(Debug()) printStEventSummary(event);
109 void StFmsFastSimulatorMaker::fillStEvent(
StEvent* event) {
117 St_g2t_emc_hit* hitTable =
static_cast<St_g2t_emc_hit*
>(GetDataSet(
"g2t_fpd_hit"));
119 LOG_DEBUG <<
"g2t_fpd_hit table is empty" << endm;
124 const Int_t nHits = hitTable->GetNRows();
127 LOG_DEBUG <<
"g2t_fpd_hit table has 0 rows" << endm;
130 const g2t_emc_hit_st*
hit = hitTable->GetTable();
132 LOG_DEBUG <<
"g2t_fpd_hit GetTable failed" << endm;
138 static const int NDET=16, NCH=600;
141 auto map =
new StFmsHit*[NDET][NCH]();
143 for (Int_t i=0; i < nHits; ++i) {
145 const Int_t detectorId = getDetectorId(*hit);
147 if(detectorId==kFpsDetId) {
148 channel=dbMaker->fpsSlatIdFromG2t(hit->volume_id);
149 }
else if(detectorId==kFpostDetId) {
150 channel=dbMaker->fpostSlatIdFromG2t(hit->volume_id);
152 channel=hit->volume_id % 1000;
154 LOG_INFO << Form(
"volid=%8d det=%2d ch=%4d e=%f\n",hit->volume_id,detectorId,channel,hit->de);
155 if(detectorId<0 || detectorId>=NDET || channel<0 || channel>=NCH){
156 LOG_DEBUG << Form(
"det or ch out of range det=%d ch=%d",detectorId,channel) << endm;
159 Float_t energy = hit->de;
161 if(map[detectorId][channel]==0){
162 Int_t qtCrate, qtSlot, qtChannel, adc=0, tdc=0;
163 if(detectorId==kFpsDetId){
165 dbMaker->fpsQTMap(channel,&qtSlot,&qtChannel);
166 }
else if(detectorId==kFpostDetId){
168 dbMaker->fpostQTMap(channel,&qtSlot,&qtChannel);
170 dbMaker->getMap(detectorId, channel, &qtCrate, &qtSlot, &qtChannel);
172 fmshit =
new StFmsHit(detectorId, channel, qtCrate, qtSlot, qtChannel, adc, tdc, energy);
173 hits.push_back(fmshit);
174 map[detectorId][channel]=fmshit;
176 fmshit = map[detectorId][channel];
177 fmshit->setEnergy(fmshit->energy() + energy);
182 int nfmshit=hits.size();
186 for(
int i=0; i<nfmshit; i++){
187 const Int_t detectorId = hits[i]->detectorId();
188 const Int_t channel = hits[i]->channel();
189 Float_t energy=hits[i]->energy();
190 Float_t gain, gainCorrection;
192 if(detectorId==kFpsDetId){
193 gain = 1.0/dbMaker->fpsGain(channel);
194 gainCorrection=mFpsDEPerMIP;
196 if(mFpsNPhotonPerMIP>0.0){
198 int nPixel=
static_cast<Int_t
>(energy/gainCorrection*mFpsNPhotonPerMIP);
199 int nPixelMod = rnd.Poisson(nPixel);
200 energy = nPixelMod*gainCorrection/mFpsNPhotonPerMIP;
202 }
else if(detectorId==kFpostDetId){
203 gain = 1.0/dbMaker->fpostGain(channel);
204 gainCorrection=mFpsDEPerMIP;
206 if(mFpsNPhotonPerMIP>0.0){
208 int nPixel=
static_cast<Int_t
>(energy/gainCorrection*mFpsNPhotonPerMIP);
209 int nPixelMod = rnd.Poisson(nPixel);
210 energy = nPixelMod*gainCorrection/mFpsNPhotonPerMIP;
215 gain = dbMaker->getGain(detectorId, channel);
220 adc =
static_cast<Int_t
>(energy / (gain * gainCorrection) + 0.5);
222 adc =
static_cast<Int_t
>(energy / mAttenuationGainScale / (gain * gainCorrection) + 0.5);
224 if(mFmsBitShiftGain){
227 adc = adc & (0x0fff << bitshift);
228 }
else if(bitshift<0){
229 adc = std::min(adc, (0x1<<(12+bitshift))-1 );
233 adc = std::max(adc, 0);
234 adc = std::min(adc, 4095);
237 if(detectorId!=kFpsDetId && detectorId!=kFpostDetId){
238 digi_energy = adc * gain * gainCorrection;
240 digi_energy = adc * gain;
243 hits[i]->setAdc(adc);
244 hits[i]->setEnergy(digi_energy);
245 fmscollection->addHit(hits[i]);
247 cout << Form(
"Det=%2d Ch=%3d E=%8.3f gain=%6.3f ADC=%4d digiE=%8.3f\n",detectorId,channel,energy,gain,adc,digi_energy);
252 LOG_INFO << Form(
"Found %d g2t hits in %d cells, created %d hits with ADC>0",nHits,nfmshit,fmscollection->numberOfHits()) <<endm;
313 Int_t StFmsFastSimulatorMaker::getDetectorId(
const g2t_emc_hit_st& hit)
const {
314 enum { kFpd = 1, kFms = 2, kNorth = 0, kSouth = 1 };
315 const Int_t volumeId = hit.volume_id;
316 printf(
"voldid=%d\n",volumeId);
318 const Int_t isFPS = volumeId / 100000;
319 const Int_t fpdOrFms = (volumeId % 100000) / 10000;
320 const Int_t module = (volumeId % 10000) / 1000;
321 if(isFPS==1)
return kFpsDetId;
322 if(isFPS==2)
return kFpostDetId;
326 case 1:
return kFpdNorthDetId;
327 case 2:
return kFpdSouthDetId;
328 case 5:
return kFpdNorthPrsDetId;
329 case 6:
return kFpdSouthPrsDetId;
334 case 1:
return kFmsNorthLargeDetId;
335 case 2:
return kFmsSouthLargeDetId;
336 case 3:
return kFmsNorthSmallDetId;
337 case 4:
return kFmsSouthSmallDetId;
345 void StFmsFastSimulatorMaker::printStEventSummary(
const StEvent* event) {
346 const Int_t NDETECTORS = 16;
347 const Char_t* detectorNames[NDETECTORS] = {
366 Int_t nhits[NDETECTORS];
367 std::fill(nhits, nhits + NDETECTORS, 0);
369 Float_t detectorEnergy[NDETECTORS];
370 std::fill(detectorEnergy, detectorEnergy + NDETECTORS, 0.f);
372 const StSPtrVecFmsHit& hits =
event->fmsCollection()->hits();
373 for (
size_t i = 0; i < hits.size(); ++i) {
375 ++nhits[hit->detectorId()];
376 detectorEnergy[hit->detectorId()] += hit->energy();
377 if(Debug()>1) hit->print();
380 LOG_INFO <<
"ID\tNAME\t\tNHITS\tENERGY" << endm;
381 for (Int_t detectorId = 0; detectorId < NDETECTORS; ++detectorId) {
382 if(nhits[detectorId]>0)
383 LOG_INFO << detectorId <<
'\t' << detectorNames[detectorId] <<
'\t'
384 << nhits[detectorId] <<
'\t' << detectorEnergy[detectorId] << endm;
Float_t getGainCorrection(Int_t detectorId, Int_t ch) const
get the gain for the channel
virtual void AddData(TDataSet *data, const char *dir=".data")
User methods.
StFmsFastSimulatorMaker(const Char_t *name="fmsSim")
Short_t getBitShiftGain(Int_t detectorId, Int_t ch) const
get the gain correction for the channel
virtual TDataSet * Find(const char *path) const