From f05c6560eff86696adb378f9d2eff949285dba41 Mon Sep 17 00:00:00 2001
From: mmusich <marco.musich@cern.ch>
Date: Wed, 18 Oct 2023 18:15:30 +0200
Subject: [PATCH 1/5] add testing machinery to make sure TrackerTopology from
 DB is the same as the Standalone one

---
 .../test/BuildFile.xml                        |  13 +
 .../test/StandaloneTrackerTopologyTest.cc     | 229 ++++++++++++++++++
 .../test/testStandaloneTrackerTopology.sh     |   9 +
 .../test/testStandaloneTrackerTopology_cfg.py |  66 +++++
 4 files changed, 317 insertions(+)
 create mode 100644 CalibTracker/StandaloneTrackerTopology/test/BuildFile.xml
 create mode 100644 CalibTracker/StandaloneTrackerTopology/test/StandaloneTrackerTopologyTest.cc
 create mode 100755 CalibTracker/StandaloneTrackerTopology/test/testStandaloneTrackerTopology.sh
 create mode 100644 CalibTracker/StandaloneTrackerTopology/test/testStandaloneTrackerTopology_cfg.py

diff --git a/CalibTracker/StandaloneTrackerTopology/test/BuildFile.xml b/CalibTracker/StandaloneTrackerTopology/test/BuildFile.xml
new file mode 100644
index 0000000000000..2e31ca71dc10c
--- /dev/null
+++ b/CalibTracker/StandaloneTrackerTopology/test/BuildFile.xml
@@ -0,0 +1,13 @@
+<use name="Geometry/TrackerGeometryBuilder"/>
+<use name="Geometry/TrackerNumberingBuilder"/>
+<use name="Geometry/CommonDetUnit"/>
+<use name="FWCore/Framework"/>
+
+<library file="StandaloneTrackerTopologyTest.cc" name="StandaloneTrackerTopologyTest">
+  <use name="DataFormats/TrackerCommon"/>
+  <use name="Geometry/Records"/>
+  <use name="CalibTracker/StandaloneTrackerTopology"/>
+  <flags EDM_PLUGIN="1"/>
+</library>
+
+<test name="CalibTrackerStandaloneTrackerTopologyTestDriver" command="testStandaloneTrackerTopology.sh"/>
diff --git a/CalibTracker/StandaloneTrackerTopology/test/StandaloneTrackerTopologyTest.cc b/CalibTracker/StandaloneTrackerTopology/test/StandaloneTrackerTopologyTest.cc
new file mode 100644
index 0000000000000..19ca9be23c096
--- /dev/null
+++ b/CalibTracker/StandaloneTrackerTopology/test/StandaloneTrackerTopologyTest.cc
@@ -0,0 +1,229 @@
+// -*- C++ -*-
+//
+// Package:    CalibTracker/StandaloneTrackerTopology
+// Class:      StandaloneTrackerTopologyTest
+//
+/**\class StandaloneTrackerTopologyTest StandaloneTrackerTopologyTest.cc CalibTracker/StandaloneTrackerTopology/test/StandaloneTrackerTopologyTest.cc
+
+ Description: [one line class summary]
+
+ Implementation:
+     [Notes on implementation]
+*/
+//
+// Original Author:  Marco Musich
+//         Created:  Wed, 18 Oct 2023 10:00:00 GMT
+//
+//
+
+// system include files
+#include <memory>
+
+// user include files
+#include "FWCore/Framework/interface/Frameworkfwd.h"
+#include "FWCore/Framework/interface/global/EDAnalyzer.h"
+
+#include "FWCore/Framework/interface/Event.h"
+#include "FWCore/Framework/interface/MakerMacros.h"
+
+#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include "FWCore/Utilities/interface/InputTag.h"
+
+#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
+#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
+#include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
+#include "Geometry/Records/interface/TrackerTopologyRcd.h"
+#include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
+#include "CalibTracker/StandaloneTrackerTopology/interface/StandaloneTrackerTopology.h"
+
+//
+// class declaration
+//
+
+class StandaloneTrackerTopologyTest : public edm::global::EDAnalyzer<> {
+public:
+  explicit StandaloneTrackerTopologyTest(const edm::ParameterSet&);
+  ~StandaloneTrackerTopologyTest() override = default;
+
+  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
+
+private:
+  void analyze(edm::StreamID, edm::Event const& iEvent, edm::EventSetup const& iSetup) const override;
+  void testTopology(const TrackerGeometry* pDD,
+                    const TrackerTopology* tTopoFromDB,
+                    const TrackerTopology* tTopoStandalone) const;
+
+  // ----------member data ---------------------------
+  const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> geomEsToken_;
+  const edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> topoToken_;
+};
+
+//
+// constructors and destructor
+//
+StandaloneTrackerTopologyTest::StandaloneTrackerTopologyTest(const edm::ParameterSet& iConfig)
+    : geomEsToken_(esConsumes()), topoToken_(esConsumes()) {}
+
+//
+// member functions
+//
+void StandaloneTrackerTopologyTest::testTopology(const TrackerGeometry* pDD,
+                                                 const TrackerTopology* tTopoFromDB,
+                                                 const TrackerTopology* tTopoStandalone) const {
+  // test Barrel Pixel
+  for (auto det : pDD->detsPXB()) {
+    const PixelGeomDetUnit* pixelDet = dynamic_cast<const PixelGeomDetUnit*>(det);
+    const auto& layerA = tTopoFromDB->pxbLayer(pixelDet->geographicalId());
+    const auto& ladderA = tTopoFromDB->pxbLadder(pixelDet->geographicalId());
+    const auto& moduleA = tTopoFromDB->pxbModule(pixelDet->geographicalId());
+
+    const auto& layerB = tTopoStandalone->pxbLayer(pixelDet->geographicalId());
+    const auto& ladderB = tTopoStandalone->pxbLadder(pixelDet->geographicalId());
+    const auto& moduleB = tTopoStandalone->pxbModule(pixelDet->geographicalId());
+
+    if (layerA != layerB || ladderA != ladderB || moduleA != moduleB) {
+      throw cms::Exception("ConfigurationMismatch")
+          << "PXB: Topology from DB doesn't match with Topology from XML file!"
+          << " DetId: " << pixelDet->geographicalId() << " layerA: " << layerA << " layerB: " << layerB
+          << " ladderA :" << ladderA << " ladderB :" << ladderB << " moduleA :" << moduleA << " moduleB :" << moduleB
+          << std::endl;
+    }
+  }
+
+  // test Pixel Endcaps
+  for (auto det : pDD->detsPXF()) {
+    const PixelGeomDetUnit* pixelDet = dynamic_cast<const PixelGeomDetUnit*>(det);
+    const auto& diskA = tTopoFromDB->pxfDisk(pixelDet->geographicalId());
+    const auto& bladeA = tTopoFromDB->pxfBlade(pixelDet->geographicalId());
+    const auto& moduleA = tTopoFromDB->pxfModule(pixelDet->geographicalId());
+
+    const auto& diskB = tTopoStandalone->pxfDisk(pixelDet->geographicalId());
+    const auto& bladeB = tTopoStandalone->pxfBlade(pixelDet->geographicalId());
+    const auto& moduleB = tTopoStandalone->pxfModule(pixelDet->geographicalId());
+
+    if (diskA != diskB || bladeA != bladeB || moduleA != moduleB) {
+      throw cms::Exception("ConfigurationMismatch")
+          << "PXF: Topology from DB doesn't match with Topology from XML file"
+          << " DetId: " << pixelDet->geographicalId() << " diskA: " << diskA << " diskB: " << diskB
+          << " bladeA :" << bladeA << " bladeB :" << bladeB << " moduleA :" << moduleA << " moduleB :" << moduleB
+          << std::endl;
+    }
+  }
+
+  // test inner barrel
+  for (auto det : pDD->detsTIB()) {
+    const GeomDetUnit* Det = dynamic_cast<const GeomDetUnit*>(det);
+    const auto& sideA = tTopoFromDB->tibSide(Det->geographicalId());
+    const auto& layerA = tTopoFromDB->tibLayer(Det->geographicalId());
+    const auto& moduleA = tTopoFromDB->tibModule(Det->geographicalId());
+
+    const auto& sideB = tTopoStandalone->tibSide(Det->geographicalId());
+    const auto& layerB = tTopoStandalone->tibLayer(Det->geographicalId());
+    const auto& moduleB = tTopoStandalone->tibModule(Det->geographicalId());
+
+    if (sideA != sideB || layerA != layerB || moduleA != moduleB) {
+      throw cms::Exception("ConfigurationMismatch")
+          << "TIB: Topology from DB doesn't match with Topology from XML file"
+          << " DetId: " << Det->geographicalId() << " sideA: " << sideA << " sideB: " << sideB << " layerA :" << layerA
+          << " layerB :" << layerB << " moduleA :" << moduleA << " moduleB :" << moduleB << std::endl;
+    }
+  }
+
+  // test inner disks
+  for (auto det : pDD->detsTID()) {
+    const GeomDetUnit* Det = dynamic_cast<const GeomDetUnit*>(det);
+    const auto& sideA = tTopoFromDB->tidSide(Det->geographicalId());
+    const auto& wheelA = tTopoFromDB->tidWheel(Det->geographicalId());
+    const auto& moduleA = tTopoFromDB->tidModule(Det->geographicalId());
+
+    const auto& sideB = tTopoStandalone->tidSide(Det->geographicalId());
+    const auto& wheelB = tTopoStandalone->tidWheel(Det->geographicalId());
+    const auto& moduleB = tTopoStandalone->tidModule(Det->geographicalId());
+
+    if (sideA != sideB || wheelA != wheelB || moduleA != moduleB) {
+      throw cms::Exception("ConfigurationMismatch")
+          << "TID: Topology from DB doesn't match with Topology from XML file"
+          << " DetId: " << Det->geographicalId() << " sideA: " << sideA << " sideB: " << sideB << " wheelA :" << wheelA
+          << " wheelB :" << wheelB << " moduleA :" << moduleA << " moduleB :" << moduleB << std::endl;
+    }
+  }
+
+  // test outer barrel
+  for (auto det : pDD->detsTOB()) {
+    const GeomDetUnit* Det = dynamic_cast<const GeomDetUnit*>(det);
+
+    const auto& layerA = tTopoFromDB->tobLayer(Det->geographicalId());
+    const auto& rodA = tTopoFromDB->tobRod(Det->geographicalId());
+    const auto& moduleA = tTopoFromDB->tobModule(Det->geographicalId());
+
+    const auto& layerB = tTopoStandalone->tobLayer(Det->geographicalId());
+    const auto& rodB = tTopoStandalone->tobRod(Det->geographicalId());
+    const auto& moduleB = tTopoStandalone->tobModule(Det->geographicalId());
+
+    if (layerA != layerB || rodA != rodB || moduleA != moduleB) {
+      throw cms::Exception("ConfigurationMismatch")
+          << "TOB: Topology from DB doesn't match with Topology from XML file"
+          << " DetId: " << Det->geographicalId() << " layerA :" << layerA << " layerB :" << layerB << " rodA: " << rodA
+          << " rodB: " << rodB << " moduleA :" << moduleA << " moduleB :" << moduleB << std::endl;
+    }
+  }
+
+  // test outer disks
+  for (auto det : pDD->detsTEC()) {
+    const GeomDetUnit* Det = dynamic_cast<const GeomDetUnit*>(det);
+    const auto& sideA = tTopoFromDB->tecSide(Det->geographicalId());
+    const auto& wheelA = tTopoFromDB->tecWheel(Det->geographicalId());
+    const auto& moduleA = tTopoFromDB->tecModule(Det->geographicalId());
+
+    const auto& sideB = tTopoStandalone->tecSide(Det->geographicalId());
+    const auto& wheelB = tTopoStandalone->tecWheel(Det->geographicalId());
+    const auto& moduleB = tTopoStandalone->tecModule(Det->geographicalId());
+
+    if (sideA != sideB || wheelA != wheelB || moduleA != moduleB) {
+      throw cms::Exception("ConfigurationMismatch")
+          << "TEC: Topology from DB doesn't match with Topology from XML file"
+          << " DetId: " << Det->geographicalId() << " sideA: " << sideA << " sideB: " << sideB << " wheelA :" << wheelA
+          << " wheelB :" << wheelB << " moduleA :" << moduleA << " moduleB :" << moduleB << std::endl;
+    }
+  }
+}
+
+// ------------ method called for each event  ------------
+void StandaloneTrackerTopologyTest::analyze(edm::StreamID,
+                                            edm::Event const& iEvent,
+                                            edm::EventSetup const& iSetup) const {
+  using namespace edm;
+
+  // get the Tracker geometry from event setup
+  const TrackerGeometry* pDD = &iSetup.getData(geomEsToken_);
+  const TrackerTopology* tTopo = &iSetup.getData(topoToken_);
+
+  const char* pathToTopologyXML;
+  if ((pDD->isThere(GeomDetEnumerators::P2PXB)) || (pDD->isThere(GeomDetEnumerators::P2PXEC))) {
+    edm::LogPrint("StandaloneTrackerTopologyTest") << "===== Testing Phase-2 Pixel Tracker geometry =====" << std::endl;
+    pathToTopologyXML = "Geometry/TrackerCommonData/data/PhaseII/trackerParameters.xml";
+  } else if ((pDD->isThere(GeomDetEnumerators::P1PXB)) || (pDD->isThere(GeomDetEnumerators::P1PXEC))) {
+    edm::LogPrint("StandaloneTrackerTopologyTest") << "===== Testing Phase-1 Pixel Tracker geometry =====" << std::endl;
+    pathToTopologyXML = "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml";
+  } else {
+    edm::LogPrint("StandaloneTrackerTopologyTest") << "===== Testing Phase-0 Pixel Tracker geometry =====" << std::endl;
+    pathToTopologyXML = "Geometry/TrackerCommonData/data/trackerParameters.xml";
+  }
+
+  edm::LogPrint("StandaloneTrackerTopologyTest") << "parameters file" << pathToTopologyXML << std::endl;
+
+  TrackerTopology tTopoStandalone =
+      StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(pathToTopologyXML).fullPath());
+
+  // the actual test
+  testTopology(pDD, tTopo, &tTopoStandalone);
+}
+
+// ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
+void StandaloneTrackerTopologyTest::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
+  edm::ParameterSetDescription desc;
+  descriptions.addDefault(desc);
+}
+
+//define this as a plug-in
+DEFINE_FWK_MODULE(StandaloneTrackerTopologyTest);
diff --git a/CalibTracker/StandaloneTrackerTopology/test/testStandaloneTrackerTopology.sh b/CalibTracker/StandaloneTrackerTopology/test/testStandaloneTrackerTopology.sh
new file mode 100755
index 0000000000000..afa0a21421eae
--- /dev/null
+++ b/CalibTracker/StandaloneTrackerTopology/test/testStandaloneTrackerTopology.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+function die { echo $1: status $2 ; exit $2; }
+
+echo " testing CalibTracker/StandalonTrackerTopology"
+
+cmsRun ${SCRAM_TEST_PATH}/testStandaloneTrackerTopology_cfg.py || die "Failure using cmsRun testPixelTopologyMapTest_cfg.py (Phase-0 test)" $?
+cmsRun ${SCRAM_TEST_PATH}/testStandaloneTrackerTopology_cfg.py runNumber=300000 || die "Failure using cmsRun testPixelTopologyMapTest_cfg.py (Phase-1 test)" $?
+cmsRun ${SCRAM_TEST_PATH}/testStandaloneTrackerTopology_cfg.py globalTag=auto:phase2_realistic_T21 || die "Failure using cmsRun testPixelTopologyMapTest_cfg.py (Phase-2 test)" $?
diff --git a/CalibTracker/StandaloneTrackerTopology/test/testStandaloneTrackerTopology_cfg.py b/CalibTracker/StandaloneTrackerTopology/test/testStandaloneTrackerTopology_cfg.py
new file mode 100644
index 0000000000000..c4896e4e59c96
--- /dev/null
+++ b/CalibTracker/StandaloneTrackerTopology/test/testStandaloneTrackerTopology_cfg.py
@@ -0,0 +1,66 @@
+import FWCore.ParameterSet.Config as cms
+import FWCore.ParameterSet.VarParsing as VarParsing
+
+process = cms.Process("TopologyAnalysis")
+options = VarParsing.VarParsing("analysis")
+
+options.register ('globalTag',
+                  "auto:run2_data",
+                  VarParsing.VarParsing.multiplicity.singleton, # singleton or list
+                  VarParsing.VarParsing.varType.string,          # string, int, or float
+                  "GlobalTag")
+
+options.register ('runNumber',
+                  1,
+                  VarParsing.VarParsing.multiplicity.singleton, # singleton or list
+                  VarParsing.VarParsing.varType.int,          # string, int, or float
+                  "run number")
+
+options.parseArguments()
+
+###################################################################
+# Message logger service
+###################################################################
+process.load("FWCore.MessageService.MessageLogger_cfi")
+process.MessageLogger.cerr.FwkReport.reportEvery = 1
+
+###################################################################
+# Geometry producer and standard includes
+###################################################################
+process.load("Configuration.StandardSequences.Services_cff")
+
+if 'phase2' in options.globalTag:
+    process.load("Configuration.Geometry.GeometryExtended2026D98_cff")
+    process.load("Configuration.Geometry.GeometryExtended2026D98Reco_cff")
+else:
+    process.load("Configuration.StandardSequences.GeometryRecoDB_cff")
+
+####################################################################
+# Get the GlogalTag
+####################################################################
+process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
+from Configuration.AlCa.GlobalTag import GlobalTag
+process.GlobalTag = GlobalTag(process.GlobalTag, options.globalTag, '')
+
+###################################################################
+# Empty Source
+###################################################################
+process.source = cms.Source("EmptySource",
+                            firstRun = cms.untracked.uint32(options.runNumber),
+                            numberEventsInRun = cms.untracked.uint32(1),
+                            )
+
+process.maxEvents = cms.untracked.PSet(
+    input = cms.untracked.int32(1)
+)
+
+###################################################################
+# The analysis module
+###################################################################
+process.myanalysis = cms.EDAnalyzer("StandaloneTrackerTopologyTest")
+
+###################################################################
+# Path
+###################################################################
+process.p1 = cms.Path(process.myanalysis)
+

From 1d7cafbc7ae9fad0aea96c361e7ebf1de2011739 Mon Sep 17 00:00:00 2001
From: mmusich <marco.musich@cern.ch>
Date: Wed, 18 Oct 2023 18:17:16 +0200
Subject: [PATCH 2/5] Fix StandaloneTrackerTopology for split phase-2 sensors -
 In the case of the phase-2 IT there is an additional layer of hierarcy, due
 ot split sensors in Layer 1. First introduced in PR #41880

---
 .../src/StandaloneTrackerTopology.cc          | 30 +++++++++++++++----
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/CalibTracker/StandaloneTrackerTopology/src/StandaloneTrackerTopology.cc b/CalibTracker/StandaloneTrackerTopology/src/StandaloneTrackerTopology.cc
index a5f54f2330cbe..f137a07966830 100644
--- a/CalibTracker/StandaloneTrackerTopology/src/StandaloneTrackerTopology.cc
+++ b/CalibTracker/StandaloneTrackerTopology/src/StandaloneTrackerTopology.cc
@@ -38,13 +38,31 @@ namespace {
             const auto subDet = std::stoi(att_name.substr(SubdetName.size()));
             switch (subDet) {
               case PixelSubdetector::PixelBarrel:  // layer, ladder module
-                pxbVals_.layerStartBit_ = vals[0];
-                pxbVals_.ladderStartBit_ = vals[1];
-                pxbVals_.moduleStartBit_ = vals[2];
 
-                pxbVals_.layerMask_ = vals[3];
-                pxbVals_.ladderMask_ = vals[4];
-                pxbVals_.moduleMask_ = vals[5];
+                /*
+		  In the case of the phase-2 IT there is an additional layer of hierarcy, due ot split sensors in Layer 1
+		  What follows is a ugly hack, but at least is consistent with TrackerTopologyEP.cc
+		*/
+
+                if (vals.size() > 6) {  // Phase 2: extra hierarchy level for 3D sensors
+                  pxbVals_.layerStartBit_ = vals[0];
+                  pxbVals_.ladderStartBit_ = vals[1];
+                  pxbVals_.moduleStartBit_ = vals[2];
+                  pxbVals_.doubleStartBit_ = vals[3];
+
+                  pxbVals_.layerMask_ = vals[4];
+                  pxbVals_.ladderMask_ = vals[5];
+                  pxbVals_.moduleMask_ = vals[6];
+                  pxbVals_.doubleMask_ = vals[7];
+                } else {  // Phase-0 or Phase-1
+                  pxbVals_.layerStartBit_ = vals[0];
+                  pxbVals_.ladderStartBit_ = vals[1];
+                  pxbVals_.moduleStartBit_ = vals[2];
+
+                  pxbVals_.layerMask_ = vals[3];
+                  pxbVals_.ladderMask_ = vals[4];
+                  pxbVals_.moduleMask_ = vals[5];
+                }
 
                 foundPXB = true;
                 break;

From 18d7f601df2738b6f90fb2bfe63cf5fe9d66b8ac Mon Sep 17 00:00:00 2001
From: mmusich <marco.musich@cern.ch>
Date: Wed, 18 Oct 2023 18:19:00 +0200
Subject: [PATCH 3/5] add some debug printing functionalitiy to PhaseInfo
 struct

---
 .../interface/SiPixelPayloadInspectorHelper.h  | 18 ++++++++++++++++++
 .../SiPixelLorentzAngle_PayloadInspector.cc    |  2 ++
 2 files changed, 20 insertions(+)

diff --git a/CondCore/SiPixelPlugins/interface/SiPixelPayloadInspectorHelper.h b/CondCore/SiPixelPlugins/interface/SiPixelPayloadInspectorHelper.h
index ef528b43b4b10..f4f5d9de8a0a9 100644
--- a/CondCore/SiPixelPlugins/interface/SiPixelPayloadInspectorHelper.h
+++ b/CondCore/SiPixelPlugins/interface/SiPixelPayloadInspectorHelper.h
@@ -91,6 +91,15 @@ namespace SiPixelPI {
       }
     }
 
+    const void print(std::stringstream& ss) {
+      ss << "---------------------------------------------------------------\n"
+         << "                        PhaseInfo Data                       \n\n"
+         << " Phase :    " << phase() << "\n"
+         << " DetSide:   " << m_detsize << "\n"
+         << " pathToXML: " << pathToTopoXML() << "\n"
+         << "-------------------------------------------------------------\n\n";
+    }
+
     const bool isPhase1Comparison(const PhaseInfo& theOtherPhase) const {
       if (phase() == phase::one || theOtherPhase.phase() == phase::one)
         return true;
@@ -111,6 +120,15 @@ namespace SiPixelPI {
     size_t m_detsize;
   };
 
+  //============================================================================
+  // add ostream for PhaseInfo
+  inline std::ostream& operator<<(std::ostream& os, PhaseInfo phInfo) {
+    std::stringstream ss;
+    phInfo.print(ss);
+    os << ss.str();
+    return os;
+  }
+
   //============================================================================
   inline std::pair<unsigned int, unsigned int> unpack(cond::Time_t since) {
     auto kLowMask = 0XFFFFFFFF;
diff --git a/CondCore/SiPixelPlugins/plugins/SiPixelLorentzAngle_PayloadInspector.cc b/CondCore/SiPixelPlugins/plugins/SiPixelLorentzAngle_PayloadInspector.cc
index 48d0cde750b25..4a7a699c09fe7 100644
--- a/CondCore/SiPixelPlugins/plugins/SiPixelLorentzAngle_PayloadInspector.cc
+++ b/CondCore/SiPixelPlugins/plugins/SiPixelLorentzAngle_PayloadInspector.cc
@@ -287,6 +287,8 @@ namespace {
       // deal with last IOV
       const char *path_toTopologyXML = l_phaseInfo.pathToTopoXML();
 
+      edm::LogPrint("SiPixelLorentzAngleValuesComparisonPerRegion") << l_phaseInfo;
+
       auto l_tTopo =
           StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath());
 

From 366025ac5aaff02cd131e0c29468086f854faee4 Mon Sep 17 00:00:00 2001
From: mmusich <marco.musich@cern.ch>
Date: Wed, 18 Oct 2023 18:19:38 +0200
Subject: [PATCH 4/5] add a phase-2 lorentz angle comparison test

---
 .../SiPixelPlugins/test/testSiPixelLorentzAngle.sh    | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/CondCore/SiPixelPlugins/test/testSiPixelLorentzAngle.sh b/CondCore/SiPixelPlugins/test/testSiPixelLorentzAngle.sh
index 0d23aaad8c61d..935e5a85b373e 100755
--- a/CondCore/SiPixelPlugins/test/testSiPixelLorentzAngle.sh
+++ b/CondCore/SiPixelPlugins/test/testSiPixelLorentzAngle.sh
@@ -15,6 +15,17 @@ fi
 
 mkdir $W_DIR/plots_LA
 
+getPayloadData.py \
+     --plugin pluginSiPixelLorentzAngle_PayloadInspector \
+     --plot plot_SiPixelLorentzAngleValuesBarrelCompareTwoTags \
+     --tag SiPixelLorentzAngle_phase2_T19_v1_mc \
+     --tagtwo SiPixelLorentzAngle_phase2_T15_v5_mc \
+     --time_type Run \
+     --iovs '{"start_iov": "1", "end_iov": "1"}' \
+     --iovstwo '{"start_iov": "1", "end_iov": "1"}' \
+     --db Prod \
+     --test ;
+
 getPayloadData.py \
      --plugin pluginSiPixelLorentzAngle_PayloadInspector \
      --plot plot_SiPixelLorentzAngleValuesBarrelCompareTwoTags \

From 407a61c08df9d25e18e4c616efc3271aadaee43a Mon Sep 17 00:00:00 2001
From: mmusich <marco.musich@cern.ch>
Date: Wed, 18 Oct 2023 18:20:01 +0200
Subject: [PATCH 5/5] make PixelRegionContainers throw on topology mismatches

---
 CondCore/SiPixelPlugins/interface/PixelRegionContainers.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/CondCore/SiPixelPlugins/interface/PixelRegionContainers.h b/CondCore/SiPixelPlugins/interface/PixelRegionContainers.h
index 9965eb7c3d51a..4b2adef075c62 100644
--- a/CondCore/SiPixelPlugins/interface/PixelRegionContainers.h
+++ b/CondCore/SiPixelPlugins/interface/PixelRegionContainers.h
@@ -297,9 +297,8 @@ namespace PixelRegions {
       if (m_theMap.find(myId) != m_theMap.end()) {
         m_theMap[myId]->Fill(value);
       } else {
-        edm::LogError("PixelRegionContainers")
-            << detid << " :=> " << myId << " is not a recongnized PixelId enumerator! \n"
-            << m_trackerTopo->print(detid);
+        throw cms::Exception("LogicError") << detid << " :=> " << myId << " is not a recongnized PixelId enumerator! \n"
+                                           << m_trackerTopo->print(detid);
       }
     }