#include "ICOMETLog.hxx" #include "IGeometryDatabase.hxx" #include "IECALCalibApplyEventFunction.hxx" #include "HEPUnits.hxx" IECALCalibApplyEventFunction::IECALCalibApplyEventFunction(): ICalibApplyEventFunction("ECAL") {} IECALCalibApplyEventFunction::~IECALCalibApplyEventFunction() {} //====================================================================== // ApplyCalibration //====================================================================== int IECALCalibApplyEventFunction::ApplyCalibration(COMET::ICOMETEvent& event) { // Get Digits COMET::IHandle digits = event.GetDigits("ECAL"); if(digits){ // Calibrate digits COMET::IHitSelection* hits = MakeHitSelection(digits); // Save if(hits) AddHitSelection(hits, event); } else{ COMETNamedVerbose(GetFullName(), "Cannot find digits"); } return 0; } //====================================================================== // MakeHitSelection //====================================================================== COMET::IHitSelection* IECALCalibApplyEventFunction:: MakeHitSelection(COMET::IHandle& digits) { COMET::IHitSelection* hits = new COMET::IHitSelection("ECAL", "CalibApplied ECAL Hit Selection"); COMETNamedVerbose(GetFullName(), "Digits ECAL has " << digits->size() << " components."); for(COMET::IDigitContainer::iterator digitIt = digits->begin(); digitIt != digits->end(); digitIt++){ COMET::IECALDigit* digit = static_cast(*digitIt); if(!digit){ COMETNamedVerbose(GetFullName(), "Cannot get a digit from digits ECAL"); continue; } COMET::IWritableDataHit* hit = MakeDataHit(digit); if(!hit){ COMETNamedVerbose(GetFullName(), "No data hit."); continue; } // Set digit proxy COMET::IDigitProxy proxy(*digits, digitIt); // if(! proxy.IsValid()){ // COMETNamedVerbose(GetFullName(), "A digit proxy is invalid."); // continue; // } hit->SetDigit(proxy); // Add hit hits->AddHit(COMET::IHandle(hit)); } // Check size if(hits->empty()){ COMETNamedVerbose(GetFullName(), "Cannot make hit selection: 1stECALHits"); delete hits; hits = NULL; } return hits; } //====================================================================== // MakeDataHit //====================================================================== COMET::IWritableDataHit* IECALCalibApplyEventFunction::MakeDataHit(COMET::IECALDigit* digit) { COMET::IWritableDataHit* hit = new COMET::IWritableDataHit(); hit->SetChannelId(digit->GetChannelId()); hit->SetTime(digit->GetFirstTimeTick() * 1.0 * unit::ns); // GeomId COMET::IGeometryDatabase& geomDB = COMET::IGeometryDatabase::Get(); COMET::IGeometryId geomId; Bool_t hasGeomId = geomDB.GetGeometryId(geomId, digit->GetChannelId()); if(!hasGeomId){ COMETNamedVerbose(GetFullName(), "Couldn't get GeomId."); delete hit; return NULL; } hit->SetGeomId(geomId); //------------------------ // Accumulate charges //------------------------ Double_t sumAdcs = 0.0; Double_t base = 0.0; const COMET::IWaveformDigit::TWfADC& adcs = digit->GetADCs(); // Baseline for(Int_t i=0; i<100; i++) base += adcs[i]; base /= 100; // Accumulate for(COMET::IWaveformDigit::TWfADC::const_iterator adc=adcs.begin(); adc!=adcs.end(); adc++) sumAdcs += *adc - base; // Set energy (calibrated from charge) hit->SetCharge(sumAdcs/2118.); // 2118.0 is calibration factor from sumed ADC -> energy (MeV) // This value assumes the following parameters in SimDetectorResponse // < SimDetectorResponse.APD.ElectronToADC = 10. > // < SimDetectorResponse.APD.NTimeBins = 1024 > // < SimDetectorResponse.APD.SamplingTime = 1.0 ns > // < SimDetectorResponse.APD.ShapingTime = 200.0 ns > // < SimDetectorResponse.APD.DistinctTime = 1.0 ns > // < SimDetectorResponse.APD.Pedestal = 0 > // < SimDetectorResponse.APD.GainEfficiency = 10. > // < SimDetectorResponse.APD.NoiseLevel = 0. > (Not default) // < SimDetectorResponse.APD.WaveFormPulseTime = 230.375 ns > // < SimDetectorResponse.APD.WaveFormPulseWidth = 25.1079 > // < SimDetectorResponse.APD.WaveFormPulseAsymmetry = 0.750413 > // < SimDetectorResponse.APD.WaveFormPulseHeight = 22515.9 > (Not default) // < SimDetectorResponse.APD.WaveFormPulseOffset = 381.276 > // < SimDetectorResponse.APD.WaveFormPulseSlope = 0.0 > (Not default) if(hit->GetCharge() < 1e-3){ COMETNamedVerbose(GetFullName(), "Too small charge, ignored."); delete hit; return NULL; } /* // Debug COMETNamedVerbose(GetFullName(), std::endl << "chanId: " << std::bitset<32>(digit->GetChannelId().AsUInt()) << std::endl << "geomId: " << std::bitset<32>(geomId.AsInt()) << std::endl << "posX:" << hit->GetPosition().X() ); */ return hit; }