From 0389786aa6a389e7baaef35a81684396ee962a31 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 16:20:40 +0200
Subject: [PATCH 1/9] port to master

---
 L0/L0Calo/CMakeLists.txt    |  8 ++++++++
 L0/L0Calo/src/L0Candidate.h | 15 +++++++++------
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/L0/L0Calo/CMakeLists.txt b/L0/L0Calo/CMakeLists.txt
index 732572119cf..8f951b0802f 100644
--- a/L0/L0Calo/CMakeLists.txt
+++ b/L0/L0Calo/CMakeLists.txt
@@ -3,6 +3,11 @@
 ################################################################################
 gaudi_subdir(L0Calo v11r16)
 
+# hide warnings from some external projects
+find_package(Boost)
+find_package(ROOT)
+include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS})
+
 gaudi_depends_on_subdirs(Calo/CaloDAQ
                          Calo/CaloUtils
                          Event/LinkerEvent
@@ -16,5 +21,8 @@ gaudi_add_module(L0Calo
                  INCLUDE_DIRS AIDA Calo/CaloDAQ
                  LINK_LIBRARIES CaloUtils LinkerEvent L0Base DAQKernelLib)
 
+gaudi_install_python_modules()
+
 gaudi_env(SET L0CALOOPTS \${L0CALOROOT}/options)
 
+gaudi_add_test(QMTest QMTEST)
diff --git a/L0/L0Calo/src/L0Candidate.h b/L0/L0Calo/src/L0Candidate.h
index da9e24037ed..a3bb0bc3a18 100644
--- a/L0/L0Calo/src/L0Candidate.h
+++ b/L0/L0Calo/src/L0Candidate.h
@@ -49,12 +49,15 @@ public:
    */
   void saveCandidate( L0DUBase::Fiber::Type type , 
                       LHCb::L0ProcessorDatas* L0Calo ) {
-    unsigned int word = 0x10000 |
-			( m_ID.index() << L0DUBase::Calo::Address::Shift) | 
-			( m_et << L0DUBase::Calo::Et::Shift ) ;
-    if( type == L0DUBase::Fiber::CaloSumEt || type ==  L0DUBase::Fiber::CaloSpdMult)
-      word = 0x10000 | m_et << L0DUBase::Calo::Sum::Shift;
-
+    unsigned int word = 0 ;
+    if ( L0DUBase::Fiber::CaloSumEt == type )
+      word = 0x10000 + ( m_et << L0DUBase::Calo::Sum::Shift ) ;
+    else if ( L0DUBase::Fiber::CaloSpdMult == type )
+      word = 0x10000 + ( m_et << L0DUBase::Calo::Sum::Shift ) ;
+    else
+      word = 0x10000 |
+        ( m_ID.index() << L0DUBase::Calo::Address::Shift) |
+        ( m_et << L0DUBase::Calo::Et::Shift ) ;
     LHCb::L0ProcessorData * temp = new LHCb::L0ProcessorData ( type , word ) ;
     L0Calo -> add( temp );
   }
-- 
GitLab


From 5b4ef9e3502a19602cb778aa3a8637f5fdcd9498 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 16:21:20 +0200
Subject: [PATCH 2/9] port to master

---
 L0/L0Calo/python/L0Calo/Configuration.py      | 127 ++++++++++++++++++
 L0/L0Calo/python/L0Calo/__init__.py           |   0
 .../qmtest/l0calo.qms/testL0CaloFix2016.qmt   |   9 ++
 L0/L0Calo/tests/scripts/testL0CaloFix2016.py  |  24 ++++
 4 files changed, 160 insertions(+)
 create mode 100644 L0/L0Calo/python/L0Calo/Configuration.py
 create mode 100644 L0/L0Calo/python/L0Calo/__init__.py
 create mode 100644 L0/L0Calo/tests/qmtest/l0calo.qms/testL0CaloFix2016.qmt
 create mode 100644 L0/L0Calo/tests/scripts/testL0CaloFix2016.py

diff --git a/L0/L0Calo/python/L0Calo/Configuration.py b/L0/L0Calo/python/L0Calo/Configuration.py
new file mode 100644
index 00000000000..47b10ac8ea1
--- /dev/null
+++ b/L0/L0Calo/python/L0Calo/Configuration.py
@@ -0,0 +1,127 @@
+"""
+Configuration tools for L0Calo
+"""
+
+from Configurables import LHCbConfigurableUser
+from Configurables import L0CaloAlg, DataOnDemandSvc, L0CaloCandidatesFromRaw
+from Configurables import L0CaloCandidatesFromRawBank, ToolSvc
+from Gaudi.Configuration import appendPostConfigAction, log
+
+## @class L0CaloFix2016
+# Configurable to configure L0Calo to handle 2016 electron bug
+# Definitions:
+#   GOOD = the expected correct constants, depend on cell position
+#   BAD = the wrong constants loaded in the CALO electronics in 2016,
+#         equal to 127 everywhere
+# Use cases:
+#
+# #1 Simulation was done with GOOD constants (eg Sim09b) and the DST contains
+#    the CALO RAW banks: in order to represent 2016 data taken with BAD
+#    constants, use L0CaloFix2016 with options ApproximateMethod = False
+#    and Simulation = True. Set the TCK property to the one you want to
+#    simulate (best to use the one that was used for the simulation,
+#    ie '0x160F' for most cases. In the DaVinci options, set the DB tags to
+#    these used for the simulation.
+#
+# #2 Simulation was done with GOOD constants (Sim09b) and the DST do not contain
+#    the CALO RAW banks: in order to represent 2016 data taken with BAD
+#    constants, use L0CaloFix2016 with options ApproximateMethod = True
+#    and Simulation = True. Set the TCK property to the one you want to
+#    simulate (best to use the one that was used for the simulation,
+#    ie '0x160F' for most cases.In the DaVinci options, set the DB tags to
+#    these used for the simulation.
+#
+# #3 Data was recorded in 2016 with BAD constants and you want to re-run
+#    L0 with the GOOD constants in order to reject the extra events that
+#    were triggered because of the BAD constants, in order to obtain a
+#    coherent sample with 2015, 2017 or 2018. Use ApproximateMethod = False
+#    and Simulation = False.
+#
+# NB: Check for messages when running: if there are error messages due
+#     to missing CALO banks, do not trust the results. Use the approximate
+#     method instead.
+# NB: Only L0 is redone, not HLT. If the HLT depends on L0, it has to be
+#     ran again.
+#
+# @author Patrick Robbe <robbe@lal.in2p3.fr>
+# @date   2018/03/12
+
+class L0CaloFix2016(LHCbConfigurableUser):
+
+    __slots__ = {
+        # Properties
+        "ApproximateMethod" : False,
+        "Simulation" : True ,
+        "TCK" : '0x160F'
+        }
+
+    __propertyDocDct = {
+        # Properties
+        "ApproximateMethod" : """Use approximation on L0Calo to correct energy, otherwise use full method on Calo banks. Useful when Calo banks are not available.""" ,
+        "Simulation" : """True for MC, False for data.""",
+        "TCK": """The TCK number to emulate"""
+        }
+    
+    def __apply_configuration__(self):
+        def fixL0Calo( approximate , simulation , tck ):
+            dod = DataOnDemandSvc()
+            if not approximate:
+                l0calo = L0CaloAlg()
+                l0calo.WriteBanks = False
+                l0calo.WriteOnTES = True
+                l0calo.L0CaloADCTool = "CaloTriggerAdcsFromCaloRaw"
+                from Configurables import CaloTriggerAdcsFromCaloRaw 
+                l0calo.addTool( CaloTriggerAdcsFromCaloRaw ,
+                                "EcalTriggerAdcTool" )
+                if simulation:
+                    l0calo.EcalTriggerAdcTool.FixFor2016 = True
+                else:
+                    # for data, take what is in database for the constants
+                    l0calo.EcalTriggerAdcTool.FixFor2016 = False
+                    
+                dod.AlgMap[ 'Trig/L0/FullCalo' ] = l0calo
+                dod.AlgMap[ 'Trig/L0/Calo' ] = l0calo
+            else:
+                l0calo = L0CaloCandidatesFromRaw("L0CaloFromRaw")
+                ToolSvc().addTool( L0CaloCandidatesFromRawBank )
+                ToolSvc().L0CaloCandidatesFromRawBank.FixFor2016 = True
+                if simulation:
+                    ToolSvc().L0CaloCandidatesFromRawBank.Simulation = True
+                else:
+                    # assumes that the correct database tag is given
+                    ToolSvc().L0CaloCandidatesFromRawBank.Simulation = False                    
+                l0calo.WriteProcData = True
+                dod.AlgMap[ 'Trig/L0/FullCalo' ] = l0calo
+                dod.AlgMap[ 'Trig/L0/Calo' ] = l0calo
+            
+            from Configurables import L0DUAlg, L0DUFromRawAlg, GaudiSequencer, L0DUFromRawTool
+            l0du = L0DUAlg()
+            l0du.WriteBanks = False
+            l0du.WriteOnTES = True
+            if not approximate:
+                dod.AlgMap[ 'Trig/L0/L0DUCaloData' ] = l0calo
+                l0du.ProcessorDataLocations = [ 'Trig/L0/L0DUCaloData' , 'Trig/L0/L0DUData' ]
+            else:
+                dod.AlgMap[ 'Trig/L0/L0DUL0CaloData' ] = l0calo
+                l0du.ProcessorDataLocations = [ 'Trig/L0/L0DUL0CaloData' , 'Trig/L0/L0DUData' ]
+                
+            l0du.TCK = tck
+            # CALO
+            l0seq = GaudiSequencer("L0Seq")
+            l0raw = L0DUFromRawAlg(  WriteProcData = True , WriteOnTES = False )
+            l0raw.addTool( L0DUFromRawTool )
+            l0raw.L0DUFromRawTool.Emulate = False
+            l0seq.Members = [ l0raw , l0du ]
+            dod.AlgMap[ 'Trig/L0/L0DUReport' ] = l0seq
+ 
+        log.warning( "Apply 2016 L0Calo fix" )
+        if self.getProp( "ApproximateMethod" ):
+            if self.getProp( "Simulation" ):
+                appendPostConfigAction( lambda tck = self.getProp( "TCK" ): fixL0Calo(True,True,tck) )
+            else:
+                appendPostConfigAction( lambda tck = self.getProp( "TCK" ): fixL0Calo(True,False,tck) )
+        else:
+            if self.getProp( "Simulation" ):
+                appendPostConfigAction( lambda tck = self.getProp( "TCK" ): fixL0Calo(False,True,tck) )
+            else:
+                appendPostConfigAction( lambda tck = self.getProp( "TCK" ): fixL0Calo(False,False,tck) )
diff --git a/L0/L0Calo/python/L0Calo/__init__.py b/L0/L0Calo/python/L0Calo/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/L0/L0Calo/tests/qmtest/l0calo.qms/testL0CaloFix2016.qmt b/L0/L0Calo/tests/qmtest/l0calo.qms/testL0CaloFix2016.qmt
new file mode 100644
index 00000000000..9245d5387ea
--- /dev/null
+++ b/L0/L0Calo/tests/qmtest/l0calo.qms/testL0CaloFix2016.qmt
@@ -0,0 +1,9 @@
+<?xml version="1.0" ?><!DOCTYPE extension  PUBLIC '-//QM/2.3/Extension//EN'  'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
+<extension class="GaudiTest.GaudiExeTest" kind="test">
+<argument name="program"><text>../scripts/testL0CaloFix2016.py</text></argument>
+<argument name="validator"><text>
+findReferenceBlock("""
+Number of L0 electron decisions =  515
+""")
+</text></argument>
+</extension>
diff --git a/L0/L0Calo/tests/scripts/testL0CaloFix2016.py b/L0/L0Calo/tests/scripts/testL0CaloFix2016.py
new file mode 100644
index 00000000000..d3b62644e61
--- /dev/null
+++ b/L0/L0Calo/tests/scripts/testL0CaloFix2016.py
@@ -0,0 +1,24 @@
+from Configurables import LHCbApp
+from PRConfig import TestFileDB
+TestFileDB.test_file_db['2016-lb2l0gamma.strip.dst'].run(configurable=LHCbApp())
+
+from Configurables import L0Conf, DataOnDemandSvc, ApplicationMgr
+ApplicationMgr().ExtSvc += [ DataOnDemandSvc() ]
+L0Conf( FullL0MuonDecoding = True , EnableL0DecodingOnDemand = True )
+
+from Configurables import L0CaloFix2016
+L0CaloFix2016( ApproximateMethod = False , Simulation = True , TCK = '0x160F' )
+
+import GaudiPython
+appMgr = GaudiPython.AppMgr()
+evt = appMgr.evtsvc()
+
+counter_electron = 0
+
+for i in xrange( 1000 ) :
+    appMgr.run(1)
+    l0du = evt['Trig/L0/L0DUReport']
+    if l0du.channelDecisionByName( "Electron" ):
+        counter_electron += 1
+
+print "Number of L0 electron decisions = ", counter_electron
-- 
GitLab


From b2c81ff17ff1c9fec406febde437548d2eb666cc Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 16:23:28 +0200
Subject: [PATCH 3/9] port to master

---
 L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.cpp | 34 ++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.cpp b/L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.cpp
index 9f688c66b07..8ff53227bc2 100644
--- a/L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.cpp
+++ b/L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.cpp
@@ -26,8 +26,16 @@ CaloTriggerAdcsFromCaloRaw::CaloTriggerAdcsFromCaloRaw( const std::string& type,
 {
   declareInterface<ICaloTriggerAdcsFromRaw>(this);
   declareProperty( "DoubleScale" , m_doubleScale = false ) ;
+  // fix L0Calo to reproduce 2016 bug
+  declareProperty( "FixFor2016" , m_fixFor2016 = false ) ;
+  declareProperty( "RawEventLocations" , m_rawEventLocations ) ;
   int index = name.find_first_of(".",0) +1 ;
   m_detectorName = name.substr( index, 4 );
+  if( "Ecal" == m_detectorName ){
+    m_bank = LHCb::RawBank::EcalPacked;
+  } else if( "Hcal" == m_detectorName ){
+    m_bank = LHCb::RawBank::HcalPacked;
+  }
   m_data.clear() ;
 }
 
@@ -53,6 +61,15 @@ StatusCode CaloTriggerAdcsFromCaloRaw::initialize() {
     return StatusCode::FAILURE ;
   }
 
+  // Initialise the RawEvent locations
+  if (std::find(m_rawEventLocations.begin(), m_rawEventLocations.end(),
+                LHCb::RawEventLocation::Default)
+      == m_rawEventLocations.end()) {
+    // append the defaults to the search path
+    m_rawEventLocations.push_back(LHCb::RawEventLocation::Calo);
+    m_rawEventLocations.push_back(LHCb::RawEventLocation::Default);
+  }
+
   long nCells = m_calo -> numberOfCells() ;
   m_data.reserve( nCells ) ;
   m_data.clear() ;
@@ -62,6 +79,20 @@ StatusCode CaloTriggerAdcsFromCaloRaw::initialize() {
 //=============================================================================
 const std::vector< LHCb::L0CaloAdc > & CaloTriggerAdcsFromCaloRaw::adcs( ) 
 {
+  // Retrieve the RawEvent:
+  LHCb::RawEvent* rawEvt = nullptr ;
+  for (auto p = m_rawEventLocations.begin(); p != m_rawEventLocations.end() &&
+         ! rawEvt; ++p) {
+    rawEvt = getIfExists<LHCb::RawEvent>(*p);
+  }
+
+  if( rawEvt == nullptr )
+    Exception( "No CALO Raw bank in the event" ) ;
+
+  bool bank = ( 0 == (rawEvt->banks( m_bank )).size() ) ?  false : true ;
+  if ( ! bank )
+    Exception( "No Calo packed bank in the event" ) ;
+
   m_data.clear() ;
   const CaloVector< LHCb::CaloAdc >& adcs = m_adcs -> adcs( -1 ) ;
   std::transform( adcs.begin(), adcs.end(), std::back_inserter(m_data),
@@ -96,6 +127,9 @@ int CaloTriggerAdcsFromCaloRaw::l0adcFromAdc( const int adc ,
   unsigned long calibCte = m_calo -> cellParam( id ).l0Constant() ;
   if ( m_doubleScale ) calibCte = calibCte / 2 ;
 
+  // for 2016, all constants were set to 127 in ECAL
+  if ( ( m_fixFor2016 ) && ( id.calo() == 2 ) ) calibCte = 127 ;
+
   int theAdc = adc ;
 
   if ( calibCte > 255 ) { 
-- 
GitLab


From e7c33ce924aded7580b9297baf19b76584a8eb4c Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 16:25:48 +0200
Subject: [PATCH 4/9] port to master

---
 L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.h b/L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.h
index 45fb0c46269..b83bfc29fbd 100644
--- a/L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.h
+++ b/L0/L0Calo/src/CaloTriggerAdcsFromCaloRaw.h
@@ -50,6 +50,10 @@ private:
   DeCalorimeter     * m_calo = nullptr ;
 
   bool m_doubleScale ;
+  bool m_fixFor2016 ;
+  LHCb::RawBank::BankType m_bank;
+  /// List of locations in the transient store to search the RawEvent object.
+  std::vector<std::string> m_rawEventLocations;
 
   int l0adcFromAdc( const int adc , const LHCb::CaloCellID & id ) const ;
 };
-- 
GitLab


From 614b9d6a6066a180fdbc2ed2467853859c4d6ec4 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 16:26:44 +0200
Subject: [PATCH 5/9] port to master

---
 L0/L0Calo/src/L0CaloAlg.cpp | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/L0/L0Calo/src/L0CaloAlg.cpp b/L0/L0Calo/src/L0CaloAlg.cpp
index c40d70f983a..f0964bb6c52 100755
--- a/L0/L0Calo/src/L0CaloAlg.cpp
+++ b/L0/L0Calo/src/L0CaloAlg.cpp
@@ -324,7 +324,11 @@ StatusCode L0CaloAlg::initialize() {
 //=============================================================================
 StatusCode L0CaloAlg::execute() {
   // Get the ECAL data, store them in the Front-End card
-  sumEcalData( );
+  try { sumEcalData( ); }
+  catch ( const GaudiException & exc ) {
+    fatal() << "The L0Calo trigger will be wrong, dont rely on it" << endmsg ;
+    return StatusCode::FAILURE ;
+  }
 
   // Get Spd+Prs data
   m_PrsSpdIds = m_bitsFromRaw -> prsSpdCells( ) ;
@@ -414,8 +418,12 @@ StatusCode L0CaloAlg::execute() {
   } // eCard
 
   //  Do a similar processing for HCAL Data
-  sumHcalData( );
-  
+  try { sumHcalData( ); }
+  catch ( const GaudiException & exc ) {
+    fatal() << "The L0Calo trigger will be wrong, dont rely on it" << endmsg ;
+    return StatusCode::FAILURE ;
+  }
+
   // Add the highest ECAL energy in matching cards and store
   // the candidates (one per Selection Board input, in 3 vectors
   // one vector per SB: (0 - master, 1 - slave1, 2 - slave2)
-- 
GitLab


From 93b03574ba837c2fd1f878cf6ca2fda4ace120d1 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 16:45:40 +0200
Subject: [PATCH 6/9] port to master

---
 L0/L0Calo/src/L0CaloCandidatesFromRaw.cpp | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/L0/L0Calo/src/L0CaloCandidatesFromRaw.cpp b/L0/L0Calo/src/L0CaloCandidatesFromRaw.cpp
index 1ee607f1442..20b6bbe91fc 100644
--- a/L0/L0Calo/src/L0CaloCandidatesFromRaw.cpp
+++ b/L0/L0Calo/src/L0CaloCandidatesFromRaw.cpp
@@ -66,12 +66,6 @@ StatusCode L0CaloCandidatesFromRaw::execute() {
   readoutStatus.addStatus( 0 , LHCb::RawBankReadoutStatus::Status::OK ) ;
   readoutStatus.addStatus( 1 , LHCb::RawBankReadoutStatus::Status::OK ) ;
 
-  // Scan the list of input location and select the first existing one.
-  // no need to do this any longer, the base class takes care of it
-  //std::string rawEventLocation;
-  //if ( selectRawEventLocation(rawEventLocation).isFailure() )
-  //  return Error("No valid raw event location found",StatusCode::SUCCESS,50);
-
   LHCb::L0CaloCandidates * outFull = new LHCb::L0CaloCandidates( ) ;
   LHCb::L0CaloCandidates * out = new LHCb::L0CaloCandidates() ;
 
-- 
GitLab


From e6c8c7c2c868213d5ffe242c4d073cf77d80bf23 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 16:48:01 +0200
Subject: [PATCH 7/9] port to master

---
 L0/L0Calo/src/L0CaloCandidatesFromRaw.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/L0/L0Calo/src/L0CaloCandidatesFromRaw.h b/L0/L0Calo/src/L0CaloCandidatesFromRaw.h
index 2994b0f0888..60eaadbe986 100755
--- a/L0/L0Calo/src/L0CaloCandidatesFromRaw.h
+++ b/L0/L0Calo/src/L0CaloCandidatesFromRaw.h
@@ -67,6 +67,5 @@ private:
     }
     return false;
   }
-  
 };
 #endif // L0CALOCANDIDATESFROMRAW_H
-- 
GitLab


From 54cf5d4ce1a8153b0e17f3f7bde14d47b9997b41 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 16:59:36 +0200
Subject: [PATCH 8/9] port to master

---
 L0/L0Calo/src/L0CaloCandidatesFromRawBank.cpp | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/L0/L0Calo/src/L0CaloCandidatesFromRawBank.cpp b/L0/L0Calo/src/L0CaloCandidatesFromRawBank.cpp
index 276811fd70e..b709145e616 100755
--- a/L0/L0Calo/src/L0CaloCandidatesFromRawBank.cpp
+++ b/L0/L0Calo/src/L0CaloCandidatesFromRawBank.cpp
@@ -36,6 +36,10 @@ L0CaloCandidatesFromRawBank::L0CaloCandidatesFromRawBank
   // Store also the intermediate informations for debugging the Selection boards
   // such as the partial results of the hadron Selection Boards
   declareProperty( "DebugDecoding" , m_doDebugDecoding = false ) ;
+  // Correct the L0electron and photon energies to reflect 2016 bug
+  declareProperty( "FixFor2016" , m_fixFor2016 = false ) ;
+  // Data or simulation (relevant for FixFor2016 only !)
+  declareProperty( "Simulation" , m_simulation = false ) ;
 }
 
 //=============================================================================
@@ -311,6 +315,13 @@ void L0CaloCandidatesFromRawBank::convertRawBankToTES
             }
           }
         } else {
+          // ECAL trigger
+          // Apply 2016 correction here if requested
+          if ( m_fixFor2016 ) {
+            et = correctedEnergy( et , id ) ;
+            if ( et > 255 ) et = 255 ;
+          }
+
           myL0Cand = new LHCb::L0CaloCandidate ( type, id, et,
                                                  et * m_etScale, center,
                                                  tol );
@@ -389,3 +400,15 @@ void L0CaloCandidatesFromRawBank::convertRawBankToTES
     outFull -> add( *it ) ;
 }
 //=============================================================================
+// Function to correct ECAL energy (approximatively) for 2016 bug
+//=============================================================================
+int L0CaloCandidatesFromRawBank::correctedEnergy( const int oldEnergy ,
+                                                  const LHCb::CaloCellID & id )
+  const
+{
+  // Get correct calib constant
+  unsigned long calibCte = m_ecal -> cellParam( id ).l0Constant() ;
+  // compute energy with wrong calib constant (127)
+  if ( m_simulation ) return (int) ( (double) oldEnergy * 127. / ( (double) calibCte ) ) ;
+  return (int) ( (double) oldEnergy * ( (double) calibCte ) / 127. ) ;
+}
-- 
GitLab


From 8c357af824d6c00fcdbf4db80ed4e67989f71a75 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 15 Sep 2018 23:41:22 +0200
Subject: [PATCH 9/9] Port L0Calo 2016 fix software to master branch

---
 L0/L0Calo/src/L0CaloCandidatesFromRawBank.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/L0/L0Calo/src/L0CaloCandidatesFromRawBank.h b/L0/L0Calo/src/L0CaloCandidatesFromRawBank.h
index d66e60313b6..ec5825426ce 100755
--- a/L0/L0Calo/src/L0CaloCandidatesFromRawBank.h
+++ b/L0/L0Calo/src/L0CaloCandidatesFromRawBank.h
@@ -53,5 +53,9 @@ private:
   DeCalorimeter* m_hcal;         ///< HCAL detector element
   double         m_etScale;      ///< Conversion int -> Et.
   bool           m_doDebugDecoding ; ///< Store intermediate information for debug
+  bool           m_fixFor2016 ;  ///< Fix energy to correspond to 2016 conditions
+  bool           m_simulation ;  ///< Data or MC, relevant only for fixFor2016
+
+  int correctedEnergy( const int oldEnergy , const LHCb::CaloCellID & id ) const ;
 };
 #endif // L0CALO_L0CALOCANDIDATESFROMRAWBANK_H
-- 
GitLab