diff --git a/SLHCUpgradeSimulations/Configuration/python/aging.py b/SLHCUpgradeSimulations/Configuration/python/aging.py index 721460749d3e3..3fcce88e2e5f8 100644 --- a/SLHCUpgradeSimulations/Configuration/python/aging.py +++ b/SLHCUpgradeSimulations/Configuration/python/aging.py @@ -64,6 +64,12 @@ def agedHGCal(process,algo=0): process = HGCal_setEndOfLifeNoise(process,byDose=True,byDoseAlgo=algo) return process +def realisticHGCalStartup(process): + from SimCalorimetry.HGCalSimProducers.hgcalDigitizer_cfi import HGCal_setRealisticStartupNoise + process = HGCal_setRealisticStartupNoise(process) + return process + + # needs lumi to set proper ZS thresholds (tbd) def ageSiPM(process,turnon,lumi): process.es_hardcode.hbUpgrade.doRadiationDamage = turnon diff --git a/SimCalorimetry/HGCalSimAlgos/src/HGCalSiNoiseMap.cc b/SimCalorimetry/HGCalSimAlgos/src/HGCalSiNoiseMap.cc index d924c4f73a9bc..982f8583e1540 100644 --- a/SimCalorimetry/HGCalSimAlgos/src/HGCalSiNoiseMap.cc +++ b/SimCalorimetry/HGCalSimAlgos/src/HGCalSiNoiseMap.cc @@ -56,6 +56,8 @@ void HGCalSiNoiseMap::setDoseMap(const std::string &fullpath,const unsigned int HGCalRadiationMap::setDoseMap(fullpath,algo); } + + // HGCalSiNoiseMap::SiCellOpCharacteristics HGCalSiNoiseMap::getSiCellOpCharacteristics(const HGCSiliconDetId &cellId, GainRange_t gain, @@ -68,10 +70,6 @@ HGCalSiNoiseMap::SiCellOpCharacteristics HGCalSiNoiseMap::getSiCellOpCharacteris double cellCap(cellCapacitance_[cellThick]); double cellVol(cellVolume_[cellThick]); - //get fluence - if (getDoseMap().empty()) - return siop; - //leakage current and CCE [muA] if (ignoreFluence_) { siop.fluence = 0; @@ -79,6 +77,11 @@ HGCalSiNoiseMap::SiCellOpCharacteristics HGCalSiNoiseMap::getSiCellOpCharacteris siop.ileak = exp(ileakParam_[1]) * cellVol * unitToMicro_; siop.cce = 1; } else { + + if (getDoseMap().empty()) { + throw cms::Exception("BadConfiguration") << " Fluence is required but no DoseMap has been passed to HGCalSiNoiseMap";return siop; + } + //compute the radius here auto xy(ddd()->locateCell( cellId.layer(), cellId.waferU(), cellId.waferV(), cellId.cellU(), cellId.cellV(), true, true)); @@ -92,18 +95,21 @@ HGCalSiNoiseMap::SiCellOpCharacteristics HGCalSiNoiseMap::getSiCellOpCharacteris siop.lnfluence = log(siop.fluence); siop.ileak = exp(ileakParam_[0] * siop.lnfluence + ileakParam_[1]) * cellVol * unitToMicro_; - //lin+log parametrization - siop.cce = siop.fluence <= cceParam_[cellThick][0] ? 1. + cceParam_[cellThick][1] * siop.fluence - : (1. - cceParam_[cellThick][2] * siop.lnfluence) + - (cceParam_[cellThick][1] * cceParam_[cellThick][0] + - cceParam_[cellThick][2] * log(cceParam_[cellThick][0])); - siop.cce = std::max(0., siop.cce); + if(ignoreCCE_) { + siop.cce=1.0; + } + else{ + //lin+log parametrization + siop.cce = siop.fluence <= cceParam_[cellThick][0] ? 1. + cceParam_[cellThick][1] * siop.fluence + : (1. - cceParam_[cellThick][2] * siop.lnfluence) + + (cceParam_[cellThick][1] * cceParam_[cellThick][0] + + cceParam_[cellThick][2] * log(cceParam_[cellThick][0])); + siop.cce = std::max(0., siop.cce); + } } - //reset if CCE is to be ignored - if(ignoreCCE_) siop.cce=1.0; - //determine the gain to apply accounting for cce + //move computation to ROC level (one day) double S(siop.cce * mipEqfC_[cellThick]); if (gain == GainRange_t::AUTO) { double desiredLSB(S / aimMIPtoADC); @@ -115,8 +121,7 @@ HGCalSiNoiseMap::SiCellOpCharacteristics HGCalSiNoiseMap::getSiCellOpCharacteris if (gainIdx == 1) gain = HGCalSiNoiseMap::q160fC; if (gainIdx == 2) - gain = HGCalSiNoiseMap::q320fC; - // move computation to ROC level (one day) + gain = HGCalSiNoiseMap::q320fC; } //fill in the parameters of the struct @@ -126,12 +131,13 @@ HGCalSiNoiseMap::SiCellOpCharacteristics HGCalSiNoiseMap::getSiCellOpCharacteris siop.thrADC = std::floor(S / 2. / lsbPerGain_[gain]); //build noise estimate - double enc_s(encsParam_[gain][0] + encsParam_[gain][1] * cellCap + encsParam_[gain][2] * pow(cellCap, 2)); - double enc_p(encpScale_ * sqrt(siop.ileak)); - siop.noise = hypot(enc_p, enc_s* encCommonNoiseSub_ ) * qe2fc_; - - //reset if NOISE is to be ignored - if(ignoreNoise_) siop.noise=0.0; + if(ignoreNoise_) { + siop.noise=0.0; + }else { + double enc_s(encsParam_[gain][0] + encsParam_[gain][1] * cellCap + encsParam_[gain][2] * pow(cellCap, 2)); + double enc_p(encpScale_ * sqrt(siop.ileak)); + siop.noise = hypot(enc_p, enc_s* encCommonNoiseSub_ ) * qe2fc_; + } return siop; } diff --git a/SimCalorimetry/HGCalSimProducers/python/hgcalDigitizer_cfi.py b/SimCalorimetry/HGCalSimProducers/python/hgcalDigitizer_cfi.py index be8fcc9d9031e..f82d33f4b7677 100644 --- a/SimCalorimetry/HGCalSimProducers/python/hgcalDigitizer_cfi.py +++ b/SimCalorimetry/HGCalSimProducers/python/hgcalDigitizer_cfi.py @@ -325,6 +325,18 @@ endOfLifeCCEs = [0.5, 0.5, 0.7] endOfLifeNoises = [2400.0,2250.0,1750.0] def HGCal_setEndOfLifeNoise(process,byDose=True,byDoseAlgo=0): + """includes all effects from radiation and gain choice""" + process=HGCal_setRealisticNoiseSi(process,byDose=byDose,byDoseAlgo=byDoseAlgo) + process=HGCal_setRealisticNoiseSci(process,byDose=byDose,byDoseAlgo=byDoseAlgo) + return process + +def HGCal_setRealisticStartupNoise(process): + """include all effects except fluence impact on leakage current and CCE""" + #note: realistic electronics with Sci is not yet switched on + process=HGCal_setRealisticNoiseSi(process,byDose=True,byDoseAlgo=1) + return process + +def HGCal_setRealisticNoiseSi(process,byDose=True,byDoseAlgo=0): process.HGCAL_noise_fC = cms.PSet( scaleByDose = cms.bool(byDose), scaleByDoseAlgo = cms.uint32(byDoseAlgo), @@ -334,17 +346,22 @@ def HGCal_setEndOfLifeNoise(process,byDose=True,byDoseAlgo=0): process.HGCAL_chargeCollectionEfficiencies = cms.PSet( values = cms.vdouble(endOfLifeCCEs) ) + process.HGCAL_noises = cms.PSet( + values = cms.vdouble([x for x in endOfLifeNoises]) + ) + return process + +def HGCal_setRealisticNoiseSci(process,byDose=True,byDoseAlgo=0): process.HGCAL_noise_heback = cms.PSet( scaleByDose = cms.bool(byDose), scaleByDoseAlgo = cms.uint32(byDoseAlgo), doseMap = cms.string("SimCalorimetry/HGCalSimProducers/data/doseParams_3000fb_fluka-3.5.15.9.txt"), noise_MIP = cms.double(1./5.) #uses noise map ) - process.HGCAL_noises = cms.PSet( - values = cms.vdouble([x for x in endOfLifeNoises]) - ) return process + + def HGCal_disableNoise(process): process.HGCAL_noise_fC = cms.PSet( values = cms.vdouble(0,0,0), #100,200,300 um