From e198960f36a026e7044df9765328b90afd415945 Mon Sep 17 00:00:00 2001 From: Scott Snyder <scott.snyder@cern.ch> Date: Mon, 29 Aug 2016 03:27:10 +0200 Subject: [PATCH] 'Add dictionary for CaloGain.' (CaloIdentifier-00-10-95) 2016-08-29 scott snyder <snyder@bnl.gov> * Tagging CaloIdentifier-00-10-95. * Add dictionary for CaloGain. 2016-07-29 scott snyder <snyder@bnl.gov> * Tagging CaloIdentifier-00-10-94. * Disable GTower/JTower tests. 2016-07-28 scott snyder <snyder@bnl.gov> * Tagging CaloIdentifier-00-10-93. * Tagging CaloIdentifier-00-10-92. * Tag previous changes. * src/JGTowerBase_ID.cxx: Fix compilation. --- Calorimeter/CaloIdentifier/CMakeLists.txt | 14 + .../CaloIdentifier/CaloIdManager.h | 8 + .../CaloIdentifier/CaloIdentifier/GTower_ID.h | 59 + .../CaloIdentifier/JGTowerBase_ID.h | 608 +++++++++ .../CaloIdentifier/CaloIdentifier/JTower_ID.h | 59 + .../CaloIdentifier/selection.xml | 1 + Calorimeter/CaloIdentifier/cmt/requirements | 2 + .../CaloIdentifier/src/CaloIdManager.cxx | 30 +- Calorimeter/CaloIdentifier/src/GTower_ID.cxx | 52 + .../CaloIdentifier/src/JGTowerBase_ID.cxx | 1189 +++++++++++++++++ Calorimeter/CaloIdentifier/src/JTower_ID.cxx | 52 + .../CaloIdentifier/test/GTower_ID_test.cxx | 76 ++ .../CaloIdentifier/test/JTower_ID_test.cxx | 77 ++ .../test/jgtower_id_test_common.cxx | 246 ++++ 14 files changed, 2471 insertions(+), 2 deletions(-) create mode 100644 Calorimeter/CaloIdentifier/CaloIdentifier/GTower_ID.h create mode 100644 Calorimeter/CaloIdentifier/CaloIdentifier/JGTowerBase_ID.h create mode 100644 Calorimeter/CaloIdentifier/CaloIdentifier/JTower_ID.h create mode 100644 Calorimeter/CaloIdentifier/src/GTower_ID.cxx create mode 100644 Calorimeter/CaloIdentifier/src/JGTowerBase_ID.cxx create mode 100644 Calorimeter/CaloIdentifier/src/JTower_ID.cxx create mode 100644 Calorimeter/CaloIdentifier/test/GTower_ID_test.cxx create mode 100644 Calorimeter/CaloIdentifier/test/JTower_ID_test.cxx create mode 100644 Calorimeter/CaloIdentifier/test/jgtower_id_test_common.cxx diff --git a/Calorimeter/CaloIdentifier/CMakeLists.txt b/Calorimeter/CaloIdentifier/CMakeLists.txt index 29f6ec33a8c..0211e9b186d 100644 --- a/Calorimeter/CaloIdentifier/CMakeLists.txt +++ b/Calorimeter/CaloIdentifier/CMakeLists.txt @@ -60,6 +60,20 @@ atlas_add_executable( test_lvl1_id INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} CaloGeoHelpers SGTools AtlasDetDescr IdDict Identifier GaudiKernel TestTools CxxUtils StoreGateLib SGtests IdDictParser PathResolver CaloIdentifier ) +#atlas_add_test( GTower_ID_test +# SOURCES +# test/GTower_ID_test.cxx +# INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} +# LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} CaloGeoHelpers SGTools AtlasDetDescr IdDict Identifier GaudiKernel TestTools CxxUtils StoreGateLib SGtests IdDictParser PathResolver CaloIdentifier +# EXTRA_PATTERNS "mask/zero|Reading file|^AtlasDetectorID(Helper)?::" ) + +#atlas_add_test( JTower_ID_test +# SOURCES +# test/JTower_ID_test.cxx +# INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} +# LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} CaloGeoHelpers SGTools AtlasDetDescr IdDict Identifier GaudiKernel TestTools CxxUtils StoreGateLib SGtests IdDictParser PathResolver CaloIdentifier +# EXTRA_PATTERNS "mask/zero|Reading file|^AtlasDetectorID(Helper)?::" ) + atlas_add_test( LArEM_ID_test SOURCES test/LArEM_ID_test.cxx diff --git a/Calorimeter/CaloIdentifier/CaloIdentifier/CaloIdManager.h b/Calorimeter/CaloIdentifier/CaloIdentifier/CaloIdManager.h index dc979ddc996..ff9216db887 100755 --- a/Calorimeter/CaloIdentifier/CaloIdentifier/CaloIdManager.h +++ b/Calorimeter/CaloIdentifier/CaloIdentifier/CaloIdManager.h @@ -30,6 +30,8 @@ class LArHEC_SuperCell_ID; class TileID; class Tile_SuperCell_ID; class TTOnlineID; +class JTower_ID; +class GTower_ID; /** @@ -65,6 +67,8 @@ public: const LArHEC_SuperCell_ID* getHEC_SuperCell_ID (void) const; const LArFCAL_SuperCell_ID* getFCAL_SuperCell_ID (void) const; const Tile_SuperCell_ID* getTile_SuperCell_ID (void) const; + const JTower_ID* getJTower_ID (void) const; + const GTower_ID* getGTower_ID (void) const; void initialize (void); bool isInitialized (void) const; @@ -86,6 +90,8 @@ public: void set_helper (const LArHEC_SuperCell_ID* idHelper); void set_helper (const LArFCAL_SuperCell_ID* idHelper); void set_helper (const Tile_SuperCell_ID* idHelper); + void set_helper (const JTower_ID* idHelper); + void set_helper (const GTower_ID* idHelper); private: @@ -106,6 +112,8 @@ private: const LArHEC_SuperCell_ID* m_hec_supercell_id; const LArFCAL_SuperCell_ID* m_fcal_supercell_id; const Tile_SuperCell_ID* m_tile_supercell_id; + const JTower_ID* m_jTower_id; + const GTower_ID* m_gTower_id; }; diff --git a/Calorimeter/CaloIdentifier/CaloIdentifier/GTower_ID.h b/Calorimeter/CaloIdentifier/CaloIdentifier/GTower_ID.h new file mode 100644 index 00000000000..6c82891d651 --- /dev/null +++ b/Calorimeter/CaloIdentifier/CaloIdentifier/GTower_ID.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GTOWER_ID_H +#define GTOWER_ID_H + +#include "CLIDSvc/CLASS_DEF.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "Identifier/IdentifierHash.h" +#include "IdDict/IdDictFieldImplementation.h" +#include "IdDict/IdDictDefs.h" + +#include "CaloIdentifier/JGTowerBase_ID.h" +#include "SGTools/BaseInfo.h" + +#include <vector> +#include <algorithm> + +/** +* +* @class GTower_ID +* @brief Helper class for jTower offline identifiers +* +* This class provides an interface to decode and generate offline identifiers +* for jTowers. <p> +* +* Definition and range of values for the elements of the identifier are: <p> +* <pre> + +* </pre> +* @author based on code by RD Schaffer +* @author maintained by Walter Hopkins +*/ + +class Range; + +class GTower_ID : public JGTowerBase_ID +{ +public: + + typedef Identifier::size_type size_type ; + + GTower_ID(void); + ~GTower_ID(void); + + + + /** initialization from the identifier dictionary*/ + virtual int initialize_from_dictionary (const IdDictMgr& dict_mgr); +}; + +//using the macro below we can assign an identifier (and a version) +//This is required and checked at compile time when you try to record/retrieve +CLASS_DEF( GTower_ID , 49678914 , 1 ) +SG_BASE (GTower_ID, JGTowerBase_ID); + + +#endif // GTOWER_ID_H diff --git a/Calorimeter/CaloIdentifier/CaloIdentifier/JGTowerBase_ID.h b/Calorimeter/CaloIdentifier/CaloIdentifier/JGTowerBase_ID.h new file mode 100644 index 00000000000..11dafba231d --- /dev/null +++ b/Calorimeter/CaloIdentifier/CaloIdentifier/JGTowerBase_ID.h @@ -0,0 +1,608 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file CaloIdentifier/JGTowerBase_ID.h + * @author scott snyder <whopkins@uoregon.edu> + * @date Oct, 2014 + * @brief Factor out code common between JTower_ID and GTower_ID. + */ +#ifndef JGTOWERBASE_ID_H +#define JGTOWERBASE_ID_H + +#include "CLIDSvc/CLASS_DEF.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "Identifier/IdentifierHash.h" +#include "Identifier/Range.h" +#include "IdDict/IdDictFieldImplementation.h" + +#include "CaloIdentifier/CaloID_Exception.h" + +#include "boost/range/iterator_range.hpp" +#include <vector> +#include <algorithm> + +class IdentifierHash; +class IdDictRegion; + +class JGTowerBase_ID : public AtlasDetectorID +{ +public: + enum { NOT_VALID=999999 }; + + typedef Identifier::size_type size_type ; + + JGTowerBase_ID(void); + + virtual ~JGTowerBase_ID(); + + /** build a tower identifier */ + Identifier tower_id (int pos_neg, int sampling, int region, + int eta, int phi ) const ; + + /** build a tower identifier */ + Identifier tower_id (const Identifier regionId, + int eta, int phi ) const ; + + /** build a region (of towers) identifier */ + Identifier region_id ( int pos_neg, int sampling, int region ) const; + + /** access to IdContext's which define which levels of fields are contained in the id */ + /** id for towers ("reduced" id) */ + IdContext region_context (void) const; + + /** access to IdContext's which define which levels of fields are contained in the id */ + /** id for towers ("normal" id) */ + IdContext tower_context (void) const; + + /** create compact id from hash id (return == 0 for OK)*/ + virtual int get_id (const IdentifierHash& hash_id, Identifier& id, const IdContext* context = 0 ) const; + + /** create hash id from compact id (return == 0 for OK)*/ + virtual int get_hash (const Identifier& id, IdentifierHash& hash_id, const IdContext* context = 0 ) const; + + IdentifierHash calo_region_hash(const Identifier id) const; + + /** create region id from hash id*/ + Identifier region_id (IdentifierHash region_hash_id) const; + + Identifier region_id ( const Identifier tower_Id ) const; + + /** create tower id from hash id*/ + Identifier tower_id (IdentifierHash tower_hash_id) const; + + /** create hash id from tower id*/ + IdentifierHash tower_hash (Identifier towerId) const; + /** create hash id from tower id -- method NOT optimised, please use tower_hash() above */ + IdentifierHash tower_hash_binary_search (Identifier towerId) const; + + /** initialization from the identifier dictionary*/ + virtual int initialize_base_from_dictionary (const IdDictMgr& dict_mgr, const std::string& group_name, const std::string& t_pre); + + /** tower hash table max size */ + size_type tower_hash_max (void) const; + + /** region hash table max size */ + size_type calo_region_hash_max (void) const; + + + /** Type for iterators over identifiers. */ + typedef std::vector<Identifier>::const_iterator id_iterator; + /** Type for range over identifiers. */ + typedef boost::iterator_range<id_iterator> id_range; + + + /** begin iterator over regions */ + id_iterator region_begin () const; + /** end iterator over regions */ + id_iterator region_end () const; + /** range over regions */ + id_range reg_range () const; + + /** begin iterator over towers */ + id_iterator tower_begin () const; + /** end iterator over towers */ + id_iterator tower_end () const; + /** range over towers */ + id_range tower_range () const; + + // /** Test wether given tower or layer is part of the Tile Calorimeter + // @warning does NOT take as input a REGION identifier */ + // bool has_tile (const Identifier id) const; + // /** Test wether given tower or layer is part of the EM barrel + // @warning does NOT take as input a REGION identifier + // @warning excluding 'barrel end'! */ + // bool has_emb (const Identifier id) const; + // /** Test wether given tower or layer is part of the EM barrel END + // @warning does NOT take as input a REGION identifier */ + // bool has_barrel_end (const Identifier id) const; + // /** Test wether given tower or layer is part of the EM end-cap + // @warning does NOT take as input a REGION identifier */ + // bool has_emec (const Identifier id) const; + // /** Test wether given tower or layer is part of the HEC + // @warning does NOT take as input a REGION identifier */ + // bool has_hec (const Identifier id) const; + // /** Test wether given tower or layer is part of the FCAL + // @warning does NOT take as input a REGION identifier */ + // bool has_fcal (const Identifier id) const; + + /** + * return pos_neg according to : <br> + * + * <pre> + * element range meaning + * ------- ----- ------- + * DETZSIDE +/-1 positive/negative + * + * failure returns 0 + * + * </pre> + */ + int pos_neg (const Identifier id)const; + + /** + * return sampling according to : <br> + * + * <pre> + * element range meaning + * ------- ----- ------- + * LVL1sampling 0 EM + * " 1 Hadronic + * + * failure returns 0 + * + * </pre> + */ + int sampling (const Identifier id)const; + + /** + * return region according to : <br> + * + * <pre> + * GTowers + * element range meaning + * ------- ----- ------- + * region [0,1] 2 regions of different eta/phi granularity (FCAL and not FCAL) + * + * JTowers + * element range meaning + * ------- ----- ------- + * region [0,3] 4 regions of different eta/phi granularity + * + * failure returns 0 + * + * </pre> + */ + int region (const Identifier id)const; + + /** + * return eta according to : <br> + * + * <pre> + * GTower + * element range meaning + * ------- ----- ------- + * eta [0,15] region 0(|eta|<3.2), granularity = 0.2 + * " [0,2] region 1(3.2<|eta|<4.9), granularity = 0.6 ***** NEEDS IMPROVEMENT ***** + * + * JTowers + * element range meaning + * ------- ----- ------- + * eta [0,24] region 0(|eta|<2.5), granularity = 0.1 + * " [0,2] region 1(2.5|eta|<3.1), granularity = 0.1 + * " [0] region 2(3.1|eta|<3.2), granularity = 0.1 + * " [0,2] region 3(3.2|eta|<4.9), granularity = 0.6 + * + * failure returns 0 + * + * </pre> + */ + int eta (const Identifier id)const; + + /** + * return phi according to : <br> + * + * <pre> + * GTower + * element range meaning + * ------- ----- ------- + * phi [0,31] region 0(|eta|<3.2), granularity = 0.2 + * " [0,15] region 1(3.2<|eta|<4.9), granularity = 0.4 + * + * JTower + * element range meaning + * ------- ----- ------- + * phi [0,63] region 0(|eta|<2.5), granularity = 0.1 + * " [0,31] region 1(2.5<|eta|<3.1), granularity = 0.2 + * " [0,31] region 1(3.1<|eta|<3.2), granularity = 0.2 + * " [0,15] region 1(3.2<|eta|<4.9), granularity = 0.4 + * + * failure returns 0 + * + * </pre> + */ + int phi (const Identifier id)const; + + /** min value of eta index (-999 == failure) + @warning input = REGION ID !! */ + int eta_min(const Identifier regId) const; + /** max value of eta index (-999 == failure) + @warning input = REGION ID !! */ + int eta_max(const Identifier regId) const; + /** min value of phi index (-999 == failure) + @warning input = REGION ID !! */ + int phi_max(const Identifier regId) const; + + /** + * @brief Return the eta granularity of a region, or @c NOT_VALID. + * @param regHash REGION ID code. + */ + float etaGranularity(const Identifier regId) const; + + /** + * @brief Return the phi granularity of a region, or @c NOT_VALID. + * @param regHash REGION ID code. + */ + float phiGranularity(const Identifier regId) const; + + /** + * @brief Return the minimum eta of region, or @c NOT_VALID. + * @param regHash REGION ID code. + */ + float eta0(const Identifier regId) const; + + /** + * @brief Return the minimum phi of region, or @c NOT_VALID. + * @param regHash REGION ID code. + */ + float phi0(const Identifier regId) const; + + /** access to hashes for neighbours in phi -- towers only (no extended) + return == 0 for neighbours found */ + int get_prev_in_phi(const IdentifierHash& id, IdentifierHash& prev) const; + /** access to hashes for neighbours in phi -- towers only (no extended) + return == 0 for neighbours found */ + int get_next_in_phi(const IdentifierHash& id, IdentifierHash& next) const; + /** access to hashes for neighbours in eta -- towers only (no extended) + return == 0 for neighbours found */ + int get_prev_in_eta(const IdentifierHash& id, IdentifierHash& prev) const; + /** access to hashes for neighbours in eta -- towers only (no extended) + return == 0 for neighbours found */ + int get_next_in_eta(const IdentifierHash& id, IdentifierHash& next) const; + + int fill_vec_of_dict_regions (const std::string& group_name = ""); + + const std::vector<const IdDictRegion*>& dictRegions() const; + +private: + + + enum {NOT_VALID_HASH = 64000}; + + + /** create expanded Identifier from Identifier (return == 0 for OK) */ + int get_expanded_id (const Identifier& id, ExpandedIdentifier& exp_id, const IdContext* context) const; + void tower_id_checks (int pos_neg, int sampling, int region, + int eta, int phi ) const throw(CaloID_Exception); + void tower_id_checks (const Identifier regionId, + int eta, int phi ) const throw(CaloID_Exception); + void region_id_checks ( int pos_neg, int sampling, int region ) const throw(CaloID_Exception); + + int initLevelsFromDict(const std::string& t_pre) ; + + int init_hashes(void) ; + + int init_neighbors(void) ; + + + size_type m_jgtower_region_index; + size_type m_CALO_INDEX; + size_type m_DETZSIDE_INDEX; + size_type m_SAMPLING_INDEX; + size_type m_REGION_INDEX; + size_type m_ETA_INDEX; + size_type m_PHI_INDEX; + + const IdDictDictionary* m_dict; + + MultiRange m_full_reg_range; + MultiRange m_full_tower_range; + size_type m_tower_hash_max; + size_type m_calo_region_hash_max; + std::vector<Identifier> m_tower_vec; + std::vector<Identifier> m_region_vec; + std::vector<unsigned short> m_prev_phi_vec; + std::vector<unsigned short> m_next_phi_vec; + std::vector<unsigned short> m_prev_eta_vec; + std::vector<unsigned short> m_next_eta_vec; + + /// List of @c IdDictRegion objects. + std::vector<const IdDictRegion*> m_vecOfDictRegions; + + /** + @brief small class holding the starting hash value, the min eta and the number of phi bins of each region + + used to CPU-optimize the conversion from an identifier to a hash index + */ + class HashCalc + { + public: + HashCalc() : + m_hash(0), + m_etamin(0), + m_nphi(0) {} + IdentifierHash m_hash; + size_type m_etamin; + size_type m_nphi; + }; + std::vector<HashCalc> m_hash_calcs; + + + + IdDictFieldImplementation m_calo_impl; + IdDictFieldImplementation m_jgtower_impl; + IdDictFieldImplementation m_sampling_impl; + IdDictFieldImplementation m_region_impl; + IdDictFieldImplementation m_eta_impl; + IdDictFieldImplementation m_phi_impl; + + IdDictFieldImplementation m_pnz_reg_impl; + +}; + +//using the macros below we can assign an identifier (and a version) +//This is required and checked at compile time when you try to record/retrieve +CLASS_DEF( JGTowerBase_ID , 131336095, 1 ) + +inline Identifier JGTowerBase_ID::tower_id ( int pos_neg, int sampling, int region, + int eta, int phi ) const +{ + Identifier result(0); + // Pack fields independently + m_calo_impl.pack (calo_field_value(), result); + m_jgtower_impl.pack (pos_neg, result); + m_sampling_impl.pack (sampling, result); + m_region_impl.pack (region, result); + m_eta_impl.pack (eta, result); + m_phi_impl.pack (phi, result); + + // Do checks + if(m_do_checks) { + tower_id_checks( pos_neg, sampling, region, eta, phi ); + } + + return result; +} +//---------------------------------------------------------------------------- +inline Identifier JGTowerBase_ID::tower_id ( const Identifier regionId, + int eta, int phi ) const +{ + Identifier result(regionId); + + // Reset the fields and then set the values + m_eta_impl.reset (result); + m_phi_impl.reset (result); + m_eta_impl.pack (eta, result); + m_phi_impl.pack (phi, result); + + // Do checks + if(m_do_checks) { + tower_id_checks( regionId, eta, phi ); + } + + return result; +} + + +//---------------------------------------------------------------------------- +inline JGTowerBase_ID::size_type JGTowerBase_ID::tower_hash_max (void) const +{ + return m_tower_hash_max; +} + +//---------------------------------------------------------------------------- +inline JGTowerBase_ID::size_type JGTowerBase_ID::calo_region_hash_max (void) const +{ + return m_calo_region_hash_max; +} + + +//---------------------------------------------------------------------------- +inline JGTowerBase_ID::id_iterator JGTowerBase_ID::region_begin (void) const +{ + return(m_region_vec.begin()); +} + +//---------------------------------------------------------------------------- +inline JGTowerBase_ID::id_iterator JGTowerBase_ID::region_end (void) const +{ + return(m_region_vec.end()); +} + +//---------------------------------------------------------------------------- +inline JGTowerBase_ID::id_range JGTowerBase_ID::reg_range () const +{ + return id_range (region_begin(), region_end()); +} + +//---------------------------------------------------------------------------- +inline JGTowerBase_ID::id_iterator JGTowerBase_ID::tower_begin (void) const +{ + return(m_tower_vec.begin()); +} + +//---------------------------------------------------------------------------- +inline JGTowerBase_ID::id_iterator JGTowerBase_ID::tower_end (void) const +{ + return(m_tower_vec.end()); +} + +//---------------------------------------------------------------------------- +inline JGTowerBase_ID::id_range JGTowerBase_ID::tower_range () const +{ + return id_range (tower_begin(), tower_end()); +} + +//---------------------------------------------------------------------------- +inline int JGTowerBase_ID::pos_neg(const Identifier id) const +{ + return (m_jgtower_impl.unpack(id)); +} + +//---------------------------------------------------------------------------- +inline int JGTowerBase_ID::sampling(const Identifier id) const +{ + return (m_sampling_impl.unpack(id)); +} +//---------------------------------------------------------------------------- +inline int JGTowerBase_ID::region(const Identifier id) const +{ + return (m_region_impl.unpack(id)); +} + +//---------------------------------------------------------------------------- +inline int JGTowerBase_ID::eta(const Identifier id) const +{ + return (m_eta_impl.unpack(id)); +} + +//---------------------------------------------------------------------------- +inline int JGTowerBase_ID::phi(const Identifier id) const +{ + return (m_phi_impl.unpack(id)); +} + +// //---------------------------------------------------------------------------- +// inline bool JGTowerBase_ID::has_tile (const Identifier id) const +// { +// // Must first check if this is a normal tile id +// if (AtlasDetectorID::is_tile(id)) { +// return (true); +// } +// /* else { */ +// /* return (has_jgtower_trig_towers(id) && region(id) == 0 && sampling(id) == 1 && eta(id) < 15); */ +// /* } */ +// } + +// //---------------------------------------------------------------------------- +// inline bool JGTowerBase_ID::has_emb (const Identifier id) const +// { +// return true;//(has_jgtower_trig_towers(id) && region(id) == 0 && sampling(id) == 0 && eta(id) < 14); +// } + +// //---------------------------------------------------------------------------- +// inline bool JGTowerBase_ID::has_barrel_end (const Identifier id) const +// { +// return true;//(has_jgtower_trig_towers(id) && region(id) == 0 && sampling(id) == 0 && eta(id) == 14); +// } + +// //---------------------------------------------------------------------------- +// inline bool JGTowerBase_ID::has_emec (const Identifier id) const +// { +// return true;//(has_jgtower_trig_towers(id) && sampling(id) == 0 && +// //((region(id) == 0 && eta(id) > 14) || region(id) == 1 || region(id) == 2 )); +// } + +// //---------------------------------------------------------------------------- +// inline bool JGTowerBase_ID::has_hec (const Identifier id) const +// { +// return true;//(has_jgtower_trig_towers(id) && sampling(id) == 1 && +// //((region(id) == 0 && eta(id) > 14) || region(id) == 1 || region(id) == 2 )); +// } + +// //---------------------------------------------------------------------------- +// inline bool JGTowerBase_ID::has_fcal (const Identifier id) const +// { +// return true;//(has_jgtower_trig_towers(id) && region(id) == 3 ); +// } + +//---------------------------------------------------------------------------- +inline Identifier JGTowerBase_ID::region_id (IdentifierHash region_hash_id) const +{ + return(m_region_vec[region_hash_id]); +} +//---------------------------------------------------------------------------- +inline Identifier JGTowerBase_ID::region_id ( const Identifier tower_Id ) const +{ + Identifier result(tower_Id); + // reset eta, phi, layer + m_eta_impl.reset(result); + m_phi_impl.reset(result); + return (result); +} + +//---------------------------------------------------------------------------- +inline Identifier JGTowerBase_ID::region_id (int pos_neg, int sampling, int region)const +{ + Identifier result(0); + // Pack fields independently + m_calo_impl.pack (calo_field_value(), result); + m_jgtower_impl.pack (pos_neg, result); + m_sampling_impl.pack (sampling, result); + m_region_impl.pack (region, result); + + // Do checks + if(m_do_checks) { + region_id_checks( pos_neg, sampling, region); + } + + return result; +} + +//---------------------------------------------------------------------------- +inline Identifier JGTowerBase_ID::tower_id (IdentifierHash tower_hash_id) const +{ + return(m_tower_vec[tower_hash_id]); +} + +//---------------------------------------------------------------------------- +inline IdentifierHash JGTowerBase_ID::tower_hash (Identifier towerId) const +{ + const HashCalc& hc = m_hash_calcs[m_pnz_reg_impl.unpack(towerId)]; + return (hc.m_hash + (eta(towerId)-hc.m_etamin)*hc.m_nphi + phi(towerId)); +} + +//---------------------------------------------------------------------------- +inline IdentifierHash JGTowerBase_ID::tower_hash_binary_search (Identifier towerId) const +{ + std::vector<Identifier>::const_iterator it = std::lower_bound(m_tower_vec.begin(),m_tower_vec.end(),towerId); + if ( it != m_tower_vec.end() ){ + return (it - m_tower_vec.begin()); + } + return (0); +} + +inline +const std::vector<const IdDictRegion*>& JGTowerBase_ID::dictRegions() const +{ return m_vecOfDictRegions; +} + +#endif // CALOJGTOWER_ID_H + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Calorimeter/CaloIdentifier/CaloIdentifier/JTower_ID.h b/Calorimeter/CaloIdentifier/CaloIdentifier/JTower_ID.h new file mode 100644 index 00000000000..6aa9057705c --- /dev/null +++ b/Calorimeter/CaloIdentifier/CaloIdentifier/JTower_ID.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef JTOWER_ID_H +#define JTOWER_ID_H + +#include "CLIDSvc/CLASS_DEF.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "Identifier/IdentifierHash.h" +#include "IdDict/IdDictFieldImplementation.h" +#include "IdDict/IdDictDefs.h" + +#include "CaloIdentifier/JGTowerBase_ID.h" +#include "SGTools/BaseInfo.h" + +#include <vector> +#include <algorithm> + +/** +* +* @class JTower_ID +* @brief Helper class for jTower offline identifiers +* +* This class provides an interface to decode and generate offline identifiers +* for jTowers. <p> +* +* Definition and range of values for the elements of the identifier are: <p> +* <pre> + +* </pre> +* @author based on code by RD Schaffer +* @author maintained by Walter Hopkins +*/ + +class Range; + +class JTower_ID : public JGTowerBase_ID +{ +public: + + typedef Identifier::size_type size_type ; + + JTower_ID(void); + ~JTower_ID(void); + + + + /** initialization from the identifier dictionary*/ + virtual int initialize_from_dictionary (const IdDictMgr& dict_mgr); +}; + +//using the macro below we can assign an identifier (and a version) +//This is required and checked at compile time when you try to record/retrieve +CLASS_DEF( JTower_ID , 218674799 , 1 ) +SG_BASE (JTower_ID, JGTowerBase_ID); + + +#endif // JTOWER_ID_H diff --git a/Calorimeter/CaloIdentifier/CaloIdentifier/selection.xml b/Calorimeter/CaloIdentifier/CaloIdentifier/selection.xml index 7bfb35e6409..0f60b5c5870 100755 --- a/Calorimeter/CaloIdentifier/CaloIdentifier/selection.xml +++ b/Calorimeter/CaloIdentifier/CaloIdentifier/selection.xml @@ -23,6 +23,7 @@ <class name="TileTBID" /> <class name="CaloIdManager" /> <class name="CaloIDHelper" /> + <enum name="CaloGain::CaloGain"/> <!-- should really be in DetDescrDictionary. --> <class name="boost::iterator_range<std::vector<Identifier>::const_iterator>"/> diff --git a/Calorimeter/CaloIdentifier/cmt/requirements b/Calorimeter/CaloIdentifier/cmt/requirements index c0588264a03..1d631caf5fc 100755 --- a/Calorimeter/CaloIdentifier/cmt/requirements +++ b/Calorimeter/CaloIdentifier/cmt/requirements @@ -46,6 +46,8 @@ macro_append test_lvl1_id_dependencies CaloIdentifier macro ep "mask/zero|Reading file|^AtlasDetectorID(Helper)?::" use TestTools TestTools-* AtlasTest +#apply_pattern UnitTest_run unit_test=GTower_ID extrapatterns="$(ep)" +#apply_pattern UnitTest_run unit_test=JTower_ID extrapatterns="$(ep)" apply_pattern UnitTest_run unit_test=LArEM_ID extrapatterns="$(ep)" apply_pattern UnitTest_run unit_test=LArEM_SuperCell_ID extrapatterns="$(ep)" apply_pattern UnitTest_run unit_test=LArHEC_ID extrapatterns="$(ep)" diff --git a/Calorimeter/CaloIdentifier/src/CaloIdManager.cxx b/Calorimeter/CaloIdentifier/src/CaloIdManager.cxx index 18987fe3d08..ce4f16edc20 100755 --- a/Calorimeter/CaloIdentifier/src/CaloIdManager.cxx +++ b/Calorimeter/CaloIdentifier/src/CaloIdManager.cxx @@ -27,6 +27,8 @@ #include "CaloIdentifier/LArHEC_SuperCell_ID.h" #include "CaloIdentifier/LArFCAL_SuperCell_ID.h" #include "CaloIdentifier/Tile_SuperCell_ID.h" +#include "CaloIdentifier/JTower_ID.h" +#include "CaloIdentifier/GTower_ID.h" // Athena/Gaudi includes #include "GaudiKernel/Bootstrap.h" @@ -52,7 +54,9 @@ CaloIdManager::CaloIdManager(void) m_em_supercell_id(0), m_hec_supercell_id(0), m_fcal_supercell_id(0), - m_tile_supercell_id(0) + m_tile_supercell_id(0), + m_jTower_id(0), + m_gTower_id(0) { } @@ -204,7 +208,16 @@ CaloIdManager::getTile_SuperCell_ID (void) const { return (m_tile_supercell_id); } - +const JTower_ID* +CaloIdManager::getJTower_ID (void) const +{ + return (m_jTower_id); +} +const GTower_ID* +CaloIdManager::getGTower_ID (void) const +{ + return (m_gTower_id); +} void CaloIdManager::initialize (void) @@ -306,3 +319,16 @@ CaloIdManager::set_helper (const Tile_SuperCell_ID* idHelper) { m_tile_supercell_id = idHelper; } + +void +CaloIdManager::set_helper (const JTower_ID* idHelper) +{ + m_jTower_id = idHelper; +} + + +void +CaloIdManager::set_helper (const GTower_ID* idHelper) +{ + m_gTower_id = idHelper; +} diff --git a/Calorimeter/CaloIdentifier/src/GTower_ID.cxx b/Calorimeter/CaloIdentifier/src/GTower_ID.cxx new file mode 100644 index 00000000000..7f4afa125e4 --- /dev/null +++ b/Calorimeter/CaloIdentifier/src/GTower_ID.cxx @@ -0,0 +1,52 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "CaloIdentifier/GTower_ID.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "Identifier/IdentifierHash.h" +#include "IdDict/IdDictDefs.h" + +#include "GaudiKernel/MsgStream.h" + +#include <string> +#include <set> +#include <iostream> +#include <math.h> + + + +GTower_ID::GTower_ID(void) : + JGTowerBase_ID() +{ +} + +GTower_ID::~GTower_ID(void) +{ +} + +int GTower_ID::initialize_from_dictionary (const IdDictMgr& dict_mgr) +/*=================================================================*/ +{ + MsgStream log(m_msgSvc, "GTower_ID" ); + + log << MSG::DEBUG << "initialize_from_dictionary" << endmsg; + + // Check whether this helper should be reinitialized + if (!reinitialize(dict_mgr)) { + log << MSG::DEBUG << "Request to reinitialize not satisfied - tags have not changed" << endmsg; + return (0); + } + else { + if(m_msgSvc)log << MSG::DEBUG << "(Re)initialize" << endmsg; + } + + // init base object + if (JGTowerBase_ID::initialize_base_from_dictionary(dict_mgr, "positive_gTower_side", "GT")) + return (1); + + + return 0; +} + + diff --git a/Calorimeter/CaloIdentifier/src/JGTowerBase_ID.cxx b/Calorimeter/CaloIdentifier/src/JGTowerBase_ID.cxx new file mode 100644 index 00000000000..616fdbd335c --- /dev/null +++ b/Calorimeter/CaloIdentifier/src/JGTowerBase_ID.cxx @@ -0,0 +1,1189 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "CaloIdentifier/JGTowerBase_ID.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "Identifier/IdentifierHash.h" +#include "IdDict/IdDictDefs.h" +#include "CxxUtils/StrFormat.h" +#include "GaudiKernel/MsgStream.h" +#include <algorithm> +#include <string> +#include <set> +#include <stdio.h> +#include <iostream> +#include <math.h> +#include <assert.h> +#include "boost/foreach.hpp" + +using CxxUtils::strformat; + + +JGTowerBase_ID::JGTowerBase_ID(void) : + m_jgtower_region_index(0) + , m_CALO_INDEX(999) + , m_DETZSIDE_INDEX(999) + , m_SAMPLING_INDEX(999) + , m_REGION_INDEX(999) + , m_ETA_INDEX(999) + , m_PHI_INDEX(999) + , m_dict(0) + , m_tower_hash_max(0) + , m_calo_region_hash_max(0) + +{ + +} + +JGTowerBase_ID:: ~JGTowerBase_ID(){} + + + +IdContext +JGTowerBase_ID::region_context (void) const +{ + ExpandedIdentifier id; + return (IdContext(id, 0, m_REGION_INDEX)); +} + +IdContext +JGTowerBase_ID::tower_context (void) const +{ + ExpandedIdentifier id; + return (IdContext(id, 0, m_PHI_INDEX)); +} + + +int JGTowerBase_ID::get_id (const IdentifierHash& hash_id, Identifier& id, const IdContext* context) const +{ + MsgStream log(m_msgSvc, "JGTowerBase_ID" ); + std::stringstream strm; + std::string strg; + int result = 1; + id.clear(); + + size_t begin = (context) ? context->begin_index(): 0; + // cannot get hash if end is 0: + size_t end = (context) ? context->end_index() : 0; + + if (0 == begin) { + if (m_REGION_INDEX == end) { + if (hash_id < (unsigned int)(m_region_vec.end() - m_region_vec.begin())) + { + id = m_region_vec[hash_id]; + result = 0; + } + else + { + strm << hash_id; + strg = " hash_id out of range "+strm.str(); + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + } + } + else if (m_PHI_INDEX == end) { + if (hash_id < (unsigned int)(m_tower_vec.end() - m_tower_vec.begin())) { + id = m_tower_vec[hash_id]; + result = 0; + } + else + { + strm << hash_id; + strg = " hash_id out of range "+strm.str(); + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + } + } + } + return(result); +} + +int JGTowerBase_ID::get_hash (const Identifier& id, IdentifierHash& hash_id, const IdContext* context) const +{ + hash_id = 0; + int result = 1; + + size_t begin = (context) ? context->begin_index(): 0; + size_t end = (context) ? context->end_index() : 0; + + if (0 == begin) { + if (m_REGION_INDEX == end) { + Identifier redId = region_id (id); + std::vector<Identifier>::const_iterator it = std::lower_bound(m_region_vec.begin(),m_region_vec.end(),redId); + if ( it != m_region_vec.end() ){ + hash_id = it - m_region_vec.begin(); + result = 0; + } + } + else if (m_PHI_INDEX == end) { + + //Identifier redId = tower_id (id); + + std::vector<Identifier>::const_iterator it = std::lower_bound(m_tower_vec.begin(),m_tower_vec.end(),id); + if ( it != m_tower_vec.end() ){ + hash_id = it - m_tower_vec.begin(); + result = 0; + } + } + + else { + std::string errorMessage = + "Error in JGTowerBase_ID::get_hash, invalid context "; + throw CaloID_Exception(errorMessage , 10); + } + } + + return (result); +} + + +IdentifierHash JGTowerBase_ID::calo_region_hash(const Identifier regId) const +{ + IdentifierHash regHash; + IdContext regionContext = region_context(); + int sc = get_hash(regId, regHash, ®ionContext); + if (sc!=0) return NOT_VALID; + return regHash; +} + + +int JGTowerBase_ID::initialize_base_from_dictionary (const IdDictMgr& dict_mgr, const std::string& group_name, const std::string& t_pre) +{ + MsgStream log(m_msgSvc, "JGTowerBase_ID" ); + std::string strg = "initialize_from_dictionary"; + if(m_msgSvc) { + log << MSG::INFO << strg << endmsg; + } + else { + std::cout << strg << std::endl; + } + + // Check whether this helper should be reinitialized + if (!reinitialize(dict_mgr)) { + if(m_msgSvc)log << MSG::DEBUG << "Request to reinitialize not satisfied - tags have not changed" << endmsg; + return (0); + } + else { + if(m_msgSvc)log << MSG::DEBUG << "(Re)initialize" << endmsg; + } + + std::stringstream strm; + std::stringstream strm1; + std::stringstream strm2; + std::string strg1; + std::string strg2; + + // init base object + if(AtlasDetectorID::initialize_from_dictionary(dict_mgr)) return (1); + + // Register version of the Calorimeter dictionary + if (register_dict_tag(dict_mgr, "Calorimeter")) return(1); + + m_dict = dict_mgr.find_dictionary ("Calorimeter"); + if(!m_dict) + { + strg= " initialize_from_dict - cannot access Calorimeter dictionary "; + if(m_msgSvc) { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return(1); + } + + // Initialize the field indices + if(initLevelsFromDict(t_pre)) return (1); + + // Find values for the calo and JGTOWER (neg) fields + int caloValue = -1; + if (m_dict->get_label_value("subdet", "Calorimeter", caloValue)) + { + strm << m_dict->m_name; + strg= "Could not get value for label 'Calorimeter' of field 'subdet' in dictionary "+strm.str(); + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + int jgtowerCaloValue = -1; + // negative half + // if (m_dict->get_label_value("DetZside", "negative_jgtower_side", jgtowerCaloValue)) + // positive half FLG 12 Jul 07: negative side -> problem for test beam + if (m_dict->get_label_value("DetZside", group_name, jgtowerCaloValue)) + { + strm << m_dict->m_name; + // strg = " Could not get value for label 'negative_jgtower_side' of field 'DetZside in dictionary"+strm.str(); + strg = " Could not get value for label "+group_name+" of field 'DetZside in dictionary"+strm.str(); + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + // Set up id for region and range prefix + // NOTE: negative value is good enough to get multirange since the + // regions are symmetric in +/-eta + // FLG Jul 07: EXCEPT FOR CTB !!!!!!!!!! + + ExpandedIdentifier reg_id; + reg_id.add(caloValue); + reg_id.add(jgtowerCaloValue); + Range prefix; + m_full_reg_range = m_dict->build_multirange(reg_id, prefix, t_pre+"region"); + m_full_tower_range = m_dict->build_multirange(reg_id, prefix, t_pre+"phi"); + + // Setup the hash tables + if(init_hashes()) return (1); + + // initialize dictionary regions + if (fill_vec_of_dict_regions ("Reg_"+t_pre+"ower")) return 1; + + // Setup hash tables for finding neighbors + if(init_neighbors()) return (1); + + strm1 << (std::string)m_full_tower_range; + strg = " JGTowerBase_ID::initialize_from_dict : "; + strg1 = " tower range -> "+strm1.str(); + if(m_msgSvc) + { + log << MSG::DEBUG << strg << endmsg; + log << MSG::DEBUG << strg1 << endmsg; + log << MSG::DEBUG << strg2 << endmsg; + } + else + { + std::cout << strg << std::endl; + std::cout << strg1 << std::endl; + std::cout << strg2 << std::endl; + } + + //std::cout << " JGTowerBase_ID::initialize_from_dict : " + // << std::endl; + //std::cout << " tower range -> " << (std::string)m_full_tower_range + // << std::endl; + //std::cout << " layer range -> " << (std::string)m_full_layer_range + // << std::endl; + + + // Setup for hash calculation + + // Regions have uniform eta/phi granularity + // The lookup table only needs to contain the + // hash offset for each region, the first eta index + // and the number of phi cells. + + // The implementation requires: + + // 1) a lookup table for each region containing hash offset, + // etamin and nphi + // 2) a decoder to access the "index" corresponding to the + // pnz/samp/reg fields. These fields use 6 bits, so the + // vector has a length of 64 for 16 regions. + + + // Create decoder for fields pnz to region + IdDictFieldImplementation::size_type bits = + m_jgtower_impl.bits() + + m_sampling_impl.bits() + + m_region_impl.bits(); + IdDictFieldImplementation::size_type bits_offset = m_jgtower_impl.bits_offset(); + m_pnz_reg_impl.set_bits(bits, bits_offset); + int size = (1 << bits); + + // std::cout << "pnz_reg " + // << m_pnz_reg_impl.show_to_string() << std::endl; + // std::cout << "size " << size << std::endl; + + + // std::cout << "pnz_reg " << m_pnz_reg_impl.decode_index() << " " + // << (std::string)m_pnz_reg_impl.ored_field() << " " + // << std::hex << m_pnz_reg_impl.mask() << " " + // << m_pnz_reg_impl.zeroing_mask() << " " + // << std::dec << m_pnz_reg_impl.shift() + // << " " << m_pnz_reg_impl.bits() << " " <<m_pnz_reg_impl.bits_offset() + // << std::endl; + + + // Set up vector as lookup table for hash calculation. + m_hash_calcs.resize(size); + + for (unsigned int i = 0; i < m_calo_region_hash_max; ++i) { + + Identifier regId = region_id(i) ; + + HashCalc hc; + + int etamin = eta_min(regId); + Identifier min = tower_id ( regId, etamin, 0); + IdentifierHash min_hash = tower_hash_binary_search(min); + hc.m_hash = min_hash; + hc.m_etamin = etamin; + hc.m_nphi = phi_max(min)+1 ; + m_hash_calcs[m_pnz_reg_impl.unpack(min)] = hc; + + if (m_pnz_reg_impl.unpack(min) >= size) + { + strm << size; + strm1 << show_to_string(min); + strm2 << m_pnz_reg_impl.unpack(min); + strg = "Min > "+strm.str(); + strg1= " "+strm1.str(); + strg2= " "+strm2.str(); + if(m_msgSvc) + { + log << MSG::DEBUG << strg << endmsg; + log << MSG::DEBUG << strg1 << endmsg; + log << MSG::DEBUG << strg2 << endmsg; + } + else + { + std::cout << strg << std::endl; + std::cout << strg1 << std::endl; + std::cout << strg2 << std::endl; + } + //std::cout << "min > " << size << " " + // << i << " " + // << show_to_string(min) << " " + // << m_pnz_reg_impl.unpack(min) << " " + // << std::endl; + } + } + + // Check hash calculation + for (unsigned int i = 0; i < m_tower_hash_max; ++i) { + Identifier id = tower_id(i); + if (tower_hash(id) != i) + { + strm << show_to_string(id); + strm1 << tower_hash(id); + strm2 << i; + strg = " ***** Error tower ranges, id, hash, i = "+strm.str(); + strg1= " , "+strm1.str(); + strg2= " , "+strm2.str(); + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + log << MSG::ERROR << strg1 << endmsg; + log << MSG::ERROR << strg2 << endmsg; + } + else + { + std::cout << strg << std::endl; + std::cout << strg1 << std::endl; + std::cout << strg2 << std::endl; + } + + //std::cout << "tower ranges, id, hash, i = " + // << show_to_string(id) << ", " + // << tower_hash(id) << ", " + // << i + // << std::endl; + } + } + + return 0; + +} + + + + +int JGTowerBase_ID::eta_min(const Identifier regId) const +{ + ExpandedIdentifier expId; + IdContext region_cntxt = region_context(); + if(!get_expanded_id(regId, expId, ®ion_cntxt)) { + int result = -999; + for (unsigned int i = 0; i < m_full_tower_range.size(); ++i) { + const Range& range = m_full_tower_range[i]; + if (range.match(expId)) { + const Range::field& eta_field = range[m_ETA_INDEX]; + if (eta_field.has_minimum()) { + int etamin = eta_field.get_minimum(); + if (-999 == result) { + result = etamin; + } + else { + if (etamin < result) result = etamin; + } + } + } + } + return (result); + } + return (-999); +} + +int JGTowerBase_ID::eta_max(const Identifier regId) const +{ + ExpandedIdentifier expId; + IdContext region_cntxt = region_context(); + if(!get_expanded_id(regId, expId, ®ion_cntxt)) { + int result = -999; + for (unsigned int i = 0; i < m_full_tower_range.size(); ++i) { + const Range& range = m_full_tower_range[i]; + if (range.match(expId)) { + const Range::field& eta_field = range[m_ETA_INDEX]; + if (eta_field.has_maximum()) { + int etamax = eta_field.get_maximum(); + if (result < etamax) result = etamax; + } + } + } + return (result); + } + return (-999); // default +} + +int JGTowerBase_ID::phi_max(const Identifier regId) const +{ + ExpandedIdentifier expId; + IdContext region_cntxt = region_context(); + if(!get_expanded_id(regId, expId, ®ion_cntxt)) { + int result = -999; + for (unsigned int i = 0; i < m_full_tower_range.size(); ++i) { + const Range& range = m_full_tower_range[i]; + if (range.match(expId)) { + const Range::field& phi_field = range[m_PHI_INDEX]; + if (phi_field.has_maximum()) { + int phimax = phi_field.get_maximum(); + if (result < phimax) result = phimax; + } + } + } + return (result); + } + return (-999); // default +} + +float JGTowerBase_ID::etaGranularity(const Identifier regId) const +{ + IdentifierHash regHash = calo_region_hash(regId); + if (regHash >= m_vecOfDictRegions.size()) return NOT_VALID; + return m_vecOfDictRegions[regHash]->m_deta; +} + +float JGTowerBase_ID::phiGranularity(const Identifier regId) const +{ + IdentifierHash regHash = calo_region_hash(regId); + if (regHash >= m_vecOfDictRegions.size()) return NOT_VALID; + return m_vecOfDictRegions[regHash]->m_dphi; +} + +float JGTowerBase_ID::eta0(const Identifier regId) const +{ + IdentifierHash regHash = calo_region_hash(regId); + if (regHash >= m_vecOfDictRegions.size()) return NOT_VALID; + return m_vecOfDictRegions[regHash]->m_eta0; +} + +float JGTowerBase_ID::phi0(const Identifier regId) const +{ + IdentifierHash regHash = calo_region_hash(regId); + if (regHash >= m_vecOfDictRegions.size()) return NOT_VALID; + return m_vecOfDictRegions[regHash]->m_phi0; +} + +int +JGTowerBase_ID::get_prev_in_phi(const IdentifierHash& id, IdentifierHash& prev) const +{ + unsigned short index = id; + if (index < m_prev_phi_vec.size()) { + if (m_prev_phi_vec[index] == NOT_VALID_HASH) return (1); + prev = m_prev_phi_vec[index]; + return (0); + } + return (1); +} + +int +JGTowerBase_ID::get_next_in_phi(const IdentifierHash& id, IdentifierHash& next) const +{ + unsigned short index = id; + if (index < m_next_phi_vec.size()) { + if (m_next_phi_vec[index] == NOT_VALID_HASH) return (1); + next = m_next_phi_vec[index]; + return (0); + } + return (1); +} + +int +JGTowerBase_ID::get_prev_in_eta(const IdentifierHash& id, IdentifierHash& prev) const +{ + unsigned short index = id; + if (index < m_prev_eta_vec.size()) { + if (m_prev_eta_vec[index] == NOT_VALID_HASH) return (1); + prev = m_prev_eta_vec[index]; + return (0); + } + return (1); +} + +int +JGTowerBase_ID::get_next_in_eta(const IdentifierHash& id, IdentifierHash& next) const +{ + unsigned short index = id; + if (index < m_next_eta_vec.size()) { + if (m_next_eta_vec[index] == NOT_VALID_HASH) return (1); + next = m_next_eta_vec[index]; + return (0); + } + return (1); +} + + +int JGTowerBase_ID::get_expanded_id (const Identifier& id, ExpandedIdentifier& exp_id, const IdContext* context) const +{ + // We assume that the context is >= region + exp_id.clear(); + exp_id << calo_field_value() + << pos_neg(id) + << sampling(id) + << region(id); + if(context && context->end_index() >= m_ETA_INDEX) { + exp_id << eta(id); + if(context->end_index() >= m_PHI_INDEX) { + exp_id << phi(id); + } + } + return (0); +} +void JGTowerBase_ID::tower_id_checks ( int pos_neg, int sampling, int region, + int eta, int phi ) const throw(CaloID_Exception) +{ + // Fill expanded id + ExpandedIdentifier id(calo_exp()); + id << pos_neg << sampling << + region << eta << phi; + + if( id.last_error () != ExpandedIdentifier::none) { + std::string errorMessage = + "Error in JGTowerBase_ID::tower_id(field values), did not build, " + + strformat("pos_neg: %d , sampling: %d, region: %d , eta: %d , phi: %d ", + pos_neg, sampling, region, eta, phi); + throw CaloID_Exception(errorMessage , 2); + } + + if (!m_full_tower_range.match(id)) { + std::string errorMessage = "JGTowerBase_ID::tower_id() result is not OK: ID, range = " + + std::string(id) + " , " + (std::string)m_full_tower_range; + throw CaloID_Exception(errorMessage , 2); + } +} + +void JGTowerBase_ID::tower_id_checks ( const Identifier regionId, + int eta, int phi ) const throw(CaloID_Exception) +{ + // Fill expanded id + ExpandedIdentifier id; + + IdContext context = region_context(); + if (get_expanded_id(regionId, id, &context)) { + std::string errorMessage = "JGTowerBase_ID::tower_id(regionId) result is not OK: ID= " + + show_to_string(regionId) ; + throw CaloID_Exception(errorMessage , 2); + } + + id << eta << phi; + + if( id.last_error () != ExpandedIdentifier::none) { + + std::string errorMessage = + "Error in JGTowerBase_ID::tower_id(regionId,field values), values ok but did not build, " + + strformat ("eta: %d , phi: %d ", + eta, phi); + throw CaloID_Exception(errorMessage , 2); + } + + + if (!m_full_tower_range.match(id)) { + std::string errorMessage = "JGTowerBase_ID::tower_id(regionId,field values) result is not OK: ID, range = " + + std::string(id) + " , " + (std::string)m_full_tower_range; + throw CaloID_Exception(errorMessage , 2); + } +} + +void JGTowerBase_ID::region_id_checks (int pos_neg, int sampling, int region)const + throw(CaloID_Exception) +{ + // Fill expanded id + ExpandedIdentifier id(calo_exp()); + id << pos_neg << sampling << region ; + + if( id.last_error () != ExpandedIdentifier::none) { + std::string errorMessage = + "Error in JGTowerBase_ID::region_id(field values), did not build, " + + strformat ("pos_neg: %d , sampling: %d, region: %d ", + pos_neg , sampling , region); + throw CaloID_Exception(errorMessage , 2); + } + + if (!m_full_reg_range.match(id)) { + std::string errorMessage = "JGTowerBase_ID::region_id() result is not OK: ID, range = " + + std::string(id) + " , " + (std::string)m_full_reg_range; + throw CaloID_Exception(errorMessage , 2); + } +} + +int JGTowerBase_ID::initLevelsFromDict(const std::string& t_pre) +{ + MsgStream log(m_msgSvc, "JGTowerBase_ID" ); + std::stringstream strm; + std::stringstream strm1; + std::stringstream strm2; + std::stringstream strm3; + std::stringstream strm4; + std::stringstream strm5; + std::stringstream strm6; + std::stringstream strm7; + std::string strg; + std::string strg1; + std::string strg2; + std::string strg3; + std::string strg4; + std::string strg5; + std::string strg6; + std::string strg7; + if(!m_dict) + { + strg= "initLevelsFromDict - dictionary NOT initialized "; + if(m_msgSvc) { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + // Find out which identifier field corresponds to each level. + + m_CALO_INDEX = 999 ; + m_DETZSIDE_INDEX = 999 ; + m_SAMPLING_INDEX = 999 ; + m_REGION_INDEX = 999 ; + m_ETA_INDEX = 999 ; + m_PHI_INDEX = 999 ; + + // Save index to a JGTOWER region for unpacking - search with region name + IdDictRegion* reg = m_dict->find_region(t_pre+"ower_0"); + if (reg) + { + m_jgtower_region_index = reg->m_index; + } + else + { + strg = "initLevelsFromDict - unable to find jgtower region "; + if(m_msgSvc) { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + // Fing a JGTOWER region + IdDictField* field = m_dict->find_field("subdet") ; + if (field) { + m_CALO_INDEX = field->m_index ; + } + else + { + strg= "initLevelsFromDict - unable to find 'subdet' field "; + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + field = m_dict->find_field("DetZside") ; + if (field) { + m_DETZSIDE_INDEX = field->m_index ; + } + else + { + strg= "initLevelsFromDict - unable to find 'DetZside' field "; + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + field = m_dict->find_field(t_pre+"sampling") ; + if (field) { + m_SAMPLING_INDEX = field->m_index ; + } + else + { + + strg="initLevelsFromDict - unable to find '"+t_pre+"sampling' field "; + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + field = m_dict->find_field(t_pre+"region") ; + if (field) { + m_REGION_INDEX = field->m_index ; + } + else + { + + strg="initLevelsFromDict - unable to find 'region' field "; + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + /* std::cout << "m_region= " << m_REGION_INDEX << std::endl; */ + + field = m_dict->find_field(t_pre+"eta") ; + if (field) { + m_ETA_INDEX = field->m_index ; + } + else + { + strg= "initLevelsFromDict - unable to find 'eta' field "; + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + + field = m_dict->find_field(t_pre+"phi") ; + if (field) { + m_PHI_INDEX = field->m_index ; + } + else + { + + strg= "initLevelsFromDict - unable to find 'phi' field "; + if(m_msgSvc) + { + log << MSG::ERROR << strg << endmsg; + } + else + { + std::cout << strg << std::endl; + } + return (1); + } + // Set the field implementations + + const IdDictRegion& region = *m_dict->m_regions[m_jgtower_region_index]; + + m_calo_impl = region.m_implementation[m_CALO_INDEX]; + m_jgtower_impl = region.m_implementation[m_DETZSIDE_INDEX]; + m_sampling_impl = region.m_implementation[m_SAMPLING_INDEX]; + m_region_impl = region.m_implementation[m_REGION_INDEX]; + m_eta_impl = region.m_implementation[m_ETA_INDEX]; + m_phi_impl = region.m_implementation[m_PHI_INDEX]; + + strm1 << m_calo_impl.show_to_string(); + strm2 << m_jgtower_impl.show_to_string(); + strm3 << m_sampling_impl.show_to_string(); + strm4 << m_region_impl.show_to_string(); + strm5 << m_eta_impl.show_to_string(); + strm6 << m_phi_impl.show_to_string(); + strg = "decode index and bit fields for each level: "; + strg1= "calo "+strm1.str(); + strg2= "detzside "+strm2.str(); + strg3= "sampling "+strm3.str(); + strg4= "reg "+strm4.str(); + strg5= "eta "+strm5.str(); + strg6= "phi "+strm6.str(); + if(m_msgSvc) + { + log << MSG::DEBUG << strg << endmsg; + log << MSG::DEBUG << strg1 << endmsg; + log << MSG::DEBUG << strg2 << endmsg; + log << MSG::DEBUG << strg3 << endmsg; + log << MSG::DEBUG << strg4 << endmsg; + log << MSG::DEBUG << strg5 << endmsg; + log << MSG::DEBUG << strg6 << endmsg; + } + else + { + std::cout << strg << std::endl; + std::cout << strg1 << std::endl; + std::cout << strg2 << std::endl; + std::cout << strg3 << std::endl; + std::cout << strg4 << std::endl; + std::cout << strg5 << std::endl; + std::cout << strg6 << std::endl; + } + + return(0) ; +} + + +int JGTowerBase_ID::init_hashes(void) +{ + MsgStream log(m_msgSvc, "JGTowerBase_ID" ); + std::stringstream strm; + std::stringstream strm1; + std::stringstream strm2; + std::string strg; + std::string strg1; + std::string strg2; + // tower hash + m_tower_hash_max = m_full_tower_range.cardinality(); + m_tower_vec.resize(m_tower_hash_max); + unsigned int nids = 0; + std::set<Identifier> ids; + for (unsigned int i = 0; i < m_full_tower_range.size(); ++i) { + const Range& range = m_full_tower_range[i]; + Range::const_identifier_factory first = range.factory_begin(); + Range::const_identifier_factory last = range.factory_end(); + for (; first != last; ++first) { + const ExpandedIdentifier& exp_id = (*first); + Identifier tow_id = tower_id ( exp_id[m_DETZSIDE_INDEX], + exp_id[m_SAMPLING_INDEX], + exp_id[m_REGION_INDEX] , + exp_id[m_ETA_INDEX] , + exp_id[m_PHI_INDEX] ) ; + if(!(ids.insert(tow_id)).second) + { + if(m_msgSvc) + { + log << MSG::ERROR << " init_hashes " + << " duplicated id for J/GTower id. nids= " << nids + << " compact Id " << endmsg; + } + else + { + std::cout << " JGTowerBase_ID::init_hashes " + << " Error: duplicated id for J/GTower id. nids= " << nids + << " compact Id " ; + (*first).show(); + std::cout << " " << show_to_string(tow_id) << std::endl; + } + } + nids++; + } + } + if(ids.size() != m_tower_hash_max) + { + if( m_msgSvc) + { + log << MSG::ERROR << " init_hashes " + << " set size NOT EQUAL to hash max. size " << ids.size() + << " hash max " << m_tower_hash_max + << endmsg; + } + else + { + std::cout << " JGTowerBase_ID::init_hashes " + << " Error: set size NOT EQUAL to hash max. size " << ids.size() + << " hash max " << m_tower_hash_max + << std::endl; + } + return (1); + } + + nids=0; + std::set<Identifier>::const_iterator first = ids.begin(); + std::set<Identifier>::const_iterator last = ids.end(); + for (;first != last && nids < m_tower_vec.size(); ++first) { + m_tower_vec[nids] = (*first) ; + nids++; + } + // region hash + m_calo_region_hash_max = m_full_reg_range.cardinality(); + m_region_vec.resize(m_calo_region_hash_max); + nids = 0; + ids.clear(); + for (unsigned int i = 0; i < m_full_reg_range.size(); ++i) { + const Range& range = m_full_reg_range[i]; + Range::const_identifier_factory first = range.factory_begin(); + Range::const_identifier_factory last = range.factory_end(); + for (; first != last; ++first) { + const ExpandedIdentifier& exp_id = (*first); + Identifier reg_id = region_id ( exp_id[m_DETZSIDE_INDEX], + exp_id[m_SAMPLING_INDEX], + exp_id[m_REGION_INDEX] ); + if(!(ids.insert(reg_id)).second) + { + if(m_msgSvc) + { + log << MSG::ERROR << " JGTowerBase_ID::init_hashes " + << " duplicated id for region id. nids= " << nids + << " compact Id " << endmsg; + } + else + { + std::cout << " JGTowerBase_ID::init_hashes " + << " Error: duplicated id for region id. nids= " << nids + << " compact Id " ; + (*first).show(); + std::cout << " " << show_to_string(reg_id) << std::endl; + std::cout << std::endl; + } + } + nids++; + } + } + if(ids.size() != m_calo_region_hash_max) + { + if(m_msgSvc) + { + log << MSG::ERROR << " JGTowerBase_ID::init_hashes " + << " set size NOT EQUAL to region hash max. size " << ids.size() + << " region hash max " << m_calo_region_hash_max + << endmsg; + } + else + { + std::cout << " JGTowerBase_ID::init_hashes " + << " Error: set size NOT EQUAL to region hash max. size " << ids.size() + << " region hash max " << m_calo_region_hash_max + << std::endl; + } + return (1); + } + nids=0; + first = ids.begin(); + last = ids.end(); + for (;first != last && nids < m_region_vec.size(); ++first) { + m_region_vec[nids] = (*first) ; + nids++; + } + + return (0); +} + + + +int JGTowerBase_ID::init_neighbors(void) +{ + MsgStream log(m_msgSvc, "JGTowerBase_ID" ); + // std::cout << " JGTowerBase_ID::init_neighbors " << std::endl; + // std::cout << " m_tower_hash_max, NOT_VALID_HASH = " << m_tower_hash_max << " " << NOT_VALID_HASH << std::endl; + + m_prev_phi_vec.resize(m_tower_hash_max, NOT_VALID_HASH); + m_next_phi_vec.resize(m_tower_hash_max, NOT_VALID_HASH); + m_prev_eta_vec.resize(m_tower_hash_max, NOT_VALID_HASH); + m_next_eta_vec.resize(m_tower_hash_max, NOT_VALID_HASH); + for (unsigned int i = 0; i < m_full_tower_range.size(); ++i) { + const Range& range = m_full_tower_range[i]; + const Range::field& eta_field = range[m_ETA_INDEX]; + const Range::field& phi_field = range[m_PHI_INDEX]; + Range::const_identifier_factory first = range.factory_begin(); + Range::const_identifier_factory last = range.factory_end(); + for (; first != last; ++first) { + const ExpandedIdentifier& exp_id = (*first); + ExpandedIdentifier::element_type previous_eta; + ExpandedIdentifier::element_type next_eta; + ExpandedIdentifier::element_type previous_phi; + ExpandedIdentifier::element_type next_phi; + bool peta = eta_field.get_previous(exp_id[m_ETA_INDEX], previous_eta); + bool neta = eta_field.get_next (exp_id[m_ETA_INDEX], next_eta); + bool pphi = phi_field.get_previous(exp_id[m_PHI_INDEX], previous_phi); + bool nphi = phi_field.get_next (exp_id[m_PHI_INDEX], next_phi); + + IdContext tcontext = tower_context(); + + // Get and save region id to speed things up + Identifier reg_id = region_id ( exp_id[m_DETZSIDE_INDEX], + exp_id[m_SAMPLING_INDEX], + exp_id[m_REGION_INDEX] ); + + // First get primary hash id + IdentifierHash hash_id; + Identifier id = tower_id (reg_id, + exp_id[m_ETA_INDEX], + exp_id[m_PHI_INDEX]); + if (get_hash(id, hash_id,&tcontext)) + { + if( m_msgSvc ) + { + log << MSG::ERROR << " init_neighbors - unable to get hash, compact = " << endmsg; + } + else + { + std::cout << " JGTowerBase_ID::init_neighbors - unable to get hash, compact = "; + exp_id.show(); + std::cout << std::endl; + } + return (1); + } + + // index for the subsequent arrays + unsigned short index = hash_id; + assert (hash_id < m_prev_phi_vec.size()); + assert (hash_id < m_next_phi_vec.size()); + assert (hash_id < m_prev_eta_vec.size()); + assert (hash_id < m_next_eta_vec.size()); + + if (pphi) { + // Get previous phi hash id + id = tower_id (reg_id, + exp_id[m_ETA_INDEX], + previous_phi); + // forward to compact -> hash + if (get_hash(id, hash_id,&tcontext)) + { + if( m_msgSvc ) + { + log << MSG::ERROR << " init_neighbors - unable to get previous phi hash, exp/compact " << endmsg; + } + else + { + std::cout << " JGTowerBase_ID::init_neighbors - unable to get previous phi hash, exp/compact "; + exp_id.show(); + std::cout << " " + << std::endl; + } + return (1); + } + m_prev_phi_vec[index] = hash_id; + } + + if (nphi) { + // Get next phi hash id + id = tower_id (reg_id, + exp_id[m_ETA_INDEX], + next_phi); + // forward to compact -> hash + if (get_hash(id, hash_id,&tcontext)) + { + if(m_msgSvc) + { + log << MSG::ERROR << " init_neighbors - unable to get next phi hash, exp/compact "<<endmsg; + } + else + { + std::cout << " JGTowerBase_ID::init_neighbors - unable to get next phi hash, exp/compact "; + exp_id.show(); + std::cout << " " + << std::endl; + } + return (1); + } + m_next_phi_vec[index] = hash_id; + } + if (peta) { + // Get previous eta hash id + id = tower_id (reg_id, + previous_eta, + exp_id[m_PHI_INDEX]); + // forward to compact -> hash + if (get_hash(id, hash_id,&tcontext)) + { + if( m_msgSvc ) + { + log << MSG::ERROR << " init_neighbors - unable to get previous eta hash, exp/compact "<< endmsg; + } + else + { + std::cout << " JGTowerBase_ID::init_neighbors - unable to get previous eta hash, exp/compact "; + exp_id.show(); + std::cout << " " + << std::endl; + } + return (1); + } + m_prev_eta_vec[index] = hash_id; + } + + if (neta) { + // Get next eta hash id + id = tower_id (reg_id, + next_eta, + exp_id[m_PHI_INDEX]); + // forward to compact -> hash + if (get_hash(id, hash_id,&tcontext)) + { + if( m_msgSvc ) + { + log << MSG::ERROR << " init_neighbors - unable to get next eta hash, exp/compact "; + } + else + { + std::cout << " JGTowerBase_ID::init_neighbors - unable to get next eta hash, exp/compact "; + exp_id.show(); + std::cout << " " + << std::endl; + } + return (1); + } + m_next_eta_vec[index] = hash_id; + } // end neta cond + } // end loop on identifiers + } // end loop on ranges + return (0); +} + +int +JGTowerBase_ID::fill_vec_of_dict_regions (const std::string& group_name /*= ""*/) +{ + m_vecOfDictRegions.clear(); + m_vecOfDictRegions.reserve (m_calo_region_hash_max); + IdContext region_cntxt = region_context(); + ExpandedIdentifier expRegId; + for (unsigned int i = 0; i < m_calo_region_hash_max; ++i) { + Identifier id = region_id(i); + if(!get_expanded_id(id, expRegId, ®ion_cntxt)) { + m_vecOfDictRegions.push_back (m_dict->find_region(expRegId,group_name)); + } + } + //assert (m_vecOfDictRegions.size() == regions().hash_max()); + return 0; +} diff --git a/Calorimeter/CaloIdentifier/src/JTower_ID.cxx b/Calorimeter/CaloIdentifier/src/JTower_ID.cxx new file mode 100644 index 00000000000..50b4d5a6a92 --- /dev/null +++ b/Calorimeter/CaloIdentifier/src/JTower_ID.cxx @@ -0,0 +1,52 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "CaloIdentifier/JTower_ID.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "Identifier/IdentifierHash.h" +#include "IdDict/IdDictDefs.h" + +#include "GaudiKernel/MsgStream.h" + +#include <string> +#include <set> +#include <iostream> +#include <math.h> + + + +JTower_ID::JTower_ID(void) : + JGTowerBase_ID() +{ +} + +JTower_ID::~JTower_ID(void) +{ +} + +int JTower_ID::initialize_from_dictionary (const IdDictMgr& dict_mgr) +/*=================================================================*/ +{ + MsgStream log(m_msgSvc, "JTower_ID" ); + + log << MSG::DEBUG << "initialize_from_dictionary" << endmsg; + + // Check whether this helper should be reinitialized + if (!reinitialize(dict_mgr)) { + log << MSG::DEBUG << "Request to reinitialize not satisfied - tags have not changed" << endmsg; + return (0); + } + else { + if(m_msgSvc)log << MSG::DEBUG << "(Re)initialize" << endmsg; + } + + // init base object + if (JGTowerBase_ID::initialize_base_from_dictionary(dict_mgr, "positive_jTower_side", "JT")) + return (1); + + + return 0; +} + + diff --git a/Calorimeter/CaloIdentifier/test/GTower_ID_test.cxx b/Calorimeter/CaloIdentifier/test/GTower_ID_test.cxx new file mode 100644 index 00000000000..eca4d0f088a --- /dev/null +++ b/Calorimeter/CaloIdentifier/test/GTower_ID_test.cxx @@ -0,0 +1,76 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file CaloIdentifier/test/GTower_ID_test.cxx + * @author Walter Hopkins + * @date Oct 2014 + * @brief Unit test for GTower_ID. + */ + +#undef NDEBUG + +#include "CaloIdentifier/GTower_ID.h" +#include "IdDictParser/IdDictParser.h" +#include <iostream> + + +#include "jgtower_id_test_common.cxx" + + +GTower_ID* make_helper (bool do_neighbours = false) +{ + GTower_ID* idhelper = new GTower_ID; + IdDictParser* parser = new IdDictParser; + parser->register_external_entity ("Calorimeter", + "IdDictCalorimeter_L1Onl.xml"); + IdDictMgr& idd = parser->parse ("IdDictParser/ATLAS_IDS.xml"); + idhelper->set_do_neighbours (do_neighbours); + assert (idhelper->initialize_from_dictionary (idd) == 0); + + assert (!idhelper->do_checks()); + idhelper->set_do_checks (true); + assert (idhelper->do_checks()); + + return idhelper; +} + + +void test_basic (const JGTowerBase_ID& idhelper) +{ + std::cout << "test_basic\n"; + idhelper.tower_id (6, 0, 0, 0, 0); + // gTower positive side (detSide/subDet, sampling, regionNum, etaNum, phiNum + basic_print_id (idhelper, idhelper.tower_id (6, 0, 0, 0, 0)); + basic_print_id (idhelper, idhelper.tower_id (6, 0, 0, 1, 15)); + basic_print_id (idhelper, idhelper.tower_id (6, 0, 1, 2, 10)); + + // gTower negative side + basic_print_id (idhelper, idhelper.tower_id (-6, 0, 0, 0, 0)); + basic_print_id (idhelper, idhelper.tower_id (-6, 0, 0, 1, 15)); + basic_print_id (idhelper, idhelper.tower_id (-6, 0, 1, 2, 10)); + + // gTower positive side, had cal (detSide/subDet, sampling, regionNum, etaNum, phiNum + basic_print_id (idhelper, idhelper.tower_id (6, 1, 0, 0, 0)); + basic_print_id (idhelper, idhelper.tower_id (6, 1, 0, 1, 15)); + basic_print_id (idhelper, idhelper.tower_id (6, 1, 1, 2, 10)); +} + +int main() +{ + GTower_ID* idhelper = make_helper(); + GTower_ID* idhelper_n = make_helper(true); + try { + test_basic (*idhelper); + test_towers (*idhelper); + test_exceptions (*idhelper, 6); + test4 (*idhelper_n); + testRegionInfo(*idhelper); + } + catch(CaloID_Exception & except){ + std::cout << "Unexpected exception: " << (std::string) except << std::endl ; + } + return 0; +} diff --git a/Calorimeter/CaloIdentifier/test/JTower_ID_test.cxx b/Calorimeter/CaloIdentifier/test/JTower_ID_test.cxx new file mode 100644 index 00000000000..47954656791 --- /dev/null +++ b/Calorimeter/CaloIdentifier/test/JTower_ID_test.cxx @@ -0,0 +1,77 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file CaloIdentifier/test/GTower_ID_test.cxx + * @author Walter Hopkins + * @date Oct 2014 + * @brief Unit test for GTower_ID. + */ + +#undef NDEBUG + +#include "CaloIdentifier/JTower_ID.h" +#include "IdDictParser/IdDictParser.h" +#include <iostream> + + +#include "jgtower_id_test_common.cxx" + + +JTower_ID* make_helper (bool do_neighbours = false) +{ + JTower_ID* idhelper = new JTower_ID; + IdDictParser* parser = new IdDictParser; + parser->register_external_entity ("Calorimeter", + "IdDictCalorimeter_DC3-05.xml"); + IdDictMgr& idd = parser->parse ("IdDictParser/ATLAS_IDS.xml"); + idhelper->set_do_neighbours (do_neighbours); + assert (idhelper->initialize_from_dictionary (idd) == 0); + + assert (!idhelper->do_checks()); + idhelper->set_do_checks (true); + assert (idhelper->do_checks()); + + return idhelper; +} + + +void test_basic (const JGTowerBase_ID& idhelper) +{ + std::cout << "test_basic\n"; + idhelper.tower_id (3, 0, 0, 0, 0); + // jTower positive side (detSide/subDet, sampling regionNum, etaNum, phiNum + basic_print_id (idhelper, idhelper.tower_id (3, 0, 0, 0, 0)); + basic_print_id (idhelper, idhelper.tower_id (3, 0, 0, 1, 15)); + basic_print_id (idhelper, idhelper.tower_id (3, 0, 1, 2, 10)); + + // jTower negative side + basic_print_id (idhelper, idhelper.tower_id (-3, 0, 0, 0, 0)); + basic_print_id (idhelper, idhelper.tower_id (-3, 0, 0, 1, 15)); + basic_print_id (idhelper, idhelper.tower_id (-3, 0, 1, 2, 10)); + + // jTower positive side, had sampling (detSide/subDet, sampling regionNum, etaNum, phiNum + basic_print_id (idhelper, idhelper.tower_id (3, 1, 0, 0, 0)); + basic_print_id (idhelper, idhelper.tower_id (3, 1, 0, 1, 15)); + basic_print_id (idhelper, idhelper.tower_id (3, 1, 1, 2, 10)); +} + + +int main() +{ + JTower_ID* idhelper = make_helper(); + JTower_ID* idhelper_n = make_helper(true); + try { + test_basic (*idhelper); + test_towers (*idhelper); + test_exceptions (*idhelper, 3); + test4 (*idhelper_n); + testRegionInfo(*idhelper); + } + catch(CaloID_Exception & except){ + std::cout << "Unexpected exception: " << (std::string) except << std::endl ; + } + return 0; +} diff --git a/Calorimeter/CaloIdentifier/test/jgtower_id_test_common.cxx b/Calorimeter/CaloIdentifier/test/jgtower_id_test_common.cxx new file mode 100644 index 00000000000..0067c53df4c --- /dev/null +++ b/Calorimeter/CaloIdentifier/test/jgtower_id_test_common.cxx @@ -0,0 +1,246 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file CaloIdentifier/test/larem_id_test_common.cxx + * @author Walter Hopkins (based on scott snyder's example) + * @date Oct 2014 + * @brief Code common between GTower_ID_test and JTower_ID test. + * This file is meant to be included in another file, + * not compiled separately. + */ + + +#include "boost/foreach.hpp" + + +// This because test differencing ignored lines containing `0x...' +std::string munghex (const std::string& h) +{ + if (h.size() > 2 && h[0] == '0' && h[1] == 'x') + return "hex(" + h.substr (2, std::string::npos) + ")"; + return h; +} +void basic_print_id (const JGTowerBase_ID& idhelper, const Identifier& id) +{ + std::cout << idhelper.show_to_string (id) << " " + << munghex(id.getString()) << "\n"; +} + + +class GTower_ID_Test + : public JGTowerBase_ID +{ + // public: + // using JGTowerBase_ID::lar_field_value; + // using JGTowerBase_ID::lar_em_field_value; +}; + + +class CellCounter +{ +public: + CellCounter(); + void count(int reg); + void report(); + + +private: + enum { + N_REG = 10 + }; + unsigned m_counts[N_REG]; +}; + +CellCounter::CellCounter() +{ + for (unsigned i=0; i < N_REG; i++) + m_counts[i] = 0; +} + +void CellCounter::count (int reg) +{ + if (reg < 0 || reg >= N_REG) std::abort(); + ++m_counts[reg]; +} + +void CellCounter::report() +{ + int towerSum = 0; + for(int regI=0; regI<N_REG; ++regI){ + printf ("Region %2d: %6d\n", regI, m_counts[regI]); + towerSum+=m_counts[regI]; + } + printf ("Total: %6d\n", towerSum); +} + + + +void test_towers (const JGTowerBase_ID& tower_id) +{ + std::cout << "test_towers\n"; + + // towers + IdContext towerContext = tower_id.tower_context(); + std::vector<Identifier>::const_iterator itId = tower_id.tower_begin(); + std::vector<Identifier>::const_iterator itIdEnd = tower_id.tower_end(); + std::vector<bool> hashvec(tower_id.tower_hash_max()); + CellCounter counts; + + std::cout << " nTowers " << itIdEnd - itId << "\n"; + + int hashsum = 0; + for(; itId!=itIdEnd; ++itId) { + Identifier t_id = *itId; + + IdentifierHash hashId; + assert (tower_id.get_hash (t_id, hashId, &towerContext) == 0); + Identifier t_id2; + assert (tower_id.get_id (hashId, t_id2, &towerContext) == 0); + assert (t_id == t_id2); + assert (t_id == tower_id.tower_id (hashId)); + assert (hashId == tower_id.tower_hash (t_id)); + assert (hashId == tower_id.tower_hash_binary_search (t_id)); + assert (hashId < hashvec.size()); + assert (!hashvec[hashId]); + hashvec[hashId] = true; + + hashsum += hashId; + + int pos_neg = tower_id.pos_neg(t_id); + int sampling = tower_id.sampling(t_id); + int reg = tower_id.region(t_id); + int eta = tower_id.eta(t_id); + int phi = tower_id.phi(t_id); + + t_id2 = tower_id.tower_id (pos_neg, sampling, reg, eta, phi); + assert (t_id == t_id2); + counts.count(reg); + } + for (size_t i = 0; i < hashvec.size(); i++) + assert (hashvec[i]); + +#if __cplusplus > 201100 + for (Identifier t_id : tower_id.tower_range()) { +#else + BOOST_FOREACH (Identifier t_id, tower_id.tower_range()) { +#endif + hashsum -= tower_id.tower_hash (t_id); + } + assert (hashsum == 0); + + counts.report(); + } + + + void test_exceptions (const JGTowerBase_ID& tower_id, int detSide) +{ + std::cout << "test_exceptions\n"; + bool caught = false; + try { + /*Identifier wrongRegionId =*/ tower_id.region_id (0,0,99); + } + catch(CaloID_Exception & except){ + caught = true; + std::cout << "Exception 1: " << (std::string)except << "\n"; + } + assert (caught); + + caught = false; + try { + /*Identifier wrongChannelId =*/ tower_id.tower_id (0,0,0,0,99); + } + catch(CaloID_Exception & except){ + caught = true; + std::cout << "Exception 2: " << (std::string)except << "\n"; + } + assert (caught); + + caught = false; + try { + Identifier goodRegionId = tower_id.region_id (detSide,0, 0); + /*Identifier wrongChannelId =*/ tower_id.tower_id (goodRegionId,0,-99); + } + catch(CaloID_Exception & except){ + caught = true; + std::cout << "Exception 3: " << (std::string)except << "\n"; + } + assert (caught); +} + + +// neighbors +void test4 (const JGTowerBase_ID& idhelper) +{ + std::cout << "test4\n"; + + IdentifierHash prevPhiHash; + IdentifierHash nextPhiHash; + IdentifierHash prevEtaHash; + IdentifierHash nextEtaHash; + IdentifierHash curHash; + IdentifierHash tmpHash; + + Identifier curId; + + // towers + IdContext towerContext = idhelper.tower_context(); + std::vector<Identifier>::const_iterator itId = idhelper.tower_begin(); + std::vector<Identifier>::const_iterator itIdEnd = idhelper.tower_end(); + + for(; itId!=itIdEnd; ++itId) { + Identifier t_id = *itId; + + assert (idhelper.get_hash (t_id, curHash, &towerContext) == 0); + + // Check that previous phi works + assert (idhelper.get_prev_in_phi(curHash, prevPhiHash) == 0); + assert (idhelper.get_next_in_phi(prevPhiHash, tmpHash) == 0); + Identifier t_id2; + assert (idhelper.get_id (tmpHash, t_id2, &towerContext) == 0); + assert (t_id == t_id2); + + // Check next phi + assert (idhelper.get_next_in_phi(curHash, nextPhiHash) == 0); + assert (idhelper.get_prev_in_phi(nextPhiHash, tmpHash) == 0); + assert (idhelper.get_id (tmpHash, t_id2, &towerContext) == 0); + assert (t_id == t_id2); + +// Check that previous eta works + if (!idhelper.get_prev_in_eta(curHash, prevEtaHash)){ + assert (idhelper.get_next_in_eta(prevEtaHash, tmpHash) == 0); + assert (idhelper.get_id (tmpHash, t_id2, &towerContext) == 0); + assert (t_id == t_id2); + } + else{ + std::cout << "No previous tower in eta found for hash: " << curHash << std::endl; + } + + // Check next eta + if (!idhelper.get_next_in_eta(curHash, nextEtaHash)){; + assert (idhelper.get_prev_in_eta(nextEtaHash, tmpHash) == 0); + assert (idhelper.get_id (tmpHash, t_id2, &towerContext) == 0); + assert (t_id == t_id2); + } +else{ + std::cout << "No next tower in eta found for hash: " << curHash << std::endl; + } + } +} + + void testRegionInfo (const JGTowerBase_ID& idhelper) + { + IdContext regionContext = idhelper.region_context(); + + BOOST_FOREACH (Identifier r_id, idhelper.reg_range()) { + + //IdentifierHash hashId; + // assert (idhelper.get_hash (r_id, hashId, ®ionContext) == 0); + std::cout << "(deta,dphi) and (eta0,phi0) is: (" << idhelper.etaGranularity(r_id) + << "," << idhelper.phiGranularity(r_id) << "), (" + << idhelper.eta0(r_id) << "," << idhelper.phi0(r_id) + << ")" << std::endl; + } + } -- GitLab