From ca4885f666dbdb4d3ade281b09efdf1f3ad8585b Mon Sep 17 00:00:00 2001
From: Sarah Louise Barnes <sarah.barnes@cern.ch>
Date: Thu, 22 May 2014 14:51:53 +0200
Subject: [PATCH] Added functions to map chambers to ROB's and to return the
 chambers associated with ROB's (MuonCablingData-00-00-27)

---
 .../MuonCablingData/MdtAmtMap.h               | 105 +++
 .../MuonCablingData/MdtCsmMap.h               |  30 +
 .../MuonCablingData/MdtMapBase.h              | 198 +++++
 .../MuonCablingData/MdtMezzanineType.h        |  80 ++
 .../MuonCablingData/MdtRODMap.h               |  33 +
 .../MuonCablingData/MdtSubdetectorMap.h       |  30 +
 .../MuonCablingData/MuonMDT_CablingMap.h      | 125 +++
 .../MuonCablingData/cmt/requirements          |  20 +
 .../MuonCablingData/src/MdtAmtMap.cxx         | 234 ++++++
 .../MuonCablingData/src/MdtCsmMap.cxx         |  33 +
 .../MuonCablingData/src/MdtMezzanineType.cxx  | 115 +++
 .../MuonCablingData/src/MdtRODMap.cxx         |  35 +
 .../MuonCablingData/src/MdtSubdetectorMap.cxx |  27 +
 .../src/MuonMDT_CablingMap.cxx                | 722 ++++++++++++++++++
 14 files changed, 1787 insertions(+)
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtAmtMap.h
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtCsmMap.h
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtMapBase.h
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtMezzanineType.h
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtRODMap.h
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtSubdetectorMap.h
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MuonMDT_CablingMap.h
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/cmt/requirements
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtAmtMap.cxx
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtCsmMap.cxx
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtMezzanineType.cxx
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtRODMap.cxx
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtSubdetectorMap.cxx
 create mode 100644 MuonSpectrometer/MuonCablings/MuonCablingData/src/MuonMDT_CablingMap.cxx

diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtAmtMap.h b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtAmtMap.h
new file mode 100644
index 00000000000..b560c444ace
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtAmtMap.h
@@ -0,0 +1,105 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONMDT_CABLING_MDTAMTMAP_H
+#define MUONMDT_CABLING_MDTAMTMAP_H
+
+/**
+ *
+ *  @brief Atlas MDT Tdc Mapping class
+ *  
+ *  This class implements the channel mapping of a single MDT TDC.
+ *  The mapping is between the TDC channel and the tube multilayer, layer, number in 
+ *  the offline convention
+ *
+ *  @author Stefano.Rosati@roma1.infn.it
+ *
+ **/
+
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IMessageSvc.h"
+#include "GaudiKernel/Bootstrap.h"
+
+#include <stdint.h>
+
+class MdtMezzanineType;
+class MdtIdHelper;
+
+#define CHANMAX 24
+#define NOTSET 99
+
+class MdtAmtMap {
+
+ public:
+
+  /** empty constructor */
+  MdtAmtMap(uint8_t tdcId);
+
+  /** constructor */
+  /** arguments are the mezzanine type, one channel (usually chan 0) and the */
+  /** corresponding offline informations */
+  MdtAmtMap(const MdtMezzanineType* mezType, uint8_t tdcId, uint8_t channel, 
+	    int station, int eta, int phi, 
+	    int multiLayer, int layerZero, int tubeZero, 
+	    const MdtIdHelper* helper, MsgStream* ext_log);
+
+  /** destructor */
+  ~MdtAmtMap();
+
+  /** set multilayer */
+  //bool setMultiLayer(uint8_t multiLayer) {m_multiLayer = multiLayer;}
+
+  /** add a channel */
+  bool setChannel(uint8_t channel, uint8_t layer, uint8_t tube);
+
+  /** retrieve the full information */
+  bool offlineId(uint8_t channel, int& station, int& eta, int& phi, 
+		 int& multilayer, int& layer, int& tube);
+
+  /** get the mezzanine type */
+  uint8_t mezzanineType() {return m_mezType;}
+ 
+  /** return the tdc id */
+  uint8_t moduleId() {return m_moduleId;}
+
+  /** get the multilayer (independent of the channel) */
+  int multiLayer() {return m_multiLayer;} 
+
+  /** get the layer number */
+  int layer(uint8_t channel) {return m_layer[channel];}
+
+  /** get the tube number */
+  int tube(uint8_t channel) {return m_tube[channel];}
+
+ private:
+  
+  /** Private functions */
+
+  /** initialize the channel-to-tube map */
+  bool initMap(const MdtMezzanineType* mezType, uint8_t channel, int layerZero, int tubeZero);
+
+
+  uint8_t m_moduleId;
+
+  /** tube corresponding to each tdc channel */
+  int m_station;
+  int m_eta;
+  int m_phi;
+  int m_multiLayer;
+  int m_layer[CHANMAX];
+  int m_tube[CHANMAX];
+
+  /** mezzanine type */
+  uint8_t m_mezType;
+
+  /** Output level and message service */
+  bool m_debug;
+  MsgStream* m_log;
+
+  const MdtIdHelper* m_mdtIdHelper;
+
+};
+
+#endif   // MUONMDT_CABLING_MDTAMTMAP_H
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtCsmMap.h b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtCsmMap.h
new file mode 100644
index 00000000000..72b242f0b67
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtCsmMap.h
@@ -0,0 +1,30 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONMDT_CABLING_MDTCSMMAP_H
+#define MUONMDT_CABLING_MDTCSMMAP_H
+
+#include "MuonCablingData/MdtMapBase.h"
+
+class MdtAmtMap;
+
+class MdtCsmMap : public MdtMapBase<MdtAmtMap> {
+
+ public:
+
+  MdtCsmMap(uint8_t csmId);
+  ~MdtCsmMap();
+
+  /** Set the map information */
+  bool setAmtMap(uint8_t tdcId , MdtAmtMap* amtMap);
+
+  /** Access the map information */
+  MdtAmtMap* getTdcMap(uint8_t tdcId);
+
+ private:
+
+};
+
+
+#endif   // MUONMDT_CABLING_MDTCSMMAP_H
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtMapBase.h b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtMapBase.h
new file mode 100644
index 00000000000..1aae92731ed
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtMapBase.h
@@ -0,0 +1,198 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONMDT_CABLING_MDTMAPBASE_H
+#define MUONMDT_CABLING_MDTMAPBASE_H
+
+/**********************************************
+ *
+ * @brief Base class for the mdt mapping objects
+ *
+ * @author Stefano Rosati <Stefano.Rosati@roma1.infn.it>
+ *
+ **********************************************/
+
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IMessageSvc.h"
+#include "GaudiKernel/Bootstrap.h"
+
+#include <stdint.h>
+#include <string>
+#include <map>
+
+template<class T> class MdtMapBase 
+{
+
+ public:
+
+  typedef std::map< uint8_t, T*, std::less<uint8_t> > MapOfItems;
+
+
+  /** constructor */
+  MdtMapBase(uint8_t moduleId, const std::string itemName);
+
+  /** destructor */
+  ~MdtMapBase();
+
+  /** access function */
+  uint8_t moduleId() {return m_moduleId;}
+
+  /** cleanup */
+  void clear();
+
+  /** get full map (used for testing) */
+  MapOfItems* getListOfElements() {return m_mapOfItems;}
+
+ protected:
+  
+  /** Module ID */
+  uint8_t m_moduleId;  
+  /** Output level and message service */
+  bool m_debug;
+  MsgStream* m_log;
+
+  /** set function */
+  bool addItem(uint8_t itemId, T* item);
+
+  /** get function - fast, used for online->offline conversion */
+  T* getItem(uint8_t itemId);
+
+ private:
+
+  /** name of the mapped item */
+  const std::string m_itemName;
+  
+  /** pointer to the current item */
+  T* m_currentItem;
+
+  /** map containing the items */
+  MapOfItems* m_mapOfItems;
+
+  /** private access function */
+  T* findItem(uint8_t itemId);  
+
+};
+
+
+/** default constructor */
+template<class T> MdtMapBase<T>::MdtMapBase(uint8_t moduleId, const std::string itemName) :
+  m_moduleId(moduleId), m_itemName(itemName), m_currentItem(NULL)
+     
+{ 
+  //  m_mapOfItems = new std::map< uint8_t, T*, std::less<uint8_t> >();
+  m_mapOfItems = new MapOfItems();
+
+  // initialize the message service
+  IMessageSvc* msgSvc = 0;
+  ISvcLocator* svcLocator = Gaudi::svcLocator();
+  StatusCode sc = svcLocator->service("MessageSvc", msgSvc);
+  if (sc.isFailure())   {
+    std::cout << "Can't locate the MessageSvc" << std::endl;
+  }
+  m_log = new MsgStream(msgSvc, m_itemName);
+  m_debug = (m_log->level() <= MSG::VERBOSE);
+
+}
+
+/** destructor */
+template<class T> MdtMapBase<T>::~MdtMapBase() 
+{ 
+  // deleting all the objects in the map
+  typename MapOfItems::const_iterator it = m_mapOfItems->begin(); 
+  
+  for ( ; it != m_mapOfItems->end() ; ++it ) {
+    
+    delete (*it).second;
+    
+  }
+
+  m_mapOfItems->clear();
+  delete m_mapOfItems;
+  delete m_log;
+}
+
+template<class T> void MdtMapBase<T>::clear()
+{
+  // deleting all the objects in the map
+  typename MapOfItems::const_iterator it = m_mapOfItems->begin(); 
+  
+  for ( ; it != m_mapOfItems->end() ; ++it ) {
+    
+    delete (*it).second;
+    
+  }
+  m_mapOfItems->clear();
+  m_currentItem=NULL;
+}
+
+/** Add an item to the map */
+template<class T> bool MdtMapBase<T>::addItem(uint8_t itemId, T* item) {
+
+  bool itemAdded = false;
+  
+  // check if the id are matching
+  if (itemId != item->moduleId() ) {
+    *m_log << MSG::ERROR << m_itemName << " Id different from the module one: " 
+	   << MSG::hex << (int) item->moduleId() << MSG::dec << endreq;
+    return false;
+  }
+  
+  // check if the item has been already added
+  if (m_mapOfItems->find(itemId) != m_mapOfItems->end()) {
+    *m_log << MSG::ERROR << m_itemName << " with id " << MSG::hex << (int) itemId
+	   << MSG::dec << " already added in moduleId: " << MSG::hex 
+	   << (int) m_moduleId << endreq;
+  }
+  else {
+    if (m_debug) {
+      *m_log << MSG::VERBOSE << "Adding " << m_itemName << " with id: 0x" 
+	     << MSG::hex << (int) itemId << MSG::dec << " to module 0x" 
+	     << MSG::hex << (int) m_moduleId << MSG::dec << endreq;
+    }
+    m_mapOfItems->insert(std::pair<uint8_t,T*>(itemId,item));
+    itemAdded=true;
+  }
+
+  return itemAdded;
+}
+
+
+/** return the item for a given access key (onlineId) */
+template<class T> T* MdtMapBase<T>::getItem(uint8_t itemId) {
+
+  if ( m_currentItem ) {
+    if ( itemId == m_currentItem->moduleId() ) {
+      return m_currentItem;
+    }
+    else {
+      return findItem(itemId);
+    }
+  }
+  else {
+    return findItem(itemId);
+  }
+
+}
+
+
+/** find the item in the datamember map */
+template<class T> T* MdtMapBase<T>::findItem(uint8_t itemId) {
+
+  typename MapOfItems::const_iterator it = m_mapOfItems->find(itemId);
+
+  if (it!=m_mapOfItems->end()) {
+    m_currentItem = (*it).second;
+  }
+  else {
+    //    *m_log << MSG::ERROR << m_itemName << " with Id: " << MSG::hex << itemId 
+    //   << MSG::dec << " not found " << endreq;
+    m_currentItem=NULL;
+  }
+  
+  return m_currentItem;
+}
+
+
+#endif    //  MUONMDT_CABLING_MDTMAPBASE
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtMezzanineType.h b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtMezzanineType.h
new file mode 100644
index 00000000000..5f4480a4e9e
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtMezzanineType.h
@@ -0,0 +1,80 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONMDT_CABLING_MDTMEZZANINETYPE_H
+#define MUONMDT_CABLING_MDTMEZZANINETYPE_H
+
+/**
+ *
+ *  @brief Atlas MDT Mezzanine Type
+ *  
+ *  This class describes the internal mapping of a 
+ *  generic MDT mezzanine type. It is initialized 
+ *  by the MuonMDT_CablingSvc from COOL
+ *
+ *  @author Stefano.Rosati@roma1.infn.it
+ *
+ **/
+
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IMessageSvc.h"
+#include "GaudiKernel/Bootstrap.h"
+
+#include <vector>
+
+typedef std::vector<uint8_t> MdtLayer;
+
+class MdtMezzanineType {
+
+ public:
+
+  /** constructors with arguments */
+  MdtMezzanineType(uint8_t typeId, uint8_t nOfLayers);
+
+  /** constructor only with typeId */
+  MdtMezzanineType(uint8_t typeId);
+  
+  ~MdtMezzanineType();
+
+  /** add a layer type */
+  bool addLayer(uint8_t layerNumber, MdtLayer layer);
+
+  /** return the mezzanine type */
+  uint8_t type() const {return m_type;}
+
+  /** return the number of layers */
+  uint8_t nOfLayers() const { return m_nOfLayers;}
+
+  /** return the number of tubes in each layer */
+  uint8_t nOfTubesInLayer() const { return 24/m_nOfLayers; }
+
+  /** check if a given layer has been initialized */
+  bool hasLayer(uint8_t layerNumber) const;
+
+  /** retrieve a given layer */
+  MdtLayer getLayer(int layer) const {return m_layers[layer];}
+
+  /** dump the full layers mapping */
+  void print();
+
+ private:
+
+  /** this is the generic Id of this type (as in COOL) */
+  uint8_t m_type;
+
+  /** number of layers */
+  uint8_t m_nOfLayers;
+
+  /** Array with the layers (maximum 4) */
+  MdtLayer m_layers[5];
+
+  /** Output level and message service */
+  bool m_debug;
+  MsgStream* m_log;
+  
+};
+
+#endif // MUONMDT_CABLING_MDTMEZZANINETYPE_H
+
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtRODMap.h b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtRODMap.h
new file mode 100644
index 00000000000..cb4d16a1590
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtRODMap.h
@@ -0,0 +1,33 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONMDT_CABLING_MDTRODMAP_H
+#define MUONMDT_CABLING_MDTRODMAP_H
+
+#include "MuonCablingData/MdtMapBase.h"
+
+class MdtCsmMap;
+
+class MdtRODMap : public MdtMapBase<MdtCsmMap> {
+
+ public:
+
+  MdtRODMap(uint8_t rodId);
+  ~MdtRODMap();
+
+  /** set functions */
+  bool setCsmMap( uint8_t csmId, MdtCsmMap* mdtCsmMap );
+
+  /** get functions */
+  MdtCsmMap* getCsmMap(uint8_t csmId);
+
+ private:
+
+};
+
+
+#endif
+
+
+
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtSubdetectorMap.h b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtSubdetectorMap.h
new file mode 100644
index 00000000000..9fcb931e6c4
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MdtSubdetectorMap.h
@@ -0,0 +1,30 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONMDT_CABLING_MDTSUBDETECTORMAP_H
+#define MUONMDT_CABLING_MDTSUBDETECTORMAP_H
+
+#include "MuonCablingData/MdtMapBase.h"
+
+class MdtRODMap;
+
+class MdtSubdetectorMap : public MdtMapBase<MdtRODMap> {
+
+ public:
+
+  MdtSubdetectorMap(uint8_t subdetectorId);
+  ~MdtSubdetectorMap();
+
+  /** set functions */
+  bool setRODMap(uint8_t rodId, MdtRODMap* mdtRODMap);
+
+  /** get function */
+  MdtRODMap* getRODMap(uint8_t rodId);
+  
+ private:
+
+};
+
+
+#endif    // MUONMDT_CABLING_MDTSUBDETECTORMAP
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MuonMDT_CablingMap.h b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MuonMDT_CablingMap.h
new file mode 100644
index 00000000000..cc098e2866a
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/MuonCablingData/MuonMDT_CablingMap.h
@@ -0,0 +1,125 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONMDT_CABLING_MUONMDT_CABLINGMAP_H
+#define MUONMDT_CABLING_MUONMDT_CABLINGMAP_H
+
+#include "MuonCablingData/MdtSubdetectorMap.h"
+#include "MuonCablingData/MdtRODMap.h"
+#include "MuonCablingData/MdtCsmMap.h"
+#include "MuonCablingData/MdtAmtMap.h"
+
+#include "MuonCablingData/MdtMapBase.h"
+
+#include "CLIDSvc/CLASS_DEF.h"
+
+/**********************************************
+ *
+ * @brief MDT map data object
+ *
+ * @author Stefano Rosati <Stefano.Rosati@roma1.infn.it>
+ *
+ **********************************************/
+
+class MdtMezzanineType;
+class MdtIdHelper;
+class IdentifierHash;
+
+/** typedef to implement the csm mapping to ROD */
+/* mapping from hashid to ROD identifier as Subdetector+Rodid */
+typedef std::map< IdentifierHash , uint32_t , std::less<int> > ChamberToRODMap;
+
+typedef std::map< uint32_t, std::vector<IdentifierHash> > RODToChamberMap;
+
+/** full list of ROB numbers */
+typedef std::vector<uint32_t> ListOfROD;
+
+/** typedef to implement the list of mezzanine types */
+typedef std::map< uint8_t, MdtMezzanineType*, std::less<uint8_t> > MezzanineTypes;
+
+
+class MuonMDT_CablingMap : public MdtMapBase<MdtSubdetectorMap> {
+
+ public:
+  
+  MuonMDT_CablingMap();
+  ~MuonMDT_CablingMap();
+
+  /** cleanup function */
+  bool cleanup();
+  
+  /** Set functions */
+  bool setSubdetectorMap(uint8_t subdetectorId,MdtSubdetectorMap* mdtSubdetectorMap);
+
+  /** Add a new line describing a mezzanine type */
+  bool addMezzanineLine(const int type, const int layer, const int sequence);  
+
+  /** Add a new mezzanine */
+  /** the indexes multilayer, layer, tube refer to the tube connected to the channelZero */
+  bool addMezzanine(int mezzanineType, int station, int eta, int phi,
+		    int multilayer, int layerZero, int tubeZero,
+		    int subdetectorId, int rodId, int csmId,
+		    int tdcId, int channelZero);
+
+  /** Get function */
+  MdtSubdetectorMap* getSubdetectorMap(uint8_t subdetectorId);
+
+  /** return the ROD id of a given chamber, given station, eta, phi */
+  uint32_t getROBId(int station, int eta, int phi);
+
+  /** return the ROD id of a given chamber, given the hash id */
+  uint32_t getROBId(const IdentifierHash stationCode);
+
+ /** return a vector of HashId lists for a  given list of ROD's */
+  const std::vector<IdentifierHash> getChamberHashVec(const std::vector< uint32_t> &ROBId_list);
+
+ /** return a HashId list for a  given ROD */
+  const std::vector<IdentifierHash>& getChamberHashVec(const uint32_t ROBId);
+
+  /** return the ROD id of a given chamber */
+  std::vector<uint32_t> getAllROBId();
+
+  /** return the offline id given the online id */
+  bool getOfflineId(uint8_t subdetectorId,uint8_t rodId,uint8_t csmId,
+		    uint8_t tdcId,uint8_t channelId,
+		    int& stationName, int& stationEta, int& stationPhi,
+		    int& multiLayer, int& layer, int& tube);
+
+  /** return the online id given the offline id */
+  bool getOnlineId(int stationName, int stationEta, int stationPhi,
+		   int multiLayer, int layer, int tube,
+		   uint8_t& subdetectorId, uint8_t& rodId, uint8_t& csmId,
+		   uint8_t& tdcId, uint8_t& channelId);
+
+ private:
+
+  /** private function to add a chamber to the ROD map */
+  bool addChamberToRODMap(int station, int eta, int phi, uint8_t subdetectorId, 
+			  uint8_t rodId);
+
+  /** List of mezzanine types, to be initialized from the conditions db */
+  MezzanineTypes* m_listOfMezzanineTypes;
+
+  /** map returning the RODid for a given chamber ID */
+  ChamberToRODMap* m_chamberToROD;
+
+ /** map returning a vecotr of Hashid's associated with a given ROD */
+  //new sbarnes
+   RODToChamberMap* m_RODToChamber;
+   std::vector<IdentifierHash> m_emptyIdHashVec;
+
+  /** full list of RODs */
+  ListOfROD* m_listOfROD;
+
+  /** private function to compute a station code for the chamber to ROD map */
+  bool getStationCode(int station, int eta, int phi, IdentifierHash& mdtIdHash);
+
+  /** Pointer to the MdtIdHelper */
+  const MdtIdHelper* m_mdtIdHelper;
+
+};
+
+CLASS_DEF( MuonMDT_CablingMap , 51038731 , 1 )
+
+#endif
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/cmt/requirements b/MuonSpectrometer/MuonCablings/MuonCablingData/cmt/requirements
new file mode 100644
index 00000000000..22a4eb69736
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/cmt/requirements
@@ -0,0 +1,20 @@
+package MuonCablingData
+
+#use GaudiPython v*
+#apply_pattern do_genconf
+
+use AtlasPolicy		AtlasPolicy-*
+use GaudiInterface	GaudiInterface-*	External
+use CLIDSvc             CLIDSvc-*               Control
+
+private
+use StoreGate		   StoreGate-*		Control
+use MuonIdHelpers          MuonIdHelpers-*            MuonSpectrometer
+end_private
+
+library MuonCablingData *.cxx
+
+apply_pattern installed_library
+
+
+
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtAmtMap.cxx b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtAmtMap.cxx
new file mode 100644
index 00000000000..57746c95a43
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtAmtMap.cxx
@@ -0,0 +1,234 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MuonCablingData/MdtAmtMap.h"
+#include "MuonCablingData/MdtMezzanineType.h"
+
+#include "MuonIdHelpers/MdtIdHelper.h"
+
+MdtAmtMap::MdtAmtMap(uint8_t tdcId) :
+  m_moduleId(tdcId),
+  m_station(0),
+  m_eta(0),
+  m_phi(0),
+  m_multiLayer(0),
+  m_mezType(0)
+{ }
+
+
+// constructor
+// constructor
+MdtAmtMap::MdtAmtMap(const MdtMezzanineType* mezType, uint8_t tdcId, uint8_t channel, 
+		     int station, 
+		     int eta, int phi, int multiLayer, int layer, int tube, 
+		     const MdtIdHelper* helper, MsgStream* ext_log) :
+  m_moduleId(tdcId),
+  m_station(station),
+  m_eta(eta),
+  m_phi(phi),
+  m_multiLayer(multiLayer),
+  m_mezType(mezType->type()),
+  m_log(ext_log),
+  m_mdtIdHelper(helper)
+{
+
+
+  //std::cout<<" Here we are "<<std::endl;
+  m_debug = (m_log->level() <= MSG::VERBOSE);
+
+  if (m_debug) { 
+    *m_log << MSG::VERBOSE << "Adding Tdc number: " << (int) tdcId << endreq;
+  }
+
+
+  // Initialize the values to un-filled
+  for (int i = 0 ; i<CHANMAX ; ++i) {
+    m_layer[i] = NOTSET;
+    m_tube[i] = NOTSET;
+  }
+  
+  // call the function that initializes the actual map
+  if ( initMap(mezType, channel, layer, tube) ) {
+
+    if (m_debug) {
+      *m_log << MSG::VERBOSE << "Map initialized successfully for tdc number: " << MSG::hex 
+	     << (int) tdcId << MSG::dec << endreq;
+    }
+
+  }
+  else {
+    if (m_debug) {
+      *m_log << MSG::VERBOSE << "Could not initialize completely the TDC map" << endreq;
+    }
+  }
+
+}
+
+
+// destructor
+MdtAmtMap::~MdtAmtMap() 
+{ 
+}
+
+
+/** initialize the channel-to-tube map */
+/** channel, layer, tube, contain the channel and position of the first tube */
+bool MdtAmtMap::initMap(const MdtMezzanineType* mezType, uint8_t chanZero, int layerZero, int tubeZero)
+{
+
+  bool successful = true;
+
+  if (m_debug) {
+    *m_log << MSG::VERBOSE << "Initializing the map, the mezzanine type is " 
+	   << (int) m_mezType << " with " << (int) mezType->nOfTubesInLayer() << " tubes per layer and " << (int) mezType->nOfLayers() << " layers"  
+	   << endreq;
+  }
+
+  for (uint8_t chan=0 ; chan<24 ; ++chan) {
+
+    int layer=0;
+    int tube=0;
+
+    // special case of the BME of end 2013
+    if ( mezType->type()==50 ) {
+
+      layer = 4-chan%4 ;
+      tube = tubeZero - int ( chan/4 );
+
+    }
+    else if ( mezType->type()==60 ) {
+      layer = chan%4+1 ;
+      tube = tubeZero + int ( chan/4 );
+    }
+    else {
+            
+      // calculate the layer
+      if (layerZero==1) {
+	layer=chan/(mezType->nOfTubesInLayer())+1;
+      }
+      else {
+	layer=layerZero-chan/(mezType->nOfTubesInLayer());
+      }
+      
+      std::vector<uint8_t> chanOrder = mezType->getLayer(layer);
+      
+      //    if (m_debug) {
+      //      *m_log << MSG::DEBUG << "Channel order : ";
+      //      for (int i=0 ; i< chanOrder.size() ; ++i) {
+      //	*m_log << MSG::DEBUG << (int) chanOrder[i];
+      //      }
+      //      *m_log << MSG::DEBUG << endreq;
+      //    }
+      
+      // calculate the tube
+      uint8_t localchan = chan%(mezType->nOfTubesInLayer());
+      
+      // special case of the BIR with 3 tubes overlapping to another mezzanine
+      if (chanZero==5 && m_station==7 && abs(m_eta)==3 && ((mezType->type()>40
+							    && localchan%2==0) || (mezType->type()<40 && localchan<3))) continue;
+      
+      //    *m_log << "the zero channel is: " << (int) chanZero 
+      //	   << " and the local channel is: " << (int) localchan << endreq;
+      tube=chanOrder[localchan]-chanOrder[chanZero]+tubeZero;
+
+    }
+
+
+    bool setChan = setChannel(chan,layer,tube);
+
+    if (!setChan) {
+      *m_log << MSG::ERROR << "Could not set the channel " << (int) chan << endreq;
+      successful = false;
+    }
+
+    //    m_layer[chan]=layer;
+    //m_tube[chan]=tube;
+
+  }
+
+  return successful;
+}
+
+/** setting the single channel in the map */
+bool MdtAmtMap::setChannel(uint8_t channel, uint8_t layer, uint8_t tube)
+{
+
+  bool channelSet = false;
+
+  /** set the channel if not already set */
+  if (m_layer[channel]==NOTSET && m_tube[channel]==NOTSET) {
+
+    /** Comment momentarily the output channel by channel (to be uncommented for debugging...) */
+    //
+    //if (m_debug) {
+    //
+    //*m_log << MSG::VERBOSE << "Adding channel: " << (int) channel << " connected to tube: " 
+    //     << (int) tube  << " layer: " << (int) layer << endreq;
+    //
+    //}    
+
+    // do the validity check only for the BIR (some mezzanines are exceeding the tube range)
+    //
+    if (m_station==7) {
+
+      Identifier id = m_mdtIdHelper->channelID(m_station,m_eta,m_phi,
+					       m_multiLayer,layer,tube);
+
+      if ( tube > m_mdtIdHelper->tubeMax(id) || tube < m_mdtIdHelper->tubeMin(id) ) {
+	
+	if (m_debug) {
+	  *m_log << MSG::VERBOSE << "The tube is invalid (as expected) ! not adding it..." 
+		 << endreq;
+	}
+
+	return true;
+
+      }
+
+    }
+      
+
+    m_layer[channel] = layer;
+    m_tube[channel] = tube;
+    channelSet = true;
+  }
+  /** otherwise return an error */
+  else {
+
+    *m_log << MSG::ERROR << "Error in TDC number " << m_moduleId << endreq;
+    *m_log << MSG::ERROR << "The channel: " << channel << " has been already assigned to tube: "
+	   << m_tube[channel] << " layer: " << m_layer[channel] << endreq;
+
+    channelSet = false;
+  }
+
+  return channelSet;
+}
+
+// get the offlineId
+bool MdtAmtMap::offlineId(uint8_t channel, int& station, int& eta, int& phi, 
+			  int& multilayer, int& layer, int& tube) 
+{
+
+  if ( channel >= CHANMAX ) {
+    *m_log << MSG::WARNING << "Error in tdc " << MSG::hex << (int) m_moduleId << MSG::dec    
+	   << " channel: " << MSG::hex << (int) channel << MSG::dec << " not defined!!" << endreq;  
+    return false;
+  }
+
+  if ( m_layer[channel]==NOTSET || m_tube[channel]==NOTSET ) {
+    //    *m_log << MSG::ERROR << "Error in tdc " << MSG::hex << m_moduleId << MSG::dec
+    //   << ". channel: " << MSG::hex << channel << MSG::dec << " not found" << endreq;
+    return false;
+  }
+
+  station = m_station;
+  eta = m_eta;
+  phi = m_phi;
+  multilayer = m_multiLayer;
+  layer = m_layer[channel];
+  tube = m_tube[channel];
+
+  return true;
+}
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtCsmMap.cxx b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtCsmMap.cxx
new file mode 100644
index 00000000000..f415348fcbe
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtCsmMap.cxx
@@ -0,0 +1,33 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MuonCablingData/MdtCsmMap.h"
+#include "MuonCablingData/MdtAmtMap.h"
+
+
+// default constructor
+MdtCsmMap::MdtCsmMap(uint8_t csmId):
+  MdtMapBase<MdtAmtMap>(csmId,"MdtAmtMap")
+{
+  if (m_debug) { 
+    *m_log << MSG::VERBOSE << "Adding Csm number: " << (int) csmId << endreq;
+  }
+}
+
+
+// destructor
+MdtCsmMap::~MdtCsmMap()
+{ }
+
+// add a TDC, with its Id, to the CSM
+bool MdtCsmMap::setAmtMap(uint8_t tdcId, MdtAmtMap* amtMap) {
+  bool tdcAdded = addItem(tdcId,amtMap);
+  return tdcAdded;
+}
+
+// retrieve the TDC corresponding to a given online Id
+MdtAmtMap* MdtCsmMap::getTdcMap(uint8_t tdcId)
+{
+  return getItem(tdcId);
+}
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtMezzanineType.cxx b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtMezzanineType.cxx
new file mode 100644
index 00000000000..d32a6254e7d
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtMezzanineType.cxx
@@ -0,0 +1,115 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MuonCablingData/MdtMezzanineType.h"
+
+MdtMezzanineType::MdtMezzanineType(uint8_t typeId, uint8_t nOfLayers) :
+  m_type(typeId),
+  m_nOfLayers(nOfLayers)
+{
+  // initialize the message service
+  IMessageSvc* msgSvc = 0;
+  ISvcLocator* svcLocator = Gaudi::svcLocator();
+  StatusCode sc = svcLocator->service("MessageSvc", msgSvc);
+  if (sc.isFailure())   {
+    std::cout << "Can't locate the MessageSvc" << std::endl;
+  }
+  m_log = new MsgStream(msgSvc, "MdtMezzanineType");
+  
+  m_debug = (m_log->level() <= MSG::VERBOSE);
+
+  // intialize the layer maps
+  for (int i=0 ; i<5 ; i++) {
+    m_layers[i].clear();
+  }
+  
+}
+
+MdtMezzanineType::MdtMezzanineType(uint8_t typeId) :
+  m_type(typeId),
+  m_nOfLayers(0)
+{
+  // initialize the message service
+  IMessageSvc* msgSvc = 0;
+  ISvcLocator* svcLocator = Gaudi::svcLocator();
+  StatusCode sc = svcLocator->service("MessageSvc", msgSvc);
+  if (sc.isFailure())   {
+    std::cout << "Can't locate the MessageSvc" << std::endl;
+  }
+  m_log = new MsgStream(msgSvc, "MdtMezzanineType");
+  
+  m_debug = (m_log->level() <= MSG::VERBOSE);
+
+  // intialize the layer maps
+  for (int i=0 ; i<5 ; i++) {
+    m_layers[i].clear();
+  }
+  
+}
+
+/** Destructor */
+MdtMezzanineType::~MdtMezzanineType()
+{
+  delete m_log;
+}
+
+
+/** add a layer to the mezzanine type */
+bool MdtMezzanineType::addLayer(uint8_t layerNumber, MdtLayer layer)
+{
+
+  if (layerNumber>4) {
+    *m_log << MSG::ERROR << "layer number " << layerNumber << " not accepted!" << endreq;
+    return false;
+  }
+  if (m_layers[layerNumber].size() != 0) {
+    *m_log << MSG::ERROR << "The layer number " << layerNumber 
+	   << " is not empty " << endreq;
+    return false;
+  }
+    
+  m_layers[layerNumber]=layer;
+  
+  // dump the layer content for debugging
+  if (m_debug) {
+    *m_log << MSG::VERBOSE << "Adding layer " << (int) layerNumber << " ";
+    for (unsigned int i=0 ; i<m_layers[layerNumber].size() ; ++i) {
+      *m_log << MSG::VERBOSE << (int) m_layers[layerNumber][i];
+    }
+    *m_log << MSG::VERBOSE << endreq;
+  }
+
+  m_nOfLayers++;
+
+  return true;
+}
+
+
+bool MdtMezzanineType::hasLayer(uint8_t layerNumber) const {
+
+  bool hasL = (m_layers[layerNumber].size()>0);
+  return hasL;
+}
+
+
+/** print out the mezzanine content to the MSG stream */
+void MdtMezzanineType::print() {
+  
+  std::cout << "==============================" << std::endl;
+  std::cout << "Dumping mezzanine type: " << m_type << std::endl;
+
+  for (int i=0 ; i<m_nOfLayers ; ++i) {
+    
+    std::cout << "Number of channels in layer " << i << " is: " << m_layers[i].size();
+    
+    for (std::vector<uint8_t>::const_iterator ic=m_layers[i].begin() ; 
+	 ic != m_layers[i].end() ; ++ic) {
+
+      std::cout << "Channel: " << i << "  tube number: " << (*ic) << std::endl;
+
+    }
+    
+  }
+
+}
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtRODMap.cxx b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtRODMap.cxx
new file mode 100644
index 00000000000..b285594ad1d
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtRODMap.cxx
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MuonCablingData/MdtRODMap.h"
+#include "MuonCablingData/MdtCsmMap.h"
+
+
+// constructor
+MdtRODMap::MdtRODMap(uint8_t rodId) :
+  MdtMapBase<MdtCsmMap>(rodId,"MdtCsmMap")
+{ }
+
+// destructor
+MdtRODMap::~MdtRODMap()
+{ }
+
+
+// add a CSM map to this ROD
+bool MdtRODMap::setCsmMap(uint8_t csmId, MdtCsmMap* csmMap)
+{ 
+  bool csmAdded = addItem(csmId,csmMap);
+  if (!csmAdded) {
+    *m_log << MSG::ERROR << "Could not add csm " << MSG::hex 
+	   << (int) csmId << MSG::dec << " to the MDT cabling map" << endreq;
+  }
+  return csmAdded;
+}
+
+
+// retrieve the CSM corresponding to a given online Id
+MdtCsmMap* MdtRODMap::getCsmMap(uint8_t csmId)
+{
+  return getItem(csmId);
+}
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtSubdetectorMap.cxx b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtSubdetectorMap.cxx
new file mode 100644
index 00000000000..1e1e4163dfe
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MdtSubdetectorMap.cxx
@@ -0,0 +1,27 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MuonCablingData/MdtSubdetectorMap.h"
+#include "MuonCablingData/MdtRODMap.h"
+
+MdtSubdetectorMap::MdtSubdetectorMap(uint8_t subdetectorId) :
+  MdtMapBase<MdtRODMap>(subdetectorId,"MdtRODMap")
+{ }
+
+MdtSubdetectorMap::~MdtSubdetectorMap() 
+{ }
+
+//
+// add a ROD to the cabling map
+bool MdtSubdetectorMap::setRODMap(uint8_t rodId, MdtRODMap* mdtRODMap)
+{
+  bool rodAdded = addItem(rodId,mdtRODMap);
+  return rodAdded;
+}
+
+// retrieve the ROD corresponding to a given online Id
+MdtRODMap* MdtSubdetectorMap::getRODMap(uint8_t rodId)
+{
+  return getItem(rodId);
+}
diff --git a/MuonSpectrometer/MuonCablings/MuonCablingData/src/MuonMDT_CablingMap.cxx b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MuonMDT_CablingMap.cxx
new file mode 100644
index 00000000000..e05444bef1b
--- /dev/null
+++ b/MuonSpectrometer/MuonCablings/MuonCablingData/src/MuonMDT_CablingMap.cxx
@@ -0,0 +1,722 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MuonCablingData/MuonMDT_CablingMap.h"
+#include "MuonCablingData/MdtRODMap.h"
+
+#include "MuonCablingData/MdtMezzanineType.h"
+#include "MuonIdHelpers/MdtIdHelper.h"
+
+#include "GaudiKernel/ISvcLocator.h"
+#include "StoreGate/StoreGateSvc.h"
+
+#include<cmath>
+
+MuonMDT_CablingMap::MuonMDT_CablingMap() :
+  MdtMapBase<MdtSubdetectorMap>(0,"MdtSubdetectorMap")
+{ 
+  m_chamberToROD = new ChamberToRODMap();
+  m_RODToChamber = new RODToChamberMap();
+  m_listOfROD = new ListOfROD();
+  m_listOfMezzanineTypes = new MezzanineTypes();
+
+  // initialize the message service
+
+  // retrieve the MdtIdHelper
+  ISvcLocator* svcLocator = Gaudi::svcLocator();
+  StoreGateSvc* detStore=0;
+  StatusCode sc = svcLocator->service("DetectorStore",detStore);
+  if (sc != StatusCode::SUCCESS) {
+    *m_log << MSG::ERROR << "Could not find the detctor store" << endreq;
+  }
+  sc = detStore->retrieve(m_mdtIdHelper,"MDTIDHELPER");
+  if (sc != StatusCode::SUCCESS) {
+    *m_log << MSG::ERROR << "Could not retrieve the MdtIdHelper" << endreq;
+  }
+  
+}
+
+MuonMDT_CablingMap::~MuonMDT_CablingMap()
+{ 
+  delete m_chamberToROD;
+  delete m_RODToChamber;
+  delete m_listOfROD;
+  delete m_listOfMezzanineTypes;
+}
+
+
+// cleanup function
+bool MuonMDT_CablingMap::cleanup()
+{
+  
+  return true;
+}
+
+// add a CSM map to this ROD
+bool MuonMDT_CablingMap::setSubdetectorMap(uint8_t subdetectorId, MdtSubdetectorMap* subdetectorMap)
+{ 
+  bool subdetectorAdded = addItem(subdetectorId,subdetectorMap);
+
+  if (!subdetectorAdded) {
+    *m_log << MSG::ERROR << "Could not add subdetector " << MSG::hex 
+	   << subdetectorId << MSG::dec << " to the MDT cabling map" << endreq;
+  }
+
+  return subdetectorAdded;
+}
+
+
+/** add a new line from the database, describing a mezzanine type */
+bool MuonMDT_CablingMap::addMezzanineLine(const int type, const int layer,
+					  const int sequence)
+{
+  bool added = true;
+
+  if (m_debug) {
+    *m_log << MSG::VERBOSE << "Now in MuonMDT_CablingMap::addMezzanineLine" << endreq;
+  }
+
+  MdtMezzanineType* mezType;
+  
+  MezzanineTypes::const_iterator it = m_listOfMezzanineTypes->find(type);
+
+  // check if the type already exists, if yes, retrieve it
+  bool isNewMezzanine;
+  if (it != m_listOfMezzanineTypes->end()) {
+    // if the attempt is to initialize all layers of a mezzanine already
+    // initialized, return an error message
+    if (layer==0) {
+      *m_log << MSG::ERROR << "The mezzanine type " << type 
+	     << "has been already initialized" << endreq;
+      return false;
+    }
+    mezType = it->second;
+    isNewMezzanine = false;
+  }
+  // if it does not exist, create the new type
+  else {
+    if (m_debug) {
+      *m_log << MSG::VERBOSE << "Creating a new mezzanine type: " << type << endreq;
+    }
+    mezType = new MdtMezzanineType(type);
+    // insert the new mezzanine in the map
+    m_listOfMezzanineTypes->insert(MezzanineTypes::value_type(type,mezType));
+    isNewMezzanine=true;
+  }
+  
+  int ntubes = 0;
+  int number = sequence;
+  int nOfLayers;
+  int newseq[8];
+  // now decode the sequence, up to 8 tubes per sequence
+  int tube = number%10;
+
+  while ( tube!=0 ) {
+    // add the tube to the tube sequence
+    if (ntubes>7) {
+      *m_log << MSG::ERROR << "More than 8 tubes in a layer, not possible !" 
+	     << endreq;
+      return false;
+    }
+    if (m_debug) {
+      *m_log << MSG::VERBOSE << "Adding tube number: " << tube << " to the layer " 
+	     << layer << " of mezzanine type " << type << endreq;
+    }
+    
+    newseq[ntubes]=tube;
+
+    ++ntubes;
+    number = (number-tube)/10;
+    //    tube = (int) (((number/10.)-((double)((int)(number/10.))))*10.);    
+
+    tube = number%10;
+  }
+
+  if (ntubes!=8 && ntubes!=6) {
+    *m_log << MSG::ERROR << "in type " << type 
+	   << ": number of tubes per mezzanine layer can be only 6 or 8 ! what are you doing ???";
+    return false;
+  }
+  else {
+    nOfLayers = 24/ntubes;
+    if (layer>nOfLayers) {
+      *m_log << MSG::ERROR << "The maximum number of layers for this mezzanine is: "
+	     << nOfLayers << " so you can't initialize layer: " 
+	     << layer << endreq;
+      return false;
+    }
+
+  }
+
+  if (m_debug) {
+    *m_log << MSG::VERBOSE << "Found " << ntubes << " tubes in layer " << layer << endreq;
+    *m_log << MSG::VERBOSE << "This is a " << nOfLayers 
+	   << " layers mezzanine - OK, OK..." << endreq;
+  }
+  
+  // now swap the sequence to have it as in the DB and create the real layers
+  MdtLayer newLayer;
+  for (int i=0 ; i<ntubes ; ++i) {
+    newLayer.push_back(newseq[ntubes-i-1]);
+  }
+  
+  // the mezzanine is new, add the 
+  if (isNewMezzanine) {
+    // check if the mapping is valid for all layers
+    if (layer==0) {
+      // setting all the layers of this mezzanine
+      for (int ll=1 ; ll<nOfLayers+1 ; ++ll) {
+	mezType->addLayer(ll,newLayer);
+      } 
+    }
+    else {
+      mezType->addLayer(layer,newLayer);
+    }
+  }
+  // this is an existing mezzanine so just add the single layer, but first 
+  // check that the layer does not exist yet
+  else {
+    if (mezType->hasLayer(layer)) {
+      *m_log << MSG::ERROR << "Layer: " << layer << " has been already initialized for mezzanine " << type << endreq;
+      return false;
+    }
+    mezType->addLayer(layer,newLayer);
+  }
+
+  return added;
+}
+
+
+/** Add a new mezzanine to the map */
+bool MuonMDT_CablingMap::addMezzanine( int mezType, int station, int eta, int phi,
+				       int multilayer, int layer, int tube,
+				       int subdetId, int rod, int csm, 
+				       int tdc, int chan )
+{
+
+  uint8_t mezzanineType = (uint8_t) mezType;
+  uint8_t subdetectorId = (uint8_t) subdetId;
+  uint8_t rodId = (uint8_t) rod;
+  uint8_t csmId = (uint8_t) csm;
+  uint8_t tdcId = (uint8_t) tdc;
+  uint8_t channel = (uint8_t) chan;
+
+  /** check if the subdetector exists, otherwise create it */
+  MdtSubdetectorMap* subdetectorMap = this->getSubdetectorMap(subdetectorId);
+  if (!subdetectorMap) {
+    if (m_debug) *m_log << MSG::VERBOSE << "Subdetector: 0x" << MSG::hex << (int) subdetectorId 
+	   << MSG::dec << " not found: create it" << endreq;
+  
+    subdetectorMap = new MdtSubdetectorMap(subdetectorId);
+
+    this->setSubdetectorMap(subdetectorId, subdetectorMap);
+  }
+  else {
+    if (m_debug) *m_log << MSG::VERBOSE << "Found the subdetector: 0x" << MSG::hex << (int) subdetectorId 
+	   << MSG::dec << endreq;
+  }
+
+  /** look for the correct ROD in the subdetector */
+  MdtRODMap* rodMap = subdetectorMap->getRODMap(rodId);
+  if (!rodMap) {
+    if (m_debug) *m_log << MSG::VERBOSE << "ROD with id: 0x" << MSG::hex << (int) rodId 
+	   << MSG::dec << " not found, create it" << endreq;
+    rodMap = new MdtRODMap(rodId);
+    subdetectorMap->setRODMap(rodId,rodMap);
+  }
+  else {
+    if (m_debug) *m_log << MSG::VERBOSE << "Found the RODid: 0x" << MSG::hex << (int) rodId << MSG::dec
+	   << endreq;
+  }
+  
+  /** look for the correct CSM in the ROD */
+  MdtCsmMap* csmMap = rodMap->getCsmMap(csmId);
+  if (!csmMap) {
+    if (m_debug) *m_log << MSG::VERBOSE << "CSM with id: 0x" << MSG::hex << (int) csmId 
+	   << MSG::dec << " not found, create it" << endreq;
+    csmMap = new MdtCsmMap(csmId);
+    rodMap->setCsmMap(csmId,csmMap);
+
+    //    if (!added) {
+
+    //*m_log << MSG::ERROR << "Could not add to the chamber->ROD map the station: " 
+    //     << station << " eta: " << eta
+    //     << " phi: " << phi << " subdet: 0x" << MSG::hex << (int) subdetectorId 
+    //     << MSG::dec << "rod: 0x" << MSG::hex << (int) rodId << endreq;
+      //return false;
+    //}
+
+  }
+  else {
+    if (m_debug) *m_log << MSG::VERBOSE << "Found the CSMid: 0x" << MSG::hex << (int) csmId 
+	   << MSG::dec << endreq;
+  }
+
+  // if it's a new CSM (here), update the chamber to ROD map at the same time
+  bool added = addChamberToRODMap(station,eta,phi,subdetectorId,rodId);
+  if (!added) {
+    if (m_debug) {
+      *m_log << MSG::VERBOSE << "Station already in the map !" << endreq;
+    }
+  }
+  
+  /** check that the tdc does not exist yet */
+  MdtAmtMap* amtMap = csmMap->getTdcMap(tdcId);
+  if (!amtMap) {
+    // find the corresponding mezzanine type
+    const MdtMezzanineType* mezzaType; 
+    MezzanineTypes::const_iterator it = m_listOfMezzanineTypes->find(mezzanineType);
+    if ( it != m_listOfMezzanineTypes->end() ) {
+      mezzaType = (*it).second;
+    }
+    else {
+      *m_log << MSG::ERROR << "Mezzanine Type: " << (int) mezzanineType << " not found in the list !" << endreq;
+      return false;
+    }
+
+    // create the mezzanine !
+    amtMap = new MdtAmtMap(mezzaType, tdcId, channel, station, eta, phi, multilayer,layer,tube,m_mdtIdHelper, m_log);
+    // store it in the csm
+    csmMap->setAmtMap(tdcId,amtMap);
+
+  }
+  else {
+    *m_log << MSG::ERROR << "Tdc with Id: 0x" << MSG::hex << (int) tdcId << MSG::dec 
+	   << " already found, cannot be added" << endreq;
+    return false;
+  }
+  
+  
+  return true;
+}
+
+
+
+MdtSubdetectorMap* MuonMDT_CablingMap::getSubdetectorMap(uint8_t subdetectorId) {
+  return getItem(subdetectorId);
+}
+
+
+bool MuonMDT_CablingMap::addChamberToRODMap(int station, int eta, int phi,
+					    uint8_t subdetectorId, uint8_t rodId)
+{
+  int sub = (int) subdetectorId;
+  int rod = (int) rodId;
+
+  IdentifierHash chamberId;
+  bool hashFound = getStationCode(station, eta, phi,chamberId);
+  if (!hashFound) {
+    *m_log << MSG::ERROR << "Could not found hashId for station: " << station 
+	   << " eta: " << eta << " phi: " << phi << endreq;
+    return false;
+  }
+
+  uint32_t hardId = (sub<<16) | rod;
+  if (m_debug) {
+    *m_log << MSG::VERBOSE << "Adding the chamber with Id: " << chamberId
+	   << " and subdetector+rod ID: 0x" << MSG::hex << hardId << MSG::dec << endreq;
+  }
+
+  // check if the chamber has already been put in the map
+  ChamberToRODMap::const_iterator it = m_chamberToROD->find(chamberId);
+  if ( it != m_chamberToROD->end() ) {
+    //    *m_log << MSG::ERROR << "Station with Id: " << chamberId << " already in the map !" << endreq;
+    return false;
+  }
+
+  m_chamberToROD->insert(std::pair<IdentifierHash,uint32_t>(chamberId,hardId));
+
+  //new function to do the opposite of the above
+  RODToChamberMap::iterator Rod_it = m_RODToChamber->find(hardId);
+  if ( Rod_it == m_RODToChamber->end() ) {
+    std::vector<IdentifierHash> Idvec;    
+    Idvec.push_back(chamberId);
+    m_RODToChamber->insert(std::make_pair(hardId, Idvec));
+  }
+  else{
+    Rod_it->second.push_back(chamberId);
+  }
+
+  // now check if the ROD is already in the list of ROD vector
+  bool rodInitialized = false;
+  for (unsigned int i=0 ; i<m_listOfROD->size() ; ++i) {
+    if (hardId==(*m_listOfROD)[i]) {
+      rodInitialized=true;
+    }
+  }
+  if (!rodInitialized) {
+    if (m_debug) {
+      *m_log << MSG::VERBOSE << "Adding the ROD 0x" << MSG::hex << hardId << MSG::dec
+	     << " to the list" << endreq;
+    }
+    m_listOfROD->push_back(hardId);
+  }
+
+  return true;
+}
+
+/*
+ * get an integer station code for each chamber
+ *
+ */
+bool MuonMDT_CablingMap::getStationCode(int station, int eta, int phi, 
+					IdentifierHash& mdtHashId)
+{
+  // create the station identifier
+  Identifier elementId = m_mdtIdHelper->elementID(station,eta,phi);
+
+  if(m_mdtIdHelper->get_module_hash(elementId, mdtHashId) ) {
+    *m_log << MSG::ERROR << "Could not find HashId for module: " << endreq;
+    elementId.show();
+    return false;
+  }
+  
+  return true;
+}
+
+
+
+/*
+ * return the ROBid of a given station, identified through station, eta, phi
+ *
+ */
+uint32_t MuonMDT_CablingMap::getROBId(int station, int eta, int phi)
+{
+
+  int rodId = 0;
+
+  // convert to hash id
+  IdentifierHash mdtHashId;
+  bool hashFound = getStationCode(station,eta,phi,mdtHashId);
+  if (!hashFound) {
+    *m_log << MSG::ERROR << "Could not find HashId for station: " << station 
+	   << " eta: " << eta << " phi: " << phi << endreq;
+    return rodId;
+  }
+
+  rodId = getROBId(mdtHashId);
+
+  return rodId;
+}
+
+// get the ROBid given the identifier hash
+uint32_t MuonMDT_CablingMap::getROBId(const IdentifierHash stationCode)
+{
+  int rodId = 0;
+
+  ChamberToRODMap::const_iterator it = m_chamberToROD->find(stationCode);
+  if (it != m_chamberToROD->end()) {
+    rodId = it->second;
+  }
+  else {
+    *m_log << MSG::ERROR << "Rod ID not found !" << endreq;
+    return 0;
+  }
+
+  return rodId;
+}
+
+const std::vector<IdentifierHash>& MuonMDT_CablingMap::getChamberHashVec(const uint32_t ROBId)
+{
+  RODToChamberMap::const_iterator Rob_it = m_RODToChamber->find(ROBId);
+  if(Rob_it != m_RODToChamber->end()) {
+    return Rob_it->second;
+  }
+  else {
+    *m_log << MSG::ERROR << "Rod ID not found !" << endreq;
+    return m_emptyIdHashVec;
+  }
+}
+
+const std::vector<IdentifierHash> MuonMDT_CablingMap::getChamberHashVec(const std::vector< uint32_t> &ROBId_list)
+{
+   std::vector<IdentifierHash> HashVec;
+  
+  for(unsigned int i = 0; i< ROBId_list.size(); ++i)
+    {
+      RODToChamberMap::const_iterator Rob_it = m_RODToChamber->find(ROBId_list[i]);
+      if(Rob_it != m_RODToChamber->end()) {
+	HashVec.insert(HashVec.end(), Rob_it->second.begin(), Rob_it->second.end());
+      }
+      else {
+	*m_log << MSG::WARNING << "Rod ID "<<ROBId_list[i]<<" not found, continuing with the rest of the ROBId" << endreq;
+      }
+
+    }
+  return HashVec;
+}
+
+/*
+ * get the full list of ROBid
+ *
+ */
+std::vector<uint32_t> MuonMDT_CablingMap::getAllROBId() 
+{
+  return *m_listOfROD;
+}
+
+
+
+/*
+ *
+ * translate an online Id into an offline Id
+ *
+ */
+bool MuonMDT_CablingMap::getOfflineId(uint8_t subdetectorId,
+				      uint8_t rodId,
+				      uint8_t csmId,
+				      uint8_t tdcId,
+				      uint8_t channelId,
+				      int& stationName, int& stationEta, int& stationPhi,
+				      int& multiLayer, int& layer, int& tube)
+{
+  
+  // get the subdetector
+  MdtSubdetectorMap* subdetectorMap = this->getSubdetectorMap(subdetectorId);
+  if (!subdetectorMap) {
+    *m_log << MSG::WARNING << "Subdetector: 0x" << MSG::hex << (int) subdetectorId << MSG::dec 
+	   << " not found in the map" << endreq;
+    return false;
+  }
+  // get the rod
+  MdtRODMap* rodMap = subdetectorMap->getRODMap(rodId);
+  if (!rodMap) {
+    *m_log << MSG::WARNING << "MROD: 0x" << MSG::hex << (int) rodId << MSG::dec 
+	   << " not found in the map of subdetector: 0x" << MSG::hex << (int) subdetectorId 
+	   << MSG::dec << endreq;
+    return false;
+  }
+  // retrieve the csm
+  MdtCsmMap* csmMap = rodMap->getCsmMap(csmId);
+  if (!csmMap) {
+    *m_log << MSG::WARNING << "CSM: 0x" << MSG::hex << (int) csmId << MSG::dec 
+	   << " not found in MROD: 0x" << MSG::hex << (int) rodId 
+	   << MSG::dec << " of subdetector: 0x" << MSG::hex << (int) subdetectorId << MSG::dec << endreq;
+    return false;
+  }  
+  // retrieve the tdc
+  MdtAmtMap* amtMap;
+  // if it's the dummy TDC (i.e. the 0xff used to convert the full station)
+  
+ if (tdcId==0xff && channelId==0xff) {
+
+   std::map<uint8_t, MdtAmtMap*, std::less<uint8_t> >* listOfAmt = csmMap->getListOfElements();
+   std::map<uint8_t, MdtAmtMap*, std::less<uint8_t> >::const_iterator it_amt = listOfAmt->begin();
+
+
+   for ( ; it_amt != listOfAmt->end() ; ++it_amt) {
+     
+     // get the second tdc of that chamber
+     amtMap = (*it_amt).second;
+     
+     if (!amtMap) {
+       *m_log << MSG::WARNING << "CSM: 0x" << MSG::hex << (int) csmId 
+	      << MSG::dec << " of MROD: 0x" << MSG::hex << (int) rodId << MSG::dec 
+	      << " subdetector: 0x" << MSG::hex << (int) subdetectorId << MSG::dec  
+	      << " not identified !!" <<   endreq;
+       return false;
+     }
+     
+     channelId=0;
+     
+     bool foundTdc = amtMap->offlineId(channelId, stationName, stationEta, stationPhi, 
+				       multiLayer, layer, tube);
+   
+     if (foundTdc) return true;
+   }
+
+   // if no channel 0 has been found, there must be an error !!
+   return false;
+
+ } 
+ 
+ else {
+   
+   amtMap = csmMap->getTdcMap(tdcId);
+   if (!amtMap) {
+     *m_log << MSG::WARNING << "Tdc: 0x" << MSG::hex << (int) tdcId << MSG::dec 
+	     << " not found in CSM: 0x" << MSG::hex << (int) csmId 
+	     << MSG::dec << " of MROD: 0x" << MSG::hex << (int) rodId << MSG::dec 
+	     << " subdetector: 0x" << MSG::hex << (int) subdetectorId << MSG::dec << endreq;
+      return false;
+    }
+
+  }
+  
+  // retrieve the full information
+  bool found = amtMap->offlineId(channelId, stationName, stationEta, stationPhi, 
+				 multiLayer, layer, tube);
+  
+  if (!found) {
+    
+    //    *m_log << MSG::WARNING << "Channel: 0x" << MSG::hex << (int) channelId << MSG::dec  
+    //   << " Tdc: 0x" << MSG::hex << (int) tdcId << MSG::dec 
+    //   << " not found in CSM: 0x" << MSG::hex << (int) csmId 
+    //   << MSG::dec << " of MROD: 0x" << MSG::hex << (int) rodId << MSG::dec 
+    //   << " subdetector: 0x" << MSG::hex << (int) subdetectorId << MSG::dec << endreq;
+    return false;
+  }
+
+  if (m_debug) {
+
+    *m_log << MSG::VERBOSE << "Channel: 0x" << MSG::hex << (int) channelId << MSG::dec  
+	   << " Tdc: 0x" << MSG::hex << (int) tdcId << MSG::dec 
+	   << " CSM: 0x" << MSG::hex << (int) csmId 
+	   << MSG::dec << " of MROD: 0x" << MSG::hex << (int) rodId << MSG::dec 
+	   << " subdetector: 0x" << MSG::hex << (int) subdetectorId 
+	   << MSG::dec << endreq;
+
+    *m_log << MSG::VERBOSE << "Mapped to: Station: " << stationName << " eta: " << stationEta
+	   << " phi: " << stationPhi << " multiLayer: " << multiLayer 
+	   << " layer: " << layer << " tube: " << tube << endreq;
+  }
+
+  return true;
+}
+
+
+/** get the online id from the offline id */
+bool MuonMDT_CablingMap::getOnlineId(int stationName, int stationEta, int stationPhi,
+				     int multiLayer, int layer, int tube,
+				     uint8_t& subdetectorId, uint8_t& rodId, 
+				     uint8_t& csmId, uint8_t& tdcId, 
+				     uint8_t& channelId)
+{
+
+  
+  // get the station ROD from the ROD map
+  int module = getROBId(stationName, stationEta, stationPhi);
+
+  rodId = (module & 0xff);
+  subdetectorId = (module>>16) & 0xff;
+
+  if (m_debug) {
+
+    *m_log << MSG::VERBOSE << "Station: " << stationName << " eta: " << stationEta 
+	   << " phi: " << stationPhi << " mapped to subdet: 0x" << MSG::hex << subdetectorId
+	   << MSG::dec << " rodId: 0x" << MSG::hex << rodId << MSG::dec << endreq;
+
+  }
+  
+  // get correct subdetector and rod
+
+  // get the subdetector
+  MdtSubdetectorMap* subdetectorMap = this->getSubdetectorMap(subdetectorId);
+  if (!subdetectorMap) {
+    *m_log << MSG::WARNING << "Subdetector: 0x" << MSG::hex << (int) subdetectorId 
+	   << MSG::dec << " not found in the map" << endreq;
+    return false;
+  }
+  // get the rod
+  MdtRODMap* rodMap = subdetectorMap->getRODMap(rodId);
+  if (!rodMap) {
+    *m_log << MSG::WARNING << "MROD: 0x" << MSG::hex << (int) rodId << MSG::dec 
+	   << " not found in the map of subdetector: 0x" << MSG::hex 
+	   << (int) subdetectorId 
+	   << MSG::dec << endreq;
+    return false;
+  }
+  
+
+  // loop on the CSMs of this ROD
+  std::map<uint8_t, MdtCsmMap*, std::less<uint8_t> >* listOfCsm;
+  listOfCsm = rodMap->getListOfElements();
+  
+  std::map<uint8_t, MdtCsmMap*, std::less<uint8_t> >::const_iterator it_csm;
+ 
+  std::map<uint8_t, MdtAmtMap*, std::less<uint8_t> >* listOfAmt;
+  std::map<uint8_t, MdtAmtMap*, std::less<uint8_t> >::const_iterator it_amt;
+
+  if (m_debug) {
+    *m_log << MSG::VERBOSE << "number of csm to loop: " << listOfCsm->size()
+	   << endreq;
+  }
+
+  for ( it_csm = listOfCsm->begin(); it_csm != listOfCsm->end() ; ++it_csm) {
+    
+    csmId = ((*it_csm).second)->moduleId();
+    
+    if (m_debug) {
+      *m_log << MSG::VERBOSE << "Csm number: " << MSG::hex << (int) csmId << MSG::dec << endreq;
+    }
+
+    listOfAmt = ((*it_csm).second)->getListOfElements();
+
+    //    std::cout << "number of amt to loop: " << listOfAmt->size() << std::endl;
+
+
+    for (it_amt=listOfAmt->begin() ; it_amt !=listOfAmt->end() ; ++it_amt) {
+
+      int test_station=0;
+      int test_eta=0;
+      int test_phi=0;
+      int test_multi=0;
+      int test_layer=0;
+      int test_tube=0;
+      
+      MdtAmtMap* amtMap = (*it_amt).second;
+
+      tdcId = amtMap->moduleId();
+
+      //  std::cout << "Tdc number: 0x" << std::hex << (int) tdcId << std::dec << std::endl;
+
+      // convert channel 0
+      bool found = amtMap->offlineId(0,test_station,test_eta,test_phi,
+				     test_multi,test_layer,test_tube);
+      if (!found) {
+
+	found = amtMap->offlineId(23,test_station,test_eta,test_phi,
+				     test_multi,test_layer,test_tube);
+	if (!found) {
+	  if (m_debug) {
+	    *m_log << MSG::VERBOSE << "Error converting offline->online" << endreq;
+	  }
+	  return false;
+	}
+      }
+
+      //      std::cout << "Test from channel 0: " << test_station << " " << test_eta
+      //	<< " " << test_phi << " " << test_multi << std::endl;
+      
+      //std::cout << "I am looking for: " << stationName << " " << stationEta
+      //	<< " " << stationPhi << " " << multiLayer << std::endl;
+      
+      
+
+      // if it's not the right station, exit from the loop 
+      if (test_station == stationName && test_eta == stationEta &&
+	  test_phi == stationPhi && test_multi==multiLayer ) {
+	
+	//	std::cout << "found !! " << std::endl;
+	// look for the correct channel
+	for (int i=0 ; i<24 ; ++i) {
+	  found = amtMap->offlineId(i,test_station,test_eta,test_phi,
+				    test_multi,test_layer,test_tube);
+	  //	  if (!found) {
+	  //  *m_log << MSG::WARNING << "Error converting offline->online, looping on TDC channels" << endreq;
+	  // return false;
+	  //}
+	  
+	  //  std::cout << "test_layer: " << test_layer << " test_tube: " << test_tube
+	  ///    << std::endl;
+	  //std::cout << "I am looking for: " << layer << "  tube: " << tube
+	  //    << std::endl;
+
+	  // if it's the good one, then set the channel
+	  if (found && test_layer==layer && test_tube==tube) {
+	    
+	    channelId = i;
+	    return true;
+	  }
+	}
+      }  // if to check that it's the right station
+
+
+    }
+
+  }
+
+
+  return false;
+}
-- 
GitLab