diff --git a/LumiBlock/LumiBlockComps/LumiBlockComps/ILumiCalcSvc.h b/LumiBlock/LumiBlockComps/LumiBlockComps/ILumiCalcSvc.h
index c3047c8ec2aec79630dc1d94edbe7aa62ea79d65..e0669369d6a9f1f5f50b12ef24f5a1f10bf3ca19 100644
--- a/LumiBlock/LumiBlockComps/LumiBlockComps/ILumiCalcSvc.h
+++ b/LumiBlock/LumiBlockComps/LumiBlockComps/ILumiCalcSvc.h
@@ -31,8 +31,6 @@
 #include "GaudiKernel/INamedInterface.h"
 #include "GaudiKernel/Property.h"
 
-
-class LumiBlockCollection;
 class TTree;
 
 typedef std::pair< TString, std::list<TString> > tvtPair;
diff --git a/LumiBlock/LumiBlockComps/LumiBlockComps/LumiBlockMetaDataTool.h b/LumiBlock/LumiBlockComps/LumiBlockComps/LumiBlockMetaDataTool.h
index 65b3c8d7dde12a6bdd87e9e48fdba9acf836f95e..c6b349cff7067f445cffc4ae6c5b4c8c51abc428 100755
--- a/LumiBlock/LumiBlockComps/LumiBlockComps/LumiBlockMetaDataTool.h
+++ b/LumiBlock/LumiBlockComps/LumiBlockComps/LumiBlockMetaDataTool.h
@@ -31,7 +31,7 @@
 class StoreGateSvc;
 class ILumiCalcSvc;
 class IGoodRunsListSelectorTool;
-//class LumiBlockCollectionConverter;
+class LumiBlockRangeContainerConverter;
 class ITriggerRegistryTool;
 
 namespace Root {
@@ -97,7 +97,7 @@ private:
    bool m_calcLumi;
    bool m_storexmlfiles;
    bool m_applydqcuts;
-   //   LumiBlockCollectionConverter* m_converter;
+   LumiBlockRangeContainerConverter* m_converter;
    Root::TGRLCollection* m_grlcollection;
 
    ServiceHandle<ILumiCalcSvc> m_lcSvc;
diff --git a/LumiBlock/LumiBlockComps/LumiBlockComps/LumiBlockTester.h b/LumiBlock/LumiBlockComps/LumiBlockComps/LumiBlockTester.h
index 6124d157c35c18876e47b169a663cae45b599745..595ff38267913cb7edb3d0e13d43ccb5d39a4b85 100644
--- a/LumiBlock/LumiBlockComps/LumiBlockComps/LumiBlockTester.h
+++ b/LumiBlock/LumiBlockComps/LumiBlockComps/LumiBlockTester.h
@@ -15,6 +15,7 @@
 #include "GaudiKernel/ToolHandle.h"
 #include "LumiBlockComps/ILuminosityTool.h"
 #include "LumiBlockComps/ITrigLivefractionTool.h"
+#include "LumiBlockComps/ILumiBlockMuTool.h"
 
 #include <string>
 
@@ -28,6 +29,7 @@ class LumiBlockTester: public AthAlgorithm {
  private:
   ToolHandle<ILuminosityTool> m_lumiTool;
   ToolHandle<ITrigLivefractionTool> m_liveTool;
+  ToolHandle<ILumiBlockMuTool> m_muTool;
   
 };
 
diff --git a/LumiBlock/LumiBlockComps/LumiBlockComps/LumiCalcSvc.h b/LumiBlock/LumiBlockComps/LumiBlockComps/LumiCalcSvc.h
index e72f3976d885c04e4aa47f128e5827afaafdbecd..dcf6dc282ea2621e981ab54f3d3c5457f23fcc44 100644
--- a/LumiBlock/LumiBlockComps/LumiBlockComps/LumiCalcSvc.h
+++ b/LumiBlock/LumiBlockComps/LumiBlockComps/LumiCalcSvc.h
@@ -73,12 +73,17 @@ public:
   bool registerLBCollection(const TString& tname, const TString& regexpr, const std::list<TString>& trigpar);
 
 private:
-  StatusCode doDbQuery(StoreGateSvc * sg);
+  typedef ServiceHandle<StoreGateSvc> StoreGateSvc_t;
+  StatusCode doDbQuery(StoreGateSvc_t sg);
   void doRecordTree(bool b){m_recordTTree = b;}
   void printTree();
 
-  StoreGateSvc* p_inputstore; // input metadata store
-  StoreGateSvc* p_metadatastore; // metadata store
+
+  StoreGateSvc_t m_pMetaDataStore;
+  StoreGateSvc_t m_pInputStore;
+
+  //  StoreGateSvc* p_inputstore; // input metadata store
+  //  StoreGateSvc* p_metadatastore; // metadata store
   ITHistSvc * tHistSvc;
 
   // Configurable Properties
diff --git a/LumiBlock/LumiBlockComps/LumiBlockComps/LuminosityTool.h b/LumiBlock/LumiBlockComps/LumiBlockComps/LuminosityTool.h
index 11475015d2b95b2c5f4d05d5b56ada9fd70eb2ac..8683ecbcb0332098b2f9c0d93ba212cbc2a7b8d7 100644
--- a/LumiBlock/LumiBlockComps/LumiBlockComps/LuminosityTool.h
+++ b/LumiBlock/LumiBlockComps/LumiBlockComps/LuminosityTool.h
@@ -25,6 +25,8 @@
 #include "CoolLumiUtilities/IBunchLumisTool.h"
 #include "CoolLumiUtilities/IOnlineLumiCalibrationTool.h"
 
+#include "CoralBase/Blob.h"
+
 #include <string>
 #include <vector>
 #include <map>
@@ -129,6 +131,11 @@ class LuminosityTool: public AthAlgTool, virtual public ILuminosityTool {
   // Calibration data
   // std::map<unsigned int, LumiCalibrator> m_cali;
 
+  // Pointer to per-BCID blob (Run2 only)
+  const coral::Blob *m_bunchInstLumiBlob;
+
+  // Channel to use to get muToLumi from calibration tool
+  unsigned int m_calibChannel;
 };
 
 
diff --git a/LumiBlock/LumiBlockComps/python/LuminosityToolDefault.py b/LumiBlock/LumiBlockComps/python/LuminosityToolDefault.py
index 3aaa02791bfbcd9ae20104ffee10dd36e08bb211..3c090633690a8a34cc7ecb497a7c869a9d183447 100644
--- a/LumiBlock/LumiBlockComps/python/LuminosityToolDefault.py
+++ b/LumiBlock/LumiBlockComps/python/LuminosityToolDefault.py
@@ -16,7 +16,13 @@ def LuminosityToolDefault(name="LuminosityTool"):
         return getattr(svcMgr.ToolSvc, name)
 
     from IOVDbSvc.CondDB import conddb
-    if conddb.dbdata == "COMP200":
+
+    # For MC, return unconfigured tool (which will do nothing)
+    if conddb.isMC:
+        mlog.info("LuminosityToolDefault called for MC!")
+        return LuminosityTool(name)
+
+    elif conddb.dbdata == "COMP200":
         return LuminosityToolOfflineRun1(name)
 
     elif conddb.dbdata == "CONDBR2":
@@ -29,7 +35,7 @@ def LuminosityToolDefault(name="LuminosityTool"):
 # Configuration for offline default tool used in Run1
 # Change logic so that folders names are blank by default and must be configured
 def LuminosityToolOfflineRun1(name="LuminosityTool"):
-        
+       
     mlog = logging.getLogger(name)
 
     # Instantiate new tool
@@ -44,13 +50,13 @@ def LuminosityToolOfflineRun1(name="LuminosityTool"):
         lumiFolder  = "/TRIGGER/LUMI/LBLESTONL"
         if not conddb.folderRequested( lumiFolder ):
             conddb.addFolder('TRIGGER_ONL', lumiFolder)
-            mlog.info("LuminosityToolDefault requested %s", lumiFolder)
+            mlog.info("LuminosityToolOfflineRun1 requested %s", lumiFolder)
 
     else:
         lumiFolder = "/TRIGGER/OFLLUMI/LBLESTOFL"
         if not conddb.folderRequested( lumiFolder ):
             conddb.addFolder('TRIGGER_OFL', lumiFolder)
-            mlog.info("LuminosityToolDefault requested %s", lumiFolder)
+            mlog.info("LuminosityToolOfflineRun1 requested %s", lumiFolder)
 
     lumiTool.LumiFolderName = lumiFolder
 
@@ -58,7 +64,7 @@ def LuminosityToolOfflineRun1(name="LuminosityTool"):
     folder = "/TRIGGER/LUMI/LBLB"
     if not conddb.folderRequested( folder ):
         conddb.addFolder('TRIGGER', folder)
-        mlog.info("LuminosityToolDefault requested %s", folder)
+        mlog.info("LuminosityToolOfflineRun1 requested %s", folder)
 
     lumiTool.LBLBFolderName = folder
 
@@ -69,28 +75,28 @@ def LuminosityToolOfflineRun1(name="LuminosityTool"):
     if not hasattr(svcMgr.ToolSvc, toolName):
         from CoolLumiUtilities.FillParamsToolDefault import FillParamsToolDefault
         svcMgr.ToolSvc += FillParamsToolDefault(toolName)
-        mlog.info("LuminosityToolDefault added tool %s", toolName)
+        mlog.info("LuminosityToolOfflineRun1 added tool %s", toolName)
 
     toolName = "BunchLumisTool"
     lumiTool.BunchLumisTool = toolName
     if not hasattr(svcMgr.ToolSvc, toolName):
         from CoolLumiUtilities.BunchLumisToolDefault import BunchLumisToolDefault
         svcMgr.ToolSvc += BunchLumisToolDefault(toolName)
-        mlog.info("LuminosityToolDefault added tool %s", toolName)
+        mlog.info("LuminosityToolOfflineRun1 added tool %s", toolName)
 
     toolName = "BunchGroupTool"
     lumiTool.BunchGroupTool = toolName
     if not hasattr(svcMgr.ToolSvc, toolName):
         from CoolLumiUtilities.BunchGroupToolDefault import BunchGroupToolDefault
         svcMgr.ToolSvc += BunchGroupToolDefault(toolName)
-        mlog.info("LuminosityToolDefault added tool %s", toolName)
+        mlog.info("LuminosityToolOfflineRun1 added tool %s", toolName)
 
     toolName = "OnlineLumiCalibrationTool"
     lumiTool.OnlineLumiCalibrationTool = toolName
     if not hasattr(svcMgr.ToolSvc, toolName):
         from CoolLumiUtilities.OnlineLumiCalibrationToolDefault import OnlineLumiCalibrationToolDefault
         svcMgr.ToolSvc += OnlineLumiCalibrationToolDefault(toolName)
-        mlog.info("LuminosityToolDefault added tool %s", toolName)
+        mlog.info("LuminosityToolOfflineRun1 added tool %s", toolName)
 
 
     mlog.info("Created Run1 %s using folder %s" % (name, lumiFolder))
@@ -102,24 +108,41 @@ def LuminosityToolOfflineRun2(name="LuminosityTool"):
     mlog = logging.getLogger(name)
 
     # Set up DB configuration
-    #from IOVDbSvc.CondDB import conddb
-    #from InDetRecExample.InDetJobProperties import InDetFlags
+    from IOVDbSvc.CondDB import conddb
+    from InDetRecExample.InDetJobProperties import InDetFlags
 
-    # Will eventually use our new online/offline folder, but not ready
-    # Set up with dummy configuration for now (this is also now the default)
     lumiTool = LuminosityTool(name)
-    lumiTool.LBLBFolderName = ''
 
-    lumiTool.LumiFolderName = ''
-    lumiTool.FillParamsTool = ''
-    lumiTool.BunchLumisTool = ''
-    lumiTool.BunchGroupTool = ''
-    lumiTool.OnlineLumiCalibrationTool = ''
-    
-    mlog.info("Created Run2 %s using a dummy Run2 configuration!" % name)
+    # Check if this is express stream or bulk
+    if not InDetFlags.useBeamConstraint():
+        lumiFolder  = "/TRIGGER/LUMI/OnlPrefLumi"
+        if not conddb.folderRequested( lumiFolder ):
+            conddb.addFolder('TRIGGER_ONL', lumiFolder)
 
-    return lumiTool
+    else:
+        lumiFolder = "/TRIGGER/OFLLUMI/OflPrefLumi"
+        if not conddb.folderRequested( lumiFolder ):
+            conddb.addFolder('TRIGGER_OFL', lumiFolder)
+
+    mlog.info("LuminosityToolOfflineRun2 requested %s", lumiFolder)
+    lumiTool.LumiFolderName = lumiFolder
+
+    mlog.info("Created Run2 %s using folder %s" % (name, lumiFolder))
 
+    # Need the calibration tool just to get the proper MuToLumi value
+    toolName = "OnlineLumiCalibrationTool"
+    lumiTool.OnlineLumiCalibrationTool = toolName
+    if not hasattr(svcMgr.ToolSvc, toolName):
+        from CoolLumiUtilities.OnlineLumiCalibrationToolDefault import OnlineLumiCalibrationToolDefault
+        svcMgr.ToolSvc += OnlineLumiCalibrationToolDefault(toolName)
+        mlog.info("LuminosityToolOfflineRun2 added tool %s", toolName)
+    else:
+        mlog.info("LuminosityToolOfflineRun2 found %s already defined!" % toolName)
+
+    # Other folder names are now blank by default
+
+    return lumiTool
+    
 class LuminosityToolOnline(LuminosityTool):
     """LuminosityTool for use in the online/HLT"""
     
@@ -137,23 +160,31 @@ class LuminosityToolOnline(LuminosityTool):
             #conddb.addFolder('TDAQ', '/TDAQ/OLC/BUNCHLUMIS')
 
             self.LumiFolderName = folder
-            self.LBLBFolderName = ''
-
-            self.FillParamsTool = ''
-            self.BunchLumisTool = ''
-            self.BunchGroupTool = ''
-            self.OnlineLumiCalibrationTool = ''
-        
+            # Other folder names are now blank by default
             mlog.info("Created online %s using folder %s" % (name, folder))
 
         
         elif conddb.dbdata == "CONDBR2": # Run2
-            # Folder names are now blank by default
-            mlog.info("Created online %s using a dummy Run2 configuration!" % name)
+            folder  = "/TRIGGER/LUMI/HLTPrefLumi"
+            conddb.addFolder('TRIGGER_ONL', folder)
+
+            self.LumiFolderName = folder
+            # Other folder names are now blank by default
+            mlog.info("Created online %s using folder %s" % (name, folder))
 
         else:
-            mlog.warning("LuminosityToolDefault can't resolve conddb.dbdata = %s, assume Run2!" % conddb.dbdata)
+            mlog.warning("LuminosityToolOnline can't resolve conddb.dbdata = %s, assume Run2!" % conddb.dbdata)
             mlog.info("Created online %s using a dummy Run2 configuration!" % name)
 
+        # Also need helper tool to make mu values properly
+        if not conddb.isMC:
+            toolName = "OnlineLumiCalibrationTool"
+            self.OnlineLumiCalibrationTool = toolName
+            if not hasattr(svcMgr.ToolSvc, toolName):
+                from CoolLumiUtilities.OnlineLumiCalibrationToolDefault import OnlineLumiCalibrationToolDefault
+                svcMgr.ToolSvc += OnlineLumiCalibrationToolDefault(toolName)
+                mlog.info("LuminosityToolOnline added tool %s", toolName)
+            else:
+                mlog.info("LuminosityToolOnline found %s already defined!" % toolName)
 
 
diff --git a/LumiBlock/LumiBlockComps/share/CreateLumiBlockFromFile_jobOptions.py b/LumiBlock/LumiBlockComps/share/CreateLumiBlockFromFile_jobOptions.py
index 8dc30a0a4ff0ee5ea260b78d830aa5f77f72375c..389769954858802ce3ab5b4d160cb2bef383f524 100644
--- a/LumiBlock/LumiBlockComps/share/CreateLumiBlockFromFile_jobOptions.py
+++ b/LumiBlock/LumiBlockComps/share/CreateLumiBlockFromFile_jobOptions.py
@@ -1,11 +1,13 @@
 # Create LumiBlock meta data containers *before* creating the output StreamESD/AOD
 from LumiBlockComps.LumiBlockCompsConf import CreateLumiBlockCollectionFromFile
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+
 createlb = CreateLumiBlockCollectionFromFile()
 topSequence += createlb
-if globalflags.DataSource()=='data':
+if globalflags.DataSource()=='data' and athenaCommonFlags.isOnline==False:
     from IOVDbSvc.CondDB import conddb
     countfolder="/GLOBAL/FILECOUNT/PROMPT <tag>GlobalFileCountPrompt-Tier0</tag>"
     conddb.addFolder('GLOBAL_OFL',countfolder)
     trstreamName=str(rec.triggerStream())
     if(trstreamName != "") :
-       createlb.streamName = "physics_"+trstreamName
+       createlb.streamName = trstreamName
diff --git a/LumiBlock/LumiBlockComps/src/LumiBlockMetaDataTool.cxx b/LumiBlock/LumiBlockComps/src/LumiBlockMetaDataTool.cxx
index 8f3137adf0544151586d3379eac1c4bbf772e1de..09ce1eb8b449b941b38b53f39bd1685ec4a7ed80 100755
--- a/LumiBlock/LumiBlockComps/src/LumiBlockMetaDataTool.cxx
+++ b/LumiBlock/LumiBlockComps/src/LumiBlockMetaDataTool.cxx
@@ -12,7 +12,7 @@
 #include "GoodRunsLists/IGoodRunsListSelectorTool.h"
 #include "GoodRunsLists/TGoodRunsListReader.h"
 #include "GoodRunsLists/ITriggerRegistryTool.h"
-#include "LumiCalc/LumiBlockCollectionConverter.h"
+#include "LumiCalc/LumiBlockRangeContainerConverter.h"
 #include "LumiBlockComps/ILumiCalcSvc.h"
 #include "xAODLuminosity/SortLumiBlockRangeByStart.h"
 
@@ -40,6 +40,7 @@ LumiBlockMetaDataTool::LumiBlockMetaDataTool(const std::string& type, const std:
    m_tagDataStore   ("StoreGateSvc/TagMetaDataStore", name),
    m_nfiles(0),
    m_fileCurrentlyOpened(false),
+   m_converter(new LumiBlockRangeContainerConverter()),
    m_grlcollection(new Root::TGRLCollection()),
    m_lcSvc("LumiCalcSvc/LumiCalcSvc",name),
    m_GoodRunsListSelectorTool("GoodRunsListSelectorTool"),
@@ -287,30 +288,36 @@ StatusCode   LumiBlockMetaDataTool::finishUp() {
      p_tempLBColl->push_back(iovr);
      ATH_MSG_INFO(  "Push_back tmpLBColl with run  " 
 		<< (*i)->startRunNumber() << " LB " << (*i)->startLumiBlockNumber() << " events seen "     
-		    << (*ilast)->eventsExpected() << " expected " << (*i)->eventsExpected());
+		    << (*ilast)->eventsSeen() << " expected " << (*i)->eventsExpected());
      i++;
      while (i != ie) {
        if( ((*i)->startRunNumber()==(*ilast)->startRunNumber()) &&
            ((*i)->stopRunNumber()==(*ilast)->stopRunNumber()) &&
            ((*i)->startLumiBlockNumber()==(*ilast)->startLumiBlockNumber()) &&
-	   ((*i)->startLumiBlockNumber()==(*ilast)->startLumiBlockNumber()) ) {
+	   ((*i)->stopLumiBlockNumber()==(*ilast)->stopLumiBlockNumber()) ) {
 
 	 if((*ilast)->eventsExpected()!=(*i)->eventsExpected()) {
 	   ATH_MSG_WARNING(  "Error: tmpLBColl with run  " << (*i)->startRunNumber() << " LB " << (*i)->startLumiBlockNumber() << " events expected "     
 	 	 		  << (*ilast)->eventsExpected() << " and " << (*i)->eventsExpected() );
 	 }
          else {
-	   ATH_MSG_INFO(  "Merge Run " << (*i)->startRunNumber() << " LB " << (*i)->startLumiBlockNumber() << " events seen "     
-	 	 		  << (*ilast)->eventsSeen() << "+" << (*i)->eventsSeen() << " and events expected "
-				  << (*ilast)->eventsExpected() );
+	   ATH_MSG_INFO(  "Merge Run " << (*i)->startRunNumber() << " LB " << (*i)->startLumiBlockNumber() 
+			               << " events seen "  << iovr->eventsSeen() << "+" 
+                                       << (*i)->eventsSeen() << " and events expected "
+				       << iovr->eventsExpected() );
 
-	     iovr->setEventsSeen((*i)->eventsSeen()+(*ilast)->eventsSeen());
+	     iovr->setEventsSeen((*i)->eventsSeen()+iovr->eventsSeen());
 	 }
        }
        else {
          iovr = new xAOD::LumiBlockRange(*(*i));
-	 ATH_MSG_INFO(  "Push_back tmpLBColl with run  " << (*i)->startRunNumber() << " LB " << (*i)->startLumiBlockNumber() << " events seen "     
-	 	 		  << (*ilast)->eventsExpected() << "+" << (*i)->eventsExpected() );
+
+         ATH_MSG_INFO(  "Push_back tmpLBColl with run  " 
+		<< iovr->startRunNumber() << " LB " << iovr->startLumiBlockNumber() << " events seen "     
+		    << iovr->eventsSeen() << " expected " << iovr->eventsExpected());
+
+     //	 ATH_MSG_INFO(  "Push_back tmpLBColl with run  " << (*i)->startRunNumber() << " LB " << (*i)->startLumiBlockNumber() << " events seen "     
+     //	 	 		  << (*ilast)->eventsExpected() << "+" << (*i)->eventsExpected() );
          p_tempLBColl->push_back(iovr);
          ilast = i;
        }
@@ -390,19 +397,55 @@ StatusCode   LumiBlockMetaDataTool::finishUp() {
     ATH_CHECK( m_pMetaDataStore->record( piovSuspect, m_suspectLBColl_name ) );
     ATH_CHECK( m_pMetaDataStore->record( piovSuspectAux, m_suspectLBColl_name + "Aux." ) );
   }
+
+  if (m_storexmlfiles) {
+    if(piovComplete->size()>0) {
+       TString _version("30"); // [0-10): ATLRunQuery, [10-20): ntuple production, [20-30): xml merging, [30-40): LumiCalc 
+       std::map<TString,TString> _metadata;
+       _metadata["complete"]=TString("complete");
+       TString complete   = m_converter->GetSuggestedName(*piovComplete);
+       TString subname = "complete"+complete;
+       TString filename = "LumiBlockMetaData_" + subname + ".xml";
+       Root::TGoodRunsList* pgrl = m_converter->GetGRLObject(*piovComplete,_metadata,_version);
+       m_converter->CreateXMLFile(*pgrl,filename.Data());
+    }
+    if(piovUnfinished->size()>0) {
+       TString _version("30"); // [0-10): ATLRunQuery, [10-20): ntuple production, [20-30): xml merging, [30-40): LumiCalc 
+       std::map<TString,TString> _metadata;
+       _metadata["complete"]=TString("unfinished");
+       TString unfinished   = m_converter->GetSuggestedName(*piovUnfinished);
+       TString subname = "unfinished"+unfinished;
+       TString filename = "LumiBlockMetaData_" + subname + ".xml";
+       Root::TGoodRunsList* pgrl = m_converter->GetGRLObject(*piovUnfinished,_metadata,_version);
+       m_converter->CreateXMLFile(*pgrl,filename.Data());
+    }
+    if(piovSuspect->size()>0) {
+       TString _version("30"); // [0-10): ATLRunQuery, [10-20): ntuple production, [20-30): xml merging, [30-40): LumiCalc 
+       std::map<TString,TString> _metadata;
+       _metadata["suspect"]=TString("suspect");
+       TString suspect   = m_converter->GetSuggestedName(*piovSuspect);
+       TString subname = "suspect"+suspect;
+       TString filename = "LumiBlockMetaData_" + subname + ".xml";
+       Root::TGoodRunsList* pgrl = m_converter->GetGRLObject(*piovSuspect,_metadata,_version);
+       m_converter->CreateXMLFile(*pgrl,filename.Data());
+    }
+
+  }
+
+
   return(StatusCode::SUCCESS);
 }
 
 const TString
 LumiBlockMetaDataTool::getGRLString( const TString& grlname ) const
 {
-  /*
+  
   std::vector< Root::TGoodRunsList >::const_iterator itr = m_grlcollection->find( grlname );
   if (itr!=m_grlcollection->end())
     return m_converter->GetXMLString(*itr);
 
   ATH_MSG_WARNING("getGRLString() : GoodRunsList with name <" << grlname << "> not found. Return empty string." );
-  */
+  
   return "";
 }
 
diff --git a/LumiBlock/LumiBlockComps/src/LumiBlockTester.cxx b/LumiBlock/LumiBlockComps/src/LumiBlockTester.cxx
index 4810e156dab35214ec27946b3ea7853f8e331940..00e820711a3d8041f826d838075cb24d7de0c929 100644
--- a/LumiBlock/LumiBlockComps/src/LumiBlockTester.cxx
+++ b/LumiBlock/LumiBlockComps/src/LumiBlockTester.cxx
@@ -12,10 +12,12 @@
 LumiBlockTester::LumiBlockTester(const std::string& name, ISvcLocator* pSvcLocator):
   AthAlgorithm(name,pSvcLocator),
   m_lumiTool("LuminosityTool"),
-  m_liveTool("TrigLivefractionTool")
+  m_liveTool("TrigLivefractionTool"),
+  m_muTool("LumiBlockMuTool")
 {
   declareProperty("LuminosityTool", m_lumiTool);
   declareProperty("TrigLivefractionTool", m_liveTool);
+  declareProperty("LumiBlockMuTool", m_muTool);
 }
 
 StatusCode
@@ -29,6 +31,9 @@ LumiBlockTester::initialize()
   // Get the livefration tool
   CHECK(m_liveTool.retrieve());
 
+  // Get the mu tool
+  CHECK(m_muTool.retrieve());
+
   ATH_MSG_INFO("LumiBlockTester::initialize() done");
 
   return StatusCode::SUCCESS;
@@ -60,6 +65,16 @@ LumiBlockTester::execute()
 
   ATH_MSG_INFO( "LB: " << lumiblock << " BCID: " << bcid << " <mu>: " << avgmu << " mu: " << instmu << " livefraction: " << live << " lumiavg livefraction: " << lumilive );
 
+  avgmu = m_muTool->averageInteractionsPerCrossing();
+  instmu = m_muTool->actualInteractionsPerCrossing();
+  ATH_MSG_INFO( "From muTool - <mu>: " << avgmu << " mu: " << instmu);
+
+  const EventInfo* eventInfo;
+  CHECK(evtStore()->retrieve(eventInfo));
+  instmu = eventInfo->actualInteractionsPerCrossing();
+  avgmu = eventInfo->averageInteractionsPerCrossing();
+  ATH_MSG_INFO( "From EvInfo - <mu>: " << avgmu << " mu: " << instmu);
+
   ATH_MSG_DEBUG("LumiBlockTester::execute() done");
   return StatusCode::SUCCESS;
 }
diff --git a/LumiBlock/LumiBlockComps/src/LumiCalcSvc.cxx b/LumiBlock/LumiBlockComps/src/LumiCalcSvc.cxx
index 96145f24da3bca79b7dd35c03fc8b3a25d52476d..bccfa45f83b0a310bbce5833a6eb696284a50adb 100644
--- a/LumiBlock/LumiBlockComps/src/LumiCalcSvc.cxx
+++ b/LumiBlock/LumiBlockComps/src/LumiCalcSvc.cxx
@@ -42,12 +42,16 @@
 #include <iostream>
 
 #include "LumiBlockComps/LumiCalcSvc.h"
+#include "xAODLuminosity/LumiBlockRangeContainer.h"
+#include "xAODLuminosity/LumiBlockRangeAuxContainer.h"
 
 LumiCalcSvc::LumiCalcSvc(const std::string& name, 
 		       ISvcLocator* pSvcLocator ) : 
   AthService(name, pSvcLocator),
-  p_inputstore(0),
-  p_metadatastore(0),
+  //  p_inputstore(0),
+  //  p_metadatastore(0),
+  m_pMetaDataStore ("StoreGateSvc/MetaDataStore",      name),
+  m_pInputStore    ("StoreGateSvc/InputMetaDataStore", name),
   tHistSvc(0),
   m_sourcedb("COOLONL_TRIGGER/OFLP200"),
   m_parlumiestfolder("/TRIGGER/LUMI/LBLEST"),
@@ -97,6 +101,10 @@ StatusCode LumiCalcSvc::initialize(){
   // locate the conditions store ptr to it.
 
   // locate input metadata store
+
+  ATH_CHECK( m_pMetaDataStore.retrieve() );
+  ATH_CHECK( m_pInputStore.retrieve() );
+  /*
   StatusCode sc = service("StoreGateSvc/InputMetaDataStore", p_inputstore);
   //sc = m_pInputStore.retrieve();
   if (!sc.isSuccess() || 0 == p_inputstore) {
@@ -111,10 +119,10 @@ StatusCode LumiCalcSvc::initialize(){
     return StatusCode::FAILURE;
   }
 
-
+  */
   // Set to be listener for begin/end of event
   ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", this->name());
-  sc = incSvc.retrieve();
+  StatusCode sc = incSvc.retrieve();
   if (!sc.isSuccess()) {
     log << MSG::ERROR << "Unable to get the IncidentSvc" << endreq;
     return(sc);
@@ -163,7 +171,7 @@ void LumiCalcSvc::print(){
 // Calculates lumi on a user defined input MetaData LumiBlockCollection
 StatusCode LumiCalcSvc::calcLumi(){
   MsgStream log(msgSvc(), name());
-  StatusCode status = doDbQuery(p_metadatastore);
+  StatusCode status = doDbQuery(m_pMetaDataStore);
   if (!status.isSuccess()){
     log << MSG::WARNING << "Couldn't do Db Query for LumiCalcSvc" << endreq;
   }
@@ -173,12 +181,12 @@ StatusCode LumiCalcSvc::calcLumi(){
 }
 
 //===========================================================================
-StatusCode LumiCalcSvc::doDbQuery(StoreGateSvc * sg) {
+StatusCode LumiCalcSvc::doDbQuery(StoreGateSvc_t sg) {
   MsgStream log(msgSvc(), name());
   StatusCode status = StatusCode::SUCCESS;
     
   doRecordTree(true);// record history to LumiTree TTree
-  StoreGateSvc * store = sg;
+  StoreGateSvc_t store = sg;
   LumiTree=m_lumicalc->getTree();
 
   if (!m_triggers.value().empty() && !m_lbcnames.value().empty()) {
@@ -210,19 +218,23 @@ StatusCode LumiCalcSvc::doDbQuery(StoreGateSvc * sg) {
         trignames.push_back(*it);
     }
 
-    if (store->contains<LumiBlockCollection>(lbcollname)) {
-      const DataHandle<LumiBlockCollection> iovc;
-      status = store->retrieve(iovc, lbcollname);
+    if (store->contains<xAOD::LumiBlockRangeContainer>(lbcollname)) {
+      //      const DataHandle<xAOD::LumiBlockRangeContainer> iovc;
+      const xAOD::LumiBlockRangeContainer* lbcoll = 0;
+      status = store->retrieve(lbcoll, lbcollname);
+
       if (!status.isSuccess()) {
-        log << MSG::DEBUG << "Could not find LumiBlockCollection >>" << lbcollname << "<< in " << store->name() << endreq;
+        log << MSG::DEBUG << "Could not find LumiBlockRangeContainer >>" << lbcollname << "<< in " << store->name() << endreq;
       }else {
-        log << MSG::DEBUG << " Found LumiBlockCollection >>" << lbcollname << "<< in " << store->name() << " OK " << endreq;
+        log << MSG::DEBUG << " Found LumiBlockRangeContainer >>" << lbcollname << "<< in " << store->name() << " OK " << endreq;
         log << MSG::INFO << " Calculating Integrated Luminosity based on >>" << lbcollname <<  "<< in " << store->name() << endreq;
         if (!description.empty()) { log << MSG::INFO << " Description of >>" << lbcollname << "<< = " << description << endreq; }
-        const LumiBlockCollection* lbcoll = iovc;
+
+	/*
+        const LumiBlockRangeContainer* lbcoll = iovc;
         // check against problems
         if(dynamic_cast< const LumiBlockCollection * >(lbcoll) == 0){
-          log << MSG::ERROR << "Input LumiBlockCollection to LumiCalcSvc is not of type LumiBlockCollection" << endreq;
+          log << MSG::ERROR << "Input LumiBlockRangeContainer to LumiCalcSvc is not of type LumiBlockRangeContainer" << endreq;
           status = StatusCode::FAILURE;
           return status;
         }else{
@@ -232,6 +244,8 @@ StatusCode LumiCalcSvc::doDbQuery(StoreGateSvc * sg) {
             return status;
           }
         } 
+	*/
+
         for( std::list<TString>::const_iterator it = trignames.begin(); it != trignames.end(); ++it){
           const std::string trigname = it->Data();
           m_lumicalc->SetCollName(lbcollname);
@@ -269,7 +283,7 @@ void LumiCalcSvc::handle(const Incident& inc) {
     log << MSG::DEBUG << "BeginTagFile incident fired!" << endreq;
     m_fileCurrentlyOpened = true;
     if(m_UseInputStore == true){
-      doDbQuery(p_inputstore);
+      doDbQuery(m_pInputStore);
     }
   }
   else if (inc.type() == "EndInputFile") {
diff --git a/LumiBlock/LumiBlockComps/src/LuminosityTool.cxx b/LumiBlock/LumiBlockComps/src/LuminosityTool.cxx
index 32eb646ec689c5e4c8223630103a44dab9de35e5..c830cb20d03a0ad749cc24fa37fb7093b0386bd5 100644
--- a/LumiBlock/LumiBlockComps/src/LuminosityTool.cxx
+++ b/LumiBlock/LumiBlockComps/src/LuminosityTool.cxx
@@ -9,10 +9,11 @@
 #include "EventInfo/EventType.h"
 
 #include "CoolKernel/IObject.h"
-#include "CoralBase/Blob.h"
 #include "AthenaPoolUtilities/CondAttrListCollection.h"
 #include "AthenaPoolUtilities/AthenaAttributeList.h"
 
+#include "CoolLumiUtilities/BunchLumisUtil.h"
+
 #include "AthenaKernel/errorcheck.h"
 
 // Total number of BCIDs in one turn - this must match value used in /TDAQ/OLC/BUNCHLUMIS for storage mode 1
@@ -33,7 +34,9 @@ LuminosityTool::LuminosityTool(const std::string& type,
     m_lblbFolderName(""), ///TRIGGER/LUMI/LBLB"),
     m_recalcPerBCIDLumi(true),
     m_preferredChannel(0),
-    m_luminousBunches(0)
+    m_luminousBunches(0),
+    m_bunchInstLumiBlob(NULL),
+    m_calibChannel(0)
 {
   declareInterface<ILuminosityTool>(this);
   declareProperty("LumiFolderName", m_lumiFolderName);
@@ -250,6 +253,8 @@ LuminosityTool::updateAvgLumi( IOVSVC_CALLBACK_ARGS_P(/*idx*/, /*keys*/) )
   m_LBAvEvtsPerBX = 0.;
   m_Valid = 0xFFFFFFFF;
   m_preferredChannel = 0;
+  m_calibChannel = 0;
+  m_bunchInstLumiBlob = NULL;
 
   // Check if we have anything to do
   // Shouldn't actually get a callback if this folder doesn't exist...
@@ -288,18 +293,41 @@ LuminosityTool::updateAvgLumi( IOVSVC_CALLBACK_ARGS_P(/*idx*/, /*keys*/) )
     return StatusCode::SUCCESS;
   }
 
-  // Check validity
-  cool::UInt32 m_Valid = attrList["Valid"].data<cool::UInt32>();
-  if (m_Valid & 0x03) {
-    ATH_MSG_WARNING( " Invalid luminosity ... set lumi to 0" );
+  // Check validity (don't bother continuing if invalid)
+  m_Valid = attrList["Valid"].data<cool::UInt32>();
+  if (m_Valid & 0x01) {
+    ATH_MSG_WARNING( " Invalid LB Average luminosity ... set lumi to 0" );
     return StatusCode::SUCCESS;
   }
 
   // Get preferred channel (needed for per-BCID calculation)
   if (m_lumiChannel == 0) {
-    m_preferredChannel = (m_Valid >> 22);
+
+    // Check if we have a payload for this (Run2 only)      
+    bool hasAlgorithmID = false;
+    for (coral::AttributeList::const_iterator attr = attrList.begin();
+	 attr != attrList.end(); ++attr) {
+      //const std::string& name = attr->specification().name();
+      if (attr->specification().name() == "AlgorithmID") {
+	hasAlgorithmID = true;
+	break;
+      }
+    }
+
+    if (hasAlgorithmID) {
+      // In Run2, channel 0 should be good.  Leave as is
+      m_preferredChannel = m_lumiChannel;
+      m_calibChannel = attrList["AlgorithmID"].data<cool::UInt32>();
+
+    } else {
+      // In Run1, we need to recalculate from the actual channel number
+      m_preferredChannel = (m_Valid >> 22);
+      m_calibChannel = m_preferredChannel;
+    }
+
   } else {
     m_preferredChannel = m_lumiChannel;
+    m_calibChannel = m_lumiChannel;
   }
 
   m_LBAvInstLumi = attrList["LBAvInstLumi"].data<cool::Float>();   // Lumi
@@ -316,9 +344,25 @@ LuminosityTool::updateAvgLumi( IOVSVC_CALLBACK_ARGS_P(/*idx*/, /*keys*/) )
     m_LBAvEvtsPerBX=0.;
   }
 
-  // Also update muToLumi as this may have changed with the channel number
-  if (!m_onlineLumiCalibrationTool.empty())
-    m_MuToLumi = m_onlineLumiCalibrationTool->getMuToLumi(m_preferredChannel);
+  // MuToLumi gets updated in recalcPerBCIDLumi
+
+  // Check validity of per-BCID luminosity (will issue warning in recalcPerBCIDLumi
+  int perBcidValid = (m_Valid/10) % 10;
+  if (perBcidValid > 0) {
+    return StatusCode::SUCCESS;
+  }
+
+  // Also save per-BCID blob if it exists
+  for (coral::AttributeList::const_iterator attr = attrList.begin();
+       attr != attrList.end(); ++attr) {
+    //const std::string& name = attr->specification().name();
+    if (attr->specification().name() == "BunchInstLumi") {
+      if (!attrList["BunchInstLumi"].isNull())
+	m_bunchInstLumiBlob = &attrList["BunchInstLumi"].data<coral::Blob>();
+
+      break;
+    }
+  }
 
   return StatusCode::SUCCESS;
 }
@@ -376,107 +420,188 @@ LuminosityTool::recalculatePerBCIDLumi()
   // Clear the calibrated luminosity data
   m_LBInstLumi.assign(TOTAL_LHC_BCIDS, 0.);
 
-  // Make some sanity checks that we have everyting we need
-  if (m_preferredChannel == 0) return;
-  if (m_LBAvInstLumi == 0.) return;
+  // Update muToLumi 
+  if (!m_onlineLumiCalibrationTool.empty()) {
+    // This is the only correct way to do this!
+    // The division below gives average mu (over all bunches) to total lumi
+    m_MuToLumi = m_onlineLumiCalibrationTool->getMuToLumi(m_calibChannel);
+    //} else if (m_LBAvEvtsPerBX > 0.) {
+    //m_MuToLumi = m_LBAvInstLumi / m_LBAvEvtsPerBX;
+  } else {
+    m_MuToLumi = 0.;
+  } 
+  ATH_MSG_DEBUG(" Found muToLumi = " << m_MuToLumi << " for channel " << m_calibChannel );
 
-  // Nothing to do if we don't have the ingredients
-  if (m_onlineLumiCalibrationTool.empty()) {
-    ATH_MSG_DEBUG( "OnlineLumiCalibrationTool.empty() is TRUE, skipping..." );
-    return;
-  }
-  if (m_bunchLumisTool.empty()) {
-    ATH_MSG_DEBUG( "BunchLumisTool.empty() is TRUE, skipping..." );
+  // Make some sanity checks that we have everyting we need
+  if (m_lumiFolderName.empty()) {
+    ATH_MSG_INFO( "LumiFolderName is empty in recalculatePerBCIDLumi()!");
     return;
   }
-  if (m_bunchGroupTool.empty()) {
-    ATH_MSG_DEBUG( "BunchGroupTool.empty() is TRUE, skipping..." );
+  int perBcidValid = (m_Valid/10) % 10;
+  if ((m_Valid & 0x03) || (perBcidValid > 0)) {  // Skip if either per-BCID or LBAv is invalid
+    ATH_MSG_WARNING( " Invalid per-BCID luminosity found: " << m_Valid << "!" );
     return;
   }
-  if (m_fillParamsTool.empty()) {
-    ATH_MSG_DEBUG( "FillParamsTool.empty() is TRUE, skipping..." );
+  if (m_LBAvInstLumi <= 0.) {
+    ATH_MSG_INFO( "LBAvInstLumi is zero or negative in recalculatePerBCIDLumi():" << m_LBAvInstLumi);
     return;
   }
 
-  // Update data from FillParamsTool
-  m_luminousBunches = m_fillParamsTool->nLuminousBunches();
-  m_luminousBunchesVec = m_fillParamsTool->luminousBunches();
 
-  ATH_MSG_DEBUG( "N LuminousBunches:" << m_luminousBunches );
-  //ATH_MSG_DEBUG( m_luminousBunchesVec[0] << " " <<  m_luminousBunchesVec[1] );
+  // Check here if we want to do this the Run1 way (hard) or the Run2 way (easy)
 
-  // Get the raw data for the preferred channel
-  m_bunchLumisTool->setChannel(m_preferredChannel);
-  std::vector<float> rawLumiVec = m_bunchLumisTool->rawLuminosity();
+  if (m_bunchInstLumiBlob != NULL) { // Run2 way, easy
+    ATH_MSG_DEBUG( "starting Run2 recalculatePerBCIDLumi() for alg: " << m_preferredChannel );
 
+    // Check that the length isn't zero
+    if (m_bunchInstLumiBlob->size() == 0) {
+      ATH_MSG_WARNING("BunchInstLumi blob found with zero length!");
+      return;
+    }
 
-  //
-  // Calibration step
-  //
+    // Utility class to do the work
+    //BunchLumisUtil lumiUtil;
+    //if (!lumiUtil.unpackBlob(m_bunchInstLumiBlob)) {
+    //  ATH_MSG_WARNING( "Failed to unpack blob: " << lumiUtil.error );
+    //  return;
+    //}
 
-  //  Here we want to go through and calibrate raw values in the luminous bunches only.
-  // This is what the OL adds up, and since these are online calibrations, we want to rescale the total
-  // to agree to whatever offline tag we are using.
-  std::vector<float> calLumiVec(TOTAL_LHC_BCIDS, 0.);
+    //m_LBInstLumi = lumiUtil.bunchLumis();
 
-  // Update muToLumi while we are at it (also check that calibration exists)
-  m_MuToLumi = m_onlineLumiCalibrationTool->getMuToLumi(m_preferredChannel);
-  if (m_MuToLumi <= 0.) {
-    ATH_MSG_WARNING( " dont have calibration information for preferred channel " << m_preferredChannel << "!" );
-    return;
-  }
+    // Hardcode the Run2 BLOB decoding (should use CoolLumiUtilities...)
+    const char* pchar = static_cast<const char*>(m_bunchInstLumiBlob->startingAddress()); // First byte holds storage size and mode
+    unsigned int bss = ((*pchar) % 100) / 10;  // Byte storage size
+    unsigned int smod = ((*pchar) % 10);       // Storage mode
 
-  double lumiSum = 0.;
-  for (unsigned int i = 0; i<m_luminousBunches; i++) {
-    unsigned int bcid = m_luminousBunchesVec[i];
+    ATH_MSG_DEBUG( "BunchInstLumi blob found with storage mode " << smod << " and byte storage size " << bss );
 
-    // Don't waste time on zero lumi 
-    if (rawLumiVec[bcid] <= 0.) {
-      ATH_MSG_DEBUG( "Calibrate BCID " << bcid << " with raw " << rawLumiVec[bcid] << " -> skipping" );
-      continue;
+    // Make sure we have what we think we have
+    if (bss != 4 || smod != 1) {
+      ATH_MSG_WARNING( "BunchInstLumi blob found with storage mode " << smod << " and byte storage size " << bss << " - Unknown!");
+      return;
     }
 
-    // Calibrate
-    if (!m_onlineLumiCalibrationTool->calibrateLumi(m_preferredChannel, rawLumiVec[bcid], calLumiVec[bcid])) {
-      ATH_MSG_DEBUG( "Calibrate BCID " << bcid << " with raw " << rawLumiVec[bcid] << " -> calibration failed!" );
-      ATH_MSG_WARNING( "Per-BCID calibration failed for bcid " << bcid << " with raw lumi = " << rawLumiVec[bcid] );
-      continue;
+    unsigned int nbcids = TOTAL_LHC_BCIDS;
+    unsigned int bloblength = bss * nbcids + 1;
+
+    if (static_cast<cool::UInt32>(m_bunchInstLumiBlob->size()) != bloblength) {
+      ATH_MSG_WARNING( "BunchRawInstLumi blob found with length" << m_bunchInstLumiBlob->size() << "in storage mode" << smod <<  ", expecting " << bloblength << "!" );
+      return;
     }
 
-    lumiSum += calLumiVec[bcid];
+    // Length is correct, read raw data according to packing scheme
+    // This is absolute luminosity, so just unpack values into our array
+    
+    ATH_MSG_DEBUG( "Unpacking lumi value from blob");
+    const float* p4 = (const float*) ++pchar;  // Points to next char after header
+    for (unsigned int i=0; i<nbcids; i++, p4++) {
+      m_LBInstLumi[i] = *p4;
+      ATH_MSG_DEBUG( "Bcid: " << i << " Lumi: " << *p4 );
+    }
+    
+  } else { // Run1 way, hard!
+    ATH_MSG_DEBUG( "starting Run1 recalculatePerBCIDLumi() for alg: " << m_preferredChannel );
+    
+    if (m_preferredChannel == 0) return;
+
+    // Nothing to do if we don't have the ingredients
+    if (m_onlineLumiCalibrationTool.empty()) {
+      ATH_MSG_DEBUG( "OnlineLumiCalibrationTool.empty() is TRUE, skipping..." );
+      return;
+    }
+    if (m_bunchLumisTool.empty()) {
+      ATH_MSG_DEBUG( "BunchLumisTool.empty() is TRUE, skipping..." );
+      return;
+    }
+    if (m_bunchGroupTool.empty()) {
+      ATH_MSG_DEBUG( "BunchGroupTool.empty() is TRUE, skipping..." );
+      return;
+    }
+    if (m_fillParamsTool.empty()) {
+      ATH_MSG_DEBUG( "FillParamsTool.empty() is TRUE, skipping..." );
+      return;
+    }
 
-    ATH_MSG_DEBUG( "Calibrate BCID " << bcid << " with raw " << rawLumiVec[bcid] << " -> " << calLumiVec[bcid] );
-  }
+    // Update data from FillParamsTool
+    m_luminousBunches = m_fillParamsTool->nLuminousBunches();
+    m_luminousBunchesVec = m_fillParamsTool->luminousBunches();
 
-  // Work out scale factor between offline and online estimate
-  float offlineOnlineRatio = 1.;
-  if (lumiSum > 0.) offlineOnlineRatio = m_LBAvInstLumi / lumiSum;
+    ATH_MSG_DEBUG( "N LuminousBunches:" << m_luminousBunches );
+    //ATH_MSG_DEBUG( m_luminousBunchesVec[0] << " " <<  m_luminousBunchesVec[1] );
 
-  ATH_MSG_DEBUG( " Offline/Online scale factor: " << m_LBAvInstLumi << " / " << lumiSum << " = " << offlineOnlineRatio );
+    // Get the raw data for the preferred channel
+    m_bunchLumisTool->setChannel(m_preferredChannel);
+    std::vector<float> rawLumiVec = m_bunchLumisTool->rawLuminosity();
 
-  // Make sure we have values for all BCIDs in the physics bunch group
-  // std::vector<unsigned int> m_bgBunchesVec = m_bunchGroupTool->bunchGroup1();
-  for (unsigned int i = 0; i<m_bunchGroupTool->nBunchGroup1(); i++) {
-    unsigned int bcid = m_bunchGroupTool->bunchGroup1()[i];
 
-    // Don't repeat if value already exists
-    if (calLumiVec[bcid] > 0.) continue;
-    if (rawLumiVec[bcid] <= 0.) continue;
+    //
+    // Calibration step
+    //
+    
+    //  Here we want to go through and calibrate raw values in the luminous bunches only.
+    // This is what the OL adds up, and since these are online calibrations, we want to rescale the total
+    // to agree to whatever offline tag we are using.
+    std::vector<float> calLumiVec(TOTAL_LHC_BCIDS, 0.);
+    
+    // Update muToLumi while we are at it (also check that calibration exists)
+    m_MuToLumi = m_onlineLumiCalibrationTool->getMuToLumi(m_preferredChannel);
+    if (m_MuToLumi <= 0.) {
+      ATH_MSG_WARNING( " dont have calibration information for preferred channel " << m_preferredChannel << "!" );
+      return;
+    }
 
-    // Calibrate
-    if (!m_onlineLumiCalibrationTool->calibrateLumi(m_preferredChannel, rawLumiVec[bcid], calLumiVec[bcid])) {
-      if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << " -> Calibration failed!" << endreq;
-      ATH_MSG_WARNING( "Per-BCID calibration failed for bcid " << bcid << " with raw lumi = " << rawLumiVec[bcid] );
-      continue;
+    double lumiSum = 0.;
+    for (unsigned int i = 0; i<m_luminousBunches; i++) {
+      unsigned int bcid = m_luminousBunchesVec[i];
+      
+      // Don't waste time on zero lumi 
+      if (rawLumiVec[bcid] <= 0.) {
+	ATH_MSG_DEBUG( "Calibrate BCID " << bcid << " with raw " << rawLumiVec[bcid] << " -> skipping" );
+	continue;
+      }
+
+      // Calibrate
+      if (!m_onlineLumiCalibrationTool->calibrateLumi(m_preferredChannel, rawLumiVec[bcid], calLumiVec[bcid])) {
+	ATH_MSG_DEBUG( "Calibrate BCID " << bcid << " with raw " << rawLumiVec[bcid] << " -> calibration failed!" );
+	ATH_MSG_WARNING( "Per-BCID calibration failed for bcid " << bcid << " with raw lumi = " << rawLumiVec[bcid] );
+	continue;
+      }
+      
+      lumiSum += calLumiVec[bcid];
+      
+      ATH_MSG_DEBUG( "Calibrate BCID " << bcid << " with raw " << rawLumiVec[bcid] << " -> " << calLumiVec[bcid] );
     }
-  }
 
-  // Almost done, now we apply the scale factor to all BCIDs
-  for (unsigned int i=0; i<calLumiVec.size(); i++) 
-    calLumiVec[i] *= offlineOnlineRatio;
+    // Work out scale factor between offline and online estimate
+    float offlineOnlineRatio = 1.;
+    if (lumiSum > 0.) offlineOnlineRatio = m_LBAvInstLumi / lumiSum;
+    
+    ATH_MSG_DEBUG( " Offline/Online scale factor: " << m_LBAvInstLumi << " / " << lumiSum << " = " << offlineOnlineRatio );
+
+    // Make sure we have values for all BCIDs in the physics bunch group
+    // std::vector<unsigned int> m_bgBunchesVec = m_bunchGroupTool->bunchGroup1();
+    for (unsigned int i = 0; i<m_bunchGroupTool->nBunchGroup1(); i++) {
+      unsigned int bcid = m_bunchGroupTool->bunchGroup1()[i];
+      
+      // Don't repeat if value already exists
+      if (calLumiVec[bcid] > 0.) continue;
+      if (rawLumiVec[bcid] <= 0.) continue;
+      
+      // Calibrate
+      if (!m_onlineLumiCalibrationTool->calibrateLumi(m_preferredChannel, rawLumiVec[bcid], calLumiVec[bcid])) {
+	if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << " -> Calibration failed!" << endreq;
+	ATH_MSG_WARNING( "Per-BCID calibration failed for bcid " << bcid << " with raw lumi = " << rawLumiVec[bcid] );
+	continue;
+      }
+    }
 
-  // And finally assign this vector to our final data location
-  m_LBInstLumi = calLumiVec;
+    // Almost done, now we apply the scale factor to all BCIDs
+    for (unsigned int i=0; i<calLumiVec.size(); i++) 
+      calLumiVec[i] *= offlineOnlineRatio;
+    
+    // And finally assign this vector to our final data location
+    m_LBInstLumi = calLumiVec;
+  }
 
   ATH_MSG_DEBUG( "finished recalculatePerBCIDLumi() for alg: " << m_preferredChannel );
   return;