diff --git a/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileDigitsFromPulse.h b/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileDigitsFromPulse.h index 74ea25116319ddc18bce1eb204d1adb7cf325003..893d1f228831c15999c83348e540d1517b1372dc 100755 --- a/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileDigitsFromPulse.h +++ b/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileDigitsFromPulse.h @@ -133,7 +133,6 @@ private: int nPul; //!< number of pileup pulses int nPul_eff; //Used for symetrization of PU in computation std::vector<float> m_PUAmp; - double n_inTimeAmp; //!< Local loop variable for amplitude of in-time pulse //Members for simulator TilePulseShape* m_ps[2]; //!< Class for defining pulse. One element for lo gain and one for hi. diff --git a/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileMuonReceiverDecision.h b/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileMuonReceiverDecision.h index 3643a317d0edbf2b92d89c6d437f58685625a088..fb94d224c81cde2aaa88c3e3cf163b702c3b1fd0 100644 --- a/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileMuonReceiverDecision.h +++ b/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileMuonReceiverDecision.h @@ -40,6 +40,7 @@ class TileID; class TileHWID; class TileInfo; class TileCablingService; +class TileCondToolEmscale; class TileMuonReceiverDecision: public AthAlgorithm { @@ -61,13 +62,16 @@ class TileMuonReceiverDecision: public AthAlgorithm { const TileID* m_tileID; const TileHWID* m_tileHWID; const TileCablingService* m_cablingService; //!< TileCabling instance - + const TileInfo* m_tileInfo; + float m_threshold_d6_lo; float m_threshold_d6_hi; float m_threshold_d5d6_lo; float m_threshold_d5d6_hi; float m_selCutQf; + ToolHandle<TileCondToolEmscale> m_tileToolEmscale; //!< main Tile Calibration tool + }; #endif diff --git a/TileCalorimeter/TileSimAlgs/TileSimAlgs/TilePulseForTileMuonReceiver.h b/TileCalorimeter/TileSimAlgs/TileSimAlgs/TilePulseForTileMuonReceiver.h index 6a6037c54f7afd30347ae295f7c03ca6baed9275..b64dfd58b46301b104ce7f08b58bd8729aa7c59c 100644 --- a/TileCalorimeter/TileSimAlgs/TileSimAlgs/TilePulseForTileMuonReceiver.h +++ b/TileCalorimeter/TileSimAlgs/TileSimAlgs/TilePulseForTileMuonReceiver.h @@ -63,8 +63,6 @@ class TileRawChannelBuilderMF; #include <string> #include <vector> -// missing includes - class TilePulseForTileMuonReceiver: public AthAlgorithm { public: // constructor @@ -95,7 +93,7 @@ class TilePulseForTileMuonReceiver: public AthAlgorithm { int nSamp; //!< Number of time slices for each channel int iTrig; //!< Index of the triggering time slice int adcMax; //!< ADC saturation value - double tileThresh; //!< Actual threshold value + double tileThresh; //!< Actual threshold value // This is used when loading a pulse from db // diff --git a/TileCalorimeter/TileSimAlgs/share/TileDigiCommon_jobOptions.py b/TileCalorimeter/TileSimAlgs/share/TileDigiCommon_jobOptions.py index b6620cff7a767cbe791f4a48781914de02aad4f0..464720da3c41260d68e6b95a8c13f2e9f0ee1638 100644 --- a/TileCalorimeter/TileSimAlgs/share/TileDigiCommon_jobOptions.py +++ b/TileCalorimeter/TileSimAlgs/share/TileDigiCommon_jobOptions.py @@ -72,14 +72,29 @@ if doTileDigitsFromPulse: if doTileDigitToRawChannel: - # Reconstruction method: OF2 (default in full ATLAS reco) - from TileRecUtils.TileRecFlags import jobproperties - jobproperties.TileRecFlags.doTileFit = False - jobproperties.TileRecFlags.doTileManyAmps = False - jobproperties.TileRecFlags.doTileOpt = False - if jobproperties.Beam.beamType == 'collisions': - jobproperties.TileRecFlags.doTileOptATLAS = True + #from AtlasGeoModel.InDetGMJobProperties import GeometryFlags as geoFlags + #RUN1=(geoFlags.Run() == "RUN1" or (geoFlags.Run() == "UNDEFINED" and geoFlags.isIBL() == False)) + OF2asDefault=True + # Reconstruction method: COF or OF2-NI for collisions, OF2-I for cosmics + from TileRecUtils.TileRecFlags import jobproperties + if not (jobproperties.TileRecFlags.doTileFlat \ + or jobproperties.TileRecFlags.doTileFit \ + or jobproperties.TileRecFlags.doTileFitCool \ + or jobproperties.TileRecFlags.doTileOpt \ + or jobproperties.TileRecFlags.doTileOF1 \ + or jobproperties.TileRecFlags.doTileOpt2 \ + or jobproperties.TileRecFlags.doTileOptATLAS \ + or jobproperties.TileRecFlags.doTileMF): + if jobproperties.Beam.beamType == 'collisions': + if OF2asDefault: + jobproperties.TileRecFlags.doTileOptATLAS = True + else: + jobproperties.TileRecFlags.doTileMF = True + else: + jobproperties.TileRecFlags.doTileOpt2 = True + + if jobproperties.Beam.beamType == 'collisions': if jobproperties.Beam.bunchSpacing.get_Value()<75: from Digitization.DigitizationFlags import digitizationFlags halfBS=float(digitizationFlags.bunchSpacing.get_Value()) @@ -105,17 +120,46 @@ if doTileDigitToRawChannel: mlog.info("Setting max/min time for parabolic correction to +/- %4.1f ns" % halfBS) jobproperties.TileRecFlags.TimeMinForAmpCorrection = -halfBS jobproperties.TileRecFlags.TimeMaxForAmpCorrection = halfBS - else: - jobproperties.TileRecFlags.doTileOpt2 = True from TileRecUtils.TileRawChannelGetter import * theTileRawChannelGetter=TileRawChannelGetter() jobproperties.TileRecFlags.TileRawChannelContainer = "TileRawChannelCnt" + # make sure that only one output container has default name "TileRawChannelCnt" if jobproperties.Beam.beamType == 'collisions': - ToolSvc.TileRawChannelBuilderOptATLAS.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + if OF2asDefault: + if jobproperties.TileRecFlags.doTileOptATLAS(): + ToolSvc.TileRawChannelBuilderOptATLAS.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + if jobproperties.TileRecFlags.doTileMF(): + ToolSvc.TileRawChannelBuilderMF.TileRawChannelContainer = "TileRawChannelMF" + if jobproperties.TileRecFlags.doTileOpt2(): + ToolSvc.TileRawChannelBuilderOpt2Filter.TileRawChannelContainer = "TileRawChannelOpt2" + elif jobproperties.TileRecFlags.doTileMF(): + ToolSvc.TileRawChannelBuilderMF.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + elif jobproperties.TileRecFlags.doTileOpt2(): + ToolSvc.TileRawChannelBuilderOpt2Filter.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + else: + if jobproperties.TileRecFlags.doTileMF(): + ToolSvc.TileRawChannelBuilderMF.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + if jobproperties.TileRecFlags.doTileOptATLAS(): + ToolSvc.TileRawChannelBuilderOptATLAS.TileRawChannelContainer = "TileRawChannelFixed" + if jobproperties.TileRecFlags.doTileOpt2(): + ToolSvc.TileRawChannelBuilderOpt2Filter.TileRawChannelContainer = "TileRawChannelOpt2" + elif jobproperties.TileRecFlags.doTileOptATLAS(): + ToolSvc.TileRawChannelBuilderOptATLAS.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + elif jobproperties.TileRecFlags.doTileOpt2(): + ToolSvc.TileRawChannelBuilderOpt2Filter.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() else: - ToolSvc.TileRawChannelBuilderOpt2Filter.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + if jobproperties.TileRecFlags.doTileOpt2(): + ToolSvc.TileRawChannelBuilderOpt2Filter.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + if jobproperties.TileRecFlags.doTileMF(): + ToolSvc.TileRawChannelBuilderMF.TileRawChannelContainer = "TileRawChannelMF" + if jobproperties.TileRecFlags.doTileOptATLAS(): + ToolSvc.TileRawChannelBuilderOptATLAS.TileRawChannelContainer = "TileRawChannelFixed" + elif jobproperties.TileRecFlags.doTileOptATLAS(): + ToolSvc.TileRawChannelBuilderOptATLAS.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() + elif jobproperties.TileRecFlags.doTileMF(): + ToolSvc.TileRawChannelBuilderMF.TileRawChannelContainer = jobproperties.TileRecFlags.TileRawChannelContainer() if not hasattr( ToolSvc, "TileBeamInfoProvider" ): diff --git a/TileCalorimeter/TileSimAlgs/share/TileMuonReceiver_jobOptions.py b/TileCalorimeter/TileSimAlgs/share/TileMuonReceiver_jobOptions.py index 54ce9c5586464d8e893670b58ae3448dd80acade..0f0de41609ca0a94a3ec6d544bd5bf2125f00ae3 100755 --- a/TileCalorimeter/TileSimAlgs/share/TileMuonReceiver_jobOptions.py +++ b/TileCalorimeter/TileSimAlgs/share/TileMuonReceiver_jobOptions.py @@ -10,7 +10,8 @@ TileMuRcvPedestal = 11.73 # Should be the same in TileInfo and TileRawChannelBui from AthenaCommon.AppMgr import ServiceMgr as svcMgr svcMgr.TileInfoLoader.MuRcvNoiseSigma = TileMuRcvNoiseSigma svcMgr.TileInfoLoader.MuRcvPed = TileMuRcvPedestal -# svcMgr.TileCablingSvc.CablingType = 4 # COMMENT this line prior to a upload to SVN +# Uncomment for a local run BUT *COMMENT* this line prior to an upload to SVN +# svcMgr.TileCablingSvc.CablingType = 4 from AthenaCommon import CfgMgr toolSvc = CfgMgr.ToolSvc() @@ -41,6 +42,7 @@ topSequence = AlgSequence() # Set up TilePulseForTileMuonReceiver topSequence += CfgMgr.TilePulseForTileMuonReceiver('TilePulseForTileMuonReceiver' +# , OutputLevel = VERBOSE , IntegerDigits = True , UseCoolPedestal = False , UseCoolPulseShapes = True @@ -52,6 +54,7 @@ topSequence += CfgMgr.TilePulseForTileMuonReceiver('TilePulseForTileMuonReceiver jobproperties.Digitization.rndmSeedList.addSeed("Tile_PulseForTileMuonReceiver", 4789899, 989240512) topSequence += CfgMgr.TileMuonReceiverDecision('TileMuonReceiverDecision' +# , OutputLevel = VERBOSE , MuonReceiverEneThreshCellD6Low = 500 , MuonReceiverEneThreshCellD6andD5Low = 500 , MuonReceiverEneThreshCellD6High = 600 diff --git a/TileCalorimeter/TileSimAlgs/src/TileDigitsFromPulse.cxx b/TileCalorimeter/TileSimAlgs/src/TileDigitsFromPulse.cxx index b0caa33e20edc8e2e12ccc636d5a791ff9a5f7f4..6cbd308553117838ec14f459fccdccc0c5c2b66c 100755 --- a/TileCalorimeter/TileSimAlgs/src/TileDigitsFromPulse.cxx +++ b/TileCalorimeter/TileSimAlgs/src/TileDigitsFromPulse.cxx @@ -247,7 +247,7 @@ StatusCode TileDigitsFromPulse::execute() { TileRawChannelContainer * pRawChannelContainer; pRawChannelContainer=new TileRawChannelContainer(true, m_rChType, m_rChUnit); #ifdef USE_TILEDIGITS_DATAPOOL - static DataPool<TileDigits> tileDigitsPool(m_tileHWID->adc_hash_max()); + DataPool<TileDigits> tileDigitsPool(m_tileHWID->adc_hash_max()); #endif TRandom3 *random = new TRandom3(m_seed); //Randomizer for pulshe-shape imperfection @@ -262,6 +262,8 @@ StatusCode TileDigitsFromPulse::execute() { ATH_MSG_DEBUG ("Starting loop"); int gain=1; + double n_inTimeAmp=0.0; //!< Local loop variable for amplitude of in-time pulse + for (int ros=1; ros<5; ++ros) { for (int drawer=0; drawer<64; ++drawer) { unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer); @@ -340,7 +342,7 @@ StatusCode TileDigitsFromPulse::execute() { ATH_MSG_VERBOSE("New ADC " << ros << "/" << drawer << "/" << channel << "/ saving gain " << gain); - TileDigits * digit = tileDigitsPool.nextElementPtr(); + TileDigits * digit = NEWTILEDIGITS(); digit->m_adc_hwid = m_tileHWID->adc_id(ros,drawer,channel,gain); digit->m_digits = samples; outputCont->push_back(digit); diff --git a/TileCalorimeter/TileSimAlgs/src/TileMuonReceiverDecision.cxx b/TileCalorimeter/TileSimAlgs/src/TileMuonReceiverDecision.cxx index 5f33d61578fe0bd9e112035ee25f4c28354f95a9..f9f007b5fac816d5e63ec67a1b9e5881d7e68549 100755 --- a/TileCalorimeter/TileSimAlgs/src/TileMuonReceiverDecision.cxx +++ b/TileCalorimeter/TileSimAlgs/src/TileMuonReceiverDecision.cxx @@ -28,13 +28,14 @@ // Calo includes #include "CaloIdentifier/TileID.h" - +#include "TileConditions/TileInfo.h" // Tile includes #include "TileIdentifier/TileHWID.h" #include "TileCalibBlobObjs/TileCalibUtils.h" #include "TileConditions/TileCablingService.h" #include "TileEvent/TileRawChannelContainer.h" +#include "TileConditions/TileCondToolEmscale.h" #include "TileSimAlgs/TileMuonReceiverDecision.h" #include "TileEvent/TileContainer.h" @@ -46,7 +47,9 @@ TileMuonReceiverDecision::TileMuonReceiverDecision(std::string name, ISvcLocator m_TileMuRcvContainer("TileMuRcvCnt"), m_tileID(0), m_tileHWID(0), - m_cablingService(0) + m_cablingService(0), + m_tileInfo(0), + m_tileToolEmscale("TileCondToolEmscale") { // declare properties... declareProperty( "MuonReceiverEneThreshCellD6Low" , m_threshold_d6_lo = 500. , "Setting the lowest trigger threshold for cell D6 in MeV (Def=500 MeV)"); @@ -55,6 +58,8 @@ TileMuonReceiverDecision::TileMuonReceiverDecision(std::string name, ISvcLocator declareProperty( "MuonReceiverEneThreshCellD6andD5High" , m_threshold_d5d6_hi = 600. , "Setting the highest trigger threshold for cell D5+D6 in MeV (Def=600 MeV)"); declareProperty( "SelectionCutForMatchedFilterQf" , m_selCutQf=0. , "Selection cut for the quality factor of the matched filters"); declareProperty( "TileMuonReceiverContainer" , m_TileMuRcvContainer , "Tile Calorimeter decision to TGC Sector Logic"); + declareProperty( "TileCondToolEmscale" , m_tileToolEmscale , "Service to calibrate all channels"); + declareProperty( "TileInfoName" , m_infoName = "TileInfo" ); } TileMuonReceiverDecision::~TileMuonReceiverDecision() @@ -75,6 +80,9 @@ StatusCode TileMuonReceiverDecision::initialize() { //=== retrieve TileID helper from det store CHECK( detStore()->retrieve(m_tileID) ); CHECK( detStore()->retrieve(m_tileHWID) ); + CHECK(detStore()->retrieve(m_tileInfo, m_infoName)); + + CHECK(m_tileToolEmscale.retrieve()); ATH_MSG_INFO("TileMuonReceiverDecision initialization completed" ); return StatusCode::SUCCESS; @@ -100,6 +108,8 @@ StatusCode TileMuonReceiverDecision::execute() { TileRawChannelContainer::const_iterator collItr = MuonReceiverRawChannelContainer->begin(); TileRawChannelContainer::const_iterator lastColl = MuonReceiverRawChannelContainer->end(); + // Vectors for managemnt for TMDB 2015 configuration with inclusion in trigger in 1.1<eta<1.3 + // std::vector<bool> tile2SL(4,false); std::vector<float> ene(2,0.0); std::vector<float> time(2,0.0); @@ -110,104 +120,172 @@ StatusCode TileMuonReceiverDecision::execute() { thresholds.push_back(m_threshold_d6_hi); thresholds.push_back(m_threshold_d6_lo); - // Create teh container to store the decision from the algorthm + // Create the container to store the decision from the algorithm // TileMuonReceiverContainer * decisionContainer = new TileMuonReceiverContainer(); - TileMuonReceiverObj * TileMuRcvObj = new TileMuonReceiverObj(0,thresholds); // special object with thresholds + TileMuonReceiverObj * TileMuRcvObj = new TileMuonReceiverObj(0,thresholds); // Special object with thresholds decisionContainer->push_back(TileMuRcvObj); - for ( ; collItr != lastColl; ++collItr ) - { - TileRawChannelCollection::const_iterator chanItr = (*collItr)->begin(); - TileRawChannelCollection::const_iterator lastChan = (*collItr)->end(); + // Conversion from TMDB channel number the index to channel number in a drawer + // +#define nEBchan 6 +#define nLBchan 9 +#define maxCell 5 + // EB: D5(L,R),D6(L,R),D4(L,R) + int EBchan[nEBchan]={17,16,37,38,3,2}; + // LB: D0,D1(L,R),D2(L,R),D3(L,R),BC8(L,R) + int LBchan[nLBchan]={0,13,14,25,24,41,44,39,40}; + // Auxiliary array for cell index + int EBIdCell[nEBchan]={0,0,1,1,2,2}; + int LBIdCell[nLBchan]={0,1,1,2,2,3,3,4,4}; + // Used for validation only not including in container at the moment + float energy_HLX[maxCell]={0.,0.,0.,0.,0.}; + float time_HLX[maxCell]={0.,0.,0.,0.,0.}; + + for ( ; collItr != lastColl; ++collItr ) { + + TileRawChannelCollection::const_iterator chanItr = (*collItr)->begin(); + TileRawChannelCollection::const_iterator lastChan = (*collItr)->end(); + + if (chanItr==lastChan) continue; + int frag_id = (*collItr)->identify(); + int drawerIdx = TileCalibUtils::getDrawerIdxFromFragId(frag_id); + int ros = frag_id>>8; + bool eb_ros = ((ros == TileHWID::EXTBAR_POS) || (ros == TileHWID::EXTBAR_NEG)); + int upperLim = (eb_ros) ? nEBchan : nLBchan; + + if (msgLvl(MSG::VERBOSE)) { + int drawer = (frag_id&0xFF); + memset(energy_HLX,0,sizeof(energy_HLX)); + memset(time_HLX,0,sizeof(time_HLX)); + msg(MSG::VERBOSE) << "(E.0.0) Frag_id: 0x"<< MSG::hex << frag_id << MSG::dec <<" ros: "<< ros <<" drawer: "<< drawer << endreq; + } - if (chanItr==lastChan) continue; - int frag_id = (*collItr)->identify(); - int ros=frag_id>>8; - int drawer=(frag_id&0xFF); + float energy_d6 = 0.0; + float energy_d5d6 = 0.0; + float time_d6 = 0.0; + float time_d5d6 = 0.0; + + int ich = 0; + int jch6 = 0; + int jch56 = 0; + + for ( ; chanItr != lastChan; ++chanItr ) { + + ++ich; + // For TMDB channel numbers are being set differently (17,16,37,38)->(D5L,D5r,D6L,D6R)->(0,1,2,3) + HWIdentifier adc_id = (*chanItr)->adc_HWID() ; + // TMDB channel is used in COOL and goes from 0..n with n=5 for EB and n=8 in LB + int TMDBchan = m_tileHWID->channel(adc_id) ; + if ( TMDBchan >= upperLim ) { + msg(MSG::WARNING) << "(E.1."<< ich <<") hwid: "<< m_tileHWID->to_string(adc_id,-1) <<" ch: "<< TMDBchan <<" --> Tile ch: UNKNOWN" << endreq ; + continue; + } + // TILE channel is the Tile HW channel + int TILEchan = (eb_ros) ? EBchan[TMDBchan] : LBchan[TMDBchan]; - float energy_d6 = 0.0; - float energy_d5d6 = 0.0; - float time_d6 = 0.0; - float time_d5d6 = 0.0; - - ATH_MSG_VERBOSE("A.00 " << tile2SL.size() ); - int j=2; - - for ( ; chanItr != lastChan; ++chanItr ) - { - // this is a temporary fix this is not being done in TilePulseForTileMuonReceiver - - HWIdentifier hwid = (*chanItr)->adc_HWID() ; - int channel = m_tileHWID->channel(hwid) ; - - if (msgLvl(MSG::VERBOSE)) { - ATH_MSG_VERBOSE(" " << m_tileHWID->to_string(hwid,-1)) ; - ATH_MSG_VERBOSE("channel " << channel << " ros " << ros << " drawer " << drawer); - ATH_MSG_VERBOSE("A.0"<< j <<" E[MeV] "<<(*chanItr)->amplitude()<<" t[ns] "<<(*chanItr)->time()<<" QF "<<(*chanItr)->quality()); - } - - energy_d5d6 += (*chanItr)->amplitude(); - time_d5d6 += (*chanItr)->time()/4.; - - if ( /*choose d6 cell*/ channel==37 || channel==38 ) { - energy_d6 += (*chanItr)->amplitude(); - time_d6 += (*chanItr)->time()/2.; - } - j++; - } - - // A. for a clear reading first producing a bool format response for each thershold - // d5+d6 - // - bool pass_d5d6_hi = (energy_d5d6>m_threshold_d5d6_hi); - bool pass_d5d6_lo = (energy_d5d6>m_threshold_d5d6_lo); - - // d6 - // - bool pass_d6_hi = (energy_d6>m_threshold_d6_hi); - bool pass_d6_lo = (energy_d6>m_threshold_d6_lo); + float ADC2MeV_factor = m_tileToolEmscale->channelCalib(drawerIdx, TILEchan, TileID::LOWGAIN, 1. + , TileRawChannelUnit::PicoCoulombs + , TileRawChannelUnit::MegaElectronVolts) + / m_tileInfo->MuRcvCalib(adc_id); + float energy = (*chanItr)->amplitude()*ADC2MeV_factor; + float time = (*chanItr)->time(); - // B. Now producing a vector with 4 bits each defining a unique tile decission - // HLHL:3210:[d5+d6][d6] - // + if (msgLvl(MSG::DEBUG)) { + msg(MSG::DEBUG) << "(E.1."<< ich <<") hwid: "<< m_tileHWID->to_string(adc_id,-1) <<" ch: "<< TMDBchan <<" --> Tile ch: "<< TILEchan << endreq ; + msg(MSG::DEBUG) << " E[ADC]: "<<(*chanItr)->amplitude()<<" E[MeV]: "<<energy<<" t[ns]: "<<time<<" QF: "<<(*chanItr)->quality() << endreq; + } - // output::bool decision entry 0 is the most significant digit in the 4 bits output - // entry 3 is the least significant digit in the 4 bits output + if ( eb_ros ) { + if ( TMDBchan<4 ) { + energy_d5d6 += energy; + time_d5d6 += time; + ++jch56; - tile2SL[0] = pass_d5d6_hi; - tile2SL[1] = (!pass_d5d6_hi && pass_d5d6_lo); - tile2SL[2] = pass_d6_hi; - tile2SL[3] = (!pass_d6_hi && pass_d6_lo); - - if (msgLvl(MSG::VERBOSE)) { - ATH_MSG_VERBOSE("A.06 Summary : e(d5+d6)= " << energy_d5d6 << " e(d6)= " << energy_d6); - ATH_MSG_VERBOSE(" Thresholds : " << m_threshold_d5d6_lo << " " << m_threshold_d5d6_hi << " " << m_threshold_d6_lo << " " << m_threshold_d6_hi ); - ATH_MSG_VERBOSE("A.07 Checking which tresholds have been passed: d56 high " << pass_d5d6_hi << " d56 low " << pass_d5d6_lo << " d6 high " << pass_d6_hi << " d6 low " << pass_d6_lo ); - ATH_MSG_VERBOSE("A.08 output to SL : " << tile2SL[0] << tile2SL[1] << tile2SL[2] << tile2SL[3] ); + if ( TMDBchan==2 || TMDBchan==3 ) { /* choose d6 cell */ + energy_d6 += energy; + time_d6 += time; + ++jch6; + } + } + if (msgLvl(MSG::VERBOSE)) { + energy_HLX[EBIdCell[TMDBchan]] += energy; + time_HLX[EBIdCell[TMDBchan]] += time; + } + } else { + if (msgLvl(MSG::VERBOSE)) { + energy_HLX[LBIdCell[TMDBchan]] += energy; + time_HLX[LBIdCell[TMDBchan]] += time; + } } - - if (tile2SL[0] || tile2SL[1] || tile2SL[2] || tile2SL[3]) { + } - int id_mod = ros*100+drawer;// 256*ros [3 eta>0 4 eta<0] + drawer [0-63 if <32 phi>0] + if (msgLvl(MSG::VERBOSE)) { + msg(MSG::VERBOSE) << "(X.0.0) Summary of the exteded results for HL-LHC: " << endreq; + if ( eb_ros ) { + msg(MSG::VERBOSE) << "(X.1.0) Energy D-5 "<<energy_HLX[0]<<" D-6 "<<energy_HLX[1]<<" D-4 "<<energy_HLX[2]<< endreq; + msg(MSG::VERBOSE) << "(X.2.0) Time D-5 "<<time_HLX[0]/2.<<" D-6 "<<time_HLX[1]/2.<<" D-4 "<<time_HLX[2]/2.<< endreq; + } else { + msg(MSG::VERBOSE) << "(X.1.0) Energy D-0 "<<energy_HLX[0]<<" D-1 "<<energy_HLX[1]<<" D-2 "<<energy_HLX[2]<<" D-3 "<<energy_HLX[3]<<" BC-8 "<<energy_HLX[4]<< endreq; + msg(MSG::VERBOSE) << "(X.2.0) Time D-0 "<<time_HLX[0]<<" D-1 "<<time_HLX[1]/2.<<" D-2 "<<time_HLX[2]/2.<<" D-3 "<<time_HLX[3]/2.<<" BC-8 "<<time_HLX[4]/2.<< endreq; + } + } + + if (jch56 == 0) { // neigher D5 nor D6 found - nothing to do + ATH_MSG_VERBOSE( "== NO trigger for this drawer " ); + continue; + } + + if (jch56>1) { + time_d5d6 /= jch56; + if (jch6>1) time_d6 /= jch6; + } - ene[0] = energy_d5d6; - ene[1] = energy_d6; - time[0] = time_d5d6; - time[1] = time_d6; + // A. Above threshold (hi and lo) d5+d6 + // + bool pass_d5d6_hi = (energy_d5d6>m_threshold_d5d6_hi); + bool pass_d5d6_lo = (energy_d5d6>m_threshold_d5d6_lo); + + // (hi and lo) d6 + // + bool pass_d6_hi = (energy_d6>m_threshold_d6_hi); + bool pass_d6_lo = (energy_d6>m_threshold_d6_lo); + + // B. Fill a vector with size 4 reproducing the 4-bit word with the structure HLHL:[d5+d6][d6] + // vector at 0 (d56hi) is the most significant digit in the 4 bits output + // vector at 3 (d6lo) is the least significant digit in the 4 bits output + // + tile2SL[0] = pass_d5d6_hi; + tile2SL[1] = (!pass_d5d6_hi && pass_d5d6_lo); + tile2SL[2] = pass_d6_hi; + tile2SL[3] = (!pass_d6_hi && pass_d6_lo); + + if (msgLvl(MSG::VERBOSE)) { + msg(MSG::VERBOSE) << "(E.2.0) Summary: e(d5+d6)= " << energy_d5d6 << " e(d6)= " << energy_d6 << endreq; + msg(MSG::VERBOSE) << "(E.3.0) Thresholds: " << m_threshold_d5d6_lo << " " << m_threshold_d5d6_hi << " " << m_threshold_d6_lo << " " << m_threshold_d6_hi << endreq; + msg(MSG::VERBOSE) << "(E.4.0) Checking which tresholds have been passed: d56 high " << pass_d5d6_hi << " d56 low " << pass_d5d6_lo << " d6 high " << pass_d6_hi << " d6 low " << pass_d6_lo << endreq; + msg(MSG::VERBOSE) << "(E.5.0) Output to SL: " << tile2SL[0] << tile2SL[1] << tile2SL[2] << tile2SL[3] << endreq; + } + + if (tile2SL[0] || tile2SL[1] || tile2SL[2] || tile2SL[3]) { - TileMuonReceiverObj * TileMuRcvObj = new TileMuonReceiverObj(id_mod,ene,time,tile2SL); - decisionContainer->push_back(TileMuRcvObj); + ene[0] = energy_d5d6; + ene[1] = energy_d6; + time[0] = time_d5d6; + time[1] = time_d6; - } else { - ATH_MSG_VERBOSE( " NULL trigger not include in container " ); - } + TileMuonReceiverObj * TileMuRcvObj = new TileMuonReceiverObj(frag_id,ene,time,tile2SL); + decisionContainer->push_back(TileMuRcvObj); + + } else { + ATH_MSG_VERBOSE( "== NULL trigger not include in container " ); } + } - if (msgLvl(MSG::VERBOSE)) { - ATH_MSG_VERBOSE("== Print TileD decision container output to SL") ; + if (msgLvl(MSG::DEBUG)) { + msg(MSG::DEBUG) << "== Print TileD decision container output to SL" << endreq ; decisionContainer->print(); } CHECK(evtStore()->record( decisionContainer, m_TileMuRcvContainer, false)); @@ -217,8 +295,6 @@ StatusCode TileMuonReceiverDecision::execute() { } StatusCode TileMuonReceiverDecision::finalize() { - ATH_MSG_DEBUG( "Finalizing TileMuonReceiverDecision"); - ATH_MSG_INFO( "TileMuonReceiverDecision finalized successfully"); return StatusCode::SUCCESS; } diff --git a/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.cxx b/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.cxx index dbb4f4468a1e5ff999fbd59694b776eab65dcf1b..82f02ba5bbdb56fd6c1020f9fc755702e6e515d6 100755 --- a/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.cxx +++ b/TileCalorimeter/TileSimAlgs/src/TilePulseForTileMuonReceiver.cxx @@ -21,10 +21,11 @@ // // 10.dec.2013 ready for submission in svn // 16.jan.2014 fixed coverity errors +// 06.oct.2015 including the barrel cells +// +// BUGS: +// // -// BUGS: -// * scaleAmplitude for TileRawChannel objects is not recognized (line 523 is commented) -// * output is still in adc counts // //**************************************************************************************** @@ -95,18 +96,18 @@ TilePulseForTileMuonReceiver::TilePulseForTileMuonReceiver(std::string name, ISv declareProperty("TileHitContainer" , m_hitContainer = "TileHitCnt"); declareProperty("MuonReceiverDigitsContainer" , m_MuRcvDigitsContainer = "MuRcvDigitsCnt"); declareProperty("MuonReceiverRawChannelContainer", m_MuRcvRawChContainer = "MuRcvRawChCnt"); - declareProperty("TileInfoName" , m_infoName = "TileInfo"); - declareProperty("IntegerDigits" , m_integerDigits = false, "Round digits (default=false)"); - declareProperty("TileBadChanTool" , m_tileBadChanTool); - declareProperty("TileCondToolPulseShape" , m_tileToolPulseShape); - declareProperty("MaskBadChannels" , m_maskBadChannels = false, "Remove channels tagged bad (default=false)"); - declareProperty("UseCoolPulseShapes" , m_useCoolPulseShapes = false, "Pulse shapes from database (default=false)"); - declareProperty("TileCondToolNoiseSample", m_tileToolNoiseSample); - declareProperty("UseCoolNoise" , m_tileNoise = false, "Noise from database (default=false)"); - declareProperty("UseCoolPedestal" , m_tilePedestal = false, "Pedestal from database (default=false)"); - declareProperty("RndmSvc" , m_rndmSvc, "Random Number Service used in TilePulseForTileMuonReceiver"); - declareProperty("TileCondToolEmscale" , m_tileToolEmscale, "Service to calibrate all channels"); - declareProperty("TileRawChannelBuilderMF", m_MuRcvBuildTool, "The tool by default is the Matched Filter"); + declareProperty("TileInfoName" , m_infoName = "TileInfo"); + declareProperty("IntegerDigits" , m_integerDigits = false, "Round digits (default=false)"); + declareProperty("TileBadChanTool" , m_tileBadChanTool); + declareProperty("TileCondToolPulseShape" , m_tileToolPulseShape); + declareProperty("MaskBadChannels" , m_maskBadChannels = false, "Remove channels tagged bad (default=false)"); + declareProperty("UseCoolPulseShapes" , m_useCoolPulseShapes = false, "Pulse shapes from database (default=false)"); + declareProperty("TileCondToolNoiseSample" , m_tileToolNoiseSample); + declareProperty("UseCoolNoise" , m_tileNoise = false, "Noise from database (default=false)"); + declareProperty("UseCoolPedestal" , m_tilePedestal = false, "Pedestal from database (default=false)"); + declareProperty("RndmSvc" , m_rndmSvc, "Random Number Service used in TilePulseForTileMuonReceiver"); + declareProperty("TileCondToolEmscale" , m_tileToolEmscale, "Service to calibrate all channels"); + declareProperty("TileRawChannelBuilderMF" , m_MuRcvBuildTool, "The tool by default is the Matched Filter"); } // destructor @@ -118,7 +119,6 @@ TilePulseForTileMuonReceiver::~TilePulseForTileMuonReceiver() { // StatusCode TilePulseForTileMuonReceiver::initialize() { - // ATH_MSG_INFO( "Initializing TilePulseForTileMuonReceiver" ); // Check cabling RUN>=RUN2 OK // m_cablingService = TileCablingService::getInstance(); @@ -143,13 +143,13 @@ StatusCode TilePulseForTileMuonReceiver::initialize() { nSamp = m_tileInfo->NdigitSamples(); // number of time slices for each chan iTrig = m_tileInfo->ItrigSample(); // index of the triggering time slice - adcMax = m_tileInfo->ADCmax(); // adc saturation value + adcMax = m_tileInfo->ADCmax(); // adc saturation value tileThresh = m_tileInfo->ThresholdDigits(TileID::LOWGAIN); - ATH_MSG_VERBOSE("Cabling Services: " << m_cablingService - << " Number of Samples: " << nSamp - << " Triggering tile slice: " << iTrig - << " ADC saturation value: " << adcMax + ATH_MSG_VERBOSE("Cabling Services: " << m_cablingService + << " Number of Samples: " << nSamp + << " Triggering tile slice: " << iTrig + << " ADC saturation value: " << adcMax << " TileCal Threshold LOW GAIN: " << tileThresh); m_pHRengine = m_rndmSvc->GetEngine("Tile_PulseForTileMuonReceiver"); @@ -159,14 +159,15 @@ StatusCode TilePulseForTileMuonReceiver::initialize() { binTime0 = m_tileInfo->MuRcvTime0Bin(); timeStep = 25.0 / nBinsPerX; - ATH_MSG_INFO( "Pulse info : " - << "shape "<< nShape - <<" nbins "<< nBinsPerX - <<" time "<< binTime0 - <<" time step "<< timeStep - <<" Triggering tile sample "<< iTrig); + ATH_MSG_VERBOSE( "Pulse info : " + << "shape " << nShape + <<" nbins " << nBinsPerX + <<" time " << binTime0 + <<" time step " << timeStep + <<" Triggering tile sample " << iTrig); - // Decrease by 1, now they are indexes of last element in a vector + // decrease by 1, now it is the position of lastest element in a vector + // --nShape; if (m_useCoolPulseShapes) { @@ -199,9 +200,22 @@ StatusCode TilePulseForTileMuonReceiver::execute() { ATH_MSG_DEBUG( "Executing TilePulseForTileMuonReceiver" ); } - int Dchan[4]; - int jch = 0; - int ind = 0; + // Conversion from TMDB channel number to channel number in a drawer: EB (0-3) LB(0-13) + // Including the cells used in the "The potential of using the ATLAS Tile calorimeter in Phase-II for the + // Level-0 muon trigger" (ATL-COM-TILECAL-2015-007.pdf): ALL D-layer + BC-8. + // +#define nEBchan 6 +#define nLBchan 9 + // EB: D5(L,R),D6(L,R),D4(L,R) + int EBchan[nEBchan]={17,16,37,38,3,2}; + // LB: D0,D1(L,R),D2(L,R),D3(L,R),BC8(L,R) + int LBchan[nLBchan]={0,13,14,25,24,41,44,39,40}; + // Set to maximum possible index +#if (nEBchan > nLBchan) + double pDigitSamplesArray[nEBchan][7]; +#else + double pDigitSamplesArray[nLBchan][7]; +#endif // PULSE @@ -210,16 +224,6 @@ StatusCode TilePulseForTileMuonReceiver::execute() { double Rndm[16]; double Rndm_dG[1]; - // Set of variables for management when fetching the pulse from COOL - // - int ishift; - int n_hits; - int k; - float phase; - float y; - float dy; - double shape; - // Noise and pedestal from db // double pedSim = 0.; @@ -236,24 +240,6 @@ StatusCode TilePulseForTileMuonReceiver::execute() { double muRcv_Max; // double muRcv_Thresh; - // Tile_Base_ID::pmt_id ( int section, int side, - // int module, int tower, - // int sample, int pmt ) const - - for (int tower = 10; tower < 13; tower += 2) { - // for (int tower = 0; tower<16; tower+=2) { - for (int pm = 0; pm < 2; pm++) { - Identifier pmt_id = m_tileID->pmt_id(TileID::EXTBAR, 1, 0, tower, TileID::SAMP_D, pm); - HWIdentifier ch_id = m_cablingService->s2h_channel_id(pmt_id); - Dchan[ind] = m_tileHWID->channel(ch_id); - ATH_MSG_VERBOSE( "Used channels " << ind - << " " << m_tileID->to_string(pmt_id) - << " " << m_tileHWID->to_string(ch_id) - << " " << Dchan[ind]); - ind++; - } - } - // Get hit container from TES // const TileHitContainer* hitCont; @@ -267,7 +253,7 @@ StatusCode TilePulseForTileMuonReceiver::execute() { // Get a container for the digits // TileDigitsContainer* MuonReceiverDigitsContainer = new TileDigitsContainer(true); - + // Get a container for the raw channels // TileRawChannelContainer* MuonReceiverRawChannelContainer = new TileRawChannelContainer(true, TileFragHash::MF, TileRawChannelUnit::MegaElectronVolts, SG::VIEW_ELEMENTS); @@ -276,171 +262,188 @@ StatusCode TilePulseForTileMuonReceiver::execute() { // std::vector<float> digitsBuffer(nSamp); - // (a) iterate over all collections in the HIT container : access 'ros' and 'drawer' + ///////////////////////////////////////////////////////////////////////////////// + // (a.0) iterate over collections in the HIT container: access 'ros' and 'drawer' // TileHitContainer::const_iterator collItr = hitCont->begin(); TileHitContainer::const_iterator lastColl = hitCont->end(); for (; collItr != lastColl; ++collItr) { - ATH_MSG_VERBOSE("(A.01) Looping over all collections in the HIT container"); - // Get array of HWID's for this drawer (stored locally). // HWIdentifier drawer_id = m_tileHWID->drawer_id((*collItr)->identify()); int ros = m_tileHWID->ros(drawer_id); int drawer = m_tileHWID->drawer(drawer_id); int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer); + bool eb_ros = ((ros == TileHWID::EXTBAR_POS) || (ros == TileHWID::EXTBAR_NEG)); + int upperLim = (eb_ros) ? nEBchan : nLBchan; - // In here a first selection of the events to follow can be made by selection of the interesting ros - // - if (ros == 1 || ros == 2) continue; - - double pDigitSamplesArray[4][7]; + ATH_MSG_VERBOSE("(A.00) Looping over all collections for TMDB in the HIT container"); memset(pDigitSamplesArray, 0, sizeof(pDigitSamplesArray)); - ATH_MSG_VERBOSE("Going through collection ROS/DRAWER : "<< ros <<"/"<< drawer); + ATH_MSG_VERBOSE("(A.01) Going through collection ROS/DRAWER : "<< ros <<"/"<< drawer); + ATH_MSG_DEBUG(" Going through collection ROS/DRAWER : "<< ros <<"/"<< drawer); if (m_cablingService->connected(ros, drawer)) { ATH_MSG_VERBOSE("(A.02) ROS: "<< ros << " drawer: " << drawer << " is connected"); } else { - ATH_MSG_VERBOSE("(A.03) ROS: "<< ros << " drawer: " << drawer << " is not connected"); + ATH_MSG_VERBOSE("(A.02) ROS: "<< ros << " drawer: " << drawer << " is NOT connected"); continue; } - // Get drawer idhash for later access to the database to get ped and noi + // Get drawer idhash for later access to the database to get ped and noise // m_tileHWID->get_hash(drawer_id, idhash, &drawer_context); + ////////////////////////////////////////////////////////////////////////////// // (a.1) Iterate over all hits in a collection : access 'channel' // TileHitCollection::const_iterator hitItr = (*collItr)->begin(); TileHitCollection::const_iterator lastHit = (*collItr)->end(); - for (; hitItr != lastHit; ++hitItr) { + if ( !(*collItr)->size() ) ATH_MSG_DEBUG("-- No hits in this drawer! Filling channels with noise and pedestal. --"); - n_hits = 0; - - ATH_MSG_VERBOSE("(B.00) Iterate over all the hits in the ExtBar collection"); + for (; hitItr != lastHit; ++hitItr) { // Get the pmt ID + // Identifier pmt_id = (*hitItr)->pmt_ID(); - if (m_tileID->section(pmt_id) != TileID::EXTBAR || m_tileID->sample(pmt_id) != TileID::SAMP_D) + // keep only D-cells and in addition cell BC8 + // + int tower = m_tileID->tower(pmt_id); + int sample = m_tileID->sample(pmt_id); + if ( ! ((sample == TileID::SAMP_D) || (sample == TileID::SAMP_BC && tower == 7)) ) continue; - int index = m_tileID->pmt(pmt_id) + m_tileID->tower(pmt_id) - 10; - - jch = Dchan[index]; + ATH_MSG_VERBOSE("(B.00) ++ Iterate over all the D layer channels with hits for TMDB"); - ATH_MSG_VERBOSE(" Test01: Channel " << jch << " has index " << index); + // In COOL database data will be organized acoording to TMDB channel (TMDBchan): 0..n with n=5 in EB and n=8 in LB + int TMDBchan; + // In here we need to access the real TILE HW channel (TILEchan) that it has a correspondance with TMDB chan given by EBchan and LBNchan + int TILEchan; - if (ros == 3) { - jch = Dchan[index]; - } else if (ros == 4) { - //index = index + std::pow(-1, index); - int sgn = (index&1) ? -1 : 1; - index += sgn; - jch = Dchan[index]; + if (eb_ros) { + // cells D5, D6 and then D4 at the end + if (m_tileID->side(pmt_id) > 0) + TMDBchan = 1 - m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4); + else + TMDBchan = m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4); + TILEchan=EBchan[TMDBchan]; + } else { + // Barrel (extension for HL-LHC) + if (tower == 0) { + TMDBchan = 0; // cell D0, channel 0 always + } else { + // cells D1. D2, D3 and BC8 + if (m_tileID->side(pmt_id) > 0) + TMDBchan = 1 - m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7); + else + TMDBchan = m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7); + } + TILEchan=LBchan[TMDBchan]; } - HWIdentifier adc_id = m_tileHWID->adc_id(drawer_id, jch, TileID::LOWGAIN); + double* pDigitSamples = pDigitSamplesArray[TMDBchan]; - ATH_MSG_VERBOSE( " Test02: Correct pmt being transported in Dchan[]: " << index << " " << Dchan[index] - << "=?" << m_tileHWID->channel(m_cablingService->s2h_channel_id(pmt_id)) - << " then Ok. For reference get adc_id: " << m_tileHWID->to_string(adc_id, -1)); - - double* pDigitSamples = pDigitSamplesArray[index]; - - // Prepare to construct your pulse - // - ATH_MSG_DEBUG(" New hit in ROS/DRAWER/PMT " << ros << "/" << drawer << "/" << jch << " pmt_id " << m_tileID->to_string(pmt_id) <<" adc_id "<< m_tileHWID->to_string(adc_id,-1)); + if (msgLvl(MSG::VERBOSE)){ + HWIdentifier adc_id = m_tileHWID->adc_id(drawer_id, TMDBchan, TileID::LOWGAIN); + msg(MSG::VERBOSE) << "(B.01) Correct pmt being transported in XXchan[]: "<<TMDBchan<<" "<<TILEchan<< "=?" + << m_tileHWID->channel(m_cablingService->s2h_channel_id(pmt_id)) + << " For reference get TMDB adc_id: " << m_tileHWID->to_string(adc_id) << endreq; + msg(MSG::VERBOSE) << "(B.02) New hit in ROS/DRAWER/PMT "<<ros<<"/"<<drawer<<"/"<<TMDBchan<<" ("<<TILEchan<<")" + << " pmt_id "<< m_tileID->to_string(pmt_id,-1) + << " adc_id "<< m_tileHWID->to_string(adc_id) << endreq; + } + // Scintillator Energy -> Cell Energy (uses sampling fraction) // double hit_calib = m_tileInfo->HitCalib(pmt_id); - ATH_MSG_VERBOSE("(B.01) Sampling fraction: " << hit_calib); + ATH_MSG_VERBOSE("------ Sampling fraction: " << hit_calib); - // (a.2) Loop over the subhits of this channel + ///////////////////////////////////////////////////////////////////////////////////// + // (a.2) Loop over the hits of this channel // Calibrations are applied per subhit and energy added per subhit of a channel // - n_hits = (*hitItr)->size(); - ATH_MSG_VERBOSE("(B.02) Number of sub-hits in channel: " << n_hits); + int n_hits = (*hitItr)->size(); + + ATH_MSG_VERBOSE("------ Number of hits in channel: " << n_hits); for (int ihit = 0; ihit < n_hits; ++ihit) { - ATH_MSG_VERBOSE("(C.00) Iterating over the subhits of the channel : Sub-hit #" << ihit); + ATH_MSG_VERBOSE("(C.00) ++ Iterating over the hits of channel " << TILEchan <<": hit #" << ihit); double e_hit = (*hitItr)->energy(ihit); // [MeV] energy deposited in scintillator - double e_pmt = e_hit * hit_calib; // [MeV] true cell energy + double e_pmt = e_hit * hit_calib; // [MeV] true cell energy - ATH_MSG_VERBOSE("(C.01) Energy in scintillator [MeV]: " << e_hit - << " true cell energy [MeV]: " << e_pmt); + ATH_MSG_VERBOSE("(C.01) Energy in scintillator [MeV]: " << e_hit << " true cell energy [MeV]: " << e_pmt); // Need to pass the negative of t_hit, this is because the trigger returns the amplitude // at a given phase whereas the t_hit returns it from t=0 when the hit took place // - double t_hit = (*hitItr)->time(ihit); - ATH_MSG_VERBOSE("(C.02.01) phase " << t_hit); + + ATH_MSG_VERBOSE("(C.02.01) Phase " << t_hit); // Load pulse // - ishift = 0; - k = 0; - phase = 0; - y = 0; - dy = 0; - shape = 0; - - ishift = (int) (t_hit / timeStep + 0.5); + int k = 0; + float phase = 0.0; + float y = 0.0; + float dy = 0.0; + double shape = 0.0; + + int ishift = (int) (t_hit / timeStep + 0.5); + ATH_MSG_VERBOSE( "(C.02.02) ishift :" << t_hit << "/" << timeStep << "+0.5 = " << ishift); if (m_useCoolPulseShapes) { - for (int js = 0; js < nSamp; ++js) { k = binTime0 + (js - iTrig) * nBinsPerX - ishift; if (k < 0) k = 0; else if (k > nShape) k = nShape; + ATH_MSG_VERBOSE( "(C.02.03) k : " << binTime0 << "+(" << js << "-" << iTrig << ")*" << nBinsPerX << "-" << ishift << " = " << k); phase = (k - binTime0) * timeStep; + ATH_MSG_VERBOSE( "(C.02.04) phase : " << k << "-" << binTime0 << "*" << timeStep << " = " << phase); - m_tileToolPulseShape->getPulseShapeYDY(drawerIdx, jch, TileID::LOWGAIN, phase, y, dy); + m_tileToolPulseShape->getPulseShapeYDY(drawerIdx, TMDBchan, TileID::LOWGAIN, phase, y, dy); shape = (double) y; pDigitSamples[js] += e_pmt * shape; // MeV + ATH_MSG_VERBOSE( "(C.03.0) Sample no.= " << js << " idx= " << k << " Shape wt. = " << shape - << " Amp = " << pDigitSamples[js] - << "[MeV] Energy: " << e_pmt << "[MeV] LOGAIN from COOL"); - + << " Amp = " << pDigitSamples[js] << " [MeV]"); } //END loop over samples - } else { for (int js = 0; js < nSamp; ++js) { k = binTime0 + (js - iTrig) * nBinsPerX - ishift; if (k < 0) k = 0; else if (k > nShape) k = nShape; + ATH_MSG_VERBOSE( "(C.02.03) k : " << binTime0 << "+(" << js << "-" << iTrig << ")*" << nBinsPerX << "-" << ishift << " = " << k); pDigitSamples[js] += e_pmt * m_shapeMuonReceiver[k]; // MeV + ATH_MSG_VERBOSE( "(C.03.0) Sample no.= " << js << " idx= " << k << " Shape wt. = " << m_shapeMuonReceiver[k] << " Amp = " << pDigitSamples[js] << "[MeV] Energy: " << e_pmt << " LOGAIN from TileInfo"); - } //END loop over samples } // END if (m_useCoolPulseShapes) } // END loop over sub-HITS - ATH_MSG_VERBOSE("(C.04) ENDED Loop over sub hits"); + ATH_MSG_VERBOSE("(C.04) ENDED Loop over hits"); ATH_MSG_DEBUG(" Number of hits " << n_hits - << " channel " << m_tileHWID->to_string(drawer_id,-1) << "/" << Dchan[index] + << " channel " << m_tileHWID->to_string(drawer_id,-2) << "/" << TMDBchan << "<-->" << TILEchan << " digitized pulse [MeV] "<< pDigitSamples[0] << "/" << pDigitSamples[1] << "/" << pDigitSamples[2] @@ -451,36 +454,36 @@ StatusCode TilePulseForTileMuonReceiver::execute() { } // END loop over a HIT collection - ATH_MSG_VERBOSE("(B.04) ENDED Loop over a hit collection"); - - // (a.3) The pulse has a shape and a amplitude in MeV now we convert it to ADC counts and add NOISE and PEDESTAL - // PEDESTAL [ADC counts] and NOISE [ADC counts] as stored in Tile Conditions (for NOW are fixed values) - // Keep containers for each module (each partition) the same size between events + ///////////////////////////////////////////////////////////////////////// + // (a.3) The pulse has a shape and a amplitude in MeV now it is converted + // into ADC counts and add the NOISE and the PEDESTAL + // PEDESTAL [ADC counts] and NOISE [ADC counts] as stored in Tile + // Conditions (for NOW are fixed values LATER from COOL) + // Keep containers for each module (each partition) the same size + // between events // - - for (int index = 0; index < 4; index++) { - - jch = Dchan[index]; - double* pDigitSamples = pDigitSamplesArray[index]; - - HWIdentifier adc_id = m_tileHWID->adc_id(drawer_id, jch, TileID::LOWGAIN); - - if (index == 0) - ATH_MSG_VERBOSE( "(D.00) Add noise and pedestal for interesting channels (4 per module)" - << " in ROS (3/4): " << ros - << " drawer: " << drawer - << " drawer idx: " << drawerIdx - << " drawer_id: " << m_tileHWID->to_string(adc_id,-1)); - - ATH_MSG_DEBUG(" Add noise and pedestal for : " << m_tileHWID->to_string(adc_id,-1)); - - // different for each channel_id might be the case in the future (now a const. in TileInfoLoader.cxx) + for (int TMDBchan = 0; TMDBchan < upperLim; ++TMDBchan) { + + double* pDigitSamples=pDigitSamplesArray[TMDBchan]; + int TILEchan = (eb_ros) ? EBchan[TMDBchan] : LBchan[TMDBchan]; + + HWIdentifier adc_id = m_tileHWID->adc_id(drawer_id, TMDBchan, TileID::LOWGAIN); + + ATH_MSG_DEBUG( "(D.00) ++ Add noise and pedestal in " + << " TMDBchan: " << TMDBchan << " TILEchan: " << TILEchan + << " ROS: " << ros + << " drawer: " << drawer + << " drawer idx: " << drawerIdx + << " drawer_id: " << m_tileHWID->to_string(drawer_id,-2) + << " channel: " << m_tileHWID->to_string(adc_id,-1)); + + // Different for each channel_id might be the case in the future (now a const. in TileInfoLoader.cxx) // muRcv_NoiseSigma = m_tileInfo->MuRcvNoiseSigma(adc_id); // [adc] - // muRcv_Thresh = m_tileInfo->MuRcvThresh(adc_id); // [adc] ... not used - muRcv_Ped = m_tileInfo->MuRcvPed(adc_id); // [adc] - muRcv_Calib = m_tileInfo->MuRcvCalib(adc_id); // pCb->[adc] - muRcv_Max = m_tileInfo->MuRcvMax(adc_id); // [adc] + // muRcv_Thresh = m_tileInfo->MuRcvThresh(adc_id); // [adc] ... not used + muRcv_Ped = m_tileInfo->MuRcvPed(adc_id); // [adc] + muRcv_Calib = m_tileInfo->MuRcvCalib(adc_id); // pCb->[adc] + muRcv_Max = m_tileInfo->MuRcvMax(adc_id); // [adc] ATH_MSG_VERBOSE( "(D.01) Tile Muon Receiver parameters:" << " sig " << muRcv_NoiseSigma @@ -491,7 +494,7 @@ StatusCode TilePulseForTileMuonReceiver::execute() { // adc/pCb / MeV/pCb = adc/MeV // - double mev2ADC_factor = muRcv_Calib / m_tileToolEmscale->channelCalib(drawerIdx, jch, TileID::LOWGAIN, 1. + double mev2ADC_factor = muRcv_Calib / m_tileToolEmscale->channelCalib(drawerIdx,TILEchan,TileID::LOWGAIN, 1. , TileRawChannelUnit::PicoCoulombs , TileRawChannelUnit::MegaElectronVolts); @@ -509,129 +512,104 @@ StatusCode TilePulseForTileMuonReceiver::execute() { << " " << pDigitSamples[6] << " [All ZERO if there is no hit in channel.] "); - ATH_MSG_VERBOSE( "(D.02.00) Channel: " << ros << '/' << drawer << '/' << jch - << " adc/pCb: " << muRcv_Calib - << " Mev/pCb: " << m_tileToolEmscale->channelCalib(drawerIdx , jch , TileID::LOWGAIN , 1., TileRawChannelUnit::PicoCoulombs, TileRawChannelUnit::MegaElectronVolts) - << " final calibration factor adc/MeV: " << mev2ADC_factor); + ATH_MSG_VERBOSE( "(D.02.00) Channel: "<<ros<<'/'<<drawer<<'/'<< TMDBchan + << " adc/pCb: "<< muRcv_Calib + << " Mev/pCb: "<< m_tileToolEmscale->channelCalib( drawerIdx, TILEchan, TileID::LOWGAIN, 1., TileRawChannelUnit::PicoCoulombs, TileRawChannelUnit::MegaElectronVolts) + << " final calibration factor adc/MeV: "<< mev2ADC_factor); // Collecting pedestal from the database + // if (m_tilePedestal) { - pedSim = m_tileToolNoiseSample->getPed(idhash, jch, TileID::LOWGAIN); + pedSim = m_tileToolNoiseSample->getPed(idhash, TMDBchan, TileID::LOWGAIN); // As in TileDigitsMaker bug fix for wrong ped value in DB + // if (pedSim == 0.0) pedSim = 30.; } else { pedSim = muRcv_Ped; } - // Collecting noise from the database + // if (m_tileNoise) { RandFlat::shootArray(m_pHRengine, 1, Rndm_dG, 0.0, 1.0); - - sigma_Hfn1 = m_tileToolNoiseSample->getHfn1(idhash, jch, TileID::LOWGAIN); - sigma_Hfn2 = m_tileToolNoiseSample->getHfn2(idhash, jch, TileID::LOWGAIN); - + sigma_Hfn1 = m_tileToolNoiseSample->getHfn1(idhash, TMDBchan, TileID::LOWGAIN); + sigma_Hfn2 = m_tileToolNoiseSample->getHfn2(idhash, TMDBchan, TileID::LOWGAIN); if (sigma_Hfn1 > 0 || sigma_Hfn2) { - sigma_Norm = sigma_Hfn1 / (sigma_Hfn1 + sigma_Hfn2 * m_tileToolNoiseSample->getHfnNorm(idhash, jch, TileID::LOWGAIN)); + sigma_Norm = sigma_Hfn1 / (sigma_Hfn1 + sigma_Hfn2 * m_tileToolNoiseSample->getHfnNorm(idhash, TMDBchan, TileID::LOWGAIN)); } else { - sigma_Hfn1 = m_tileToolNoiseSample->getHfn(idhash, jch, TileID::LOWGAIN); + sigma_Hfn1 = m_tileToolNoiseSample->getHfn(idhash, TMDBchan, TileID::LOWGAIN); sigma_Norm = 1.; } - if (Rndm_dG[0] < sigma_Norm) sigmaSim = sigma_Hfn1; else sigmaSim = sigma_Hfn2; - } else { sigmaSim = muRcv_NoiseSigma; } - // Loop over samples and either use noise and ped from db or user location (TileInfoLoader.cxx) + // for (int js = 0; js < nSamp; ++js) { - - ATH_MSG_VERBOSE("(D.02.0" << js << ") sample " << js - << " E [MeV]: " << pDigitSamples[js]); - + ATH_MSG_VERBOSE( "(D.02.0"<< js <<") sample "<< js <<" E [MeV]: "<< pDigitSamples[js]); digitsBuffer[js] = pDigitSamples[js] * mev2ADC_factor; - - ATH_MSG_VERBOSE( "(D.02.0" << js << ") sample " << js - << " calibration Mev->adc "<< mev2ADC_factor - << "-> E [adc]: " << digitsBuffer[js]); + ATH_MSG_VERBOSE( "(D.02.0"<< js <<") sample "<< js <<" calibration Mev->adc "<< mev2ADC_factor <<"-> E [adc]: "<< digitsBuffer[js]); // Pedestal (amp) + // digitsBuffer[js] += pedSim; - ATH_MSG_VERBOSE("(D.02.0" << js << ") sample " << js - << " adding pedestal " << pedSim - << "-> E [adc]: "<< digitsBuffer[js]); - + ATH_MSG_VERBOSE( "(D.02.0"<< js <<") sample "<< js <<" adding pedestal "<< pedSim <<"-> E [adc]: "<< digitsBuffer[js]); // Noise (rms) + // digitsBuffer[js] += sigmaSim * Rndm[js]; - ATH_MSG_VERBOSE( "(D.02.0" << js << ") sample " << js - << " adding noise " << sigmaSim * Rndm[js] - << "-> E [adc]: " << digitsBuffer[js]); - - // simulated pulse above allowed maximum + ATH_MSG_VERBOSE( "(D.02.0"<< js <<") sample "<< js <<" adding noise "<< sigmaSim * Rndm[js] <<"-> E [adc]: "<< digitsBuffer[js]); + // Simulated pulse above allowed maximum // if (digitsBuffer[js] > muRcv_Max) digitsBuffer[js] = muRcv_Max; - // rounding the ADC counts + // Rounding the ADC counts // if (m_integerDigits) digitsBuffer[js] = round(digitsBuffer[js]); } - // If channel is good, create TileDigits object and store in container. // bool chanIsBad = false; - if (m_maskBadChannels) { - TileBchStatus status = m_tileBadChanTool->getAdcStatus(drawerIdx, jch, TileID::LOWGAIN); + TileBchStatus status = m_tileBadChanTool->getAdcStatus(drawerIdx, TILEchan, TileID::LOWGAIN); chanIsBad = status.isBad(); } - if (chanIsBad) { for (int js = 0; js < nSamp; ++js) { - digitsBuffer[js] = 2047; + digitsBuffer[js] = 255;// in TMDB we have 8-bit ADCs } - ATH_MSG_VERBOSE( "(D.03) Masking Channel: " << ros << '/' << drawer << '/' << jch << " LowGain"); + ATH_MSG_VERBOSE( "(D.03) Masking Channel: "<< ros << '/' << drawer << '/' << TILEchan <<" ("<< TMDBchan <<") LowGain" ); } else { - ATH_MSG_VERBOSE( "(D.03) Good Channel: " << ros << '/' << drawer << '/' << jch << " LowGain"); + ATH_MSG_VERBOSE( "(D.03) Good Channel: "<< ros << '/' << drawer << '/' << TILEchan <<" ("<< TMDBchan <<") LowGain" ); } - - ATH_MSG_VERBOSE(" Create a TileDigits object and set it into a container for adc_id : " << m_tileHWID->to_string(adc_id,-1)); - + ATH_MSG_VERBOSE( "(D.04) Changed to TMDB adc_id: " << m_tileHWID->to_string(adc_id) << " and create a TileDigits object and set it into a container." ); TileDigits* MuonReceiverDigits = new TileDigits(adc_id, digitsBuffer); MuonReceiverDigitsContainer->push_back(MuonReceiverDigits); - - ATH_MSG_VERBOSE("(D.04.1) Create a TileRawChannelObject object and set it into a container "); - ATH_MSG_VERBOSE("(D.04.2) Create a TileRawChannelObject object "); - + ATH_MSG_VERBOSE( "(D.05) Create a TileRawChannelObject object and set it into a container " ); TileRawChannel* MuRcvRawChannel = m_MuRcvBuildTool->rawChannel(MuonReceiverDigits); - - ATH_MSG_VERBOSE( "(D.04.3) Set amplitude units back to MeV "); - - MuRcvRawChannel->scaleAmplitude((float) 1./mev2ADC_factor); - - ATH_MSG_VERBOSE("(D.04.3) Put it in a container "); - MuonReceiverRawChannelContainer->push_back(MuRcvRawChannel); - - ATH_MSG_DEBUG( " Raw channel reconstruction Ch: " << m_tileHWID->to_string(adc_id,-1) - << " E [MeV]: " << MuRcvRawChannel->amplitude() / mev2ADC_factor - << " Time [ns]: " << MuRcvRawChannel->time() - << " Qf: " << MuRcvRawChannel->quality()); + if (msgLvl(MSG::DEBUG)){ + msg(MSG::DEBUG) << " Channel " << m_tileHWID->to_string(adc_id,-1) + << " Digitized pulse [ADC] "<< digitsBuffer[0] + << "/" << digitsBuffer[1] + << "/" << digitsBuffer[2] + << "/" << digitsBuffer[3] + << "/" << digitsBuffer[4] + << "/" << digitsBuffer[5] + << "/" << digitsBuffer[6] << endreq; + msg(MSG::DEBUG) << " Raw channel reconstruction Ch: "<< m_tileHWID->to_string(adc_id,-1) + <<" E [ADC]: "<< MuRcvRawChannel->amplitude() + <<" Time [ns]: "<< MuRcvRawChannel->time() + <<" Qf: "<< MuRcvRawChannel->quality() << endreq; + } } - } // END loop over all HIT collections in container - - - if (msgLvl(MSG::DEBUG)) MuonReceiverDigitsContainer->print(); - - ATH_MSG_VERBOSE( "(A.03) ENDED Loop over a hit collection " ); - + } // END loop over all HIT collections in container + if (msgLvl(MSG::VERBOSE)) MuonReceiverDigitsContainer->print(); // (b) Register the digits container in the TES // - ATH_MSG_VERBOSE ("(A.04) Send to event store all collected TileDigits objects for this event " ); + ATH_MSG_VERBOSE ( "(A.05) Send to event store all collected objects " ); CHECK(evtStore()->record(MuonReceiverDigitsContainer, m_MuRcvDigitsContainer, false)); - - ATH_MSG_VERBOSE( "(A.05) Send to event store all collected TileRawChannel objects for this event " ); CHECK(evtStore()->record(MuonReceiverRawChannelContainer, m_MuRcvRawChContainer, false)); + ATH_MSG_VERBOSE( "TilePulseForTileMuonReceiver execution completed" ); - ATH_MSG_DEBUG( "TilePulseForTileMuonReceiver execution completed" ); return StatusCode::SUCCESS; }