New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HGCAL ToA for overlapping events #20460
Changes from 14 commits
32248a6
e3eee8a
93e68e9
cc0cb1c
2184fa2
eed3ee2
af66820
ffa7b97
c61fc02
ca9fc04
5a77424
7c1ad33
4725d7b
f77358f
dca6a3d
f85d3fa
418a17a
ded5a66
866397f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,13 +43,27 @@ class HGCFEElectronics | |
} | ||
} | ||
|
||
|
||
void SetNoiseValues(std::vector<float> noise_fC){ | ||
for( auto noise : noise_fC ) { noise_fC_.push_back( noise ); } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just do |
||
}; | ||
|
||
float getTimeJitter(float totalCharge, int thickness){ | ||
float A2 = jitterNoise2_ns_[thickness-1]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it guaranteed that the value of |
||
float C2 = jitterConstant2_ns_[thickness-1]; | ||
float X2 = pow((totalCharge/noise_fC_[thickness-1]), 2.); | ||
float jitter2 = A2 / X2 + C2; | ||
return sqrt(jitter2); | ||
}; | ||
|
||
/** | ||
@short returns the LSB in MIP currently configured | ||
*/ | ||
float getADClsb() { return adcLSB_fC_; } | ||
float getTDClsb() { return tdcLSB_fC_; } | ||
float getADCThreshold() { return adcThreshold_fC_; } | ||
float getTDCOnset() { return tdcOnset_fC_; } | ||
std::array<float,3> getTDCForToaOnset() { return tdcForToaOnset_fC_; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In |
||
void setADClsb(float newLSB) { adcLSB_fC_=newLSB; } | ||
|
||
/** | ||
|
@@ -83,13 +97,16 @@ class HGCFEElectronics | |
//private members | ||
uint32_t fwVersion_; | ||
std::array<float,6> adcPulse_, pulseAvgT_; | ||
std::array<float,3> tdcForToaOnset_fC_; | ||
std::vector<float> tdcChargeDrainParameterisation_; | ||
float adcSaturation_fC_, adcLSB_fC_, tdcLSB_fC_, tdcSaturation_fC_, | ||
adcThreshold_fC_, tdcOnset_fC_, toaLSB_ns_, tdcResolutionInNs_; | ||
adcThreshold_fC_, tdcOnset_fC_, toaLSB_ns_, tdcResolutionInNs_; | ||
std::array<float,3> jitterNoise2_ns_, jitterConstant2_ns_; | ||
std::vector<float> noise_fC_; | ||
uint32_t toaMode_; | ||
bool thresholdFollowsMIP_; | ||
//caches | ||
std::array<bool,hgc::nSamples> busyFlags, totFlags; | ||
std::array<bool,hgc::nSamples> busyFlags, totFlags, toaFlags; | ||
hgc::HGCSimHitData newCharge, toaFromToT; | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,10 @@ namespace { | |
|
||
constexpr std::array<double,3> occupancyGuesses = { { 0.5,0.2,0.2 } }; | ||
|
||
bool comparePairs(const std::pair<float, float>& i, const std::pair<float, float>& j){ | ||
return i.second < j.second; | ||
} | ||
|
||
float getPositionDistance(const HGCalGeometry* geom, const DetId& id) { | ||
return geom->getPosition(id).mag(); | ||
} | ||
|
@@ -36,6 +40,20 @@ namespace { | |
return geom->getGeometry(id)->getPosition().mag(); | ||
} | ||
|
||
int getCellThickness(const HGCalGeometry* geom, const DetId& detid ) { | ||
const auto& topo = geom->topology(); | ||
const auto& dddConst = topo.dddConstants(); | ||
uint32_t id(detid.rawId()); | ||
HGCalDetId hid(id); | ||
int wafer = HGCalDetId(id).wafer(); | ||
int waferTypeL = dddConst.waferTypeL(wafer); | ||
return waferTypeL; | ||
} | ||
|
||
int getCellThickness(const HcalGeometry* geom, const DetId& detid ) { | ||
return 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. magic number should be made into a descriptive const, or ideally accessed from geometry/topology info somehow There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This I don’t know how to change. I copied from elsewhere as in https://github.com/amartelli/cmssw/blob/HGChits_ToAforPU_PR94X/SimCalorimetry/HGCalSimProducers/src/HGCDigitizerBase.cc#L13 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm... okay. Something to standardize in the future. |
||
} | ||
|
||
void getValidDetIds(const HGCalGeometry* geom, std::unordered_set<DetId>& valid) { | ||
const std::vector<DetId>& ids = geom->getValidDetIds(); | ||
valid.reserve(ids.size()); | ||
|
@@ -187,6 +205,7 @@ void HGCDigitizer::initializeEvent(edm::Event const& e, edm::EventSetup const& e | |
// | ||
void HGCDigitizer::finalizeEvent(edm::Event& e, edm::EventSetup const& es, CLHEP::HepRandomEngine* hre) | ||
{ | ||
hitRefs_bx0.clear(); | ||
|
||
const CaloSubdetectorGeometry* theGeom = ( nullptr == gHGCal_ ? | ||
static_cast<const CaloSubdetectorGeometry*>(gHcal_) : | ||
|
@@ -296,21 +315,22 @@ void HGCDigitizer::accumulate(edm::Handle<edm::PCaloHitContainer> const &hits, | |
|
||
//configuration to apply for the computation of time-of-flight | ||
bool weightToAbyEnergy(false); | ||
float tdcOnset(0.f),keV2fC(0.f); | ||
std::array<float, 3> tdcForToaOnset{ {0.f, 0.f, 0.f} }; | ||
float keV2fC(0.f); | ||
switch( mySubDet_ ) { | ||
case ForwardSubdetector::HGCEE: | ||
weightToAbyEnergy = theHGCEEDigitizer_->toaModeByEnergy(); | ||
tdcOnset = theHGCEEDigitizer_->tdcOnset(); | ||
tdcForToaOnset = theHGCEEDigitizer_->tdcForToaOnset(); | ||
keV2fC = theHGCEEDigitizer_->keV2fC(); | ||
break; | ||
case ForwardSubdetector::HGCHEF: | ||
weightToAbyEnergy = theHGCHEfrontDigitizer_->toaModeByEnergy(); | ||
tdcOnset = theHGCHEfrontDigitizer_->tdcOnset(); | ||
tdcForToaOnset = theHGCHEfrontDigitizer_->tdcForToaOnset(); | ||
keV2fC = theHGCHEfrontDigitizer_->keV2fC(); | ||
break; | ||
case ForwardSubdetector::HGCHEB: | ||
weightToAbyEnergy = theHGCHEbackDigitizer_->toaModeByEnergy(); | ||
tdcOnset = theHGCHEbackDigitizer_->tdcOnset(); | ||
tdcForToaOnset = theHGCHEbackDigitizer_->tdcForToaOnset(); | ||
keV2fC = theHGCHEbackDigitizer_->keV2fC(); | ||
break; | ||
default: | ||
|
@@ -363,7 +383,7 @@ void HGCDigitizer::accumulate(edm::Handle<edm::PCaloHitContainer> const &hits, | |
//accumulate in 15 buckets of 25ns (9 pre-samples, 1 in-time, 5 post-samples) | ||
const float tof = toa-dist2center/refSpeed_+tofDelay_ ; | ||
const int itime= std::floor( tof/bxTime_ ) + 9; | ||
|
||
//no need to add bx crossing - tof comes already corrected from the mixing module | ||
//itime += bxCrossing; | ||
//itime += 9; | ||
|
@@ -375,32 +395,59 @@ void HGCDigitizer::accumulate(edm::Handle<edm::PCaloHitContainer> const &hits, | |
|
||
(simHitIt->second).hit_info[0][itime] += charge; | ||
float accCharge=(simHitIt->second).hit_info[0][itime]; | ||
|
||
|
||
|
||
//working version with pileup only for in-time hits | ||
int waferThickness = getCellThickness(geom,id); | ||
float accChargeForToA = 0.f; | ||
bool orderChanged = false; | ||
if(itime == 9){ | ||
if(hitRefs_bx0[id].empty()){ | ||
hitRefs_bx0[id].push_back(std::pair<float, float>(charge, tof)); | ||
accChargeForToA += charge; | ||
} | ||
else if(tof <= hitRefs_bx0[id].back().second){ | ||
hitRefs_bx0[id].push_back(std::pair<float, float>(charge, tof)); | ||
std::sort(hitRefs_bx0[id].begin(), hitRefs_bx0[id].end(), comparePairs); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a good place to use a lambda:
|
||
for(const auto& step : hitRefs_bx0[id]){ | ||
accChargeForToA += step.first; | ||
if(accChargeForToA > tdcForToaOnset[waferThickness-1] && step.second != hitRefs_bx0[id].back().second){ | ||
while(step != hitRefs_bx0[id].back()) hitRefs_bx0[id].pop_back(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not entirely sure I understand what this is doing, but maybe it could be more efficient to use a binary search (e.g. |
||
break; | ||
} | ||
} | ||
orderChanged = true; | ||
} | ||
else{ | ||
if(accCharge - charge <= tdcForToaOnset[waferThickness-1]){ | ||
hitRefs_bx0[id].push_back(std::pair<float, float>(charge, tof)); | ||
accChargeForToA = accCharge; | ||
} | ||
} | ||
} | ||
|
||
//time-of-arrival (check how to be used) | ||
if(weightToAbyEnergy) (simHitIt->second).hit_info[1][itime] += charge*tof; | ||
else if((simHitIt->second).hit_info[1][itime]==0) { | ||
if( accCharge>tdcOnset) | ||
{ | ||
//extrapolate linear using previous simhit if it concerns to the same DetId | ||
float fireTDC=tof; | ||
if(i>0) | ||
{ | ||
uint32_t prev_id = std::get<1>(hitRefs[i-1]); | ||
if(prev_id==id) | ||
{ | ||
float prev_toa = std::get<2>(hitRefs[i-1]); | ||
float prev_tof(prev_toa-dist2center/refSpeed_+tofDelay_); | ||
//float prev_charge = std::get<3>(hitRefs[i-1]); | ||
float deltaQ2TDCOnset = tdcOnset-((simHitIt->second).hit_info[0][itime]-charge); | ||
float deltaQ = charge; | ||
float deltaT = (tof-prev_tof); | ||
fireTDC = deltaT*(deltaQ2TDCOnset/deltaQ)+prev_tof; | ||
} | ||
} | ||
|
||
(simHitIt->second).hit_info[1][itime]=fireTDC; | ||
else if(accChargeForToA > tdcForToaOnset[waferThickness-1] && | ||
((simHitIt->second).hit_info[1][itime] == 0 || orderChanged == true) ){ | ||
float fireTDC = hitRefs_bx0[id].back().second; | ||
if (hitRefs_bx0[id].size() > 1){ | ||
float chargeBeforeThr = 0.f; | ||
float tofchargeBeforeThr = 0.f; | ||
for(const auto& step : hitRefs_bx0[id]){ | ||
if(step.first + chargeBeforeThr <= tdcForToaOnset[waferThickness-1]){ | ||
chargeBeforeThr += step.first; | ||
tofchargeBeforeThr = step.second; | ||
} | ||
else break; | ||
} | ||
float deltaQ = accChargeForToA - chargeBeforeThr; | ||
float deltaTOF = fireTDC - tofchargeBeforeThr; | ||
fireTDC = (tdcForToaOnset[waferThickness-1] - chargeBeforeThr) * deltaTOF / deltaQ + tofchargeBeforeThr; | ||
} | ||
(simHitIt->second).hit_info[1][itime] = fireTDC; | ||
} | ||
|
||
} | ||
hitRefs.clear(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass vector by const reference