From 0dd94efd191e202a06be8c3fee86add50425f9f0 Mon Sep 17 00:00:00 2001
From: Scott Snyder <scott.snyder@cern.ch>
Date: Thu, 28 Jun 2012 16:27:29 +0200
Subject: [PATCH] Update for clhep 2 (LArGeoHec-00-00-38)

---
 .../LArGeoModel/LArGeoHec/GNUmakefile         |   7 +
 .../LArGeoHec/HEC2WheelConstruction.h         |  39 +
 .../LArGeoHec/HECClampConstruction.h          |  45 ++
 .../LArGeoHec/HECModuleConstruction.h         |  42 ++
 .../LArGeoHec/HECWheelConstruction.h          |  45 ++
 .../LArGeoModel/LArGeoHec/cmt/requirements    |  22 +
 .../LArGeoModel/LArGeoHec/doc/MainPage.h      |  19 +
 .../LArGeoHec/src/HEC2WheelConstruction.cxx   | 260 +++++++
 .../LArGeoHec/src/HECClampConstruction.cxx    | 459 ++++++++++++
 .../LArGeoHec/src/HECModuleConstruction.cxx   | 706 ++++++++++++++++++
 .../LArGeoHec/src/HECWheelConstruction.cxx    | 283 +++++++
 11 files changed, 1927 insertions(+)
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/GNUmakefile
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HEC2WheelConstruction.h
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECClampConstruction.h
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECModuleConstruction.h
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECWheelConstruction.h
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/cmt/requirements
 create mode 100644 LArCalorimeter/LArGeoModel/LArGeoHec/doc/MainPage.h
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/src/HEC2WheelConstruction.cxx
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/src/HECClampConstruction.cxx
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/src/HECModuleConstruction.cxx
 create mode 100755 LArCalorimeter/LArGeoModel/LArGeoHec/src/HECWheelConstruction.cxx

diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/GNUmakefile b/LArCalorimeter/LArGeoModel/LArGeoHec/GNUmakefile
new file mode 100755
index 00000000000..a577fb56798
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/GNUmakefile
@@ -0,0 +1,7 @@
+# Packages needed to compile this one:
+
+PACKAGES := DetectorDescription/GeoModel/GeoModelKernel
+PACKAGES += LArCalorimeter/LArGeoModel/LArGeoCode
+
+# Standardized compilation commands.
+include $(MAKEPACKAGE)
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HEC2WheelConstruction.h b/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HEC2WheelConstruction.h
new file mode 100755
index 00000000000..1a9d302317e
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HEC2WheelConstruction.h
@@ -0,0 +1,39 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file HEC2WheelConstruction.h
+ *
+ * @brief Declaration of HEC2WheelConstruction class
+ *
+ * $Id: HEC2WheelConstruction.h,v 1.2 2007-11-27 20:02:16 fincke Exp $
+ */
+#ifndef __HEC2WheelConstruction_H__
+#define __HEC2WheelConstruction_H__
+
+class GeoFullPhysVol;
+
+namespace LArGeo 
+{
+  /** @class LArGeo::HEC2WheelConstruction
+      @brief GeoModel description of LAr HEC
+
+      The geometry is built and placed within HEC envelope which is implemented
+      by LArGeoEndcap.
+   */
+  class HEC2WheelConstruction 
+    {
+    public:
+      HEC2WheelConstruction();
+      virtual ~HEC2WheelConstruction();
+      // Get the envelope containing this detector.
+      GeoFullPhysVol* GetEnvelope(bool fullGeo, bool posZSide=true);
+      
+    private:
+      GeoFullPhysVol* m_physiHEC;
+      bool	      m_posZSide;
+    };
+  
+}
+#endif // __HEC2WheelConstruction_H__
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECClampConstruction.h b/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECClampConstruction.h
new file mode 100755
index 00000000000..fa44c4e9823
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECClampConstruction.h
@@ -0,0 +1,45 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// HECClampConstruction.h
+// 
+// Construct Outer Conneting Bars and Rails for HEC
+// and apply them
+//
+// M. Fincke  25.Oct2007
+//
+#ifndef __HECClampConstruction_H__
+#define __HECClampConstruction_H__
+
+#include <string>
+
+class GeoFullPhysVol;
+class GeoPhysVol;
+
+namespace LArGeo 
+{
+
+  class HECClampConstruction 
+    {
+    public:
+      HECClampConstruction(bool front=true, bool posZSide=true);
+      virtual ~HECClampConstruction();
+      void AddClamps(GeoFullPhysVol*physiHECWheel);      
+
+
+    private:
+      GeoPhysVol* GetClampingBar(bool rail=false,bool left=false);
+      bool     m_front;
+      bool     m_rail;
+      bool     m_left;
+      bool     m_posZSide;
+      int      m_moduleNumber   ;
+      double   m_moduleRouter   ;
+      double   m_modulePhistart ;
+      double   m_rOuter         ;
+      double   m_moduleDeltaPhi ;
+    };
+  
+}
+#endif // __HECClampConstruction_H__
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECModuleConstruction.h b/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECModuleConstruction.h
new file mode 100755
index 00000000000..799c7911f8f
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECModuleConstruction.h
@@ -0,0 +1,42 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file HECModuleConstruction.h
+ *
+ * @brief Declaration of HECModuleConstruction class
+ *
+ * $Id: HECModuleConstruction.h,v 1.1 2007-10-09 16:43:20 fincke Exp $
+ */
+#ifndef __HECModuleConstruction_H__
+#define __HECModuleConstruction_H__
+
+class GeoFullPhysVol;
+
+namespace LArGeo 
+{
+  /** @class LArGeo::HECModuleConstruction
+      @brief GeoModel description of LAr HECModule
+
+      The geometry is built and placed within HECModule envelope which is implemented
+      by LArGeoEndcap.
+   */
+  class HECModuleConstruction 
+    {
+    public:
+      HECModuleConstruction(bool threeBoards=false, bool frontWheel=true, bool tb=false, int tbyear=2002);
+      virtual ~HECModuleConstruction();
+      // Get the envelope containing this detector.
+      GeoFullPhysVol* GetEnvelope();
+      
+    private:
+      GeoFullPhysVol* m_physiHECModule;
+      bool	      m_threeBoards;
+      bool     	      m_frontWheel;
+      bool	      m_tb;
+      int 	      m_tbyear;
+    };
+  
+}
+#endif // __HECModuleConstruction_H__
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECWheelConstruction.h b/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECWheelConstruction.h
new file mode 100755
index 00000000000..360a58ccf49
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/LArGeoHec/HECWheelConstruction.h
@@ -0,0 +1,45 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// HECWheelConstruction.h
+//
+// Construct an Atlas HEC Wheel (Front or Rear)
+// 
+// Oct 2007 M. Fincke
+//
+
+#ifndef __HECWheelConstruction_H__
+#define __HECWheelConstruction_H__
+
+#include <string>
+
+class GeoFullPhysVol;
+
+namespace LArGeo 
+{
+
+  class HECWheelConstruction 
+    {
+    public:
+      HECWheelConstruction(bool fullGeo, std::string wheelType="front", bool threeBoards=false, bool posZSide=true);
+      virtual ~HECWheelConstruction();
+
+      // Get the envelope containing this detector.
+      GeoFullPhysVol* GetEnvelope();
+      
+    private:
+      GeoFullPhysVol* m_physiHECWheel;
+      bool	      m_posZSide;
+      bool	      m_rail;
+      bool	      m_left;
+      bool	      m_threeBoards;
+      bool	      m_frontWheel;
+      std::string     m_wheelType;
+      double          m_clampLength;
+      double          m_clampAngle;
+      bool            m_fullGeo;  // true->FULL, false->RECO
+    };
+  
+}
+#endif // __HECWheelConstruction_H__
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/cmt/requirements b/LArCalorimeter/LArGeoModel/LArGeoHec/cmt/requirements
new file mode 100755
index 00000000000..1f86956925c
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/cmt/requirements
@@ -0,0 +1,22 @@
+package LArGeoHec
+
+author Pavol Stavina <stavina@mppmu.mpg.de>
+
+# This package defines the geometry for the ATLAS liquid-argon
+# hadronic endcap calorimeter.
+
+use AtlasPolicy    AtlasPolicy-*
+
+# Build the library (and export the headers)
+library LArGeoHec *.cxx
+apply_pattern installed_library
+
+private
+use AthenaKernel   AthenaKernel-*      Control
+use StoreGate      StoreGate-*         Control
+use AtlasCLHEP     AtlasCLHEP-*        External
+use GaudiInterface GaudiInterface-*    External
+use GeoModelKernel GeoModelKernel-*    DetectorDescription/GeoModel
+use RDBAccessSvc   RDBAccessSvc-*      Database/AthenaPOOL
+use GeoModelInterfaces    GeoModelInterfaces-*       DetectorDescription/GeoModel
+use GeoModelUtilities     GeoModelUtilities-*        DetectorDescription/GeoModel
\ No newline at end of file
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/doc/MainPage.h b/LArCalorimeter/LArGeoModel/LArGeoHec/doc/MainPage.h
new file mode 100644
index 00000000000..f885a380e71
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/doc/MainPage.h
@@ -0,0 +1,19 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+
+
+@mainpage
+
+GeoModel description of LAr HEC
+
+--------------------------------
+  REQUIREMENTS 
+--------------------------------
+
+@include requirements
+@htmlinclude used_packages.html 
+
+*/
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/src/HEC2WheelConstruction.cxx b/LArCalorimeter/LArGeoModel/LArGeoHec/src/HEC2WheelConstruction.cxx
new file mode 100755
index 00000000000..8bfa24300be
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/src/HEC2WheelConstruction.cxx
@@ -0,0 +1,260 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////////////
+//  HEC2WheelConstruction.cxx 
+// 
+//  This should only be TEMPORARY!
+//  It is a way of placing the individual HEC Wheels into the Endcap cryostat.
+//  (Needs a modificatio in LArGeoEndcap/EndcpcrypstatConstruction, where 
+//   the present HECConstruction get the old HEC; replace HECConstruction by 
+//   HEC2WheelConstruction there and you should get this construciotnof 2 separate wheels.)
+//  What we really want is placing the HEC wheels individually into the Endcap cryostat.    
+//  
+//  When placing the wheel we have to take into account that they are fastened
+//  to the cryostat at their rear ends. 
+//  This means that, longitudinally, they will shrink from front to back as the cryostat
+//  cools down. 
+//  The number given in the database at the moment (Oct 2007) are still the warm
+//  dimensions!... 
+//  
+//  In here, use hard coded numbers for the placement (outch!....)
+//  but then this is hopefully only very, very temporary!!!!
+//   
+//  mgf.
+//
+/////////////////////////////////////////////////////////////////////
+#include "LArGeoHec/HEC2WheelConstruction.h"
+#include "LArGeoHec/HECWheelConstruction.h"
+
+#include "GeoModelKernel/GeoElement.h"  
+#include "GeoModelKernel/GeoMaterial.h"  
+#include "GeoModelKernel/GeoFullPhysVol.h"  
+#include "GeoModelKernel/GeoPhysVol.h"  
+#include "GeoModelKernel/GeoVPhysVol.h"  
+#include "GeoModelKernel/GeoLogVol.h"  
+#include "GeoModelKernel/GeoPcon.h"  
+#include "GeoModelKernel/GeoTubs.h"  
+#include "GeoModelKernel/GeoNameTag.h"  
+#include "GeoModelKernel/GeoTransform.h"  
+#include "GeoModelKernel/GeoAlignableTransform.h"  
+#include "GeoModelKernel/GeoIdentifierTag.h"  
+#include "GeoModelKernel/GeoSerialTransformer.h"
+#include "GeoModelKernel/GeoSerialIdentifier.h"
+#include "GeoModelKernel/GeoXF.h"
+#include "CLHEP/Geometry/Transform3D.h" 
+#include "CLHEP/Vector/Rotation.h" 
+#include "CLHEP/Units/PhysicalConstants.h"
+#include "CLHEP/GenericFunctions/Variable.hh"
+#include "StoreGate/StoreGateSvc.h"
+#include "StoreGate/DataHandle.h"
+#include "GeoModelInterfaces/AbsMaterialManager.h"
+#include "GeoModelInterfaces/StoredMaterialManager.h"
+#include "GeoModelUtilities/StoredPhysVol.h"
+#include "GeoModelUtilities/StoredAlignX.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+#include "GeoModelUtilities/GeoDBUtils.h"
+#include "RDBAccessSvc/IRDBAccessSvc.h"
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "RDBAccessSvc/IRDBRecordset.h"
+//#include "RDBAccessSvc/IRDBQuery.h"
+#include "GeoModelInterfaces/IGeoModelSvc.h"
+
+#include <string>
+#include <cmath>
+#include <iostream>
+
+
+using CLHEP::cm;
+using CLHEP::mm;
+using CLHEP::deg;
+using HepGeom::Transform3D;
+using HepGeom::Translate3D;
+
+
+//Constructor
+LArGeo::HEC2WheelConstruction::HEC2WheelConstruction():
+  m_physiHEC(0),
+  m_posZSide(false)
+{
+
+}
+
+//~Destructor
+LArGeo::HEC2WheelConstruction::~HEC2WheelConstruction() 
+{;}
+
+
+GeoFullPhysVol* LArGeo::HEC2WheelConstruction::GetEnvelope(bool fullGeo, bool posZSide)
+{
+  m_posZSide = posZSide;
+
+  if(m_physiHEC) return m_physiHEC->clone();
+
+  // Get access to the material manager:
+  
+  ISvcLocator *svcLocator = Gaudi::svcLocator();
+
+  MsgStream log(Athena::getMessageSvc(),"HEC2WheelConstruction " );
+  
+
+  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++" << endreq;
+  log << MSG::DEBUG << "+                                                   +" << endreq;
+  log << MSG::DEBUG << "+         Start of HEC2Wheel GeoModel definition    +" << endreq;
+  log << MSG::DEBUG << "+                                                   +" << endreq;
+  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++" << endreq;
+
+
+  StoreGateSvc *detStore;
+  if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) {
+    throw std::runtime_error("Error in HEC2WheelConstruction, cannot access DetectorStore");
+  }
+ 
+  DataHandle<StoredMaterialManager> materialManager;
+  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) {
+    throw std::runtime_error("Error in HEC2WheelConstruction, cannot access Material Manager");
+  }
+
+  StatusCode sc;
+  IRDBAccessSvc *pAccessSvc;
+  sc=svcLocator->service("RDBAccessSvc",pAccessSvc);
+  if (sc != StatusCode::SUCCESS) {
+    throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
+  }
+
+  IGeoModelSvc *geoModel;
+  sc = svcLocator->service ("GeoModelSvc",geoModel);
+  if (sc != StatusCode::SUCCESS) {
+    throw std::runtime_error ("Cannot locate GeoModelSvc!!");
+  }
+
+  std::string AtlasVersion = geoModel->atlasVersion();
+  std::string LArVersion = geoModel->LAr_VersionOverride();
+  std::string detectorKey  = LArVersion.empty() ? AtlasVersion : LArVersion;
+  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
+
+  IRDBRecordset_ptr hadronicEndcap = pAccessSvc->getRecordsetPtr("HadronicEndcap",detectorKey, detectorNode); 
+  if(hadronicEndcap->size()>0)
+    log << MSG::ALWAYS << "Using numbers from HadronicEndcap tag:  " << hadronicEndcap->tagName() << endreq;
+  else
+    throw std::runtime_error("Error in HECConstruction:  hadronicEendcap not found");
+
+  IRDBRecordset_ptr hecLongitudinalBlock = pAccessSvc->getRecordsetPtr("HecLongitudinalBlock",detectorKey, detectorNode); 
+  if(hecLongitudinalBlock->size()>0) 
+    log << MSG::ALWAYS << "Using numbers from HecLongitudinalBlock tag:  " << hecLongitudinalBlock->tagName() << endreq;
+  else 
+    throw std::runtime_error("Error in HECConstruction:  hecLongitudinalBlock not found");
+
+  IRDBRecordset_ptr larPosition  =  pAccessSvc->getRecordsetPtr("LArPosition",detectorKey, detectorNode);
+  if (larPosition->size()==0 ) {
+    larPosition = pAccessSvc->getRecordsetPtr("LArPosition", "LArPosition-00");
+    if (larPosition->size()==0 ) {
+      throw std::runtime_error("Error, no lar position table in database!");
+    }
+  }
+
+  // This is a start for letting everyhting go cold (shrinkCold = 1.0 means warm; = 0.997 means cold)
+  double shrinkCold            = 1.0 ; 
+
+  double rInner1               = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMN")*cm;
+  double rInner2               = shrinkCold * (*hecLongitudinalBlock)[1]->getDouble("BLRMN")*cm;
+  double rOuter                = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
+  double wheelGap              = shrinkCold * (*hadronicEndcap)[0]->getDouble("GAPWHL")*cm;
+
+  
+  GeoMaterial *LAr  = materialManager->getMaterial("std::LiquidArgon");
+  if (!LAr) throw std::runtime_error("Error in HEC2WheelConstruction, std::LiquidArgon is not found.");
+
+  GeoPcon*           solidHEC;     //pointer to the solid HEC
+  const GeoLogVol*   logicHEC;     //pointer to the logical HEC
+  GeoFullPhysVol*    physiHEC;     //pointer to the physical HEC
+
+  
+
+  // YIKES! Hard-coded numbers!!!
+
+  if (rOuter<2100.*mm) rOuter  = shrinkCold *2130*mm;  // Needs fixing in database to make room for HEC Clamping bars! 
+                                           // Caution: We'll need 2 Routers - One for Wheel, one for Module!
+
+  double     HEC1length = shrinkCold * 816.5*mm;
+  double     HEC2length = shrinkCold * 961.0*mm;
+  double     TotalWarmHEC = HEC1length + wheelGap + HEC2length ;  // For the moment, this defines the HEC rear face  
+  double     TotalHECLength = TotalWarmHEC;                      // (where is that -cold- in the cryostat?
+
+  double     zCoordinate[4];
+  zCoordinate[0]=shrinkCold * 0.0*cm; 
+  zCoordinate[1]=shrinkCold * 28.05*cm; 
+  zCoordinate[2]=shrinkCold * 28.051*cm; 
+  zCoordinate[3]=shrinkCold * (181.9*cm+4.0*mm); // JFB, MGF:  more room in the mother fiducal volume for misalignment.
+ // 37.2, 47.5, 203 cm for R
+
+  solidHEC = new GeoPcon(0., 2.*M_PI);
+  for (int i=0; i< 4; i++) 
+    {
+      if (i<2) solidHEC->addPlane(zCoordinate[i],rInner1 - shrinkCold*1.*mm,rOuter);
+      else     solidHEC->addPlane(zCoordinate[i],rInner2 - shrinkCold*1.*mm,rOuter);
+   }
+  
+  std::string hecName = "LAr::HEC::Mother";
+  logicHEC = new GeoLogVol(hecName, solidHEC , LAr);
+  physiHEC = new GeoFullPhysVol(logicHEC);
+  
+  //--- Make the Front Wheel alignable:
+
+  const IRDBRecord *posHec1 = GeoDBUtils::getTransformRecord(larPosition, m_posZSide ? "HEC1_POS":"HEC1_NEG");
+  Transform3D xfPosHec1 = posHec1 ? GeoDBUtils::getTransform(posHec1) : Translate3D(0.,0.,0.);
+  GeoAlignableTransform *xfHec1 = new GeoAlignableTransform(xfPosHec1);
+
+  std::string tag1 = m_posZSide? std::string("HEC1_POS") : std::string("HEC1_NEG");
+
+  HECWheelConstruction theFrontHEC(fullGeo,"front",false,m_posZSide) ;
+  GeoFullPhysVol* EnvelopeF = theFrontHEC.GetEnvelope();
+
+  StoredPhysVol *sPhysVolHec1 = new StoredPhysVol(EnvelopeF);
+  sc=detStore->record(sPhysVolHec1,tag1);
+  if(!sc.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag1).c_str());
+
+  StoredAlignX *sAlignX1 = new StoredAlignX(xfHec1);
+  sc=detStore->record(sAlignX1,tag1);
+  if(!sc.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag1).c_str());
+
+  physiHEC->add(xfHec1);
+  physiHEC->add(new GeoIdentifierTag(0));
+  physiHEC->add(EnvelopeF);
+
+  //--- Now the Rear Wheel:
+
+  double Zpos = TotalHECLength - HEC2length  ;  // It is fixed at its end; position it from there.
+  const IRDBRecord *posHec2 = GeoDBUtils::getTransformRecord(larPosition, m_posZSide ? "HEC2_POS":"HEC2_NEG");
+  Transform3D xfPosHec2 = posHec2 ? GeoDBUtils::getTransform(posHec2):Translate3D(0.,0.,Zpos);
+
+ 
+  GeoAlignableTransform *xfHec2 = new GeoAlignableTransform(xfPosHec2);
+
+  std::string tag2 = m_posZSide? std::string("HEC2_POS") : std::string("HEC2_NEG");
+
+  HECWheelConstruction theRearHEC(fullGeo,"rear",false,m_posZSide);
+  GeoFullPhysVol* EnvelopeR = theRearHEC.GetEnvelope();
+
+  StoredPhysVol *sPhysVolHec2 = new StoredPhysVol(EnvelopeR);
+  sc=detStore->record(sPhysVolHec2,tag2);
+  if(!sc.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag2).c_str());
+
+  StoredAlignX *sAlignX2 = new StoredAlignX(xfHec2);
+  sc=detStore->record(sAlignX2,tag2);
+  if(!sc.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag2).c_str());
+
+  physiHEC->add(xfHec2);
+  physiHEC->add(new GeoIdentifierTag(1));
+  physiHEC->add(EnvelopeR);
+
+
+
+
+
+  return physiHEC;
+}
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECClampConstruction.cxx b/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECClampConstruction.cxx
new file mode 100755
index 00000000000..7ff83f528d7
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECClampConstruction.cxx
@@ -0,0 +1,459 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//  HECClampConstruction.cxx 1.0.0
+//  
+//  GetClampingBar:
+//  Construct Outer Connecting Bars and Support Rails for the
+//  HEC Wheels (Front or Rear)
+//  AddClamps:
+//  Places the Bars and Rails on the HEC Wheel 
+//  
+//  25. Oct 2007  M. Fincke-Keeler 
+//  
+//====================================================================
+#include "LArGeoHec/HECClampConstruction.h"
+#include "LArGeoHec/HECModuleConstruction.h"
+
+#include "GeoModelKernel/GeoElement.h"  
+#include "GeoModelKernel/GeoMaterial.h"  
+#include "GeoModelKernel/GeoFullPhysVol.h"  
+#include "GeoModelKernel/GeoPhysVol.h"  
+#include "GeoModelKernel/GeoVPhysVol.h"  
+#include "GeoModelKernel/GeoLogVol.h"  
+#include "GeoModelKernel/GeoPcon.h"  
+#include "GeoModelKernel/GeoTubs.h"  
+#include "GeoModelKernel/GeoNameTag.h"  
+#include "GeoModelKernel/GeoTransform.h"  
+#include "GeoModelKernel/GeoAlignableTransform.h"  
+#include "GeoModelKernel/GeoIdentifierTag.h"  
+#include "GeoModelKernel/GeoSerialTransformer.h"
+#include "GeoModelKernel/GeoSerialIdentifier.h"
+#include "GeoModelKernel/GeoXF.h"
+#include "CLHEP/Geometry/Transform3D.h" 
+#include "CLHEP/Vector/Rotation.h" 
+#include "CLHEP/Units/PhysicalConstants.h"
+#include "CLHEP/GenericFunctions/Variable.hh"
+#include "StoreGate/StoreGateSvc.h"
+#include "StoreGate/DataHandle.h"
+#include "GeoModelInterfaces/AbsMaterialManager.h"
+#include "GeoModelInterfaces/StoredMaterialManager.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+
+#include "RDBAccessSvc/IRDBAccessSvc.h"
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "RDBAccessSvc/IRDBRecordset.h"
+#include "GeoModelInterfaces/IGeoModelSvc.h"
+
+#include <string>
+#include <cmath>
+#include <iostream>
+
+using CLHEP::cm;
+using CLHEP::mm;
+using CLHEP::deg;
+using HepGeom::RotateZ3D;
+using HepGeom::Translate3D;
+using HepGeom::TranslateZ3D;
+
+
+//Constructor
+LArGeo::HECClampConstruction::HECClampConstruction(bool front, bool posZSide)
+  : m_rail(false),
+    m_left(false),
+    m_moduleNumber(0),
+    m_moduleRouter(0),
+    m_modulePhistart(0),
+    m_rOuter(0),
+    m_moduleDeltaPhi(0)
+{
+  m_front    = front;
+  m_posZSide = posZSide;
+}
+
+//~Destructor
+LArGeo::HECClampConstruction::~HECClampConstruction() 
+{
+}
+
+
+GeoPhysVol* LArGeo::HECClampConstruction::GetClampingBar(bool rail,bool left)
+{
+  
+  ISvcLocator *svcLocator = Gaudi::svcLocator();
+
+  MsgStream log(Athena::getMessageSvc(),"HECClampConstruction " );
+  log << MSG::DEBUG << " In HECClampConstruction " << endreq;
+  
+
+  StoreGateSvc *detStore;
+  if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) {
+    throw std::runtime_error("Error in HECModuleConstruction(ClampBar), cannot access DetectorStore");
+  }
+  
+
+  // Get access to the material manager:
+  DataHandle<StoredMaterialManager> materialManager;
+  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) {
+    throw std::runtime_error("Error in HECModuleConstruction(ClampBar), cannot access Material Manager");
+  }  
+  GeoMaterial *LAr  = materialManager->getMaterial("std::LiquidArgon");
+  if (!LAr) throw std::runtime_error("Error in HECModuleConstruction(ClampBar), std::LiquidArgon is not found.");  
+  GeoMaterial *Iron  = materialManager->getMaterial("std::Iron");
+  if (!Iron) throw std::runtime_error("Error in HECModuleConstruction(ClampBar), std::Iron is not found.");
+ 
+
+  StatusCode sc;
+  IRDBAccessSvc *pAccessSvc;
+  sc=svcLocator->service("RDBAccessSvc",pAccessSvc);
+  if (sc != StatusCode::SUCCESS) {
+    throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
+  }
+
+  IGeoModelSvc *geoModel;
+  sc = svcLocator->service ("GeoModelSvc",geoModel);
+  if (sc != StatusCode::SUCCESS) {
+    throw std::runtime_error ("Cannot locate GeoModelSvc!!");
+  }
+  
+  std::string AtlasVersion = geoModel->atlasVersion();
+  std::string LArVersion = geoModel->LAr_VersionOverride();
+
+  std::string detectorKey  = LArVersion.empty() ? AtlasVersion : LArVersion;
+  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
+
+  IRDBRecordset_ptr hecLongitudinalBlock = pAccessSvc->getRecordsetPtr("HecLongitudinalBlock",detectorKey, detectorNode); 
+  IRDBRecordset_ptr hadronicEndcap       = pAccessSvc->getRecordsetPtr("HadronicEndcap",detectorKey, detectorNode); 
+  
+
+  //----------------------------------------------------------------
+  // Collect all the numbers we need from the database: 
+  //----------------------------------------------------------------
+  //
+  // NOT READY YET
+  //
+  
+  //----------------------------------------------------------------
+  //   Add outer clamping bars for Atlas wheels
+  //----------------------------------------------------------------
+  // NB.: The outer clamping bars have notches for the HEC cables.
+  //      that sit at different levels for Front/Rear Wheel
+  //  
+  double shrinkCold = 1.0;   // thermal expansion factor: 1.0 = warm
+
+  int    moduleNumber   = (*hadronicEndcap)[0]->getInt("NSCT");
+  double moduleRouter   = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
+  double modulePhistart = 264.375*deg;          // (270.-11.25/2.)*deg
+  double rOuter         = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
+  double moduleDeltaPhi = 2*M_PI/moduleNumber; //11.25*deg;  
+  m_moduleNumber  = moduleNumber;
+  m_moduleRouter  = moduleRouter;
+  m_modulePhistart= modulePhistart;
+  m_rOuter        = rOuter;
+  m_moduleDeltaPhi= moduleDeltaPhi ;
+
+  std::string clampName = "LAr::HEC::Clamp";
+  std::string larName = "LAr::HEC::Clamp::LiquidArgon";
+  double    g4allow     =   0.01 *mm;
+  double    extThick    = shrinkCold *   37.*mm;
+  double    extLength   = shrinkCold *   84.*mm;
+  double    clampWidth  = shrinkCold *  147.0 *mm;
+  double    clampThick  = shrinkCold *   50.*mm;
+  double    notchLevel  = shrinkCold *   25.*mm;
+  double    notchHeight = shrinkCold *   15.*mm;
+  double    notchWidth  = shrinkCold *   20.*mm;
+  double    slotWidth   = shrinkCold *   20.*mm;
+  double    clampLength = shrinkCold *  815.*mm;  
+  double    clampAngle  =  2.* asin(clampWidth/(2.*(moduleRouter+clampThick/2.)));
+  double    slotAngle   =  2.* asin(notchWidth/(2.*(moduleRouter+clampThick/2.)));
+
+  std::vector<double>  notchLocation;
+  if (m_front){
+    if (!rail){
+//       notchLocation.push_back(shrinkCold * 201.*mm);
+//       notchLocation.push_back(shrinkCold * 469.*mm);
+//       notchLocation.push_back(shrinkCold * 737.*mm);
+      notchLocation.push_back(shrinkCold * 200.*mm); // adjust for shortened clamp
+      notchLocation.push_back(shrinkCold * 468.*mm);
+      notchLocation.push_back(shrinkCold * 736.*mm);
+    } 
+    else {
+//       notchLocation.push_back(shrinkCold * 206.*mm);
+//       notchLocation.push_back(shrinkCold * 474.*mm);
+//       notchLocation.push_back(shrinkCold * 742.*mm);
+      notchLocation.push_back(shrinkCold * 201.*mm); // adjust for shortened rail
+      notchLocation.push_back(shrinkCold * 469.*mm);
+      notchLocation.push_back(shrinkCold * 737.*mm);
+      clampWidth  =  shrinkCold * 148.5 *mm;
+      clampThick  =  shrinkCold *  98.*mm;   //  98.*mm   (this is the total overall rail thickness)
+      clampLength =  shrinkCold * 815.*mm;
+    } 
+  } 
+  else {
+    if (!rail){
+//       notchLocation.push_back(shrinkCold * 364.0*mm); 
+//       notchLocation.push_back(shrinkCold * 832.0*mm); 
+      notchLocation.push_back(shrinkCold * 363.0*mm); // adjust for shortened clamp
+      notchLocation.push_back(shrinkCold * 831.0*mm); 
+      clampLength =  shrinkCold * 960.*mm;
+    } 
+    else {
+//       notchLocation.push_back(shrinkCold * 372.5*mm); 
+//       notchLocation.push_back(shrinkCold * 840.5*mm); 
+      notchLocation.push_back(shrinkCold * 364.*mm);  // adjust for shortened rail
+      notchLocation.push_back(shrinkCold * 832.*mm); 
+      clampWidth  =  shrinkCold * 148.5 *mm;
+      clampThick  =  shrinkCold *  98.*mm;   
+      clampLength =  shrinkCold * 960.*mm;
+      extLength   =  shrinkCold * 132.*mm;
+    } 
+    notchWidth  = shrinkCold * 16.*mm;
+    notchHeight = shrinkCold * 16.*mm;
+    notchLevel  = shrinkCold * 0.*mm;
+  }
+  
+
+
+
+  // Construct the the slots and notches here. For the support rails, they have to be inserted
+  // into the physExt[0] volume. For the regular clamps they go into physClamp.
+  GeoTubs*         clampExt[3];
+  const GeoLogVol* logExt[3];
+  GeoPhysVol*      physExt[3];
+
+  GeoTubs*         Notch      = new GeoTubs(moduleRouter+notchLevel+g4allow, moduleRouter+notchLevel+notchHeight-g4allow, 
+					    notchWidth/2.,
+					    modulePhistart-(clampAngle/2.) , clampAngle);
+  const GeoLogVol* logNotch   = new GeoLogVol(larName, Notch, LAr);  
+  GeoPhysVol*      physiNotch = new GeoPhysVol(logNotch);
+  
+  GeoTubs*         Slot      = new GeoTubs(moduleRouter+g4allow, moduleRouter+notchLevel-g4allow, slotWidth/2. ,
+					   modulePhistart-(slotAngle/2.) , slotAngle);
+  const GeoLogVol* logSlot   = new GeoLogVol(larName, Slot, LAr);  
+  GeoPhysVol*      physiSlot = new GeoPhysVol(logSlot);
+
+
+
+  GeoTubs*         clampBar;
+  const GeoLogVol* logClamp;
+  GeoPhysVol*      physClamp;
+
+  if(!rail){
+    clampBar = new GeoTubs(moduleRouter, moduleRouter+clampThick, clampLength/2. ,
+			   modulePhistart-(clampAngle/2.) , clampAngle);
+    logClamp = new GeoLogVol(clampName, clampBar, Iron);  
+    physClamp= new GeoPhysVol(logClamp);
+  }
+  else{
+
+    //For the support rails, make the mother LAr and the place the steel inside: 
+
+    clampBar = new GeoTubs(moduleRouter, moduleRouter+clampThick, clampLength/2. ,
+			   modulePhistart-(clampAngle/2.) , clampAngle);
+    logClamp = new GeoLogVol(larName, clampBar, LAr);  
+    physClamp= new GeoPhysVol(logClamp);
+
+
+    clampExt[0] = new GeoTubs(moduleRouter+g4allow,                     moduleRouter+clampThick-extThick, 
+			      clampLength/2. , modulePhistart-(clampAngle/2.), clampAngle);
+    clampExt[1] = new GeoTubs(moduleRouter+clampThick-extThick+g4allow, moduleRouter+clampThick-g4allow, 
+			      clampLength/2. , modulePhistart,                 clampAngle/2.);
+    clampExt[2] = new GeoTubs(moduleRouter+clampThick-extThick+g4allow, moduleRouter+clampThick-g4allow, 
+			      extLength/2. , modulePhistart,                   clampAngle/2.);
+
+
+
+
+    for (int iext=0; iext<3; iext++){
+
+      logExt[iext] = new GeoLogVol(clampName, clampExt[iext], Iron);  
+      physExt[iext]= new GeoPhysVol(logExt[iext]);
+
+      
+      if   (iext==0) {
+	for ( unsigned int i = 0; i < notchLocation.size(); i++ ) 
+	  {
+	    physExt[0]->add( new GeoIdentifierTag(i) );
+	    physExt[0]->add( new GeoTransform(Translate3D(0,0,-clampLength/2.+notchLocation[i])) );  
+	    physExt[0]->add( physiNotch );
+	    if (m_front){
+	      physExt[0]->add( new GeoIdentifierTag(i) );
+	      physExt[0]->add( new GeoTransform(Translate3D(0,0,-clampLength/2.+notchLocation[i])) );  
+	      physExt[0]->add( physiSlot );
+	    }
+	  }
+      }
+
+
+      if     (iext==1 && !left) physClamp->add(new GeoTransform(RotateZ3D(-clampAngle/2.)));
+      else if(iext==2 && left)  physClamp->add(new GeoTransform(TranslateZ3D((clampLength-extLength)/2.)
+								*RotateZ3D(-clampAngle/2.)));
+      else if(iext==2)          physClamp->add(new GeoTransform(TranslateZ3D((clampLength-extLength)/2.)
+								*RotateZ3D( 0.)));
+
+      if (left) physClamp->add( new GeoIdentifierTag(16) );
+      else      physClamp->add( new GeoIdentifierTag(32) );
+
+
+      physClamp->add(physExt[iext]);
+
+    }
+
+
+    for (int i=0; i<3; i++){
+      clampExt[i]->ref();     clampExt[i]->unref();
+      logExt[i]->ref();       logExt[i]->unref();
+      physExt[i]->ref();      physExt[i]->unref();
+    }
+ 
+  }
+    
+
+  for ( unsigned int i = 0; i < notchLocation.size(); i++ ) 
+    {
+      if(!rail){
+	physClamp->add( new GeoIdentifierTag(i) );
+	physClamp->add( new GeoTransform(Translate3D(0,0,-clampLength/2.+notchLocation[i])) );  
+	physClamp->add( physiNotch );
+      }
+    }
+  
+  if(m_front)  
+    {      
+      for ( unsigned int i = 0; i < notchLocation.size(); i++ ) 
+	{
+	  if(!rail){
+	    physClamp->add( new GeoIdentifierTag(i) );
+	    physClamp->add( new GeoTransform(Translate3D(0,0,-clampLength/2.+notchLocation[i])) );  
+	    physClamp->add( physiSlot );
+	  }
+	}
+      
+    }
+  
+  
+
+  Slot->ref();          Slot->unref();     
+  logSlot->ref();       logSlot->unref();     
+  physiSlot->ref();     physiSlot->unref();     
+  clampBar->ref();       clampBar->unref();     
+  logClamp->ref();       logClamp->unref();     
+  Notch->ref();          Notch->unref();     
+  logNotch->ref();       logNotch->unref();     
+  physiNotch->ref();     physiNotch->unref();     
+
+
+  return physClamp;
+}
+
+
+
+void LArGeo::HECClampConstruction::AddClamps(GeoFullPhysVol* physiHECWheel)
+{
+  //----------------------------------------------------------------
+  //   Add Outer Connecting Bars to HEC Wheel
+  //----------------------------------------------------------------
+
+  double shrinkCold = 1.0 ; // thermal expansion factor: 1.0 = warm
+
+  std::string clampName = "LAr::HEC::Clamp";
+  std::string larName   = "LAr::HEC::Clamp::LiquidArgon";
+  double    clampLength =  shrinkCold * 815.*mm;  
+  double    railLength  =  shrinkCold * 815.*mm;  
+  double    railOffset  =  shrinkCold * 0.*mm;  
+  if (!m_front) { 
+    clampLength =  shrinkCold * 960.*mm;  
+    railLength  =  shrinkCold * 960.*mm;
+    railOffset  =  shrinkCold * 0.*mm;  
+  }
+
+  GeoVPhysVol* clampingBar   = GetClampingBar(false,false);
+  GeoVPhysVol* clampingRailR = GetClampingBar(true,false);
+  GeoVPhysVol* clampingRailL = GetClampingBar(true,true);
+
+
+
+  // In the below positioning sequence, the ORDER MATTERS!
+  // 
+
+  GeoTransform *xt = new GeoTransform(TranslateZ3D(clampLength/2.));
+  physiHECWheel->add(xt);
+
+  GeoSerialIdentifier  *sIC = new GeoSerialIdentifier(0);
+  Genfun::Variable    IndexC;
+
+  if (m_posZSide)
+    {
+      Genfun::GENFUNCTION ModuleRotationAngleC = -m_modulePhistart+m_moduleDeltaPhi + m_moduleDeltaPhi*IndexC;
+      GeoXF::TRANSFUNCTION tC   = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngleC);
+      GeoSerialTransformer *sTC = new GeoSerialTransformer (clampingBar,&tC,((m_moduleNumber/2)-1));
+      physiHECWheel->add(sIC);
+      physiHECWheel->add(sTC);
+      sTC->ref();  sTC->unref();
+    }
+  else
+    {
+      Genfun::GENFUNCTION ModuleRotationAngleC = -m_modulePhistart-m_moduleDeltaPhi+180*deg -  m_moduleDeltaPhi*IndexC;
+      GeoXF::TRANSFUNCTION tC   = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngleC);
+      GeoSerialTransformer *sTC = new GeoSerialTransformer (clampingBar,&tC,((m_moduleNumber/2)-1));
+      physiHECWheel->add(sIC);
+      physiHECWheel->add(sTC);
+      sTC->ref();  sTC->unref();
+    }
+
+
+  physiHECWheel->add(new GeoTransform(TranslateZ3D(railLength/2.-railOffset)*RotateZ3D(-m_modulePhistart-(180.*deg))));
+  //GeoSerialIdentifier  *sIR = new GeoSerialIdentifier(15); // For the pos z-side this is the position of module no.15
+  //physiHECWheel->add(sIR);                                 // No need to aplly it if we position clamps in this order
+  //// But for the neg z-side we do have to re-number, because the rails have sided-ness!
+  if (!m_posZSide)
+    {
+      GeoSerialIdentifier  *sIR = new GeoSerialIdentifier(31); 
+      physiHECWheel->add(sIR);                                 
+    }
+  physiHECWheel->add(clampingRailL);
+
+
+  physiHECWheel->add(xt);
+  Genfun::Variable    IndexC2;
+
+  if (m_posZSide)
+    {
+      Genfun::GENFUNCTION ModuleRotationAngleC2 = -m_modulePhistart+m_moduleDeltaPhi-(180.*deg) + m_moduleDeltaPhi*IndexC2;
+      GeoXF::TRANSFUNCTION tC2   = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngleC2);
+      GeoSerialTransformer *sTC2 = new GeoSerialTransformer (clampingBar,&tC2,((m_moduleNumber/2)-1));
+      physiHECWheel->add(sTC2);
+      sTC2->ref(); sTC2->unref();
+    }
+  else
+    {
+      Genfun::GENFUNCTION ModuleRotationAngleC2 = -m_modulePhistart-m_moduleDeltaPhi -  m_moduleDeltaPhi*IndexC2;
+      GeoXF::TRANSFUNCTION tC2   = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngleC2);
+      GeoSerialTransformer *sTC2 = new GeoSerialTransformer (clampingBar,&tC2,((m_moduleNumber/2)-1));
+      physiHECWheel->add(sTC2);
+      sTC2->ref(); sTC2->unref();
+    }
+
+  physiHECWheel->add(new GeoTransform(TranslateZ3D(railLength/2.)*RotateZ3D(-m_modulePhistart))); 
+  if (!m_posZSide)
+    {
+      GeoSerialIdentifier  *sIR = new GeoSerialIdentifier(15); 
+      physiHECWheel->add(sIR);                                 
+    }
+  physiHECWheel->add(clampingRailR);
+
+
+   clampingBar->ref();   clampingBar->unref();  
+   clampingRailR->ref(); clampingRailR->unref(); 
+   clampingRailL->ref(); clampingRailL->unref(); 
+   xt->ref();   xt->unref();   
+   sIC->ref();  sIC->unref();
+
+}
+
+
+
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECModuleConstruction.cxx b/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECModuleConstruction.cxx
new file mode 100755
index 00000000000..5fdbfcf6960
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECModuleConstruction.cxx
@@ -0,0 +1,706 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//  HECModuleConstruction.cxx 1.0.0
+//  Derived from the HECConstruction - M. Fincke,  Sept.2007
+//  
+#include "LArGeoHec/HECModuleConstruction.h"
+
+#include "GeoModelKernel/GeoElement.h"  
+#include "GeoModelKernel/GeoMaterial.h"  
+#include "GeoModelKernel/GeoFullPhysVol.h"  
+#include "GeoModelKernel/GeoPhysVol.h"  
+#include "GeoModelKernel/GeoVPhysVol.h"  
+#include "GeoModelKernel/GeoLogVol.h"  
+#include "GeoModelKernel/GeoPcon.h"  
+#include "GeoModelKernel/GeoTubs.h"  
+#include "GeoModelKernel/GeoNameTag.h"  
+#include "GeoModelKernel/GeoTransform.h"  
+#include "GeoModelKernel/GeoAlignableTransform.h"  
+#include "GeoModelKernel/GeoIdentifierTag.h"  
+#include "GeoModelKernel/GeoSerialTransformer.h"
+#include "GeoModelKernel/GeoSerialIdentifier.h"
+#include "GeoModelKernel/GeoXF.h"
+#include "CLHEP/Geometry/Transform3D.h" 
+#include "CLHEP/Vector/Rotation.h" 
+#include "CLHEP/Units/PhysicalConstants.h"
+#include "CLHEP/GenericFunctions/Variable.hh"
+#include "StoreGate/StoreGateSvc.h"
+#include "StoreGate/DataHandle.h"
+#include "GeoModelInterfaces/AbsMaterialManager.h"
+#include "GeoModelInterfaces/StoredMaterialManager.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "AthenaKernel/getMessageSvc.h"
+#include "RDBAccessSvc/IRDBAccessSvc.h"
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "RDBAccessSvc/IRDBRecordset.h"
+//#include "RDBAccessSvc/IRDBQuery.h"
+#include "GeoModelInterfaces/IGeoModelSvc.h"
+
+#include <string>
+#include <cmath>
+#include <iostream>
+
+
+using CLHEP::cm;
+using CLHEP::mm;
+using CLHEP::deg;
+using HepGeom::Translate3D;
+using HepGeom::TranslateY3D;
+using HepGeom::TranslateZ3D;
+
+
+//Constructor
+LArGeo::HECModuleConstruction::HECModuleConstruction(bool threeBoards, bool frontWheel, bool tb, int tbyear):
+  m_physiHECModule(0)
+{
+  m_threeBoards = threeBoards;  // If true, build 3 boards in gap. Else just one thick board.
+  m_frontWheel = frontWheel;    // If true, build a front Module. Else build a rear Module. 
+  m_tb = tb;                    // If true, build a Module for testbeam. 
+  m_tbyear = tbyear;            // If testbeam, specify the testbeam year. 
+
+//   if (tb && ( tbyear!=2002 && tbyear!=2004 )) {
+//     throw std::runtime_error ("TESTBEAM HEC: Asking for an unsupported HEC testbeam year!!!!! ");
+//   }
+
+}
+
+//~Destructor
+LArGeo::HECModuleConstruction::~HECModuleConstruction() 
+{;}
+
+
+GeoFullPhysVol* LArGeo::HECModuleConstruction::GetEnvelope()
+{
+  if(m_physiHECModule) return m_physiHECModule->clone();
+
+
+
+  ISvcLocator *svcLocator = Gaudi::svcLocator();
+
+  MsgStream log(Athena::getMessageSvc(),"HECModuleConstruction " );
+
+  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endreq;
+  log << MSG::DEBUG << "+                                                             +" << endreq;
+  log << MSG::DEBUG << "+         Start of HECModule GeoModel definition              +" << endreq;
+  log << MSG::DEBUG << "+                                                             +" << endreq;
+  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endreq;
+
+
+  StoreGateSvc *detStore;
+  if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) {
+    throw std::runtime_error("Error in HECModuleConstruction, cannot access DetectorStore");
+  }
+
+  
+  DataHandle<StoredMaterialManager> materialManager;
+  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) {
+    throw std::runtime_error("Error in HECModuleConstruction, cannot access Material Manager");
+  }
+  
+  GeoMaterial *LAr  = materialManager->getMaterial("std::LiquidArgon");
+  if (!LAr) throw std::runtime_error("Error in HECModuleConstruction, std::LiquidArgon is not found.");
+  
+  GeoMaterial *Iron  = materialManager->getMaterial("std::Iron");
+  if (!Iron) throw std::runtime_error("Error in HECModuleConstruction, std::Iron is not found.");
+  
+  GeoMaterial *Copper  = materialManager->getMaterial("std::Copper");
+  if (!Copper) throw std::runtime_error("Error in HECModuleConstruction, std::Copper is not found.");
+  
+  GeoMaterial *Kapton  = materialManager->getMaterial("std::Kapton");
+  if (!Kapton) throw std::runtime_error("Error in HECModuleConstruction, std::Kapton is not found.");
+  
+
+
+  StatusCode sc;
+  IRDBAccessSvc *pAccessSvc;
+  sc=svcLocator->service("RDBAccessSvc",pAccessSvc);
+  if (sc != StatusCode::SUCCESS) {
+    throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
+  }
+
+
+  IGeoModelSvc *geoModel;
+  sc = svcLocator->service ("GeoModelSvc",geoModel);
+  if (sc != StatusCode::SUCCESS) {
+    throw std::runtime_error ("Cannot locate GeoModelSvc!!");
+  }
+  
+  std::string AtlasVersion = geoModel->atlasVersion();
+  std::string LArVersion = geoModel->LAr_VersionOverride();
+
+  std::string detectorKey  = LArVersion.empty() ? AtlasVersion : LArVersion;
+  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
+
+  IRDBRecordset_ptr hadronicEndcap   = pAccessSvc->getRecordsetPtr("HadronicEndcap",detectorKey, detectorNode); 
+  if(hadronicEndcap->size()>0) 
+    log << MSG::DEBUG << "Using numbers from HadronicEndcap tag:  " << hadronicEndcap->tagName() << endreq;
+  else
+    throw std::runtime_error("Error in HECConstruction:  hadronicEendcap not found");
+
+  IRDBRecordset_ptr hecLongitudinalBlock = pAccessSvc->getRecordsetPtr("HecLongitudinalBlock",detectorKey, detectorNode); 
+  if(hecLongitudinalBlock->size()>0) 
+    log << MSG::DEBUG << "Using numbers from HecLongitudinalBlock tag:  " << hecLongitudinalBlock->tagName() << endreq;
+  else
+    throw std::runtime_error("Error in HECConstruction:  hecLongitudinalBlock not found");
+
+  //----------------------------------------------------------------
+  // Collect all the numbers we need from the database: 
+  //----------------------------------------------------------------
+
+  double shrinkCold = 1.0;  //thermal expansion factor: 1.0 = warm geometry
+                            //kapton is treated the same at Cu and Fe at the moment
+
+  int    moduleNumber          = (*hadronicEndcap)[0]->getInt("NSCT");
+  double moduleRinner1         = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMN")*cm;
+  double moduleRinner2         = shrinkCold * (*hecLongitudinalBlock)[1]->getDouble("BLRMN")*cm;
+  double moduleRouter          = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
+  if (m_tbyear==2004) moduleRouter = moduleRinner1 + 787*mm;  // Mini Modules for 2004 testbeam  CAUTION! Hard-coded number!!!
+  double copperPad             = shrinkCold * (*hadronicEndcap)[0]->getDouble("COPPER")*cm;
+  double gapSize               = shrinkCold * (*hadronicEndcap)[0]->getDouble("LARG")*cm;
+  double drModOverlap          = shrinkCold * (*hadronicEndcap)[0]->getDouble("DRMODOVERLAP")*cm;
+  double kaptonWidth[2];
+  kaptonWidth[0]               = shrinkCold * (*hadronicEndcap)[0]->getDouble("ESTPL")*cm;
+  kaptonWidth[1]               = shrinkCold * (*hadronicEndcap)[0]->getDouble("PADPL")*cm;
+  int    gapN[7];
+  for(int id=0;id<7;id++) gapN[id] = (int) (*hecLongitudinalBlock)[id]->getDouble("BLMOD");
+  double firstFrontAbsThickness= shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("PLATE0")*cm;
+  double firstRearAbsThickness = shrinkCold * (*hecLongitudinalBlock)[3]->getDouble("PLATE0")*cm;
+  double frontAbsThickness     = shrinkCold * (*hadronicEndcap)[0]->getDouble("PLATE_0")*cm;
+  double rearAbsThickness      = shrinkCold * (*hadronicEndcap)[0]->getDouble("PLATE_1")*cm;
+  double tieRodPositionX[4];
+  double tieRodPositionY[4];
+  tieRodPositionX[0]           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSX_0")*cm;
+  tieRodPositionY[0]           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSR_0")*cm;
+  tieRodPositionX[1]           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSX_1")*cm;
+  tieRodPositionY[1]           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSR_1")*cm;
+  tieRodPositionX[2]           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSX_2")*cm;
+  tieRodPositionY[2]           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSR_2")*cm;
+  tieRodPositionX[3]           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSX_3")*cm;
+  tieRodPositionY[3]           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSR_3")*cm;
+  double tieRodDiameter        = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODDIM_0")*cm;
+  double spacerDiameter        = shrinkCold * (*hadronicEndcap)[0]->getDouble("SPCDIM_0")*cm;
+  double spacerDeadZone        = shrinkCold * 3.0*mm;
+  if (!m_frontWheel) 
+    {
+      tieRodDiameter           = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODDIM_1")*cm;
+      spacerDiameter           = shrinkCold * (*hadronicEndcap)[0]->getDouble("SPCDIM_1")*cm;
+    }
+
+
+  //--- Get the right Absorber thickness and Depth number depending on Front or Rear Wheel (and TB) 
+  //    (2002 and 2004 testbeam have only 1/2 rear depth)
+  int    depthNumber           = 3; 
+  int    depthOffset           = depthNumber;  // need this to start rear wheel depth-number at 3 
+  double absThickness          = frontAbsThickness;
+  double firstAbsThickness     = firstFrontAbsThickness;
+  if (!m_frontWheel) {
+    depthNumber          = 4; 
+    if (m_tb) depthNumber= 2;         
+    absThickness         = rearAbsThickness;
+    firstAbsThickness    = firstRearAbsThickness;
+  }
+
+
+  //---- Calculate the sizes of the 7 longitudinal Depths -------------------------------------
+  double depthS[7];
+  depthS[0]              = firstFrontAbsThickness + gapN[0]*(frontAbsThickness+gapSize);
+  depthS[1]              = gapN[1]*(frontAbsThickness+gapSize);
+  depthS[2]              = gapN[2]*(frontAbsThickness+gapSize);
+  depthS[3]              = firstRearAbsThickness + gapN[3]*(rearAbsThickness+gapSize);
+  depthS[4]              = gapN[4]*(rearAbsThickness+gapSize);
+  depthS[5]              = gapN[5]*(rearAbsThickness+gapSize);
+  depthS[6]              = gapN[6]*(rearAbsThickness+gapSize);
+
+  //--- From the depth Size, calculate the boundary planes of the Module Mother volume ---------
+  //    (Add 0.1 mm to avoid clashes)
+  double zCoordinate[4];
+  double depthSize[4];
+  int    gapNumber[4];
+  int    gaptally[4];
+  double g4allow  = shrinkCold * 0.1*mm ;    
+  double g4allowS = 0.001*mm ;  
+  if (m_frontWheel){
+    zCoordinate[0] = shrinkCold * 0.0*cm; 
+    zCoordinate[1] = depthS[0]; 
+    zCoordinate[2] = depthS[0] + g4allow; 
+    zCoordinate[3] = depthS[0]+depthS[1]+depthS[2] + g4allow;                // End of front Module  
+    gaptally[0]=0;
+    for (int i=0; i<3; i++) {
+      if (i>0) gaptally[i] = gaptally[i-1] + gapN[i-1];
+      gapNumber[i] = gapN[i];         
+      depthSize[i] = depthS[i];
+    }
+  }
+  else{
+    zCoordinate[0]         = shrinkCold * 0.0*cm; 
+    zCoordinate[1]         = depthS[3]+depthS[4]+depthS[5]+depthS[6]+g4allow; // End of rear Atlas Module
+    if(m_tb) zCoordinate[1]= depthS[3]+depthS[4]+g4allow;                     // For TB only 1/2 rear depth
+    gaptally[0] = 0;
+    for (int i=0; i<4; i++) {                        // Re-number the rear wheel  
+      if (i>0) gaptally[i] =gaptally[i-1] + gapN[i+3-1];
+      gapNumber[i] = gapN[i+3];                      // gaps and depths to have
+      depthSize[i] = depthS[i+3];                    // their index start at Zero.
+    }                                  
+  }
+
+  //--- Calculate where to put the tie-rod spacers into the available LAr gap.
+  //    This depends on the configuration of the boards. 
+
+  //   +/-ztie are the center z-coordinates of the LAr sub-gaps
+  //   rodSize is the length of spacer to be fit into the LAr that is not occupied by boards
+  //   Small tolerance to fit G4 volumes into one another 
+  double ztie[2];
+  double rodSize; 
+ 
+  //-- For Three-board approach:
+  if (m_threeBoards) {
+    double halfGap    = gapSize/2.;
+    double halfGapLAr = (gapSize - kaptonWidth[1])/2.;
+    double restLAr    = (halfGapLAr-kaptonWidth[0])/2. ;
+    ztie[0]           = restLAr/2 + kaptonWidth[1]/2.; 
+    ztie[1]           = halfGap - restLAr/2.;          
+    rodSize           = restLAr - g4allowS; 
+  }
+  else{
+  //-- For One-board approach:
+    double halfGap    = gapSize/2.;
+    double halfGapLAr = (gapSize - kaptonWidth[1])/2. - kaptonWidth[0];
+    ztie[0]           = (halfGap-halfGapLAr/2.);  
+    ztie[1]           = 0.0; // fix complilation warning
+    rodSize           =  halfGapLAr-g4allowS;    
+  }
+
+
+  //---- And here we have some more (yikes!) hard-coded values: ------------------------
+  int    nZplane             = 4;
+  if (!m_frontWheel) nZplane = 2;
+  int    nRods               = 4;
+  if (m_tbyear==2004) nRods  = 2;
+  double modulePhistart      = 264.375*deg;          // (270.-11.25/2.)*deg 	  
+  double moduleDeltaPhi      = 2*M_PI/moduleNumber;  //11.25*deg;  
+  int sectMax                = 2;
+  if(!m_frontWheel) sectMax  = 1;
+  int rearOffset             = 24;   // The rear wheel slice numbering starts at 24
+                                     // This complies with the old HECConstruction. 
+
+  //--- A dead-zone in the LAr gap of depth deadZone all around the module 
+  //    requires a radial shift of size larshift
+  double deadZone   = shrinkCold * 3.*mm;                       
+  double larShift   = deadZone / sin(moduleDeltaPhi/2.);    
+
+  //--- To create a (dead) inter-module gap of 2mm (i.e. 1mm on either side of each module)
+  //    between the absorbers, use a radial shift of -1.02*cm.
+  //    This does that:
+  double deadGap = shrinkCold * 1.*mm;                       
+  double radialShift = deadGap / sin(moduleDeltaPhi/2.);    
+
+
+
+
+
+  //-------------------------------------------------------------------//
+  //-------------------------------------------------------------------//
+  //   Now start building the Module geometry                          //
+  //   First create all the little bits so that they are               //
+  //   ready to be inserted into the bigger pieces when they get       //
+  //   are created.                                                    //
+  //-------------------------------------------------------------------//
+  //-------------------------------------------------------------------//
+
+  std::string moduleName    = "LAr::HEC::Module";
+  std::string depthName     = moduleName + "::Depth";
+  std::string sliceName     = depthName + "::Slice";
+  std::string electrodeName = sliceName + "::Electrode";
+  std::string copperName    = electrodeName + "::Copper";
+  std::string tieRodName    = sliceName + "::TieRod";
+  std::string deadTieName   = sliceName + "::TieRodDead";
+  std::string absorberName  = depthName + "::Absorber";
+  std::string firstAbsorberName = depthName + "::FirstAbsorber";
+  std::string absTieRodName = absorberName + "::TieRod";
+  std::string firstabsTieRodName = firstAbsorberName + "::TieRod";
+
+  //---- Tie rods to go into Absorbers --------------------------------------
+
+  GeoTubs* solidAbsorberTieRod         = new GeoTubs(0.*cm,tieRodDiameter/2.,absThickness/2.,0.*deg,360.*deg); 
+  const GeoLogVol* logiAbsorberTieRod  = new GeoLogVol(absTieRodName,solidAbsorberTieRod,Iron);  //,0,0,0);
+  GeoPhysVol* physiAbsorberTieRod      = new GeoPhysVol(logiAbsorberTieRod);
+
+  GeoTubs* solidFirstAbsorberTieRod    = new GeoTubs(0.*cm,tieRodDiameter/2.,firstAbsThickness/2.,0.*deg,360.*deg); 
+  const GeoLogVol* logiFirstAbsorberTieRod = new GeoLogVol(firstabsTieRodName,solidFirstAbsorberTieRod,Iron);  //,0,0,0);
+  GeoPhysVol* physiFirstAbsorberTieRod = new GeoPhysVol(logiFirstAbsorberTieRod);
+
+
+  //---- Tie rods to go into Slices (i.e. sensitive LAr gaps) -----------------
+
+  GeoTubs* solidTieRod        = new GeoTubs(0.*cm,spacerDiameter/2.,rodSize/2.,0.*deg,360.*deg);  
+  const GeoLogVol* logiTieRod = new GeoLogVol(tieRodName, solidTieRod, Iron); 
+  GeoPhysVol* physiTieRod     = new GeoPhysVol(logiTieRod);
+
+
+  GeoTubs* solidDeadTie        = new GeoTubs(g4allowS+spacerDiameter/2.,
+					     spacerDeadZone+spacerDiameter/2.,
+					     rodSize/2.,
+					     0.*deg,360.*deg);  
+  const GeoLogVol* logiDeadTie = new GeoLogVol(deadTieName, solidDeadTie, LAr); 
+  GeoPhysVol* physiDeadTie     = new GeoPhysVol(logiDeadTie);
+
+
+  //----  Create PAD board and EST boards, then also Slices (ie. LAr gaps) and put the boards into Slices ------------
+  //      This requires a loop, because the frontWheel has two sections (iSect) of different radial size.
+  //      The same goes for the Absorbers - create them in this loop, too.
+  //      (NB: Each wheel has only one "firstAbsorber"; Create that ahead of everything else.)
+  //      And finally equip the LAr Slices as well as the Absorbers with their respective tie-rods.  
+
+
+  GeoTubs*         solidPadBoard[2] ;
+  const GeoLogVol* logiPadBoard[2];
+  GeoPhysVol*      physiPadBoard[2];
+
+  GeoTubs*         solidCopperPad[2];
+  const GeoLogVol* logiCopperPad[2];
+  GeoPhysVol*      physiCopperPad[2];
+
+  GeoTubs*         solidEstBoard[2];
+  const GeoLogVol* logiEstBoard[2];
+  GeoPhysVol*      physiEstBoard[2];
+
+  GeoTubs*         solidSlice[2];
+  const GeoLogVol* logiSlice[2];
+  GeoPhysVol*      physiSlice[2];
+
+  GeoTubs*         solidAbsorber[2];
+  const GeoLogVol* logiAbsorber[2];
+  GeoPhysVol*      physiAbsorber[2];
+
+  // First Absorbers in front of first and third samplings (need only one type in each wheel)
+  double rOuterF           = moduleRouter-radialShift;
+  double rInnerF           = moduleRinner2-radialShift;
+  if (m_frontWheel) rInnerF= moduleRinner1-radialShift;
+  GeoTubs* solidFirstAbsorber         = new GeoTubs(rInnerF,rOuterF,
+					    firstAbsThickness/2.,
+					    modulePhistart,moduleDeltaPhi);                   
+  const GeoLogVol* logiFirstAbsorber  = new GeoLogVol(firstAbsorberName, solidFirstAbsorber, Copper);
+  GeoPhysVol* physiFirstAbsorber      = new GeoPhysVol(logiFirstAbsorber);
+
+
+  for(int iSect=0; iSect<sectMax; iSect++)
+    {
+      //-------- First make the slice: ------------------
+      // NB: larShift produces the inter-module gap,
+      //     but the actual radial size of the board or slice also has to be
+      //     made smaller by the value of deadZone.     
+
+      double rOuter = moduleRouter - larShift - deadZone;  
+      double rInner = moduleRinner2 - larShift + deadZone;
+      if (iSect<1 && m_frontWheel) rInner = moduleRinner1 - larShift + deadZone;;
+      solidSlice[iSect] = new GeoTubs(rInner, rOuter, gapSize/2., modulePhistart, moduleDeltaPhi); 
+      logiSlice[iSect]  = new GeoLogVol(sliceName, solidSlice[iSect], LAr);
+      physiSlice[iSect] = new GeoPhysVol(logiSlice[iSect]);
+
+      //--------  Now make the boards: -------- 
+      rOuter = moduleRouter - larShift - deadZone -g4allowS;
+      rInner = moduleRinner2 - larShift + deadZone +g4allowS;
+      if (m_frontWheel && iSect==0) rInner = moduleRinner1 - larShift + deadZone +g4allowS ;
+      
+      // First, make a central PAD Board: Copper encased in Kapton
+      // In case of the one-board approach, that's the only board (just thicker)
+      if (m_threeBoards){
+	solidPadBoard[iSect] = new GeoTubs(rInner,rOuter,
+				    kaptonWidth[1]/2.,
+				    modulePhistart,moduleDeltaPhi);
+      }
+      else{
+	solidPadBoard[iSect] = new GeoTubs(rInner,rOuter,
+				    (kaptonWidth[1]/2.+ kaptonWidth[0]),
+				    modulePhistart,moduleDeltaPhi);
+      }
+      logiPadBoard[iSect]  = new GeoLogVol(electrodeName, solidPadBoard[iSect], Kapton );
+      physiPadBoard[iSect] = new GeoPhysVol(logiPadBoard[iSect]);
+      
+      // The central board contains copper pads for readout
+      solidCopperPad[iSect] = new GeoTubs(rInner,rOuter,copperPad/2.,
+				   modulePhistart,moduleDeltaPhi);                   
+      logiCopperPad[iSect]  = new GeoLogVol(copperName, solidCopperPad[iSect], Copper);
+      physiCopperPad[iSect] = new GeoPhysVol(logiCopperPad[iSect]);
+      physiPadBoard[iSect]->add(physiCopperPad[iSect]);  
+      
+      // For the three-board approach, make an individual EST board and place it twice in the LAr gap
+      if(m_threeBoards){
+	solidEstBoard[iSect] = new GeoTubs(rInner,rOuter,kaptonWidth[0]/2.,
+				    modulePhistart,moduleDeltaPhi);
+	logiEstBoard[iSect]  = new GeoLogVol(electrodeName, solidEstBoard[iSect], Kapton );
+	physiEstBoard[iSect] = new GeoPhysVol(logiEstBoard[iSect]);	
+      }
+
+      //--- Insert the Boards into the Slice ---------
+      
+      physiSlice[iSect]->add(new GeoIdentifierTag(1));
+      physiSlice[iSect]->add(physiPadBoard[iSect]);     
+      
+      
+      // For the three-board approach, make an individual EST board and place it twice in the LAr gap
+      if(m_threeBoards){
+	double halfGapLAr = (gapSize - kaptonWidth[1])/2.;
+	double ESTPos = (kaptonWidth[1]+halfGapLAr)/2.;
+	physiSlice[iSect]->add(new GeoIdentifierTag(0));
+	physiSlice[iSect]->add(new GeoTransform(Translate3D(0,0,(-ESTPos))));  
+	physiSlice[iSect]->add(physiEstBoard[iSect]);     
+	physiSlice[iSect]->add(new GeoIdentifierTag(2));
+	physiSlice[iSect]->add(new GeoTransform(Translate3D(0,0,ESTPos)));   
+	physiSlice[iSect]->add(physiEstBoard[iSect]);     
+      }
+ 
+
+
+
+  //--- Create the absorbers -----
+
+      rOuter           = moduleRouter - radialShift;
+      rInner           = moduleRinner2 - radialShift;
+      if (iSect<1 && m_frontWheel) rInner = moduleRinner1 - radialShift;
+      solidAbsorber[iSect] = new GeoTubs(rInner,rOuter,absThickness/2., modulePhistart,moduleDeltaPhi); 
+      logiAbsorber[iSect]  = new GeoLogVol(absorberName, solidAbsorber[iSect], Copper);
+      physiAbsorber[iSect] = new GeoPhysVol(logiAbsorber[iSect]);
+
+
+
+  //--- Insert tie rods into the Absorbers and Slices -----
+  //    There are three pairs (left/right symmetric-> handled by loop over isignX)
+  //    and they need to be placed in z on either side of the board(s) (loop over isign)
+  //    (Note; we did the radial shift for the absorber(and slice); have to compensate for that now in Y position)   
+
+
+      for(int indexRod=1; indexRod<nRods; indexRod++) {
+	for(double isignX=-1;isignX<2;isignX=isignX+2.){
+
+	  physiAbsorber[iSect]->add(new GeoIdentifierTag(indexRod));
+	  physiAbsorber[iSect]->add(new GeoTransform(Translate3D(isignX*tieRodPositionX[indexRod],
+								     -tieRodPositionY[indexRod]+radialShift, 0)));     
+	  physiAbsorber[iSect]->add(physiAbsorberTieRod);     
+	  if (iSect==0){ // fill the FirstAbsorber with tie-rods at the same time)
+	    physiFirstAbsorber->add(new GeoIdentifierTag(indexRod));
+	    physiFirstAbsorber->add(new GeoTransform(Translate3D(isignX*tieRodPositionX[indexRod],
+								    -tieRodPositionY[indexRod]+radialShift, 0)));     
+	    physiFirstAbsorber->add(physiFirstAbsorberTieRod);     
+	  }
+
+          // For the LAr slices, we have to insert the spacers around the boards (in Z):
+
+	  for(int itie=0; itie<2; itie++ ){  // itie=0 inserts spacers, itie=1 inserts spacer dead-zone
+	    for(double isignZ=-1;isignZ<2;isignZ=isignZ+2.){
+	      physiSlice[iSect]->add(new GeoIdentifierTag(indexRod));
+	      physiSlice[iSect]->add(new GeoTransform
+				     (Translate3D(isignX*tieRodPositionX[indexRod],
+                                                  -tieRodPositionY[indexRod]+larShift,
+                                                  isignZ*ztie[0])));
+	      if (itie==0) { physiSlice[iSect]->add(physiTieRod); }     
+	      else         { physiSlice[iSect]->add(physiDeadTie);}
+
+	      if (m_threeBoards) {  
+		physiSlice[iSect]->add(new GeoIdentifierTag(indexRod));
+		physiSlice[iSect]->add(new GeoTransform
+				       (Translate3D(isignX*tieRodPositionX[indexRod],
+                                                    -tieRodPositionY[indexRod]+larShift,
+                                                    isignZ*ztie[1])));     
+		if (itie==0) { physiSlice[iSect]->add(physiTieRod); }     
+		else         { physiSlice[iSect]->add(physiDeadTie);}     
+	      }
+	    }
+	  }
+      
+
+
+	}
+      }
+
+      //--- This is for the lonely un-paired tie-rod at the narrow end of the module (Absorber): 
+      physiAbsorber[iSect]->add(new GeoIdentifierTag(0));
+      physiAbsorber[iSect]->add(new GeoTransform(Translate3D(tieRodPositionX[0],
+                                                             -tieRodPositionY[0]+radialShift,0)));     
+      physiAbsorber[iSect]->add(physiAbsorberTieRod);     
+      if (iSect==0){ 
+	physiFirstAbsorber->add(new GeoIdentifierTag(0));
+	physiFirstAbsorber->add(new GeoTransform(Translate3D(tieRodPositionX[0],
+                                                             -tieRodPositionY[0]+radialShift,0)));     
+	physiFirstAbsorber->add(physiFirstAbsorberTieRod);     
+      }
+
+      //--- And the lonely Slice tie-rods: -------------
+      for(int itie=0; itie<2; itie++ ){  // tie=0 inserts spacers, itie=1 inserts spacer dead-zone
+	for(double isignZ=-1;isignZ<2;isignZ=isignZ+2){
+	  physiSlice[iSect]->add(new GeoIdentifierTag(0));
+	  physiSlice[iSect]->add(new GeoTransform(Translate3D(tieRodPositionX[0],
+                                                              -tieRodPositionY[0]+larShift, 
+                                                              isignZ*ztie[0])));    
+	  if (itie==0) { physiSlice[iSect]->add(physiTieRod); }     
+	  else         { physiSlice[iSect]->add(physiDeadTie);}
+
+	  if (m_threeBoards) { 
+	    physiSlice[iSect]->add(new GeoIdentifierTag(0));
+	    physiSlice[iSect]->add(new GeoTransform(Translate3D(tieRodPositionX[0],
+                                                                -tieRodPositionY[0]+larShift,
+                                                                isignZ*ztie[1])));     
+	    if (itie==0) { physiSlice[iSect]->add(physiTieRod); }      
+	    else         { physiSlice[iSect]->add(physiDeadTie);}     
+	  }
+	} 
+      }
+      
+    }//for iSect
+  
+  
+  
+  // Now that Slices and Absorbers are filled with their components,
+  // create the Depths and place the slices and absorbers into them
+
+
+  //----------------------------------------------------------------
+  //    Depths
+  //----------------------------------------------------------------
+  // There are 3 depths in the front wheel, and 4 in the rear wheel.
+  // Create them and equip them with fully assembled slices and absorbers.
+
+  GeoTubs*           solidDepth[4] ;
+  const GeoLogVol*   logiDepth[4]  ;
+  GeoPhysVol*        physiDepth[4] ;
+
+  for(int iDepth=0; iDepth<depthNumber; iDepth++)
+    {
+      double rOuter       = moduleRouter;
+      double rInner       = moduleRinner2;
+      if (iDepth<1 && m_frontWheel) rInner= moduleRinner1;
+      solidDepth[iDepth]  = new GeoTubs(rInner-drModOverlap,rOuter, 
+					depthSize[iDepth]/2.,modulePhistart,moduleDeltaPhi);                   
+      logiDepth[iDepth]   = new GeoLogVol(depthName, solidDepth[iDepth], LAr);
+      physiDepth[iDepth]  = new GeoPhysVol(logiDepth[iDepth]);
+
+
+      // Position the sensitive LAr Slice-gaps and absorbers into the just created Depth:
+      // Absorber size and position
+      double firstAbs          = 0.;
+      if (iDepth==0) firstAbs  = firstAbsThickness;       
+      double slicePositionZ    = firstAbs + gapSize/2.0 -depthSize[iDepth]/2.0;
+      double absorberPositionZ = firstAbs + gapSize + absThickness/2.0 - depthSize[iDepth]/2.0;
+
+      // sliceCopyNo is the copy number of the slice and runs consecutively from
+      // front to back throughout the module.
+      // The first gap in the rear Wheel has number 24 (=rearOffset).
+      // sliceNo refers to how many slice types there are (0,1 in Front ; 0 in Rear)
+      // gapNumber is the number of gaps in a given Depth 
+      int sliceNo           = 0;
+      int sliceCopyNo       = 0;
+      if(!m_frontWheel) sliceCopyNo = rearOffset ; 
+
+      if (iDepth>0) 
+	{
+	  sliceCopyNo += gaptally[iDepth]; 
+          if(m_frontWheel) sliceNo=1;
+	}
+
+      // Serially install all slices and _regular_ absorbers into the depths       
+      Genfun::Variable Index;
+      GeoXF::TRANSFUNCTION TS = 
+	TranslateY3D(-larShift)*GeoXF::Pow(TranslateZ3D(1.0),slicePositionZ + (absThickness+gapSize)*Index);
+      GeoXF::TRANSFUNCTION TA = 
+	TranslateY3D(-radialShift)*GeoXF::Pow(TranslateZ3D(1.0),absorberPositionZ + (absThickness+gapSize)*Index);
+
+      GeoSerialIdentifier  *sI   = new GeoSerialIdentifier(sliceCopyNo);
+      GeoSerialTransformer *sTS  = new GeoSerialTransformer(physiSlice[sliceNo],    &TS, gapNumber[iDepth]);
+      GeoSerialTransformer *sTAF = new GeoSerialTransformer(physiAbsorber[sliceNo], &TA, gapNumber[iDepth]);
+      physiDepth[iDepth]->add(sI);
+      physiDepth[iDepth]->add(sTS);
+      physiDepth[iDepth]->add(sI);
+      physiDepth[iDepth]->add(sTAF);
+
+    } //for iDepth     
+
+
+  // The first absorber is special (1/2 thickness) install that now
+  double firstAbsorberPositionZ = firstAbsThickness/2.- depthSize[0]/2.0;
+  if(m_frontWheel) physiDepth[0]->add(new GeoIdentifierTag(0));
+  else             physiDepth[0]->add(new GeoIdentifierTag(1));
+  physiDepth[0]->add(new GeoTransform(Translate3D(0,-radialShift,firstAbsorberPositionZ)));     
+  physiDepth[0]->add(physiFirstAbsorber);     
+  
+
+  //----------------------------------------------------------------
+  //   HEC Module
+  //----------------------------------------------------------------
+
+
+  GeoPcon* solidHECModule = new GeoPcon(modulePhistart, moduleDeltaPhi);
+  for (int i=0; i< nZplane; i++) 
+     {
+        double innerRadius = moduleRinner2;
+        if (i<2 && m_frontWheel) innerRadius=moduleRinner1;  
+        solidHECModule->addPlane(zCoordinate[i],innerRadius-drModOverlap,moduleRouter);
+     }
+  const GeoLogVol* logicHECModule = new GeoLogVol(moduleName, solidHECModule , LAr);
+  GeoFullPhysVol* physiHECModule  = new GeoFullPhysVol(logicHECModule);
+
+
+  //---  Place the fully instrumented depths into the Module: ----
+
+  double depthPositionZ = 0.;
+
+  for(int iDepth=0; iDepth<depthNumber; iDepth++)
+    {
+      depthPositionZ +=depthSize[iDepth]/2.;
+      if(!m_frontWheel) physiHECModule->add(new GeoIdentifierTag(iDepth+depthOffset));
+      else              physiHECModule->add(new GeoIdentifierTag(iDepth));
+      physiHECModule->add(new GeoTransform(Translate3D(0,0,depthPositionZ)));     
+      physiHECModule->add(physiDepth[iDepth]);     
+      depthPositionZ +=depthSize[iDepth]/2.;
+    } //for iDepth     
+
+
+
+  // Return the physical volume that contains everything we've placed.
+
+  //-- clean up:
+  solidAbsorberTieRod->ref();       solidAbsorberTieRod->unref();     
+  logiAbsorberTieRod->ref();        logiAbsorberTieRod->unref();  
+  physiAbsorberTieRod->ref();       physiAbsorberTieRod->unref(); 
+  solidFirstAbsorberTieRod->ref();  solidFirstAbsorberTieRod->unref(); 
+  logiFirstAbsorberTieRod->ref();   logiFirstAbsorberTieRod->unref();
+  physiFirstAbsorberTieRod->ref();  physiFirstAbsorberTieRod->unref();   
+  solidTieRod->ref();               solidTieRod->unref();    
+  logiTieRod->ref();                logiTieRod->unref(); 
+  physiTieRod->ref();               physiTieRod->unref();
+  solidDeadTie->ref();              solidDeadTie->unref();    
+  logiDeadTie->ref();               logiDeadTie->unref(); 
+  physiDeadTie->ref();              physiDeadTie->unref();
+  solidFirstAbsorber->ref();        solidFirstAbsorber->unref(); 
+  logiFirstAbsorber->ref();         logiFirstAbsorber->unref();  
+  physiFirstAbsorber->ref();        physiFirstAbsorber->unref(); 
+  for(int iSect=0; iSect<sectMax; iSect++)
+    {
+      solidCopperPad[iSect]->ref(); solidCopperPad[iSect]->unref(); 
+      logiCopperPad[iSect]->ref();  logiCopperPad[iSect]->unref();  
+      physiCopperPad[iSect]->ref(); physiCopperPad[iSect]->unref(); 
+      solidPadBoard[iSect]->ref();  solidPadBoard[iSect]->unref(); 
+      logiPadBoard[iSect]->ref();   logiPadBoard[iSect]->unref();  
+      physiPadBoard[iSect]->ref();  physiPadBoard[iSect]->unref(); 
+      if(m_threeBoards){
+	solidEstBoard[iSect]->ref();  solidEstBoard[iSect]->unref(); 
+	logiEstBoard[iSect]->ref();   logiEstBoard[iSect]->unref();  
+	physiEstBoard[iSect]->ref();  physiEstBoard[iSect]->unref(); 
+      }
+      solidAbsorber[iSect]->ref();  solidAbsorber[iSect]->unref(); 
+      logiAbsorber[iSect]->ref();   logiAbsorber[iSect]->unref();  
+      physiAbsorber[iSect]->ref();  physiAbsorber[iSect]->unref(); 
+      solidSlice[iSect]->ref();     solidSlice[iSect]->unref(); 
+      logiSlice[iSect]->ref();      logiSlice[iSect]->unref();  
+      physiSlice[iSect]->ref();     physiSlice[iSect]->unref(); 
+    }
+  for(int iDepth=0; iDepth<depthNumber; iDepth++){
+    solidDepth[iDepth]->ref();  solidDepth[iDepth]->unref();  
+    logiDepth[iDepth]->ref();   logiDepth[iDepth]->unref();   
+    physiDepth[iDepth]->ref();  physiDepth[iDepth]->unref();  
+  }
+
+  return physiHECModule;
+}
diff --git a/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECWheelConstruction.cxx b/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECWheelConstruction.cxx
new file mode 100755
index 00000000000..4cf9a858152
--- /dev/null
+++ b/LArCalorimeter/LArGeoModel/LArGeoHec/src/HECWheelConstruction.cxx
@@ -0,0 +1,283 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//  HECWheelConstruction.cxx 1.0.0
+//  
+//  This provides a mother volume for the ATLAS Front HEC or Rear HEC,
+//  gets the modules from the HECModuleConstruction and arranges
+//  them into a FrontWheel or RearWheel respectively.
+//  The LAr gaps can be equipped with either one thick PAD+EST board
+//  or with 3 individual boards (1 PAD + 2 EST). 
+//  
+//  M. Fincke-Keeler 
+//  
+//====================================================================
+#include "LArGeoHec/HECWheelConstruction.h"
+#include "LArGeoHec/HECClampConstruction.h"
+#include "LArGeoHec/HECModuleConstruction.h"
+
+#include "GeoModelKernel/GeoElement.h"  
+#include "GeoModelKernel/GeoMaterial.h"  
+#include "GeoModelKernel/GeoFullPhysVol.h"  
+#include "GeoModelKernel/GeoPhysVol.h"  
+#include "GeoModelKernel/GeoVPhysVol.h"  
+#include "GeoModelKernel/GeoLogVol.h"  
+#include "GeoModelKernel/GeoPcon.h"  
+#include "GeoModelKernel/GeoTubs.h"  
+#include "GeoModelKernel/GeoNameTag.h"  
+#include "GeoModelKernel/GeoTransform.h"  
+#include "GeoModelKernel/GeoAlignableTransform.h"  
+#include "GeoModelKernel/GeoIdentifierTag.h"  
+#include "GeoModelKernel/GeoSerialTransformer.h"
+#include "GeoModelKernel/GeoSerialIdentifier.h"
+#include "GeoModelKernel/GeoXF.h"
+#include "CLHEP/Geometry/Transform3D.h" 
+#include "CLHEP/Vector/Rotation.h" 
+#include "CLHEP/Units/PhysicalConstants.h"
+#include "CLHEP/GenericFunctions/Variable.hh"
+#include "StoreGate/StoreGateSvc.h"
+#include "StoreGate/DataHandle.h"
+#include "GeoModelInterfaces/AbsMaterialManager.h"
+#include "GeoModelInterfaces/StoredMaterialManager.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+
+#include "RDBAccessSvc/IRDBAccessSvc.h"
+#include "RDBAccessSvc/IRDBRecord.h"
+#include "RDBAccessSvc/IRDBRecordset.h"
+//#include "RDBAccessSvc/IRDBQuery.h"
+#include "GeoModelInterfaces/IGeoModelSvc.h"
+
+#include <string>
+#include <cmath>
+#include <iostream>
+
+
+using CLHEP::cm;
+using CLHEP::mm;
+using CLHEP::deg;
+using HepGeom::RotateZ3D;
+
+
+//Constructor
+LArGeo::HECWheelConstruction::HECWheelConstruction(bool fullGeo, std::string wheelType, bool threeBoards, bool posZSide):
+  m_physiHECWheel(0),
+  m_rail(false),
+  m_left(false),
+  m_clampLength(0),
+  m_clampAngle(0),
+  m_fullGeo(fullGeo)
+{
+  m_threeBoards = threeBoards;
+  m_posZSide    = posZSide;
+  m_wheelType   = wheelType;
+  if (m_wheelType=="front") m_frontWheel  = true;
+  else                      m_frontWheel  = false;
+}
+
+//~Destructor
+LArGeo::HECWheelConstruction::~HECWheelConstruction() 
+{;}
+
+
+GeoFullPhysVol* LArGeo::HECWheelConstruction::GetEnvelope()
+{
+  if(m_physiHECWheel) return m_physiHECWheel->clone();
+
+  // Get access to the material manager:
+  
+  ISvcLocator *svcLocator = Gaudi::svcLocator();
+
+  MsgStream log(Athena::getMessageSvc(),"HECWheelConstruction " );
+
+  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endreq;
+  log << MSG::DEBUG << "+                                                             +" << endreq;
+  log << MSG::DEBUG << "+         Start of HECWheel GeoModel definition               +" << endreq;
+  log << MSG::DEBUG << "+                                                             +" << endreq;
+  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endreq;
+
+
+  StoreGateSvc *detStore;
+  if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) {
+    throw std::runtime_error("Error in HECWheelConstruction, cannot access DetectorStore");
+  }
+
+  
+  DataHandle<StoredMaterialManager> materialManager;
+  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) {
+    throw std::runtime_error("Error in HECWheelConstruction, cannot access Material Manager");
+  }
+  
+  GeoMaterial *LAr  = materialManager->getMaterial("std::LiquidArgon");
+  if (!LAr) throw std::runtime_error("Error in HECWheelConstruction, std::LiquidArgon is not found.");
+  
+  GeoMaterial *Iron  = materialManager->getMaterial("std::Iron");
+  if (!Iron) throw std::runtime_error("Error in HECWheelConstruction, std::Iron is not found.");
+  
+
+
+  StatusCode sc;
+  IRDBAccessSvc *pAccessSvc;
+  sc=svcLocator->service("RDBAccessSvc",pAccessSvc);
+  if (sc != StatusCode::SUCCESS) {
+    throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
+  }
+
+
+  IGeoModelSvc *geoModel;
+  sc = svcLocator->service ("GeoModelSvc",geoModel);
+  if (sc != StatusCode::SUCCESS) {
+    throw std::runtime_error ("Cannot locate GeoModelSvc!!");
+  }
+  
+  std::string AtlasVersion = geoModel->atlasVersion();
+  std::string LArVersion = geoModel->LAr_VersionOverride();
+
+  std::string detectorKey  = LArVersion.empty() ? AtlasVersion : LArVersion;
+  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
+
+  IRDBRecordset_ptr hadronicEndcap   = pAccessSvc->getRecordsetPtr("HadronicEndcap",detectorKey, detectorNode); 
+  if(hadronicEndcap->size()>0)
+    log << MSG::DEBUG << "Using numbers from HadronicEndcap tag:  " << hadronicEndcap->tagName() << endreq;
+  else
+    throw std::runtime_error("Error in HECConstruction:  hadronicEendcap not found");
+
+  IRDBRecordset_ptr hecLongitudinalBlock = pAccessSvc->getRecordsetPtr("HecLongitudinalBlock",detectorKey, detectorNode); 
+  if(hecLongitudinalBlock->size()>0) 
+    log << MSG::DEBUG << "Using numbers from HecLongitudinalBlock tag:  " << hecLongitudinalBlock->tagName() << endreq;
+  else
+    throw std::runtime_error("Error in HECConstruction:  hecLongitudinalBlock not found");
+
+  IRDBRecordset_ptr coldContraction  = pAccessSvc->getRecordsetPtr("ColdContraction",detectorKey, detectorNode); 
+  if(coldContraction->size()>0)
+    log << MSG::DEBUG << "Numbers from ColdContraction db (not used yet) tag:  " << coldContraction->tagName() << endreq;
+  else
+    throw std::runtime_error("Error in HECConstruction:  ColdContraction not found");
+
+  //----------------------------------------------------------------
+  // Collect all the numbers we need from the database: 
+  //----------------------------------------------------------------
+
+  // This will have to come into action once we are all ready to go cold:
+  // (what's still missing right now are the proper densities to go with it) 
+  //double shrinkCold = (*coldContraction)[0]->getDouble("ABSORBERCONTRACTION");
+
+  double shrinkCold    = 1.0;   // thermal expansion factor: 1.0 = warm geometry 
+ 
+  int    moduleNumber          = (*hadronicEndcap)[0]->getInt("NSCT");
+  double drModOverlap          = shrinkCold * (*hadronicEndcap)[0]->getDouble("DRMODOVERLAP")*cm;
+  double rOuter                = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
+  if (rOuter<2100.*mm) rOuter  = shrinkCold * 2130*mm;  // Needs fixing in database to make room for HEC Clamping bars! 
+                                           // Caution: We'll need 2 Routers - One for Wheel, one for Module!
+  double rInner1               = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMN")*cm;
+  double rInner2               = shrinkCold * (*hecLongitudinalBlock)[1]->getDouble("BLRMN")*cm;
+  double firstFrontAbsThickness= shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("PLATE0")*cm;
+  double firstRearAbsThickness = shrinkCold * (*hecLongitudinalBlock)[3]->getDouble("PLATE0")*cm;
+  double frontAbsThickness     = shrinkCold * (*hadronicEndcap)[0]->getDouble("PLATE_0")*cm;
+  double rearAbsThickness      = shrinkCold * (*hadronicEndcap)[0]->getDouble("PLATE_1")*cm;
+  double gapSize               = shrinkCold * (*hadronicEndcap)[0]->getDouble("LARG")*cm;
+  int    gapNumber[7];
+  for (int id=0; id<7;id++) gapNumber[id] = (int) (*hecLongitudinalBlock)[id]->getDouble("BLMOD");
+
+ 
+  //---- Calculate the sizes of the 7 longitudinal Depths -------------------------------------
+  double depthSize[7];
+  depthSize[0]     = firstFrontAbsThickness + gapNumber[0]*(frontAbsThickness+gapSize);
+  depthSize[1]     = gapNumber[1]*(frontAbsThickness+gapSize);
+  depthSize[2]     = gapNumber[2]*(frontAbsThickness+gapSize);
+  depthSize[3]     = firstRearAbsThickness + gapNumber[3]*(rearAbsThickness+gapSize);
+  depthSize[4]     = gapNumber[4]*(rearAbsThickness+gapSize);
+  depthSize[5]     = gapNumber[5]*(rearAbsThickness+gapSize);
+  depthSize[6]     = gapNumber[6]*(rearAbsThickness+gapSize);
+
+  //--- From the depth Size, calculate the boundary planes of the Wheel Mother volume ---------
+  //    (Add 0.2 mm to avoid clashes)
+  double g4allow   = shrinkCold * 0.2*mm;;
+  double zCoordinate[4];
+  if (m_frontWheel){
+    zCoordinate[0] = shrinkCold * 0.0*cm; 
+    zCoordinate[1] = depthSize[0]; //280.5*mm;  (end of the section with the long plates)
+    zCoordinate[2] = depthSize[0] + g4allow; //280.6*mm; 
+    zCoordinate[3] = depthSize[0] + depthSize[1] + depthSize[2] + g4allow; // End of front Module  
+  }
+  else{
+    zCoordinate[0] = shrinkCold * 0.0*cm; 
+    zCoordinate[1] = depthSize[3] + depthSize[4] + depthSize[5] + depthSize[6] + g4allow; // End of rear
+  }
+
+  //---- And here we have some (yikes!) hard-coded values: -------------------------------------
+  // The somewhat odd looking phistart arranges that the y-axis lines up
+  // with the (radial) symmetry axis of of the module. 
+  // This is important for the calculator.
+  //  
+  double modulePhistart      = 264.375*deg; // (270.-11.25/2.)*deg
+  double moduleDeltaPhi      = 2*M_PI/moduleNumber; //11.25*deg;  
+
+  int  nZplane = 4;
+  if (!m_frontWheel) nZplane = 2;
+
+
+
+  //----------------------------------------------------------------
+  //   HECWheel 
+  //----------------------------------------------------------------
+  GeoPcon* solidHECWheel = new GeoPcon(0., 2.*M_PI);
+  for (int i=0; i< nZplane; i++) 
+     {
+        double innerRadius = rInner2;
+        if (i<2 && m_frontWheel) innerRadius=rInner1;  
+        solidHECWheel->addPlane(zCoordinate[i],innerRadius-drModOverlap,rOuter);
+     }
+  std::string hecFrontName = "LAr::HEC::LiquidArgon";
+  const GeoLogVol* logicHECWheel = new GeoLogVol(hecFrontName, solidHECWheel , LAr);
+  GeoFullPhysVol* physiHECWheel = new GeoFullPhysVol(logicHECWheel);
+
+
+  if(m_fullGeo) {
+
+    //----------------------------------------------------------------
+    //   Get HEC Modules
+    //----------------------------------------------------------------
+    // NB:  HECModuleConstruction( threeBoards, frontWheel, TB,TByear) ;
+
+    HECModuleConstruction HECModule(m_threeBoards,m_frontWheel,false,0) ;
+    GeoVPhysVol* moduleEnvelope = HECModule.GetEnvelope();
+    
+    //----------------------------------------------------------------
+    //   Place Modules into HEC Wheel
+    //----------------------------------------------------------------
+    // Rotation angle is: 11.25/2 + Index *  11.25*deg
+    // Modules are numbered mirror-symmetric in pos/neg z-side!
+    
+    GeoSerialIdentifier  *sIF = new GeoSerialIdentifier(0);
+    Genfun::Variable    Index;
+      
+    if (m_posZSide) {
+      Genfun::GENFUNCTION ModuleRotationAngle = -modulePhistart + moduleDeltaPhi*Index;
+      GeoXF::TRANSFUNCTION t    = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngle);
+      GeoSerialTransformer *sTF = new GeoSerialTransformer (moduleEnvelope,&t,moduleNumber);
+      physiHECWheel->add(sIF);
+      physiHECWheel->add(sTF);
+    } else {
+      //For the neg z-side have to build everything in the opposite sense from pos-z wheel.
+      Genfun::GENFUNCTION ModuleRotationAngle1 = -modulePhistart+180*deg-moduleDeltaPhi - moduleDeltaPhi*Index;
+      GeoXF::TRANSFUNCTION t1    = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngle1);
+      GeoSerialTransformer *sTF1 = new GeoSerialTransformer (moduleEnvelope,&t1,moduleNumber);
+      physiHECWheel->add(sIF);
+      physiHECWheel->add(sTF1);
+    }
+
+    //----------------------------------------------------------------
+    //   Add Outer Connecting Bars to HEC Wheel
+    //----------------------------------------------------------------
+    
+    HECClampConstruction HECClamp (m_frontWheel,m_posZSide);
+    HECClamp.AddClamps(physiHECWheel); 
+  }
+    
+  return physiHECWheel;
+}
+
-- 
GitLab