class EcalEnergyStep(CalibrationStep): def __init__(self): CalibrationStep.__init__(self, "EcalEnergy") self._marlin = None self._maxNIterations = 5 self._energyScaleAccuracy = 0.01 self._photonEnergy = 0 self._inputMinCosThetaBarrel = None self._inputMaxCosThetaBarrel = None self._inputMinCosThetaEndcap = None self._inputMaxCosThetaEndcap = None self._outputEcalBarrelFactors = None self._outputEcalEndcapFactors = None self._outputEcalRingFactors = None self._runRingCalibration = True # command line requirement self._requireSteeringFile() self._requireCompactFile() self._requireIterations() self._requirePhotonFile() self._requireECalAccuracy() """ Whether to run the ecal ring calibration """ def setRunEcalRingCalibration(self, runRingCalib): self._runRingCalibration = runRingCalib """ Should return the current list of ecal barrel energy factors from marlin xml file """ def ecalBarrelEnergyFactors(self): return [] """ Should return the current list of ecal barrel energy factors from marlin xml file """ def ecalEndcapEnergyFactors(self): return [] """ Should set the current list of ecal barrel/endcap energy factors into marlin xml file """ def setEnergyFactors(self, barrelFactors, endcapFactors): pass """ Get the step description """ def description(self): return "Calculate the constants related to the energy deposit in a ecal cell (unit GeV). Outputs the ecalFactors values" """ Read the command line arguments """ def readCmdLine(self, parsed): # setup marlin self._marlin = Marlin(parsed.steeringFile) gearFile = self._manager.getGearConverter().convertToGear( parsed.compactFile) self._marlin.setGearFile(gearFile) self._marlin.setCompactFile(parsed.compactFile) self._marlin.setMaxRecordNumber(parsed.maxRecordNumber) self._marlin.setInputFiles( self._extractFileList(parsed.lcioPhotonFile, "slcio")) self._maxNIterations = int(parsed.maxNIterations) self._energyScaleAccuracy = float(parsed.ecalCalibrationAccuracy) self._inputMinCosThetaBarrel, self._inputMaxCosThetaBarrel = self._getGeometry( ).getEcalBarrelCosThetaRange() self._inputMinCosThetaEndcap, self._inputMaxCosThetaEndcap = self._getGeometry( ).getEcalEndcapCosThetaRange() self._photonEnergy = parsed.photonEnergy """ Initialize the calibration step """ def init(self, config): self._cleanupElement(config) self._marlin.loadInputParameters(config) self._loadStepOutputs(config) if len(self._runProcessors): self._marlin.turnOffProcessorsExcept(self._runProcessors) if len(self._turnoffProcessors): self._marlin.turnOffProcessors(self._turnoffProcessors) """ Run the calibration step """ def run(self, config): # loop variables barrelCurrentPrecision = 0. endcapCurrentPrecision = 0. barrelRescaleFactor = 1. endcapRescaleFactor = 1. barrelRescaleFactorCumul = 1. endcapRescaleFactorCumul = 1. barrelAccuracyReached = False endcapAccuracyReached = False ecalBarrelFactors = self.ecalBarrelEnergyFactors() ecalEndcapFactors = self.ecalEndcapEnergyFactors() pfoAnalysisFile = "" ecalCalibrator = EcalCalibrator() ecalCalibrator.setPhotonEnergy(self._photonEnergy) for iteration in range(self._maxNIterations): # readjust iteration parameters if not barrelAccuracyReached: for index in range(len(ecalBarrelFactors)): ecalBarrelFactors[ index] = ecalBarrelFactors[index] * barrelRescaleFactor if not endcapAccuracyReached: for index in range(len(ecalEndcapFactors)): ecalEndcapFactors[ index] = ecalEndcapFactors[index] * endcapRescaleFactor pfoAnalysisFile = "./PfoAnalysis_{0}_iter{1}.root".format( self._name, iteration) # run marlin self.setEnergyFactors(ecalBarrelFactors, ecalEndcapFactors) self._marlin.setProcessorParameter(self._pfoAnalysisProcessor, "RootFile", pfoAnalysisFile) self._marlin.run() # run calibration for barrel if not barrelAccuracyReached: ecalCalibrator.setRootFile(pfoAnalysisFile) ecalCalibrator.setDetectorRegion("Barrel") ecalCalibrator.setCosThetaRange(self._inputMinCosThetaBarrel, self._inputMaxCosThetaBarrel) ecalCalibrator.run() newBarrelPhotonEnergy = ecalCalibrator.getEcalDigiMean() barrelRescaleFactor = float( self._photonEnergy) / newBarrelPhotonEnergy barrelRescaleFactorCumul = barrelRescaleFactorCumul * barrelRescaleFactor barrelCurrentPrecision = abs(1 - 1. / barrelRescaleFactor) # run calibration for endcap if not endcapAccuracyReached: ecalCalibrator.setRootFile(pfoAnalysisFile) ecalCalibrator.setDetectorRegion("EndCap") ecalCalibrator.setCosThetaRange(self._inputMinCosThetaEndcap, self._inputMaxCosThetaEndcap) ecalCalibrator.run() newEndcapPhotonEnergy = ecalCalibrator.getEcalDigiMean() endcapRescaleFactor = float( self._photonEnergy) / newEndcapPhotonEnergy endcapRescaleFactorCumul = endcapRescaleFactorCumul * endcapRescaleFactor endcapCurrentPrecision = abs(1 - 1. / endcapRescaleFactor) self._logger.info("=============================================") self._logger.info( "======= Barrel output for iteration {0} =======".format( iteration)) self._logger.info(" => calibrationFactors : {0}".format(", ".join( map(str, ecalBarrelFactors)))) self._logger.info(" => calibrationRescaleFactor : " + str(barrelRescaleFactor)) self._logger.info(" => calibrationRescaleFactorCumul : " + str(barrelRescaleFactorCumul)) self._logger.info(" => currentPrecision : " + str(barrelCurrentPrecision)) self._logger.info(" => newPhotonEnergy : " + str(newBarrelPhotonEnergy)) self._logger.info("=============================================") self._logger.info("") self._logger.info("=============================================") self._logger.info( "======= Endcap output for iteration {0} =======".format( iteration)) self._logger.info(" => calibrationFactors : {0}".format(", ".join( map(str, ecalEndcapFactors)))) self._logger.info(" => calibrationRescaleFactor : " + str(endcapRescaleFactor)) self._logger.info(" => calibrationRescaleFactorCumul : " + str(endcapRescaleFactorCumul)) self._logger.info(" => currentPrecision : " + str(endcapCurrentPrecision)) self._logger.info(" => newPhotonEnergy : " + str(newEndcapPhotonEnergy)) self._logger.info("=============================================") # write down iteration results self._writeIterationOutput( config, iteration, { "barrelPrecision": barrelCurrentPrecision, "barrelRescale": barrelRescaleFactor, "barrelRescale": barrelRescaleFactor, "newBarrelPhotonEnergy": newBarrelPhotonEnergy, "endcapPrecision": endcapCurrentPrecision, "endcapRescale": endcapRescaleFactor, "newEndcapPhotonEnergy": newEndcapPhotonEnergy }) # are we accurate enough ?? if barrelCurrentPrecision < self._energyScaleAccuracy and not barrelAccuracyReached: barrelAccuracyReached = True self._outputEcalBarrelFactors = ecalBarrelFactors # are we accurate enough ?? if endcapCurrentPrecision < self._energyScaleAccuracy and not endcapAccuracyReached: endcapAccuracyReached = True self._outputEcalEndcapFactors = ecalEndcapFactors if barrelAccuracyReached and endcapAccuracyReached: break if not barrelAccuracyReached or not endcapAccuracyReached: raise RuntimeError( "{0}: Couldn't reach the user accuracy ({1})".format( self._name, self._energyScaleAccuracy)) self._logger.info("{0}: ecal energy accuracy reached !".format( self._name)) if self._runRingCalibration: # TODO evaluate consistency of making separate ecal ring calibration self._outputEcalRingFactors = list(self._outputEcalEndcapFactors) self._logger.info( "===============================================") self._logger.info( "==== Ecal ring output after all iterations ====") self._logger.info(" => ring calib factors : {0}".format(", ".join( map(str, self._outputEcalRingFactors)))) self._logger.info( "===============================================") """ Write output (must be reimplemented) """ def writeOutput(self, config): raise RuntimeError( "EcalEnergyStep.writeOutput: method not implemented !")
class PandoraEMScaleStep(CalibrationStep) : def __init__(self) : CalibrationStep.__init__(self, "PandoraEMScale") self._marlin = None self._maxNIterations = 5 self._energyScaleAccuracy = 0.01 self._photonEnergy = 0 # step input self._inputEcalToEMGeV = None self._inputHcalToEMGeV = None # step output self._outputEcalToEMGeV = None self._outputHcalToEMGeV = None # command line requirement self._requireSteeringFile() self._requireCompactFile() self._requireIterations() self._requirePhotonFile() self._requireECalAccuracy() self._requirePandoraSettings() def description(self): return "Calibrate the electromagnetic scale of the ecal and the hcal. Outputs the constants ECalToEMGeVCalibration and HCalToEMGeVCalibration" def readCmdLine(self, parsed) : # setup marlin self._marlin = Marlin(parsed.steeringFile) gearFile = self._manager.getGearConverter().convertToGear(parsed.compactFile) self._marlin.setGearFile(gearFile) self._marlin.setCompactFile(parsed.compactFile) self._marlin.setMaxRecordNumber(parsed.maxRecordNumber) self._marlin.setInputFiles(self._extractFileList(parsed.lcioPhotonFile, "slcio")) self._maxNIterations = int(parsed.maxNIterations) self._energyScaleAccuracy = float(parsed.ecalCalibrationAccuracy) self._photonEnergy = parsed.photonEnergy # setup pandora settings pandora = PandoraXML(parsed.pandoraSettings) pandora.setRemoveEnergyCorrections(True) newPandoraSettings = pandora.generateNewXmlFile() self._marlin.setProcessorParameter(self._marlinPandoraProcessor, "PandoraSettingsXmlFile", newPandoraSettings) def init(self, config) : self._cleanupElement(config) self._marlin.loadInputParameters(config) self._loadStepOutputs(config) if len(self._runProcessors): self._marlin.turnOffProcessorsExcept(self._runProcessors) if len(self._turnoffProcessors): self._marlin.turnOffProcessors(self._turnoffProcessors) self._inputEcalToEMGeV = float(self._marlin.getProcessorParameter(self._marlinPandoraProcessor, "ECalToEMGeVCalibration")) self._inputHcalToEMGeV = float(self._marlin.getProcessorParameter(self._marlinPandoraProcessor, "HCalToEMGeVCalibration")) def run(self, config) : # loop variables currentPrecision = 0. calibrationRescaleFactor = 1. calibrationRescaleFactorCumul = 1. accuracyReached = False ecalToEMGeV = self._inputEcalToEMGeV hcalToEMGeV = self._inputHcalToEMGeV emScaleCalibrator = PandoraEMScaleCalibrator() emScaleCalibrator.setPhotonEnergy(self._photonEnergy) for iteration in range(self._maxNIterations) : # readjust iteration parameters ecalToEMGeV = ecalToEMGeV*calibrationRescaleFactor hcalToEMGeV = hcalToEMGeV*calibrationRescaleFactor pfoAnalysisFile = "./PfoAnalysis_{0}_iter{1}.root".format(self._name, iteration) # run marlin ... self._marlin.setProcessorParameter(self._marlinPandoraProcessor, "ECalToEMGeVCalibration", str(ecalToEMGeV)) self._marlin.setProcessorParameter(self._marlinPandoraProcessor, "HCalToEMGeVCalibration", str(hcalToEMGeV)) self._marlin.setProcessorParameter(self._pfoAnalysisProcessor , "RootFile", pfoAnalysisFile) self._marlin.run() # ... and calibration script emScaleCalibrator.setRootFile(pfoAnalysisFile) emScaleCalibrator.setPhotonEnergy(self._photonEnergy) emScaleCalibrator.run() newPhotonEnergy = emScaleCalibrator.getEcalToEMMean() calibrationRescaleFactor = float(self._photonEnergy) / newPhotonEnergy calibrationRescaleFactorCumul = calibrationRescaleFactorCumul*calibrationRescaleFactor currentPrecision = abs(1 - 1. / calibrationRescaleFactor) # write down iteration results self._writeIterationOutput(config, iteration, {"precision" : currentPrecision, "rescale" : calibrationRescaleFactor, "newPhotonEnergy" : newPhotonEnergy}) # are we accurate enough ?? if currentPrecision < self._energyScaleAccuracy : print "{0}: ecal energy accuracy reached !".format(self._name) accuracyReached = True self._outputEcalToEMGeV = ecalToEMGeV self._outputHcalToEMGeV = hcalToEMGeV break if not accuracyReached : raise RuntimeError("{0}: Couldn't reach the user accuracy ({1})".format(self._name, self._energyScaleAccuracy)) def writeOutput(self, config) : output = self._getXMLStepOutput(config, create=True) self._writeProcessorParameter(output, self._marlinPandoraProcessor, "ECalToEMGeVCalibration", self._outputEcalToEMGeV) self._writeProcessorParameter(output, self._marlinPandoraProcessor, "HCalToEMGeVCalibration", self._outputHcalToEMGeV)
class MipScaleStep(CalibrationStep): def __init__(self): CalibrationStep.__init__(self, "MipScale") self._marlin = None self._pfoOutputFile = "./PfoAnalysis_" + self._name + ".root" self._hcalBarrelMip = 0. self._hcalEndcapMip = 0. self._hcalRingMip = 0. self._ecalMip = 0. self._muonEnergy = 0 # set requirements self._requireMuonFile() self._requireCompactFile() self._requireSteeringFile() """ Get the step description """ def description(self): return "Calculate the mip values from SimCalorimeter collections in the muon lcio file. Outputs ecal mip, hcal barrel mip, hcal endcap mip and hcal ring mip values" """ Read command line parsing """ def readCmdLine(self, parsed): # setup marlin self._marlin = Marlin(parsed.steeringFile) gearFile = self._manager.getGearConverter().convertToGear( parsed.compactFile) self._marlin.setGearFile(gearFile) self._marlin.setCompactFile(parsed.compactFile) self._marlin.setMaxRecordNumber(parsed.maxRecordNumber) self._marlin.setInputFiles( self._extractFileList(parsed.lcioMuonFile, "slcio")) self._marlin.setProcessorParameter(self._pfoAnalysisProcessor, "RootFile", self._pfoOutputFile) self._muonEnergy = parsed.muonEnergy """ Initialize the step """ def init(self, config): self._cleanupElement(config) self._marlin.loadInputParameters(config) self._loadStepOutputs(config) """ Run the calibration step """ def run(self, config): self._marlin.loadInputParameters(config) self._loadStepOutputs(config) if len(self._runProcessors): self._marlin.turnOffProcessorsExcept(self._runProcessors) if len(self._turnoffProcessors): self._marlin.turnOffProcessors(self._turnoffProcessors) self._marlin.run() mipCalibrator = MipCalibrator() mipCalibrator.setRootFile(self._pfoOutputFile) mipCalibrator.setMuonEnergy(self._muonEnergy) mipCalibrator.run() self._hcalBarrelMip = mipCalibrator.getHcalBarrelMip() self._hcalEndcapMip = mipCalibrator.getHcalEndcapMip() self._hcalRingMip = mipCalibrator.getHcalRingMip() self._ecalMip = mipCalibrator.getEcalMip() """ Write step output (must be overriden in daughter classes) """ def writeOutput(self, config): raise RuntimeError( "MipScaleStep.writeOutput: method not implemented !")
class PandoraHadScaleStep(CalibrationStep): def __init__(self): CalibrationStep.__init__(self, "PandoraHadScale") self._marlin = None self._hadScaleCalibrator = None self._maxNIterations = 5 self._ecalEnergyScaleAccuracy = 0.01 self._hcalEnergyScaleAccuracy = 0.01 self._kaon0LEnergy = 0 # step input self._inputEcalToHadGeVBarrel = None self._inputEcalToHadGeVEndcap = None self._inputHcalToHadGeV = None # step output self._outputEcalToHadGeVBarrel = None self._outputEcalToHadGeVEndcap = None self._outputHcalToHadGeV = None # command line requirement self._requireSteeringFile() self._requireCompactFile() self._requireIterations() self._requireKaon0LFile() self._requireHCalAccuracy() self._requireECalAccuracy() self._requirePandoraSettings() def description(self): return "Calibrate the hadronic scale of the ecal and the hcal. Outputs the constants ECalToHadGeVCalibrationBarrel, ECalToHadGeVCalibrationEndCap and HCalToHadGeVCalibration" def readCmdLine(self, parsed): # setup marlin self._marlin = Marlin(parsed.steeringFile) gearFile = self._manager.getGearConverter().convertToGear( parsed.compactFile) self._marlin.setGearFile(gearFile) self._marlin.setCompactFile(parsed.compactFile) self._marlin.setMaxRecordNumber(parsed.maxRecordNumber) self._marlin.setInputFiles( self._extractFileList(parsed.lcioKaon0LFile, "slcio")) self._maxNIterations = int(parsed.maxNIterations) self._ecalEnergyScaleAccuracy = float(parsed.ecalCalibrationAccuracy) self._hcalEnergyScaleAccuracy = float(parsed.hcalCalibrationAccuracy) self._kaon0LEnergy = parsed.kaon0LEnergy # setup pandora settings pandora = PandoraXML(parsed.pandoraSettings) pandora.setRemoveEnergyCorrections(True) newPandoraSettings = pandora.generateNewXmlFile() self._marlin.setProcessorParameter(self._marlinPandoraProcessor, "PandoraSettingsXmlFile", newPandoraSettings) def init(self, config): self._cleanupElement(config) self._marlin.loadInputParameters(config) self._loadStepOutputs(config) if len(self._runProcessors): self._marlin.turnOffProcessorsExcept(self._runProcessors) if len(self._turnoffProcessors): self._marlin.turnOffProcessors(self._turnoffProcessors) def run(self, config): # loop variables currentEcalPrecision = 0. currentHcalPrecision = 0. ecalRescaleFactor = 1. hcalRescaleFactor = 1. ecalRescaleFactorCumul = 1. hcalRescaleFactorCumul = 1. ecalAccuracyReached = False hcalAccuracyReached = False ecalToHadGeVBarrel = float( self._marlin.getProcessorParameter( self._marlinPandoraProcessor, "ECalToHadGeVCalibrationBarrel")) ecalToHadGeVEndcap = float( self._marlin.getProcessorParameter( self._marlinPandoraProcessor, "ECalToHadGeVCalibrationEndCap")) hcalToHadGeV = float( self._marlin.getProcessorParameter(self._marlinPandoraProcessor, "HCalToHadGeVCalibration")) hadScaleCalibrator = PandoraHadScaleCalibrator() hadScaleCalibrator.setKaon0LEnergy(self._kaon0LEnergy) for iteration in range(self._maxNIterations): # readjust iteration parameters if not ecalAccuracyReached: ecalToHadGeVBarrel = ecalToHadGeVBarrel * ecalRescaleFactor ecalToHadGeVEndcap = ecalToHadGeVEndcap * ecalRescaleFactor if not hcalAccuracyReached: hcalToHadGeV = hcalToHadGeV * hcalRescaleFactor pfoAnalysisFile = "./PfoAnalysis_{0}_iter{1}.root".format( self._name, iteration) # run marlin ... self._marlin.setProcessorParameter( self._marlinPandoraProcessor, "ECalToHadGeVCalibrationBarrel", str(ecalToHadGeVBarrel)) self._marlin.setProcessorParameter( self._marlinPandoraProcessor, "ECalToHadGeVCalibrationEndCap", str(ecalToHadGeVEndcap)) self._marlin.setProcessorParameter(self._marlinPandoraProcessor, "HCalToHadGeVCalibration", str(hcalToHadGeV)) self._marlin.setProcessorParameter(self._pfoAnalysisProcessor, "RootFile", pfoAnalysisFile) self._marlin.run() # ... and calibration script hadScaleCalibrator.setRootFile(pfoAnalysisFile) hadScaleCalibrator.run() if not ecalAccuracyReached: newEcalKaon0LEnergy = hadScaleCalibrator.getEcalToHad() ecalRescaleFactor = float( self._kaon0LEnergy) / newEcalKaon0LEnergy ecalRescaleFactorCumul = ecalRescaleFactorCumul * ecalRescaleFactor currentEcalPrecision = abs(1 - 1. / ecalRescaleFactor) if not hcalAccuracyReached: newHcalKaon0LEnergy = hadScaleCalibrator.getHcalToHad() hcalRescaleFactor = float( self._kaon0LEnergy) / newHcalKaon0LEnergy hcalRescaleFactorCumul = hcalRescaleFactorCumul * hcalRescaleFactor currentHcalPrecision = abs(1 - 1. / hcalRescaleFactor) # write down iteration results self._writeIterationOutput( config, iteration, { "ecalPrecision": currentEcalPrecision, "ecalRescale": ecalRescaleFactor, "newEcalKaon0LEnergy": newEcalKaon0LEnergy, "hcalPrecision": currentHcalPrecision, "hcalRescale": hcalRescaleFactor, "newHcalKaon0LEnergy": newHcalKaon0LEnergy }) # are we accurate enough ?? if currentEcalPrecision < self._ecalEnergyScaleAccuracy: ecalAccuracyReached = True self._outputEcalToHadGeVBarrel = ecalToHadGeVBarrel self._outputEcalToHadGeVEndcap = ecalToHadGeVEndcap # are we accurate enough ?? if currentHcalPrecision < self._hcalEnergyScaleAccuracy: hcalAccuracyReached = True self._outputHcalToHadGeV = hcalToHadGeV if ecalAccuracyReached and hcalAccuracyReached: break if not ecalAccuracyReached or not hcalAccuracyReached: raise RuntimeError("{0}: Couldn't reach the user accuracy".format( self._name)) def writeOutput(self, config): output = self._getXMLStepOutput(config, create=True) self._writeProcessorParameter(output, self._marlinPandoraProcessor, "ECalToHadGeVCalibrationBarrel", self._outputEcalToHadGeVBarrel) self._writeProcessorParameter(output, self._marlinPandoraProcessor, "ECalToHadGeVCalibrationEndCap", self._outputEcalToHadGeVEndcap) self._writeProcessorParameter(output, self._marlinPandoraProcessor, "HCalToHadGeVCalibration", self._outputHcalToHadGeV)