diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/ExcluderConstruction.h b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/ExcluderConstruction.h new file mode 100755 index 0000000000000000000000000000000000000000..80e6779b116b32cd2f70743e9d9c98d3c8b62395 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/ExcluderConstruction.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ExcluderConstruction +// +// +// July-2006 JP Archambault, Mohsen Khakzad + +#ifndef __ExcluderConstruction_H__ +#define __ExcluderConstruction_H__ + +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoVFullPhysVol.h" + +class IRDBAccessSvc; +class IGeoModelSvc; + +namespace LArGeo { + + class ExcluderConstruction + { + public: + + ExcluderConstruction(); + virtual ~ExcluderConstruction(); + + // Get the envelope containing this detector. + virtual GeoPhysVol* GetEnvelope(); +/* virtual GeoVFullPhysVol* GetEnvelope(); */ +/* GeoPhysVol* GetLArPhysical(); */ + + + private: + + //GeoFullPhysVol* createEnvelope(); + + GeoPhysVol *PhysExcluder; +/* GeoPhysVol *cryoEnvelopePhysical; */ +/* GeoFullPhysVol *cryoMotherPhysical; */ +/* GeoPhysVol *cryoLArPhys; */ + + IRDBAccessSvc *pAccessSvc; + IGeoModelSvc *geoModelSvc; + + }; + +} // namespace LArGeo + +#endif // __ExcluderConstruction_H__ diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/FrontBeamConstructionH62002.h b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/FrontBeamConstructionH62002.h new file mode 100755 index 0000000000000000000000000000000000000000..284909dccd7a990e20032d1ad3a60ca4086c56d4 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/FrontBeamConstructionH62002.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// FrontBeamConstructionH62002 +// Return an envelope that contains the LArH62002 Beam Instrumentation. +// Apr-2006 mgf + +#ifndef __FrontBeamConstructionH62002_H__ +#define __FrontBeamConstructionH62002_H__ + +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +class IRDBAccessSvc; +class IGeoModelSvc; +class LArDetDescrManager; + +namespace LArGeo { + + class FrontBeamConstructionH62002 + { + public: + + FrontBeamConstructionH62002(); + virtual ~FrontBeamConstructionH62002(); + + // Get the envelope containing this detector. + virtual GeoVPhysVol* GetEnvelope(); + void SetManager(LArDetDescrManager* mgr){_detectorManager = mgr;} + + //void SetAxisVisState(bool state) {_axisVisState=state;} + + private: + + + GeoPhysVol *H62002FrontBeamPhysical; + LArDetDescrManager *_detectorManager; + + + IRDBAccessSvc *pAccessSvc; + IGeoModelSvc *geoModelSvc; + + }; + +} // namespace LArGeo + +#endif // __FrontBeamConstructionH62002_H__ diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/HECConstructionH62002.h b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/HECConstructionH62002.h new file mode 100755 index 0000000000000000000000000000000000000000..b2f7e4e1b1a2ebcab276898e51f1e4d7be5aca34 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/HECConstructionH62002.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// HECConstructionH62002 +// Insert the LAr FCAL into a pre-defined mother volume. +// Author: Joe Boudreau August 204 + + +#ifndef __HECConstructionH62002_H__ +#define __HECConstructionH62002_H__ + +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoPhysVol.h" + + + +// Forward declarations + +namespace LArGeo { + + class HECConstructionH62002 + { + public: + + // Constructor; + HECConstructionH62002(); + + // Destructor: + virtual ~HECConstructionH62002(); + + // Get the envelope containing this detector. + GeoVFullPhysVol* GetEnvelope(); // h6Phys is GeoVPhysVol + + + private: + + // It is illegal to copy a HECConstructionH62002: + HECConstructionH62002 (const HECConstructionH62002 &); + + // It is illegal to assign a HECConstructionH62002: + HECConstructionH62002 & operator= (const HECConstructionH62002 &); + + + // volumes that are private member variables: + GeoFullPhysVol* h6Phys; + + //static LArGeo::VDetectorParameters* m_parameters; + //static VDetectorParameters* HECConstructionH62002::m_parameters; + + + }; + + + +} // namespace LArGeo + +#endif // __HECConstructionH62002_H__ diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/LArDetectorFactoryH62002.h b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/LArDetectorFactoryH62002.h new file mode 100755 index 0000000000000000000000000000000000000000..55263d196e3d388328eaf1c138e31f9de4ad7b9f --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/LArDetectorFactoryH62002.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef LArDetectorFactoryH62002_h +#define LArDetectorFactoryH62002_h 1 +#include "GeoModelKernel/GeoVDetectorFactory.h" +#include "LArReadoutGeometry/LArDetectorManager.h" + +class StoreGateSvc; +class LArDetDescrManager; +class LArMgrInitializer; + +namespace LArGeo { + + class LArDetectorFactoryH62002 : public GeoVDetectorFactory { + + public: + + // Constructor: + LArDetectorFactoryH62002(StoreGateSvc *pDetStore); + + // Destructor: + ~LArDetectorFactoryH62002(); + + // Creation of geometry: + virtual void create(GeoPhysVol *world); + + // + virtual const LArDetectorManager * getDetectorManager() const; + + MsgStream *log ; + + private: + + double m_cryoXpos; + double m_tableYpos; + + void getSimulationParameters(); + + // Illegal operations: + const LArDetectorFactoryH62002 & operator=(const LArDetectorFactoryH62002 &right); + LArDetectorFactoryH62002(const LArDetectorFactoryH62002 &right); + + + // The Detector + StoreGateSvc *m_detectorStore; + + // The manager: + LArDetectorManager *m_detectorManager; + + }; + +} // namespace LArGeo + +#endif + + diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/LArDetectorToolH62002.h b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/LArDetectorToolH62002.h new file mode 100755 index 0000000000000000000000000000000000000000..ba5e784af9a8c814e26719f6fa6e1c370f0948c0 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/LArDetectorToolH62002.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef LARDETECTORTOOLH62002_H +#define LARDETECTORTOOLH62002_H + +#include "GeoModelUtilities/GeoModelTool.h" + +class LArDetectorToolH62002 : public GeoModelTool { + +public: + + // Standard Constructor + LArDetectorToolH62002( const std::string& type, const std::string& name, const IInterface* parent ); + + // Standard Destructor + virtual ~LArDetectorToolH62002(); + + virtual StatusCode create( StoreGateSvc* detStore ); + +}; + +#endif diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/TableConstructionH62002.h b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/TableConstructionH62002.h new file mode 100755 index 0000000000000000000000000000000000000000..94ee0c14e8f9842f130a80fff699ce6bab2b34fc --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/LArGeoH62002Algs/TableConstructionH62002.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// TableConstructionH62002 +// Return an envelope that contains the LArH62002 Beam Instrumentation. +// Apr-2006 mgf + + +#ifndef __TableConstructionH62002_H__ +#define __TableConstructionH62002_H__ + +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +class IRDBAccessSvc; +class IGeoModelSvc; +class LArDetDescrManager; + +namespace LArGeo { + + class TableConstructionH62002 + { + public: + + TableConstructionH62002(); + virtual ~TableConstructionH62002(); + + // Get the envelope containing this detector. + virtual GeoVPhysVol* GetEnvelope(); + void SetManager(LArDetDescrManager* mgr){_detectorManager = mgr;} + + + private: + + GeoPhysVol *H62002TablePhysical; + LArDetDescrManager *_detectorManager; + + IRDBAccessSvc *pAccessSvc; + IGeoModelSvc *geoModelSvc; + + }; + +} // namespace LArGeo + +#endif // __TableConstructionH62002_H__ diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/cmt/requirements b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/cmt/requirements new file mode 100755 index 0000000000000000000000000000000000000000..cfbf578826f9a63bc5b48c6ff82d0f0916362b26 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/cmt/requirements @@ -0,0 +1,40 @@ + + + +package LArGeoH62002Algs + +author Joe Boudreau <boudreau@pitt.edu> +author Mohsen Khakzad <mohsen@physics.carleton.ca> +author J.P. Archambault <jparcham@physics.carleton.ca> + +use AtlasPolicy AtlasPolicy-* +use GeoModelKernel GeoModelKernel-* DetectorDescription/GeoModel +use GeoModelUtilities GeoModelUtilities-* DetectorDescription/GeoModel +use LArReadoutGeometry LArReadoutGeometry-* LArCalorimeter/LArGeoModel + + + + +private +use GaudiInterface GaudiInterface-* External +use AtlasCLHEP AtlasCLHEP-* External +use StoreGate StoreGate-* Control +use GeoModelInterfaces GeoModelInterfaces-* DetectorDescription/GeoModel +use RDBAccessSvc RDBAccessSvc-* Database/AthenaPOOL +use LArG4RunControl LArG4RunControl-* LArCalorimeter/LArG4 +use LArGeoCode LArGeoCode-* LArCalorimeter/LArGeoModel +use LArGeoH6Cryostats LArGeoH6Cryostats-* LArCalorimeter/LArGeoModel +use LArGeoEndcap LArGeoEndcap-* LArCalorimeter/LArGeoModel +end_private + +library LArGeoH62002Algs *.cxx -s=components *.cxx +apply_pattern component_library + + +# The following line would copy the contents of LArGeoAlgs/share to +# the user's run/ directory. Since there is no LArGeoAlgs/share +# directory (yet), let's save a bit of time and comment out this line. + +# apply_pattern declare_runtime + +#macro LArGeoH62002Algs_cppflags " -g -O0 " diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/doc/MainPage.h b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/doc/MainPage.h new file mode 100644 index 0000000000000000000000000000000000000000..88e23e3e7c3ad0af6fe74466910f25d914ccbb5a --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/doc/MainPage.h @@ -0,0 +1,19 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + + +@mainpage + +This package contains GeoModel description of LAr H62002 Test Beam setup. + +-------------------------------- + REQUIREMENTS +-------------------------------- + +@include requirements +@htmlinclude used_packages.html + +*/ diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/ExcluderConstruction.cxx b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/ExcluderConstruction.cxx new file mode 100755 index 0000000000000000000000000000000000000000..398bc8fff396734e4930093d7415456dd7aac51a --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/ExcluderConstruction.cxx @@ -0,0 +1,167 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ExcluderConstruction + +// Feb-2006 JPA; +// + +#include "LArGeoH62002Algs/ExcluderConstruction.h" + + +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoVPhysVol.h" +#include "GeoModelKernel/GeoVFullPhysVol.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoTubs.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoIdentifierTag.h" +#include "StoreGate/StoreGateSvc.h" +#include "StoreGate/DataHandle.h" +#include "GeoModelInterfaces/AbsMaterialManager.h" +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "GeoModelKernel/GeoShapeUnion.h" +#include "GeoModelKernel/GeoShapeShift.h" + +// For transforms: + +#include "CLHEP/Geometry/Transform3D.h" +// For units: +#include "CLHEP/Units/PhysicalConstants.h" + +// For the database: + +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" + +#include "GeoModelInterfaces/IGeoModelSvc.h" + +#include "StoreGate/StoreGateSvc.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/Bootstrap.h" + +#include <string> +#include <cmath> + +LArGeo::ExcluderConstruction::ExcluderConstruction() + :PhysExcluder(0), + pAccessSvc(0), + geoModelSvc(0) +{ +} + +LArGeo::ExcluderConstruction::~ExcluderConstruction() {} + +//GeoVFullPhysVol* LArGeo::ExcluderConstruction::GetEnvelope() +GeoPhysVol* LArGeo::ExcluderConstruction::GetEnvelope() +{ + + // Need to do the equivalent for excluder here: <<<================ + // if (cryoMotherPhysical) return cryoMotherPhysical; + + // Detector Store + ISvcLocator *svcLocator = Gaudi::svcLocator(); + StoreGateSvc *detStore; + if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) { + throw std::runtime_error("Error in ExcluderConstruction, cannot access DetectorStore"); + } + + // Material Manager + + // Need to add Rohacell here! <<<=============== + + DataHandle<StoredMaterialManager> materialManager; + if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return 0; + + + // (use Air for the moment....) <<<================ + GeoMaterial *Air = materialManager->getMaterial("std::Air"); + if (!Air) { + throw std::runtime_error("Error in ExcluderConstruction, std::Air is not found."); + } + + // Define Rohacell Foam. + // Rohacell foam has density: 0.11g/cm3 + std::string name; + double density; + GeoElement* C=materialManager->getElement("Carbon"); + GeoElement* H=materialManager->getElement("Hydrogen"); + GeoElement* O=materialManager->getElement("Oxygen"); + GeoElement* N=materialManager->getElement("Nitrogen"); + GeoMaterial* Rohacell = new GeoMaterial(name="Rohacell", density=0.11*CLHEP::g/CLHEP::cm3); + Rohacell->add(C,0.6465); + Rohacell->add(H,0.07836); + Rohacell->add(O,0.19137); + Rohacell->add(N,0.08377); + Rohacell->lock(); + + + + // Database + StatusCode sc; + sc=svcLocator->service("RDBAccessSvc",pAccessSvc); + if (sc != StatusCode::SUCCESS) { + throw std::runtime_error ("Cannot locate RDBAccessSvc!!"); + } + + // GeoModelSvc + sc = svcLocator->service ("GeoModelSvc",geoModelSvc); + if (sc != StatusCode::SUCCESS) { + throw std::runtime_error ("Cannot locate GeoModelSvc!!"); + } + + std::string AtlasVersion = geoModelSvc->atlasVersion(); + std::string LArVersion = geoModelSvc->LAr_VersionOverride(); + + std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion; + std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr"; + + //-------- + // Now build the actual Excluder. + + // It is a Union out of a GeoBox and a GeoTubs. + // Box Dimensions: + double xbox = 300.0 *CLHEP::mm; + double ybox = 160.0 *CLHEP::mm; + double zbox = 300.7 *CLHEP::mm; + // + // Tubs Dimensions: + double ztubs = 300.0 *CLHEP::mm; + double phitubs= 76.2 *CLHEP::deg; + double delphi = 27.6 *CLHEP::deg; + double rcold = 1249.5 *CLHEP::mm; + double rmin = 1220.0 *CLHEP::mm; + + // The radius of the cryostat cold wall is: 1250 CLHEP::mm + // Before we make the union, we have to shift the box in y (that actually along the beam axis) + // and there, positive y goes from the cryostat centre towards the beam window. + + std::string ExcluderName = "LAr::H6::Cryostat::Excluder"; + + GeoBox* rohaBox = new GeoBox(xbox, ybox, zbox); // The rectangular part of the excluder + const GeoShapeShift & rohaBoxShift = (*rohaBox << HepGeom::TranslateY3D(1062.85*CLHEP::mm) ); + GeoTubs* rohaTubs = new GeoTubs(rmin, rcold, ztubs, phitubs, delphi); // The round part of the excluder + + // Combine the two parts to make one excluder of the correct shape: + const GeoShapeUnion* Excluder = new GeoShapeUnion(&rohaBoxShift, rohaTubs); + + const GeoLogVol* LogExcluder = new GeoLogVol(ExcluderName, Excluder, Rohacell); // <<<==== air should be rohacell !!! + GeoPhysVol* PhysExcluder = new GeoPhysVol(LogExcluder); + PhysExcluder->add( new GeoNameTag(ExcluderName) ); + + return PhysExcluder; + +} + + + + + diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/FrontBeamConstructionH62002.cxx b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/FrontBeamConstructionH62002.cxx new file mode 100755 index 0000000000000000000000000000000000000000..53c6033f3b73d32ad52f32c5cd30f5b6a44a440f --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/FrontBeamConstructionH62002.cxx @@ -0,0 +1,246 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "LArGeoH62002Algs/FrontBeamConstructionH62002.h" +#include "LArGeoH6Cryostats/MWPCConstruction.h" + +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoVFullPhysVol.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoVPhysVol.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoTubs.h" +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoSerialDenominator.h" +#include "GeoModelKernel/GeoSerialIdentifier.h" +#include "GeoModelKernel/GeoSerialTransformer.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoIdentifierTag.h" +#include "GeoModelKernel/GeoSerialDenominator.h" +#include "StoreGate/StoreGateSvc.h" +#include "StoreGate/DataHandle.h" +#include "GeoModelInterfaces/AbsMaterialManager.h" +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "GeoModelKernel/GeoShapeUnion.h" +#include "GeoModelKernel/GeoShapeShift.h" + +// For transforms: +#include "CLHEP/Geometry/Transform3D.h" +#include "CLHEP/GenericFunctions/Variable.hh" +// For units: +#include "CLHEP/Units/PhysicalConstants.h" + +// For the database: +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" + +#include "GeoModelInterfaces/IGeoModelSvc.h" + +#include "StoreGate/StoreGateSvc.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/Bootstrap.h" + +#include <string> +#include <cmath> +#include <iostream> + +LArGeo::FrontBeamConstructionH62002::FrontBeamConstructionH62002() + :H62002FrontBeamPhysical(0), + _detectorManager(0), + pAccessSvc(0), + geoModelSvc(0) +{ +} + + +LArGeo::FrontBeamConstructionH62002::~FrontBeamConstructionH62002() +{ +} + + + +GeoVPhysVol* LArGeo::FrontBeamConstructionH62002::GetEnvelope() +{ + + if (H62002FrontBeamPhysical) return H62002FrontBeamPhysical; + + // Get access to the material manager: + + ISvcLocator *svcLocator = Gaudi::svcLocator(); + IMessageSvc * msgSvc; + if (svcLocator->service("MessageSvc", msgSvc, true )==StatusCode::FAILURE) { + throw std::runtime_error("Error in FrontBeamConstructionH62002, cannot access MessageSvc"); + } + + MsgStream log(msgSvc, "LArGeo::FrontBeamConstructionH62002"); + log << MSG::INFO; + log << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + log << "+ +" << std::endl; + log << "+ HELLO from LArGeo::FrontBeamConstructionH62002 +" << std::endl; + log << "+ +" << std::endl; + log << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + + + StoreGateSvc *detStore; + if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) { + throw std::runtime_error("Error in FrontBeamConstructionH62002, cannot access DetectorStore"); + } + + + StatusCode sc; + + IGeoModelSvc *geoModelSvc; + sc = svcLocator->service ("GeoModelSvc",geoModelSvc); + if (sc != StatusCode::SUCCESS) { + throw std::runtime_error ("Cannot locate GeoModelSvc!!"); + } + + + + // Get the materials from the material manager:-----------------------------------------------------// + // // + + DataHandle<StoredMaterialManager> materialManager; + if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return NULL; + + + GeoMaterial *Air = materialManager->getMaterial("std::Air"); + if (!Air) throw std::runtime_error("Error in FrontBeamConstructionH62002, std::Air is not found."); + + GeoMaterial *Aluminium = materialManager->getMaterial("std::Aluminium"); + if (!Aluminium) throw std::runtime_error("Error in FrontBeamConstructionH62002, std::Aluminium is not found."); + + // Is this ok for the Scintillator? + // I don't really know for sure what kind of a scintillator we have. + // Lots of Scintillators are PMMA (Plexiglas), which has a composition of C5 H8 O2 and density 1.18 g/cm3 + // The Tile uses a composition of C H (density 1.032) + // The old FrontBeam testbeam code uses a composition of C9 H10 (density 1.032) + // ... because it's easiest at the moment and not all that different from the fractional + // composition of the old tb code, take the Tile material (polysterene)... + GeoMaterial *Scint = materialManager->getMaterial("std::Polystyrene"); + if (!Scint) throw std::runtime_error("Error in FrontBeamConstructionH62002, std::Polystyrene is not found."); + + GeoMaterial *Mylar = materialManager->getMaterial("std::Mylar"); + if (!Mylar) throw std::runtime_error("Error in FrontBeamConstructionH62002, std::Mylar is not found."); + + + // // + //-------------------------------------------------------------------------------------------------// + + + + std::string AtlasVersion = geoModelSvc->atlasVersion(); + std::string LArVersion = geoModelSvc->LAr_VersionOverride(); + + std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion; + std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr"; + + + ////////////////////////////////////////////////////////////////// + // Define geometry + ////////////////////////////////////////////////////////////////// + + + // Here we creat the envelope for the Moveable FrontBeam Instrumentation. This code is repeated + // createEnvelope() method below. There should be a way to avoid this repitition. + + //------ The FrontBeam + + std::string baseName = "LAr::TBH62002"; + std::string H62002FrontBeamName = baseName + "::FrontBeam"; + + const double H62002FrontBeamXY = 2000.*CLHEP::mm; + const double H62002FrontBeamZ = 350.*CLHEP::mm; + + + GeoBox* H62002FrontBeamShape = new GeoBox( H62002FrontBeamXY, H62002FrontBeamXY, H62002FrontBeamZ ); + const GeoLogVol* H62002FrontBeamLogical = new GeoLogVol( H62002FrontBeamName, H62002FrontBeamShape, Air ); + + H62002FrontBeamPhysical = new GeoPhysVol(H62002FrontBeamLogical); + //H62002FrontBeamPhysical->add( new GeoNameTag("LArTBFrontBeamPos") ); + + + + + + //------ W1,W2,B1 Scintillators + // In the old stand-alone code, all three were round with a radius of 5cm + // and 7.5mm thickness. + // Logbooks in the control-room say that their xyz sizes are: + // B1 : 30 x 30 x 10 CLHEP::mm + // W1,2 : 150 x 150 x 10 CLHEP::mm + // They are certainly not round, so stick with the logbook values + // The beam sees the instrumentation in the following order: + // W1, W2, B1, MWPC5 + + log << "Create Front Scintillators ..." << std::endl; + + const double Wxy= 75.0*CLHEP::mm; + const double Wz = 5.0*CLHEP::mm; + const double Bxy= 15.0*CLHEP::mm; + const double Bz = 5.0*CLHEP::mm; + + std::vector<double> v_ScintXY; + std::vector<double> v_ScintZ; + v_ScintXY.push_back(Wxy); + v_ScintXY.push_back(Wxy); + v_ScintXY.push_back(Bxy); + v_ScintZ.push_back(170.*CLHEP::mm); + v_ScintZ.push_back(200.*CLHEP::mm); + v_ScintZ.push_back(340.*CLHEP::mm); + + // Create one Scintillator and place it twice along z: + + GeoBox* ScintShapeW = new GeoBox(Wxy, Wxy, Wz); + GeoBox* ScintShapeB = new GeoBox(Bxy, Bxy, Bz); + std::string ScintName = baseName + "::Scintillator"; + GeoLogVol* WScintLogical = new GeoLogVol( ScintName, ScintShapeW, Scint ); + GeoLogVol* BScintLogical = new GeoLogVol( ScintName, ScintShapeB, Scint ); + GeoPhysVol* WScintPhysical = new GeoPhysVol( WScintLogical ); + GeoPhysVol* BScintPhysical = new GeoPhysVol( BScintLogical ); + //WScintPhysical->add( new GeoNameTag(ScintName) ); + //BScintPhysical->add( new GeoNameTag(ScintName) ); + for ( unsigned int i = 0; i < v_ScintZ.size(); i++ ) { + H62002FrontBeamPhysical->add( new GeoIdentifierTag(i) ); + H62002FrontBeamPhysical->add( new GeoTransform( HepGeom::Translate3D( 0.*CLHEP::cm, 0.*CLHEP::cm, (v_ScintZ[ i ]-H62002FrontBeamZ) ) ) ) ; H62002FrontBeamPhysical->add( new GeoNameTag(ScintName) ); + + switch(i) { + case 0: case 1: { H62002FrontBeamPhysical->add( WScintPhysical ); break; } + case 2: { H62002FrontBeamPhysical->add( BScintPhysical ); break; } + default: { throw std::runtime_error("H62002FrontBeam wants too many Scintillators!!"); break; } + } + } + + //----- Done with Scintillators + + + + + //------ Get MWPC number 5 from LArGeoH6Cryostats + const double MwpcPos = 605.*CLHEP::mm; + double WireStep = 2.*CLHEP::mm; + MWPCConstruction mwpcXConstruction (WireStep); + GeoVPhysVol* mwpcEnvelope = mwpcXConstruction.GetEnvelope(); + H62002FrontBeamPhysical->add(new GeoIdentifierTag(5)); + H62002FrontBeamPhysical->add( new GeoTransform(HepGeom::Translate3D( 0.*CLHEP::cm, 0.*CLHEP::cm, (MwpcPos-H62002FrontBeamZ) ) ) ); + H62002FrontBeamPhysical->add(mwpcEnvelope); + //------ Done with creating an MWPC from LArGeoH6Cryostats + + + + + // End Moveable FrontBeam detectors + + + return H62002FrontBeamPhysical; +} + + + diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/HECConstructionH62002.cxx b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/HECConstructionH62002.cxx new file mode 100755 index 0000000000000000000000000000000000000000..38d577338c8ae2e5aa0fe493b5ff92b998afa8e1 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/HECConstructionH62002.cxx @@ -0,0 +1,865 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "LArGeoH62002Algs/HECConstructionH62002.h" + +#include "GeoModelInterfaces/AbsMaterialManager.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoPcon.h" +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelKernel/GeoTubs.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoVFullPhysVol.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoSerialDenominator.h" +#include "GeoModelKernel/GeoSerialIdentifier.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoSerialTransformer.h" +#include "GeoModelKernel/GeoIdentifierTag.h" +#include "GeoModelKernel/GeoShapeUnion.h" +#include "CLHEP/GenericFunctions/AbsFunction.hh" +#include "CLHEP/GenericFunctions/Variable.hh" +#include "CLHEP/GenericFunctions/Sin.hh" +#include "CLHEP/GenericFunctions/Cos.hh" +#include "StoreGate/StoreGateSvc.h" +#include "StoreGate/DataHandle.h" + +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "GeoModelUtilities/StoredPhysVol.h" + +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/Bootstrap.h" +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "GeoModelInterfaces/IGeoModelSvc.h" +#include <string> +#include <cmath> +#include <iostream> + + + +using namespace Genfun; +using namespace GeoXF; + + + +LArGeo::HECConstructionH62002::HECConstructionH62002() + :h6Phys(0) +{ + // access source of detector parameters + // m_parameters = LArGeo::VDetectorParameters::GetInstance(); +} + + +LArGeo::HECConstructionH62002::~HECConstructionH62002() +{ +} + + +GeoVFullPhysVol* LArGeo::HECConstructionH62002::GetEnvelope() +{ + + if (h6Phys) return (h6Phys); + + + ISvcLocator *svcLocator = Gaudi::svcLocator(); + IMessageSvc * msgSvc; + if (svcLocator->service("MessageSvc", msgSvc, true )==StatusCode::FAILURE) { + throw std::runtime_error("Error in HECConstruction, cannot access MessageSvc"); + } + MsgStream log(msgSvc, "HECConstruction"); + log << MSG::INFO; + log << "++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + log << "+ +" << std::endl; + log << "+ Start of HEC TB GeoModel definition +" << std::endl; + log << "+ +" << std::endl; + log << "++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + + + StoreGateSvc *detectorStore; + if (svcLocator->service("DetectorStore", detectorStore, false )==StatusCode::FAILURE) { + throw std::runtime_error("Error in HECConstruction, cannot access DetectorStore"); + } + + + 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!!"); + } + + + DataHandle<StoredMaterialManager> materialManager; + if (StatusCode::SUCCESS != detectorStore->retrieve(materialManager, std::string("MATERIALS"))) { + return NULL; + } + + + + //-----------------------------------------------------------------------------------// + // Get the materials that we shall use. // + // ----------------------------------------------------------------------------------// + + //const GeoMaterial *air = materialManager->getMaterial("std::Air"); + + GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon"); + if (!LAr) throw std::runtime_error("Error in HECConstruction, std::LiquidArgon is not found."); + + GeoMaterial *Iron = materialManager->getMaterial("std::Iron"); + if (!Iron) throw std::runtime_error("Error in HECConstruction, std::Iron is not found."); + + GeoMaterial *Copper = materialManager->getMaterial("std::Copper"); + if (!Copper) throw std::runtime_error("Error in HECConstruction, std::Copper is not found."); + + GeoMaterial *Kapton = materialManager->getMaterial("std::Kapton"); + if (!Kapton) throw std::runtime_error("Error in HECConstruction, std::Kapton is not found."); + + + + 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"; + + const IRDBRecordset *hadronicEndcap = pAccessSvc->getRecordset("HadronicEndcap",detectorKey, detectorNode); + const IRDBRecordset *hecLongitudinalBlock = pAccessSvc->getRecordset("HecLongitudinalBlock",detectorKey, detectorNode); + if(!hadronicEndcap) throw std::runtime_error("Error in HECConstruction: hadronicEendcap not found"); + if(!hecLongitudinalBlock) throw std::runtime_error("Error in HECConstruction: hecLongitudinalBlock not found"); + + + //------------------------------------------------------------------ + // First some sort of a mother + //-----------------------------------------------------------------------------------// + + // This creates a "mother wedge", which we can then place into the cryostat. + // (Not the greatest way of doing it... Needs to be fixed.) + // Maybe the best way would be to declare a union of front and rear module shapes? + + // std::string tempHECName = "LAr::H62002::HEC::MotherVolume"; + std::string tempHECName = "LAr::Endcap::Cryostat::MotherVolume"; + double HECMotherZplan[] = { 0. , 1350. }; + double HECMotherRin[] = { 372. , 372. }; + double HECMotherRout[] = { 2030. , 2030. }; + int lastPlaneHEC = ( sizeof(HECMotherZplan) / sizeof(double) ); + + + double moduleDeltaPhi = 2.*M_PI/32. ; // = 11.25*CLHEP::deg; + double phiStart [] = {-19. , -18. } ; + double hecPhistart[] = { phiStart[0]*M_PI/32 , phiStart[1]*M_PI/32 } ; + double modulePhistart[] = { (phiStart[0]+2.)*M_PI/32 , (phiStart[1]+2.)*M_PI/32 } ; + + + GeoPcon* HECMotherShape = new GeoPcon(hecPhistart[0], 3.*M_PI/16. ); + + for ( int i = 0; i != lastPlaneHEC; ++i ) + { + HECMotherShape->addPlane( HECMotherZplan[i], HECMotherRin[i], HECMotherRout[i]); + } + + const GeoLogVol *h6Log = new GeoLogVol("HECMother", HECMotherShape, LAr); + h6Phys = new GeoFullPhysVol(h6Log); + + std::string tag = std::string("HEC1_POS"); + StatusCode status; + + StoredPhysVol *sPhysVol = new StoredPhysVol(h6Phys); + status=detectorStore->record(sPhysVol,tag); + if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str()); + + + + //---------------------------------------------------------------- + // LAr HEC GEOMETRY + //---------------------------------------------------------------- + // + // .... different sets of indeces: + // -- iwheel -- 0,1 -- Front and Rear Wheels + // -- islice -- 0,1,2 -- slices refer to the LAr gaps + // -- idepth -- 0-4 -- longitudinal samplings (0-2 Front;3,4 Rear) + // -- itie -- 0-3 -- radial tierod position + + + // Some volumes and related items we have to declare here. + + // Those with index - iwheel: + // First Absorber + GeoTubs* solidFirstAbsorber[2]; + const GeoLogVol* logiFirstAbsorber[2]; + GeoPhysVol* physiFirstAbsorber[2]; + double firstAbsorber[5]; + // TieRod in the gap + GeoTubs* solidTieRod[2]; + const GeoLogVol* logiTieRod[2]; + GeoPhysVol* physiTieRod[2]; + // TieRod in absorbers + GeoTubs* solidAbsorberTieRod[2]; + const GeoLogVol* logiAbsorberTieRod[2]; + GeoPhysVol* physiAbsorberTieRod[2]; + GeoTubs* solidAbsorberTieRodRear[2]; + const GeoLogVol* logiAbsorberTieRodRear[2]; + GeoPhysVol* physiAbsorberTieRodRear[2]; + double tieRodPositionX[4]; // 4 radial tie rod locations + double tieRodPositionY[4]; + double tieRodDiameter[2]; // 2 sizes for the two wheels + double spacerDiameter[2]; + + double ztie[2]; // This is the +/- z length of the tie rod in the LAr gap + ztie[0]=-0.227825*CLHEP::cm; + ztie[1]= 0.227825*CLHEP::cm; + double rodSize = 0.39435*CLHEP::cm; + + + + + // Those with index - islice: + // Slice + GeoTubs* solidSlice[3]; + const GeoLogVol* logiSlice[3]; + GeoPhysVol* physiSlice[3]; + // Absorber + double radialShift = 1.02*CLHEP::cm; // absorbers are adjusted by this amount + GeoTubs* solidFrontAbsorber[2]; + const GeoLogVol* logiFrontAbsorber[2]; + GeoPhysVol* physiFrontAbsorber[2]; + GeoTubs* solidRearAbsorber; + const GeoLogVol* logiRearAbsorber; + GeoPhysVol* physiRearAbsorber; + + + // Those with index - idepth: + // Depth = longitudinal samplings + int gapNumber[5]; + GeoTubs* solidDepth[5]; + const GeoLogVol* logiDepth[5]; + GeoPhysVol* physiDepth[5]; + + + // And some that are just more convenient here: + // EstBoard + GeoTubs* solidEstBoard; + const GeoLogVol* logiEstBoard; + GeoPhysVol* physiEstBoard; + // PadBoard + GeoTubs* solidPadBoard; + const GeoLogVol* logiPadBoard; + GeoPhysVol* physiPadBoard; + + + + // And here are some numbers: + + int numberZplane = 6; // total number of z-planes needed for HEC volume + int numberFrontZplane = 4; // number of z-planes needed for front HEC volume + int depthNumber = 5; // number of longitudinal readout segments + //int sliceNumber = 3; // LAr gap segmentation + double depthSize[5]; // z dimension of longitudinal readout segments + double kaptonPosition[3]; + double kaptonWidth[3]; + + log << MSG::DEBUG << " In the H6 2002 HEC Constr. GetEnvelope - Here we get database things " << std::endl; + + + + // set the number of Front and Rear Modules in the testbeam: + int moduleNumberFront = 3; + int moduleNumberRear = 2; + // radial dimensions of the modules: + double moduleRinner1 = (*hecLongitudinalBlock)[0]->getDouble("BLRMN")*CLHEP::cm; + double moduleRinner2 = (*hecLongitudinalBlock)[1]->getDouble("BLRMN")*CLHEP::cm; + double moduleRouter = (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*CLHEP::cm; + // thickness of Cu pads, LAr gaps and inter-wheel gap: + double copperPad = (*hadronicEndcap)[0]->getDouble("COPPER")*CLHEP::cm; + double gapSize = (*hadronicEndcap)[0]->getDouble("LARG")*CLHEP::cm; + double betweenWheel = (*hadronicEndcap)[0]->getDouble("GAPWHL")*CLHEP::cm; + + + for (int idepth=0; idepth < depthNumber; ++idepth) + { + depthSize[idepth] = (*hecLongitudinalBlock)[idepth]->getDouble("BLDPTH")*CLHEP::cm; + firstAbsorber[idepth]= (*hecLongitudinalBlock)[idepth]->getDouble("PLATE0")*CLHEP::cm; + gapNumber[idepth] = (int) (*hecLongitudinalBlock)[idepth]->getDouble("BLMOD"); + } + + for (int ikapton=0; ikapton < 3; ++ikapton) + { + std::ostringstream A0STR; + A0STR << "_" << ikapton; + const std::string A0 = A0STR.str(); + kaptonPosition[ikapton] = (*hadronicEndcap)[0]->getDouble("KPTPOS"+A0)*CLHEP::cm; + kaptonWidth[ikapton] = (*hadronicEndcap)[0]->getDouble("KPTWID"+A0)*CLHEP::cm; + } + + for (int itie=0; itie < 4; ++itie) + { + std::ostringstream A0STR; + A0STR << "_" << itie; + const std::string A0 = A0STR.str(); + tieRodPositionX[itie] = (*hadronicEndcap)[0]->getDouble("RODPOSX"+A0)*CLHEP::cm; + tieRodPositionY[itie] = (*hadronicEndcap)[0]->getDouble("RODPOSR"+A0)*CLHEP::cm; + } + + for (int i=0; i < 2; ++i) + { + std::ostringstream A0STR; + A0STR << "_" << i; + const std::string A0 = A0STR.str(); + tieRodDiameter[i] = (*hadronicEndcap)[0]->getDouble("RODDIM"+A0)*CLHEP::cm; + spacerDiameter[i] = (*hadronicEndcap)[0]->getDouble("SPCDIM"+A0)*CLHEP::cm; + } + + + double frontAbsThickness = (*hadronicEndcap)[0]->getDouble("PLATE_0")*CLHEP::cm; + double rearAbsThickness = (*hadronicEndcap)[0]->getDouble("PLATE_1")*CLHEP::cm; + + // Radial dimensions and z-plane locations + double zCoordinate[] = {0.0*CLHEP::cm, depthSize[0], depthSize[0], 816.51*CLHEP::mm, 816.51*CLHEP::mm, 1350.*CLHEP::mm }; + double innerRadius[] = {moduleRinner1,moduleRinner1, + moduleRinner2,moduleRinner2,moduleRinner2,moduleRinner2,}; + + double absorberPositionZ [5]; + //double slicePositionZ [5]; + int sliceCopyNo[]={0,0,0,0,0}; + for(int i=0; i<depthNumber; i++) // Testbeam: Front Module: i=0,1,2 Rear Module: i=3,4 + { + if (i<3) absorberPositionZ[i]=firstAbsorber[i]+ gapSize+ frontAbsThickness/2.0 -depthSize[i]/2.0; + if (i>2) absorberPositionZ[i]=firstAbsorber[i]+ gapSize+ rearAbsThickness/2.0 -depthSize[i]/2.0; + //slicePositionZ[i]=firstAbsorber[i]+ gapSize/2.0 -depthSize[i]/2.0; + + if (i>0) sliceCopyNo[i] += sliceCopyNo[i-1]+gapNumber[i-1]; + } + + + + + // And here come the important names...: + std::string hecFrontName = "LAr::HEC::LiquidArgon"; + std::string hecRearName = "LAr::HEC::LiquidArgon"; + + std::string frontmoduleName = "LAr::HEC::Module"; + std::string rearmoduleName = "LAr::HEC::Module"; + + std::string depthFrontName = frontmoduleName + "::Depth"; + std::string depthRearName = rearmoduleName + "::Depth"; + std::string sliceFrontName = depthFrontName + "::Slice"; + std::string sliceRearName = depthRearName + "::Slice"; + std::string absorberFrontName = depthFrontName + "::Absorber"; + std::string absorberRearName = depthRearName + "::Absorber"; + std::string firstFrontAbsorberName= depthFrontName + "::FirstFrontAbsorber"; + std::string firstRearAbsorberName = depthRearName + "::FirstRearAbsorber"; + std::string electrodeFrontName = sliceFrontName + "::Electrode"; + std::string electrodeRearName = sliceRearName + "::Electrode"; + std::string copperFrontName = electrodeFrontName + "::Copper"; + std::string copperRearName = electrodeRearName + "::Copper"; + std::string tieRodName = sliceFrontName + "::TieRod"; + std::string tieRodFrontName = sliceFrontName + "::TieRod"; + std::string tieRodRearName = sliceRearName + "::TieRod"; + + + + log << MSG::DEBUG << " In the H6 2002 HEC Constr. GetEnvelope - Start to assemble HEC " << std::endl; + + + //---------------------------------------------------------------- + // Front HEC + //---------------------------------------------------------------- + + // setting up the overal Front HEC volume: + + GeoPcon* solidFrontHEC = new GeoPcon( hecPhistart[0], moduleNumberFront*moduleDeltaPhi); + for (int i=0; i< numberFrontZplane; i++) + { + solidFrontHEC->addPlane(zCoordinate[i],innerRadius[i], moduleRouter); + } + const GeoLogVol* logicFrontHEC = new GeoLogVol(hecFrontName, solidFrontHEC , LAr); + GeoPhysVol* physiFrontHEC = new GeoPhysVol(logicFrontHEC); + h6Phys->add(physiFrontHEC); + + + //---------------------------------------------------------------- + // Rear HEC + //---------------------------------------------------------------- + + // setting up the overal Rear HEC volume: + + GeoPcon* solidRearHEC = new GeoPcon( hecPhistart[1], moduleNumberRear*moduleDeltaPhi); + for (int i=numberFrontZplane; i< numberZplane; i++) + { + solidRearHEC->addPlane(zCoordinate[i],innerRadius[i], moduleRouter); + } + + const GeoLogVol* logicRearHEC = new GeoLogVol(hecRearName, solidRearHEC , LAr); + GeoPhysVol* physiRearHEC = new GeoPhysVol(logicRearHEC); + h6Phys->add(physiRearHEC); + + + + // Define the generic Front and Rear modules. + + //---------------------------------------------------------------- + // HEC FrontModule + //---------------------------------------------------------------- + // FrontModule + + GeoPcon* solidFrontModule = new GeoPcon(modulePhistart[0], moduleDeltaPhi); + + for (int i=0; i< numberFrontZplane; i++) + { + solidFrontModule->addPlane(zCoordinate[i],innerRadius[i], moduleRouter); + } + const GeoLogVol* logicFrontModule = new GeoLogVol(frontmoduleName, solidFrontModule , LAr); + GeoPhysVol* physiFrontModule = new GeoPhysVol(logicFrontModule); + + //---------------------------------------------------------------- + // HEC RearModule + //---------------------------------------------------------------- + + GeoPcon* solidRearModule = new GeoPcon(modulePhistart[0], moduleDeltaPhi); + for (int i=numberFrontZplane; i< numberZplane; i++) + { + double tempZ=zCoordinate[i]; + if (i==4) (tempZ = tempZ + betweenWheel) ; // start the rear module after the inter-wheel gap. + solidRearModule->addPlane(tempZ, innerRadius[i], moduleRouter); + } + const GeoLogVol* logicRearModule = new GeoLogVol(rearmoduleName, solidRearModule , LAr); + GeoPhysVol* physiRearModule = new GeoPhysVol(logicRearModule); + + + + // At this point we have a physiFrontHEC and a physiRearHEC + // as well as a physiFrontModule and a physiRearModule .............................. + + // Now "multiply" the modules and insert them into the LAr HEC volumes + + //---------------------------------------------------------------- + // Place FrontModules into FrontHEC wheel and RearModule into RearHEC wheel + //---------------------------------------------------------------- + Genfun::Variable Index; + Genfun::GENFUNCTION ModuleRotationAngle = -moduleDeltaPhi + moduleDeltaPhi*Index; + GeoXF::TRANSFUNCTION tf = GeoXF::Pow(HepGeom::RotateZ3D(1.0),ModuleRotationAngle); + + + GeoSerialIdentifier *sIF = new GeoSerialIdentifier(1); + GeoSerialTransformer *sTF = new GeoSerialTransformer (physiFrontModule,&tf, moduleNumberFront); + physiFrontHEC->add(sIF); + physiFrontHEC->add(sTF); + + Genfun::GENFUNCTION ModuleRotationAngleR = -moduleDeltaPhi/2. + moduleDeltaPhi*Index; + GeoXF::TRANSFUNCTION tr = GeoXF::Pow(HepGeom::RotateZ3D(1.0),ModuleRotationAngleR); + + GeoSerialIdentifier *sIR = new GeoSerialIdentifier(2); + GeoSerialTransformer *sTR = new GeoSerialTransformer (physiRearModule,&tr, moduleNumberRear); + physiRearHEC->add(sIR); + physiRearHEC->add(sTR); + + + //---------------------------------------------------------------- + // Sensitive slicegap - Front + //---------------------------------------------------------------- + for(int islice=0; islice<2; islice++) + { + if (islice==0) + {solidSlice[islice] = new GeoTubs(moduleRinner1,moduleRouter,gapSize/2., + modulePhistart[0],moduleDeltaPhi); } + else + {solidSlice[islice] = new GeoTubs(moduleRinner2,moduleRouter,gapSize/2., + modulePhistart[0],moduleDeltaPhi); } + logiSlice[islice] = new GeoLogVol(sliceFrontName, solidSlice[islice], LAr); + physiSlice[islice] = new GeoPhysVol(logiSlice[islice]); + } + + //---------------------------------------------------------------- + // Sensitive slicegap - Rear + //---------------------------------------------------------------- + for(int islice=2; islice<3; islice++) + { + solidSlice[islice] = new GeoTubs(moduleRinner2,moduleRouter,gapSize/2., + modulePhistart[0],moduleDeltaPhi); + logiSlice[islice] = new GeoLogVol(sliceRearName, solidSlice[islice], LAr); + physiSlice[islice] = new GeoPhysVol(logiSlice[islice]); + } + + + //---------------------------------------------------------------- + // Absorbers , the inner and outer Radius are smaller by radialShift + // but positionned in the center of depth. this alows + // to have 2 CLHEP::mm gap between the copper plates of neighbor FrontModules + //---------------------------------------------------------------- + + // Two different Absorbers for the front depths: + solidFrontAbsorber[0] = new GeoTubs(moduleRinner1-radialShift,moduleRouter-radialShift,frontAbsThickness/2., + modulePhistart[0],moduleDeltaPhi); + solidFrontAbsorber[1] = new GeoTubs(moduleRinner2-radialShift,moduleRouter-radialShift,frontAbsThickness/2., + modulePhistart[0],moduleDeltaPhi); + + for (int frontabsorberNo=0;frontabsorberNo<2;frontabsorberNo++) + { + logiFrontAbsorber[frontabsorberNo] = new GeoLogVol(absorberFrontName, + solidFrontAbsorber[frontabsorberNo], Copper); + physiFrontAbsorber[frontabsorberNo] = new GeoPhysVol(logiFrontAbsorber[frontabsorberNo]); + } + + // there is only one rearabsorber for the two rear depths: + solidRearAbsorber = new GeoTubs(moduleRinner2-radialShift,moduleRouter-radialShift,rearAbsThickness/2., + modulePhistart[0],moduleDeltaPhi); + logiRearAbsorber = new GeoLogVol(absorberRearName,solidRearAbsorber, Copper); + physiRearAbsorber = new GeoPhysVol(logiRearAbsorber); + + + //---------------------------------------------------------------- + // First Absorbers at the "entrance" of each wheel: + //---------------------------------------------------------------- + + solidFirstAbsorber[0] = new GeoTubs(moduleRinner1-radialShift,moduleRouter-radialShift, + firstAbsorber[0]/2., modulePhistart[0],moduleDeltaPhi); + logiFirstAbsorber[0] = new GeoLogVol(firstFrontAbsorberName, solidFirstAbsorber[0], Copper); + physiFirstAbsorber[0] = new GeoPhysVol(logiFirstAbsorber[0]); + physiFirstAbsorber[0]->add(new GeoIdentifierTag(50)); + + + solidFirstAbsorber[1] = new GeoTubs(moduleRinner2-radialShift,moduleRouter-radialShift, + firstAbsorber[3]/2., modulePhistart[0],moduleDeltaPhi); + logiFirstAbsorber[1] = new GeoLogVol(firstRearAbsorberName, solidFirstAbsorber[1], Copper); + physiFirstAbsorber[1] = new GeoPhysVol(logiFirstAbsorber[1]); + physiFirstAbsorber[1]->add(new GeoIdentifierTag(51)); + + + + //---------------------------------------------------------------- + // Place 3 depths into 1 generic FrontModule of HEC + //---------------------------------------------------------------- + + double depthPositionZ = 0.; // initialized here - it increases as we work through the depths + + + for(int idepth=0; idepth<3; idepth++) // Front Module: idepth=0,1,2 + { + if (idepth==0) + {solidDepth[idepth]=new GeoTubs(moduleRinner1,moduleRouter,depthSize[idepth]/2., + modulePhistart[0],moduleDeltaPhi);} + else + {solidDepth[idepth]=new GeoTubs(moduleRinner2,moduleRouter,depthSize[idepth]/2., + modulePhistart[0],moduleDeltaPhi);} + + logiDepth[idepth] =new GeoLogVol(depthFrontName, solidDepth[idepth], LAr); + physiDepth[idepth]=new GeoPhysVol(logiDepth[idepth]); + + + // Placement of the actual depth: + depthPositionZ +=depthSize[idepth]/2.; + physiFrontModule->add(new GeoIdentifierTag(100+idepth)); + physiFrontModule->add(new GeoTransform(HepGeom::Translate3D(0,0,depthPositionZ))); + physiFrontModule->add(physiDepth[idepth]); + + + + + // Now put absorbers into the depth: + depthPositionZ +=depthSize[idepth]/2.; + if (idepth==2) depthPositionZ +=betweenWheel; + + + + // Position of 8 sensitive gaps and absorbers in 3 depths of a Front Module + int islice = 1; + int frontabsorberNo = 1; + if(idepth==0) { islice=0; frontabsorberNo=0; } + else { islice=2; frontabsorberNo=1; } + + double slicePositionZ=firstAbsorber[idepth]+ gapSize/2.0 -depthSize[idepth]/2.0; + Genfun::Variable Index; + GeoXF::TRANSFUNCTION TS = GeoXF::Pow(HepGeom::TranslateZ3D(1.0),slicePositionZ + (frontAbsThickness+gapSize)*Index); + GeoXF::TRANSFUNCTION TA = HepGeom::TranslateY3D(-radialShift)*GeoXF::Pow(HepGeom::TranslateZ3D(1.0), + absorberPositionZ[idepth] + (frontAbsThickness+gapSize)*Index); + GeoSerialIdentifier *sI = new GeoSerialIdentifier(sliceCopyNo[idepth]); + GeoSerialTransformer *sTS = new GeoSerialTransformer(physiSlice[islice], &TS, gapNumber[idepth]); + GeoSerialTransformer *sTA = new GeoSerialTransformer(physiFrontAbsorber[frontabsorberNo],&TA, gapNumber[idepth]); + physiDepth[idepth]->add(sI); + physiDepth[idepth]->add(sTS); + physiDepth[idepth]->add(sI); + physiDepth[idepth]->add(sTA); + + } //for idepth + + + //---------------------------------------------------------------- + // Place 2 depths into 1 generic Rear Module of HEC + //---------------------------------------------------------------- + + for(int idepth=3; idepth<5; idepth++) + { + depthPositionZ +=depthSize[idepth]/2.; + + // Now depth + solidDepth[idepth] = new GeoTubs(moduleRinner2,moduleRouter,depthSize[idepth]/2., + modulePhistart[0],moduleDeltaPhi); + logiDepth[idepth] = new GeoLogVol(depthRearName, solidDepth[idepth], LAr); + physiDepth[idepth] = new GeoPhysVol(logiDepth[idepth]); + + physiRearModule->add(new GeoIdentifierTag(100+idepth)); + physiRearModule->add(new GeoTransform(HepGeom::Translate3D(0,0,depthPositionZ))); + physiRearModule->add(physiDepth[idepth]); + + + depthPositionZ +=depthSize[idepth]/2.; + + + // Position 4 sensitive gaps and rear absorbers in 2 depths of a Rear Module: + int islice=2; + double slicePositionZ=firstAbsorber[idepth]+ gapSize/2.0 -depthSize[idepth]/2.0; + Genfun::Variable Index; + GeoXF::TRANSFUNCTION TS = GeoXF::Pow(HepGeom::TranslateZ3D(1.0),slicePositionZ + (rearAbsThickness+gapSize)*Index); + GeoXF::TRANSFUNCTION TA = HepGeom::TranslateY3D(-radialShift)*GeoXF::Pow(HepGeom::TranslateZ3D(1.0), + absorberPositionZ[idepth] + (rearAbsThickness+gapSize)*Index); + GeoSerialIdentifier *sI = new GeoSerialIdentifier(sliceCopyNo[idepth]); + GeoSerialTransformer *sTS = new GeoSerialTransformer(physiSlice[islice], &TS, gapNumber[idepth]); + GeoSerialTransformer *sTA = new GeoSerialTransformer(physiRearAbsorber,&TA, gapNumber[idepth]); + physiDepth[idepth]->add(sI); + physiDepth[idepth]->add(sTS); + physiDepth[idepth]->add(sI); + physiDepth[idepth]->add(sTA); + + } //for idepth + + + + // Add the 1/2 thickness front plates to the two modules: + + double firstAbsorberPositionZ = firstAbsorber[0]/2.- depthSize[0]/2.0; + physiDepth[0]->add(new GeoIdentifierTag(50)); + physiDepth[0]->add(new GeoTransform(HepGeom::Translate3D(0,-radialShift,firstAbsorberPositionZ))); + physiDepth[0]->add(physiFirstAbsorber[0]); + + + firstAbsorberPositionZ = firstAbsorber[3]/2.- depthSize[3]/2.0; + physiDepth[3]->add(new GeoIdentifierTag(51)); + physiDepth[3]->add(new GeoTransform(HepGeom::Translate3D(0,-radialShift,firstAbsorberPositionZ))); + physiDepth[3]->add(physiFirstAbsorber[1]); + + + + //---------------------------------------------------------------- + // Electronic boards of Front Slice + //---------------------------------------------------------------- + + for(int islice=0; islice<2; islice++) + { + int indexKapton=1; + if (islice==0) + { + solidPadBoard = new GeoTubs(moduleRinner1,moduleRouter,copperPad/2., + modulePhistart[0],moduleDeltaPhi); + solidEstBoard = new GeoTubs(moduleRinner1,moduleRouter,(kaptonWidth[indexKapton]/2.+kaptonWidth[0]), + modulePhistart[0],moduleDeltaPhi); + } + else + { + solidPadBoard = new GeoTubs(moduleRinner2,moduleRouter,copperPad/2., + modulePhistart[0],moduleDeltaPhi); + solidEstBoard = new GeoTubs(moduleRinner2,moduleRouter,(kaptonWidth[indexKapton]/2.+kaptonWidth[0]), + modulePhistart[0],moduleDeltaPhi); + } + logiPadBoard = new GeoLogVol(copperFrontName, solidPadBoard, Copper); + logiEstBoard = new GeoLogVol(electrodeFrontName, solidEstBoard, Kapton ); + + + double kaptonPositionZ = kaptonPosition[indexKapton]-gapSize/2.; + + physiEstBoard = new GeoPhysVol(logiEstBoard); + physiSlice[islice]->add(new GeoIdentifierTag(indexKapton)); + physiSlice[islice]->add(new GeoTransform(HepGeom::Translate3D(0,0,kaptonPositionZ))); + physiSlice[islice]->add(physiEstBoard); + + + if(indexKapton==1) + { + physiPadBoard = new GeoPhysVol(logiPadBoard); + physiEstBoard->add(new GeoIdentifierTag(indexKapton)); + physiEstBoard->add(new GeoTransform(HepGeom::Translate3D(0,0,0))); + physiEstBoard->add(physiPadBoard); + + } + + }//for islice + + + //---------------------------------------------------------------- + // Electronic boards of RearSlice + //---------------------------------------------------------------- + + + for(int islice=2; islice<3; islice++) + { + int indexKapton=1; + if (islice==0){ + solidPadBoard = new GeoTubs(moduleRinner1,moduleRouter,copperPad/2., + modulePhistart[0],moduleDeltaPhi); + solidEstBoard = new GeoTubs(moduleRinner1,moduleRouter,(kaptonWidth[indexKapton]/2.+kaptonWidth[0]), + modulePhistart[0],moduleDeltaPhi); + } + else{ + solidPadBoard = new GeoTubs(moduleRinner2,moduleRouter,copperPad/2., + modulePhistart[0],moduleDeltaPhi); + solidEstBoard = new GeoTubs(moduleRinner2,moduleRouter,(kaptonWidth[indexKapton]/2.+kaptonWidth[0]), + modulePhistart[0],moduleDeltaPhi); + } + logiPadBoard = new GeoLogVol(copperRearName, solidPadBoard, Copper); + logiEstBoard = new GeoLogVol(electrodeRearName, solidEstBoard, Kapton ); + + + double kaptonPositionZ = kaptonPosition[indexKapton]-gapSize/2.; + + physiEstBoard = new GeoPhysVol(logiEstBoard); + physiSlice[islice]->add(new GeoIdentifierTag(indexKapton)); + physiSlice[islice]->add(new GeoTransform(HepGeom::Translate3D(0,0,kaptonPositionZ))); + physiSlice[islice]->add(physiEstBoard); + + + if(indexKapton==1) + { + physiPadBoard = new GeoPhysVol(logiPadBoard); + physiEstBoard->add(new GeoIdentifierTag(indexKapton)); + physiEstBoard->add(new GeoTransform(HepGeom::Translate3D(0,0,0))); + physiEstBoard->add(physiPadBoard); + + }//if + + }//for islice + + //---------------------------------------------------------------- + // Tie rods in Slice + //---------------------------------------------------------------- + + // double rodSize = 0.85*CLHEP::cm; + for (int iwheel=0; iwheel<2; iwheel++) + { + solidTieRod[iwheel] = new GeoTubs(0.*CLHEP::cm,spacerDiameter[iwheel]/2.,rodSize/2., 0.*CLHEP::deg,360.*CLHEP::deg); + logiTieRod[iwheel] = new GeoLogVol(tieRodName, solidTieRod[iwheel], Iron); + } + + for(int islice=0; islice<3; islice++) { // loop over the 3 longitdinal depths + int numberTie=0; + if(islice==2) numberTie=1; // for the rear module + + int indexRod; + for(indexRod=1; indexRod<4; indexRod++) { // place all 7 rods: 3 pairs, one single + for(int iz=0;iz<2;iz++){ + + physiTieRod[numberTie] = new GeoPhysVol(logiTieRod[numberTie]); + physiSlice[islice]->add(new GeoIdentifierTag(indexRod)); + physiSlice[islice]->add(new GeoTransform(HepGeom::Translate3D(tieRodPositionX[indexRod], + -tieRodPositionY[indexRod],ztie[iz]))); + physiSlice[islice]->add(physiTieRod[numberTie]); + + + physiTieRod[numberTie] = new GeoPhysVol(logiTieRod[numberTie]); + physiSlice[islice]->add(new GeoIdentifierTag(indexRod)); + physiSlice[islice]->add(new GeoTransform(HepGeom::Translate3D(-tieRodPositionX[indexRod], + -tieRodPositionY[indexRod],ztie[iz]))); + physiSlice[islice]->add(physiTieRod[numberTie]); + + }//for iz (dealt with the rods that come in pairs) + } // for indexRod + for( int iz1=0;iz1<2;iz1++) + { + + physiTieRod[numberTie] = new GeoPhysVol(logiTieRod[numberTie]); + physiSlice[islice]->add(new GeoIdentifierTag(indexRod)); + physiSlice[islice]->add(new GeoTransform(HepGeom::Translate3D(tieRodPositionX[0],-tieRodPositionY[0],ztie[iz1]))); + physiSlice[islice]->add(physiTieRod[numberTie]); + + }//for iz1 (this dealt with the one last un-paired rod at the module's narrow end) + } // for islice + + //---------------------------------------------------------------- + // Tie rods in Absorbers + //---------------------------------------------------------------- + solidAbsorberTieRod[0] = new GeoTubs(0.*CLHEP::cm,tieRodDiameter[0]/2.,frontAbsThickness/2.,0.*CLHEP::deg,360.*CLHEP::deg); + solidAbsorberTieRod[1] = new GeoTubs(0.*CLHEP::cm,tieRodDiameter[1]/2.,rearAbsThickness/2.,0.*CLHEP::deg,360.*CLHEP::deg); + logiAbsorberTieRod[0] = new GeoLogVol(tieRodName,solidAbsorberTieRod[0],Iron); //,0,0,0); + logiAbsorberTieRod[1] = new GeoLogVol(tieRodName,solidAbsorberTieRod[1],Iron); //,0,0,0); + solidAbsorberTieRodRear[0] = new GeoTubs(0.*CLHEP::cm,tieRodDiameter[0]/2.,frontAbsThickness/2.,0.*CLHEP::deg,360.*CLHEP::deg); + solidAbsorberTieRodRear[1] = new GeoTubs(0.*CLHEP::cm,tieRodDiameter[1]/2.,rearAbsThickness/2.,0.*CLHEP::deg,360.*CLHEP::deg); + logiAbsorberTieRodRear[0] = new GeoLogVol(tieRodRearName,solidAbsorberTieRodRear[0],Iron); //,0,0,0); + logiAbsorberTieRodRear[1] = new GeoLogVol(tieRodRearName,solidAbsorberTieRodRear[1],Iron); //,0,0,0); + + + for(int islice=0; islice<2; islice++) + { + int indexR=0; + //if(islice>1) indexR=1; + int indexRod; + for(indexRod=1; indexRod<4; indexRod++) + { + physiAbsorberTieRod[indexR] = new GeoPhysVol(logiAbsorberTieRod[indexR]); + physiFrontAbsorber[islice]->add(new GeoIdentifierTag(indexRod)); + physiFrontAbsorber[islice]->add(new GeoTransform(HepGeom::Translate3D(tieRodPositionX[indexRod], + -(tieRodPositionY[indexRod]-radialShift), 0))); + physiFrontAbsorber[islice]->add(physiAbsorberTieRod[indexR]); + physiAbsorberTieRod[indexR] = new GeoPhysVol(logiAbsorberTieRod[indexR]); + physiFrontAbsorber[islice]->add(new GeoIdentifierTag(indexRod)); + physiFrontAbsorber[islice]->add(new GeoTransform(HepGeom::Translate3D(-tieRodPositionX[indexRod], + -(tieRodPositionY[indexRod]-radialShift), 0))); + physiFrontAbsorber[islice]->add(physiAbsorberTieRod[indexR]); + } + physiAbsorberTieRod[indexR] = new GeoPhysVol(logiAbsorberTieRod[indexR]); + physiFrontAbsorber[islice]->add(new GeoIdentifierTag(indexRod)); + physiFrontAbsorber[islice]->add(new GeoTransform(HepGeom::Translate3D(tieRodPositionX[0], + -(tieRodPositionY[0]-radialShift),0))); + + + physiFrontAbsorber[islice]->add(physiAbsorberTieRod[indexR]); + + } + + + int indexRod=1; + for(indexRod=1; indexRod<4; indexRod++) + { + physiAbsorberTieRodRear[1] = new GeoPhysVol(logiAbsorberTieRodRear[1]); + physiRearAbsorber->add(new GeoIdentifierTag(indexRod)); + physiRearAbsorber->add(new GeoTransform(HepGeom::Translate3D(tieRodPositionX[indexRod], + -(tieRodPositionY[indexRod]-radialShift), 0))); + physiRearAbsorber->add(physiAbsorberTieRodRear[1]); + + physiAbsorberTieRodRear[1] = new GeoPhysVol(logiAbsorberTieRodRear[1]); + physiRearAbsorber->add(new GeoIdentifierTag(indexRod)); + physiRearAbsorber->add(new GeoTransform(HepGeom::Translate3D(-tieRodPositionX[indexRod], + -(tieRodPositionY[indexRod]-radialShift), 0))); + + + physiRearAbsorber->add(physiAbsorberTieRodRear[1]); + } + + + //now the single tie rod at the narrow end: + physiAbsorberTieRodRear[1] = new GeoPhysVol(logiAbsorberTieRodRear[1]); + physiRearAbsorber->add(new GeoIdentifierTag(indexRod)); + physiRearAbsorber->add(new GeoTransform(HepGeom::Translate3D(tieRodPositionX[0], + -(tieRodPositionY[0]-radialShift),0))); + + + physiRearAbsorber->add(physiAbsorberTieRodRear[1]); + + + + + return h6Phys; + +} + + diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/LArDetectorFactoryH62002.cxx b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/LArDetectorFactoryH62002.cxx new file mode 100755 index 0000000000000000000000000000000000000000..ae8bd03dd209763893ae9d2e97d282071b4957d6 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/LArDetectorFactoryH62002.cxx @@ -0,0 +1,518 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "LArGeoH62002Algs/LArDetectorFactoryH62002.h" +#include "LArGeoH6Cryostats/H6CryostatConstruction.h" +#include "LArGeoH62002Algs/HECConstructionH62002.h" +#include "LArGeoH62002Algs/TableConstructionH62002.h" +#include "LArGeoH62002Algs/FrontBeamConstructionH62002.h" +#include "LArGeoH62002Algs/ExcluderConstruction.h" +#include "LArGeoH6Cryostats/WallsConstruction.h" + +#include "GeoModelInterfaces/IGeoModelSvc.h" +#include "GeoModelUtilities/DecodeVersionKey.h" +#include "GeoModelInterfaces/AbsMaterialManager.h" +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "GeoModelUtilities/StoredPhysVol.h" + +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoXF.h" +#include "GeoModelKernel/GeoSerialDenominator.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoSerialTransformer.h" +#include "CLHEP/GenericFunctions/AbsFunction.hh" +#include "CLHEP/GenericFunctions/Variable.hh" +#include "CLHEP/GenericFunctions/Sin.hh" +#include "CLHEP/GenericFunctions/Cos.hh" +#include "StoreGate/StoreGateSvc.h" +#include "StoreGate/DataHandle.h" + +// need if we want to use EMEC from LArGeoEndcap: +#include "LArGeoEndcap/EMECConstruction.h" +#include "LArGeoEndcap/EndcapPresamplerConstruction.h" + +// For run options : +#include "LArG4RunControl/LArGeoTBH1GeoOptions.h" + +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/Bootstrap.h" + +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBAccessSvc.h" + +#include "LArReadoutGeometry/EMECDetectorManager.h" +#include "LArReadoutGeometry/EMECDetectorRegion.h" +#include "LArReadoutGeometry/EMECDetDescr.h" + +#include "LArReadoutGeometry/HECDetectorManager.h" +#include "LArReadoutGeometry/HECDetDescr.h" +#include "GeoModelKernel/CellBinning.h" +#include "LArReadoutGeometry/HECLongBlock.h" +#include "LArReadoutGeometry/HECDetectorRegion.h" + +// V.N : Patch LAr materials +#include "LArGeoCode/LArMaterialManager.h" +// + +using namespace Genfun; +using namespace GeoXF; + + + + + +//LArDetectorFactoryH62002::LArDetectorFactoryH62002(StoreGateSvc *detStore) +LArGeo::LArDetectorFactoryH62002::LArDetectorFactoryH62002(StoreGateSvc *detStore) + : log(NULL), + m_cryoXpos(0), + m_tableYpos(0), + m_detectorStore(detStore), + m_detectorManager(0) +{ +} + + +LArGeo::LArDetectorFactoryH62002::~LArDetectorFactoryH62002() +{ +} + + +void LArGeo::LArDetectorFactoryH62002::getSimulationParameters() +{ + + StoreGateSvc* detStore; + const LArGeoTBH1GeoOptions *largeoTBH1geoOptions ; + StatusCode status; + + ISvcLocator* svcLocator = Gaudi::svcLocator(); + IMessageSvc * msgSvc; + + + status = svcLocator->service("MessageSvc", msgSvc); + + if(!status.isFailure()){ + log = new MsgStream(msgSvc, "LArDetectorFactory"); + } else { + throw std::runtime_error("LArDetectorFactory: cannot initialze message service"); + } + + + + + + + status = svcLocator->service("DetectorStore", detStore); + + + if( status.isSuccess() ) { + + + m_cryoXpos = 0.; + m_tableYpos = 0.; + + status = detStore->retrieve(largeoTBH1geoOptions, "LArGeoTBH1GeoOptions"); + if ( !status.isFailure() ) { + m_cryoXpos = largeoTBH1geoOptions->CryoXPosition(); + m_tableYpos = largeoTBH1geoOptions->TableYPosition(); + } + else + (*log)<< MSG::WARNING << "LArDectorFactoryH62002:\tCan't access LArGeoTBH1GeoOptions, using default values\n"; + } + + (*log)<< MSG::INFO<< endreq;; + (*log)<< MSG::INFO << " Use cryo X : " << m_cryoXpos << " CLHEP::mm" << endreq; + (*log)<< MSG::INFO << " Use table Y : " << m_tableYpos << " CLHEP::mm" << endreq; + + +} + + + + + +//## Other Operations (implementation) +void LArGeo::LArDetectorFactoryH62002::create(GeoPhysVol *world) +{ + + DataHandle<StoredMaterialManager> materialManager; + if (StatusCode::SUCCESS != m_detectorStore->retrieve(materialManager, std::string("MATERIALS"))) { + return; + } + + // V.N : Patch LAr materials + LArMaterialManager *lArMaterialManager = new LArMaterialManager(m_detectorStore); + lArMaterialManager->buildMaterials(); + // + + getSimulationParameters(); + + //-----------------------------------------------------------------------------------// + // Get the materials that we shall use. // + // ----------------------------------------------------------------------------------// + + const GeoMaterial *air = materialManager->getMaterial("std::Air"); + + // 4databa : // numbers taken from LArCalorimeter/LArG4TB/LArG4TBExpHall/src/LArG4TBEmecHecDetectorConstruction.cc + // (That's a mighty big hall.....) + double expHallX = 14000.*CLHEP::mm; + double expHallY = 14000.*CLHEP::mm; + double expHallZ = 50000.*CLHEP::mm; + //double cryoZpos = 12250.*CLHEP::mm; + //double cryoXrot = -90.*CLHEP::deg; + //double cryoXpos = m_cryoXpos * CLHEP::mm ; + //double cryoXpos = 0.*CLHEP::mm; // <-- Should be made available in RunOptions! (Perhaps default in DB...) + + //-----------------------------------------------------------------------------------// + // Next make the box that describes the shape of the expHall volume: // + // // + const GeoBox *expHallShape = new GeoBox(expHallX, expHallY, expHallZ); // + // // + // Bundle this with a material into a logical volume: // + // // + const GeoLogVol *expHallLog = new GeoLogVol("ExpHallLog", expHallShape, air); // + // // + // ..And create a physical volume: // + // // + GeoPhysVol *expHallPhys = new GeoPhysVol(expHallLog); // + // // + // Add this to the list of top level physical volumes: // + // // + //-----------------------------------------------------------------------------------// + + + // For the moment it's still hard-coded, but eventually we'll + // read a vector for translation and rotation from the database and apply it to the + // the element we want to position in the following order: + + + double Theta = -90. * CLHEP::deg; + double Phi = 0. * CLHEP::deg; + + CLHEP::HepRotation Mrot ; + Mrot.rotateX(Theta); + Mrot.rotateZ(Phi); + CLHEP::Hep3Vector pos3Vector( m_cryoXpos*CLHEP::mm, 0.*CLHEP::mm, 12250.*CLHEP::mm ); + + H6CryostatConstruction H6CryoCons; + GeoVPhysVol* Envelope = 0; + Envelope = H6CryoCons.GetEnvelope(); + expHallPhys->add(new GeoNameTag("LAr")); + //expHallPhys->add( new GeoTransform( HepGeom::Translate3D(pos3Vector)*HepGeom::RotateX3D(Theta)*HepGeom::RotateZ3D(Phi) )); + expHallPhys->add( new GeoTransform( HepGeom::Transform3D(Mrot, pos3Vector) ) ); + expHallPhys->add(Envelope); + + + + //Add the walls in front of the cryostat: + WallsConstruction* WallsConstruction2002 = new WallsConstruction(); + const double H62002WallsPos = 10182.*CLHEP::mm; // A wild guess at the moment..... + { + GeoVPhysVol* frontwalls = 0; + frontwalls = WallsConstruction2002->GetEnvelope(); + if(frontwalls !=0 && expHallPhys !=0){ + expHallPhys->add( new GeoNameTag("LAr")); + expHallPhys->add( new GeoTransform( HepGeom::TranslateZ3D(H62002WallsPos) ) ); + expHallPhys->add(frontwalls); + } + } + + + //Add the table instrumentation: + TableConstructionH62002* TableConstruction = new TableConstructionH62002(); + const double H62002TablePos = 8320.*CLHEP::mm; + { + GeoVPhysVol* table = 0; + table = TableConstruction->GetEnvelope(); + if(table !=0 && expHallPhys !=0){ + expHallPhys->add( new GeoNameTag("LAr")); + expHallPhys->add( new GeoTransform( HepGeom::TranslateZ3D(H62002TablePos) ) ); + expHallPhys->add(table); + } + } + (*log) << MSG::DEBUG << "Built Table Instrumentation " << endreq; + + //Add the front beam instrumentation: + FrontBeamConstructionH62002* FrontBeamConstruction = new FrontBeamConstructionH62002(); + const double H62002FrontBeamPos = -20215.5*CLHEP::mm; // (Use this to get the Front dets. in Peter Schacht's position) + //const double H62002FrontBeamPos = -20439.*CLHEP::mm; // (according to old code: [-21600+801+350]*CLHEP::mm) + { // (with 350=1/2 length of FrontBeam volume) + GeoVPhysVol* front = 0; + front = FrontBeamConstruction->GetEnvelope(); + if(front !=0 && expHallPhys !=0){ + expHallPhys->add( new GeoNameTag("LAr")); + expHallPhys->add( new GeoTransform( HepGeom::TranslateZ3D(H62002FrontBeamPos) ) ); + expHallPhys->add(front); + } + } + (*log) << MSG::DEBUG << "Built Frontbeam Instrumentation " << endreq; + + + + + // Get LArPhysical, which is the actual cryostat + + GeoPhysVol* LArPhysical = H6CryoCons.GetLArPhysical(); + + (*log) << MSG::DEBUG << "Got the Cryostat ready" << endreq; + + + // For the moment it is still commented out until I have + // its true geometry confirmed; But really it is ready to go: + // Add Rohacell Excluder + double ThetaRoha = 0. * CLHEP::deg; + double PhiRoha = 0. * CLHEP::deg; + CLHEP::HepRotation MrotRoha ; + MrotRoha.rotateX(ThetaRoha); + MrotRoha.rotateZ(PhiRoha); + CLHEP::Hep3Vector pos3Roha( 0*CLHEP::mm, 0.0*CLHEP::mm , 0.*CLHEP::mm); + + ExcluderConstruction* excluderConstruction = new ExcluderConstruction(); + { + GeoPhysVol* excluder = 0; + excluder = excluderConstruction->GetEnvelope(); + if(excluder !=0 && LArPhysical !=0){ + LArPhysical->add( new GeoNameTag("LAr::H6::Cryostat::Excluder")); + LArPhysical->add(excluder); + } + } + + (*log) << MSG::DEBUG << "Built Rohacell Excluder " << endreq; + + + + // Here include EMEC (from LArGeoTBEndcap): + + EMECDetectorManager *emecDetectorManager = new EMECDetectorManager(); + + + double ThetaEmec = -90. * CLHEP::deg; + double PhiEmec = 180. * CLHEP::deg; + + CLHEP::HepRotation MrotEmec ; + MrotEmec.rotateX(ThetaEmec); + MrotEmec.rotateZ(PhiEmec); + // CLHEP::Hep3Vector pos3Emec( 0*CLHEP::mm, 869.0*CLHEP::mm , 1720.*CLHEP::mm); + CLHEP::Hep3Vector pos3Emec( 0*CLHEP::mm, 808.0*CLHEP::mm , 1720.*CLHEP::mm); + + //use this line for physical construction of the EMEC outer wheel only: + EMECConstruction* emecConstruction = new EMECConstruction(true, true, true); + + GeoVFullPhysVol* emecEnvelope = emecConstruction->GetEnvelope(); + LArPhysical->add(new GeoNameTag("LAr")); + LArPhysical->add( new GeoTransform( HepGeom::Transform3D(MrotEmec, pos3Emec) ) ); + LArPhysical->add(emecEnvelope); + { + StoredPhysVol *sEmecOuterWheel; + if (StatusCode::SUCCESS==m_detectorStore->retrieve(sEmecOuterWheel, "EMEC_OUTER_WHEEL_POS" )) { + GeoFullPhysVol *emecEnvelope= sEmecOuterWheel->getPhysVol(); + // Outer Wheel Sampling 1 Region 0: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,1,0,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + + // Outer Wheel Sampling 1 Region 1: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,1,1,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + // Outer Wheel Sampling 1 Region 2: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,1,2,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + // Outer Wheel Sampling 1 Region 3: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,1,3,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + // Outer Wheel Sampling 1 Region 4: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,1,4,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + // Outer Wheel Sampling 1 Region 5: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,1,5,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + // Outer Wheel Sampling 2 Region 0: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,32,48); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,2,0,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + // Outer Wheel Sampling 2 Region 1: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,32,48); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,2,1,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + // Outer Wheel Sampling 3 Region 0: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,32,48); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,3,0,0,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + } + + StoredPhysVol *sEmecInnerWheel; + if (StatusCode::SUCCESS==m_detectorStore->retrieve(sEmecInnerWheel, "EMEC_INNER_WHEEL_POS" )) { + GeoFullPhysVol *emecEnvelope= sEmecInnerWheel->getPhysVol(); + // Inner Wheel Sampling 1 Region 0: + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,1,0,1,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + // Inner Wheel Sampling 2 Region 0: + + { + CellBinning phiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *detDescr = new EMECDetDescr(emecDetectorManager,2,0,1,phiBinning); + EMECDetectorRegion *region = new EMECDetectorRegion(emecEnvelope,detDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(region); + } + } + } + + + double ThetaPS = -90. * CLHEP::deg; + double PhiPS = 180. * CLHEP::deg; + CLHEP::HepRotation MrotPS ; + MrotPS.rotateX(ThetaPS); + MrotPS.rotateZ(PhiPS); + //CLHEP::Hep3Vector pos3PS( 0*CLHEP::mm, 945.5*CLHEP::mm , 1720.*CLHEP::mm); + CLHEP::Hep3Vector pos3PS( 0*CLHEP::mm, 888.5*CLHEP::mm , 1720.*CLHEP::mm); + + //double zPSpos = -869. -(61. +2. +13.5); + //std::string PresamplerName = baseName + "::Presampler::"; + EndcapPresamplerConstruction* PresamplerConstruction = new EndcapPresamplerConstruction(true); + GeoFullPhysVol* PresamplerEnvelope = PresamplerConstruction->Envelope(); + if ( PresamplerEnvelope != 0 && LArPhysical != 0 ) { + //LArPhysical->add( new GeoTransform( HepGeom::Translate3D(pos3PS)*HepGeom::RotateX3D(ThetaPS)*HepGeom::RotateZ3D(PhiPS) )); + LArPhysical->add( new GeoTransform( HepGeom::Transform3D(MrotPS, pos3PS) ) ); + LArPhysical->add( PresamplerEnvelope ); + } + { + // + CellBinning presamplerPhiBinning(M_PI/2-M_PI/8,M_PI/2+M_PI/8,8,12); + EMECDetDescr *presamplerDetDescr = new EMECDetDescr(emecDetectorManager,0,0,0,presamplerPhiBinning); + EMECDetectorRegion *presamplerRegion = new EMECDetectorRegion(PresamplerEnvelope,presamplerDetDescr,EMECDetectorRegion::POS); + emecDetectorManager->addDetectorRegion(presamplerRegion); + } + + (*log) << MSG::DEBUG << "Built EMEC and Presampler " << endreq; + + + + // Add HEC + double ThetaHec = 90. * CLHEP::deg; + double PhiHec = 0. * CLHEP::deg; + CLHEP::HepRotation MrotHec ; + MrotHec.rotateX(ThetaHec); + MrotHec.rotateZ(PhiHec); + CLHEP::Hep3Vector pos3Hec( 0*CLHEP::mm, 233.0*CLHEP::mm , 1720.*CLHEP::mm); + + HECConstructionH62002* hecConstruction = new HECConstructionH62002(); + { + GeoVFullPhysVol* hecEnvelope = 0; + hecEnvelope = hecConstruction->GetEnvelope(); + if(hecEnvelope !=0 && LArPhysical !=0){ + LArPhysical->add( new GeoNameTag("LAr")); + //LArPhysical->add( new GeoTransform( HepGeom::Translate3D(pos3Hec)*HepGeom::RotateX3D(ThetaHec)*HepGeom::RotateZ3D(PhiHec) )); + LArPhysical->add( new GeoTransform( HepGeom::Transform3D(MrotHec, pos3Hec) ) ); + LArPhysical->add(hecEnvelope); + } + } + + HECDetectorManager *hecDetManager = new HECDetectorManager(); + + // + // Add descriptors to the HEC detector manager: + // + + unsigned int currentBlock=0; + for (unsigned int s=0;s<3;s++) { + unsigned int nBlocks = s==0 ? 1:2; + unsigned int width = s==2 ? 2: 3; + for (unsigned int r=0;r<2;r++) { + unsigned int nPhi = r==0? 2:1; + double startPhi = s==2 ? -36*M_PI/64 : -38*M_PI/64; + CellBinning phiBinning(startPhi, startPhi+width*2*2*M_PI/64, width*nPhi); + HECDetDescr *d = new HECDetDescr(hecDetManager,s,r,phiBinning); + for (unsigned int endcap=1;endcap<2;endcap++) { + StoredPhysVol *vol; + if (StatusCode::SUCCESS==m_detectorStore->retrieve(vol, endcap==0 ? "HEC1_NEG" : "HEC1_POS")) { + HECDetectorRegion::DetectorSide side = (HECDetectorRegion::DetectorSide) endcap; + HECDetectorRegion *region = new HECDetectorRegion(vol->getPhysVol(),d,side); + hecDetManager->addDetectorRegion(region); + } + } + } + currentBlock+=nBlocks; + } + + + (*log) << MSG::DEBUG << "Built HEC " << endreq; + + + + + + + m_detectorStore->record(hecDetManager,hecDetManager->getName()); + m_detectorStore->record(emecDetectorManager,emecDetectorManager->getName()); + m_detectorManager = new LArDetectorManager(0,emecDetectorManager,hecDetManager,0); + + m_detectorManager->addTreeTop(expHallPhys); + + + + + + + //------------------------------------------------------------------------------------// + // Now insert all of this into the world... // + GeoNameTag *tag = new GeoNameTag("LAr"); // + world->add(tag); // + world->add(expHallPhys); // + //------------------------------------------------------------------------------------// + + +} + +const LArDetectorManager *LArGeo::LArDetectorFactoryH62002::getDetectorManager() const +{ + return m_detectorManager; +} + + + + + diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/LArDetectorToolH62002.cxx b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/LArDetectorToolH62002.cxx new file mode 100755 index 0000000000000000000000000000000000000000..9968ab2094d3d85782a87b794bda7bb3f7d32a49 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/LArDetectorToolH62002.cxx @@ -0,0 +1,131 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "LArGeoH62002Algs/LArDetectorToolH62002.h" +#include "LArGeoH62002Algs/LArDetectorFactoryH62002.h" + +#include "LArReadoutGeometry/HECDetectorManager.h" + + +#include "GeoModelUtilities/GeoModelExperiment.h" +#include "GeoModelInterfaces/IGeoModelSvc.h" +#include "GaudiKernel/IService.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/MsgStream.h" +#include "StoreGate/StoreGateSvc.h" + +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" + + +/** + ** Constructor(s) + **/ +LArDetectorToolH62002::LArDetectorToolH62002( const std::string& type, const std::string& name, const IInterface* parent ) +: GeoModelTool( type, name, parent ) +{ +} + +/** + ** Destructor + **/ +LArDetectorToolH62002::~LArDetectorToolH62002() +{ + // This will need to be modified once we register the Toy DetectorNode in + // the Transient Detector Store + if ( 0 != m_detector ) { + delete m_detector; + m_detector = 0; + } +} + +/** + ** Create the Detector Node corresponding to this tool + **/ +StatusCode +LArDetectorToolH62002::create( StoreGateSvc* detStore ) +{ + MsgStream log(msgSvc(), name()); + + + + + + + + // Get the detector configuration. + IGeoModelSvc *geoModel; + service ("GeoModelSvc",geoModel); + + std::string AtlasVersion = geoModel->atlasVersion(); + std::string LArVersion = geoModel->LAr_VersionOverride(); + + IRDBAccessSvc *accessSvc; + service("RDBAccessSvc",accessSvc); + + std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion; + std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr"; + log << MSG::INFO << "Keys for LAr are " << detectorKey << " " << detectorNode << endreq; + + + log << MSG::INFO << "Creating the LAr " << endreq; + log << MSG::INFO << "LAr Geometry Options:" << endreq; + + + + + // + // Locate the top level experiment node + // + DataHandle<GeoModelExperiment> theExpt; + if (StatusCode::SUCCESS != detStore->retrieve( theExpt, "ATLAS" )) { + log << MSG::ERROR + << "Could not find GeoModelExperiment ATLAS" + << endreq; + return (StatusCode::FAILURE); + } + + + // determine the geometry layout - Atlas/Testbeam + std::string geometryLayout = "Atlas"; + std::string LArTag = accessSvc->getChildTag("LAr",detectorKey,detectorNode); + + //if(LArTag.find("H6")!=std::string::npos) { + // geometryLayout = "H6"; + //} + + + LArGeo::LArDetectorFactoryH62002 theLArFactory(detStore); + + + + + + if ( 0 == m_detector ) { + // Create the H62002Node instance + try { + // + // This strange way of casting is to avoid an + // utterly brain damaged compiler warning. + // + GeoPhysVol *world=&*theExpt->getPhysVol(); + theLArFactory.create(world); + } catch (std::bad_alloc) { + log << MSG::FATAL << "Could not create new H62002Node!" << endreq; + return StatusCode::FAILURE; + } + // Register the H62002Node instance with the Transient Detector Store + theExpt->addManager(theLArFactory.getDetectorManager()); + detStore->record(theLArFactory.getDetectorManager(),theLArFactory.getDetectorManager()->getName()); + + + return StatusCode::SUCCESS; + + + } + + + return StatusCode::FAILURE; +} diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/TableConstructionH62002.cxx b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/TableConstructionH62002.cxx new file mode 100755 index 0000000000000000000000000000000000000000..77868f3088539bb05c603b06ce37e06852abae05 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/TableConstructionH62002.cxx @@ -0,0 +1,229 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "LArGeoH62002Algs/TableConstructionH62002.h" +#include "LArGeoH6Cryostats/MWPCConstruction.h" + +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoVFullPhysVol.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoVPhysVol.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoTubs.h" +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoSerialDenominator.h" +#include "GeoModelKernel/GeoSerialIdentifier.h" +#include "GeoModelKernel/GeoSerialTransformer.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoIdentifierTag.h" +#include "GeoModelKernel/GeoSerialDenominator.h" +#include "StoreGate/StoreGateSvc.h" +#include "StoreGate/DataHandle.h" +#include "GeoModelInterfaces/AbsMaterialManager.h" +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "GeoModelKernel/GeoShapeUnion.h" +#include "GeoModelKernel/GeoShapeShift.h" + +// For transforms: +#include "CLHEP/Geometry/Transform3D.h" +#include "CLHEP/GenericFunctions/Variable.hh" +// For units: +#include "CLHEP/Units/PhysicalConstants.h" + +// For the database: +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" + +#include "GeoModelInterfaces/IGeoModelSvc.h" + +#include "StoreGate/StoreGateSvc.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/Bootstrap.h" + +#include <string> +#include <cmath> +#include <iostream> + +LArGeo::TableConstructionH62002::TableConstructionH62002() + :H62002TablePhysical(0), + _detectorManager(0), + pAccessSvc(0), + geoModelSvc(0) +{ +} + + +LArGeo::TableConstructionH62002::~TableConstructionH62002() +{ +} + + + +GeoVPhysVol* LArGeo::TableConstructionH62002::GetEnvelope() +{ + + if (H62002TablePhysical) return H62002TablePhysical; + + + ISvcLocator *svcLocator = Gaudi::svcLocator(); + IMessageSvc * msgSvc; + if (svcLocator->service("MessageSvc", msgSvc, true )==StatusCode::FAILURE) { + throw std::runtime_error("Error in TableConstructionH62002, cannot access MessageSvc"); + } + + MsgStream log(msgSvc, "LArGeo::TableConstructionH62002"); + log << MSG::INFO; + log << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + log << "+ +" << std::endl; + log << "+ HELLO from LArGeo::TableConstructionH62002 +" << std::endl; + log << "+ +" << std::endl; + log << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; + + + StoreGateSvc *detStore; + if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) { + throw std::runtime_error("Error in TableConstructionH62002, cannot access DetectorStore"); + } + + + StatusCode sc; + + IGeoModelSvc *geoModelSvc; + sc = svcLocator->service ("GeoModelSvc",geoModelSvc); + if (sc != StatusCode::SUCCESS) { + throw std::runtime_error ("Cannot locate GeoModelSvc!!"); + } + + + + // Get the materials from the material manager:-----------------------------------------------------// + // // + DataHandle<StoredMaterialManager> materialManager; + if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return NULL; + + GeoMaterial *Air = materialManager->getMaterial("std::Air"); + if (!Air) throw std::runtime_error("Error in TableConstructionH62002, std::Air is not found."); + + GeoMaterial *Aluminium = materialManager->getMaterial("std::Aluminium"); + if (!Aluminium) throw std::runtime_error("Error in TableConstructionH62002, std::Aluminium is not found."); + + // Is this ok for the Scintillator? + // I don't really know for sure what kind of a scintillator we have. + // Lots of Scintillators are PMMA (Plexiglas), which has a composition of C5 H8 O2 and density 1.18 g/cm3 + // The Tile uses a composition of C H (density 1.032) + // The old testbeam code uses a composition of C9 H10 (density 1.032) + // ... because it's easiest at the moment and not all that different from the fractional + // composition of the old tb code, take the Tile material (polysterene)... + GeoMaterial *Scint = materialManager->getMaterial("std::Polystyrene"); + if (!Scint) throw std::runtime_error("Error in TableConstructionH62002, std::Polystyrene is not found."); + + GeoMaterial *Mylar = materialManager->getMaterial("std::Mylar"); + if (!Mylar) throw std::runtime_error("Error in TableConstructionH62002, std::Mylar is not found."); + + + // // + //-------------------------------------------------------------------------------------------------// + + std::string AtlasVersion = geoModelSvc->atlasVersion(); + std::string LArVersion = geoModelSvc->LAr_VersionOverride(); + + std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion; + std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr"; + + + ////////////////////////////////////////////////////////////////// + // Define geometry + ////////////////////////////////////////////////////////////////// + + + // Here we creat the envelope for the Moveable Table Instrumentation. This code is repeated + // createEnvelope() method below. There should be a way to avoid this repitition. + + //------ The Table + + std::string baseName = "LAr::TBH62002"; + std::string H62002TableName = baseName + "::Table"; + + const double H62002TableXY = 150.*CLHEP::mm; + const double H62002TableZ = 1200.*CLHEP::mm; + + + GeoBox* H62002TableShape = new GeoBox( H62002TableXY, H62002TableXY, H62002TableZ ); + const GeoLogVol* H62002TableLogical = new GeoLogVol( H62002TableName, H62002TableShape, Air ); + + H62002TablePhysical = new GeoPhysVol(H62002TableLogical); + //H62002TablePhysical->add( new GeoNameTag("LArTBTablePos") ); + + + + + + //------ F1/F2Scintillators + log << "Create F1/F2 Scintillators ..." << std::endl; + + // Universal size: + const double Fx = 10.0*CLHEP::mm; + const double Fy = 10.0*CLHEP::mm; + const double Fz = 10.0*CLHEP::mm; + + std::vector<double> v_ScintZ; + v_ScintZ.push_back(2195.*CLHEP::mm); // <-- = btas_pos + v_ScintZ.push_back(2320.*CLHEP::mm); + const double ScintDx = Fx; + const double ScintDy = Fy; + const double ScintDz = Fz; + + // Create one Scintillator and place it twice along z: + + GeoBox* ScintShape = new GeoBox(ScintDx, ScintDy, ScintDz); // A generic Box Scintillator + std::string ScintName = baseName + "::Scintillator"; + GeoLogVol* ScintLogical = new GeoLogVol( ScintName, ScintShape, Scint ); + GeoPhysVol* ScintPhysical = new GeoPhysVol( ScintLogical ); + for ( unsigned int i = 0; i < v_ScintZ.size(); i++ ) { + H62002TablePhysical->add( new GeoIdentifierTag(i) ); + H62002TablePhysical->add( new GeoTransform( HepGeom::Translate3D( 0.*CLHEP::cm, 0.*CLHEP::cm, (v_ScintZ[ i ]-H62002TableZ) ) ) ); + log << MSG::INFO << " Position the F Scintillator at: " << v_ScintZ[ i ] << endreq ; + H62002TablePhysical->add( ScintPhysical ); + } + + //----- Done with F1/F2 Scintillators + + + + + + + //------ Get the MWPCs from LArGeoH6Cryostats + const int MwpcNumber = 3; + std::vector<double> v_MwpcPos; + v_MwpcPos.push_back(105.*CLHEP::mm); + v_MwpcPos.push_back(825.*CLHEP::mm); + v_MwpcPos.push_back(1815.*CLHEP::mm); + double WireStep = 1.*CLHEP::mm; + MWPCConstruction mwpcXConstruction (WireStep); + GeoVPhysVol* mwpcEnvelope = mwpcXConstruction.GetEnvelope(); + for ( int imwpc = 0; imwpc<MwpcNumber ; imwpc++) + { + H62002TablePhysical->add(new GeoIdentifierTag(imwpc+2)); + H62002TablePhysical->add( new GeoTransform(HepGeom::Translate3D( 0.*CLHEP::cm, 0.*CLHEP::cm, (v_MwpcPos[imwpc]-H62002TableZ) ) ) ); + H62002TablePhysical->add(mwpcEnvelope); + } + //------ Done with creating an MWPC from LArGeoH6Cryostats + + + + // End Moveable Table detectors + + + return H62002TablePhysical; +} + + + diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/components/LArGeoH62002Alg_entries.cxx b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/components/LArGeoH62002Alg_entries.cxx new file mode 100755 index 0000000000000000000000000000000000000000..c0b78c82ead3274fb7e8787e265ced91a472776d --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/components/LArGeoH62002Alg_entries.cxx @@ -0,0 +1,8 @@ +#include "LArGeoH62002Algs/LArDetectorToolH62002.h" +#include "GaudiKernel/DeclareFactoryEntries.h" + +DECLARE_TOOL_FACTORY(LArDetectorToolH62002) + +DECLARE_FACTORY_ENTRIES(LArGeoH62002Algs) { + DECLARE_ALGTOOL ( LArDetectorToolH62002 ) +} diff --git a/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/components/LArGeoH62002Alg_load.cxx b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/components/LArGeoH62002Alg_load.cxx new file mode 100755 index 0000000000000000000000000000000000000000..aab2d9b9e82366254699bce7ee6e808d2d063758 --- /dev/null +++ b/LArCalorimeter/LArGeoModel/LArGeoH62002Algs/src/components/LArGeoH62002Alg_load.cxx @@ -0,0 +1,4 @@ +#include "GaudiKernel/LoadFactoryEntries.h" + +LOAD_FACTORY_ENTRIES(LArGeoH62002Algs) +