Commit 9a3aec74 authored by Shaun Roe's avatar Shaun Roe Committed by Graeme Stewart
Browse files

fix OnlineId range checks and index generation (SCT_Cabling-00-00-41)

parent 57f3023f
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ISCT_CablingSvc_h
#define ISCT_CablingSvc_h
/**
* @file ISCT_CablingSvc.h
* Header file for abstract interface to SCT cabling service
* @author Shaun Roe
* @date 20 October, 2008
**/
//standard includes
#include "boost/cstdint.hpp"
#include <vector>
//Gaudi includes
#include "GaudiKernel/IInterface.h"
//InnerDetector
//#include "Identifier/IdentifierHash.h"
//to ensure clients can actually use the conversion constructors, include these here (otherwise could be forward declared)
#include "SCT_Cabling/SCT_SerialNumber.h"
#include "SCT_Cabling/SCT_OnlineId.h"
//fwd declarations
/**
* this works but is not allowed by the standard:
* http://www.kuzbass.ru/docs/isocpp/lib-intro.html
* 17.4.3.1
* namespace std {
* template <typename T> class allocator;
* template <typename T, typename A> class vector;
* }
**/
class Identifier;
class IdentifierHash;
/**
* @class ISCT_CablingSvc
* Client interface to the cabling, providing conversions between online and offline identifiers
**/
class ISCT_CablingSvc: virtual public IInterface{
public:
/// no-op destructor
virtual ~ISCT_CablingSvc(){}
/// interfaceID re-implemented from IInterface
static const InterfaceID & interfaceID();
/// return offline hash, given the online Id (used by decoders)
virtual IdentifierHash getHashFromOnlineId(const SCT_OnlineId & onlineId, const bool withWarnings = true) = 0;
/// return the online Id, given a hash (used by simulation encoders)
virtual SCT_OnlineId getOnlineIdFromHash(const IdentifierHash & hash) = 0;
/// return the rob/rod Id, given a hash (used by simulation encoders)
virtual boost::uint32_t getRobIdFromHash(const IdentifierHash & hash) = 0;
/// return the online Id, given an offlineId
virtual SCT_OnlineId getOnlineIdFromOfflineId(const Identifier & offlineId) = 0;
/// return the rob/rod Id, given an offlineId (used by simulation encoders)
virtual boost::uint32_t getRobIdFromOfflineId(const Identifier & offlineId) = 0;
/// size of the data structure (for the SCT should be 8176, one for each module side)
virtual unsigned int size() const = 0;
/// is the data structure empty?
virtual bool empty() const = 0;
/// get hash from a module serial number, needed in the conditions service because configurations are stored by module s/n
virtual IdentifierHash getHashFromSerialNumber(const SCT_SerialNumber & sn) = 0;
/// get module serial number from hash, needed during filling of data structure
virtual SCT_SerialNumber getSerialNumberFromHash(const IdentifierHash & hash) = 0;
/// fill a users vector with all the RodIds
virtual void getAllRods(std::vector<boost::uint32_t> & usersVector) = 0;
/// fill a user's vector with all the hash ids which belong to a given rod
virtual void getHashesForRod(std::vector<IdentifierHash> & usersVector, const boost::uint32_t rodId) = 0;
};
inline const InterfaceID & ISCT_CablingSvc::interfaceID(){
static const InterfaceID IID("ISCT_CablingSvc",1,0);
return IID;
}
#endif
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ISCT_FillCabling_H
#define ISCT_FillCabling_H
/**
* @file ISCT_Fill_Cabling.h
*
* @brief Interface for services which fill an SCT cabling object
*
* @author Shaun Roe
* @date 05/10/2008
*/
//STL includes
#include <string>
//Gaudi includes
#include "GaudiKernel/IInterface.h"
//fwd declarations
class SCT_CablingSvc;
class StatusCode;
/**
* @class ISCT_FillCabling
* @brief Interface base class for objects which fill the SCT Cabling.
*
*/
class ISCT_FillCabling:virtual public IInterface{
public:
///Virtual destructor
virtual ~ISCT_FillCabling(){}
/// interfaceID re-implemented from IInterface
static const InterfaceID & interfaceID();
/** May set the data source to textFile, database etc
* @param[in] @c string name of datasource
*/
virtual StatusCode setDataSource(const std::string & dataSource) = 0;
/** Gets the data source
* @return @c string name of datasource
*/
virtual std::string getDataSource() const = 0;
/**Fill the cabling maps
* @param[in] @c SCT_CablingSvc& , reference to the underlying data service
*/
virtual StatusCode fillMaps(SCT_CablingSvc * cabling) = 0;
/**Report whether the map was filled
* @return @c bool
*/
virtual bool filled() const = 0;
/**Report whether the object can fill its data during the initialize phase
* @return @c bool
*/
virtual bool canFillDuringInitialize() const = 0;
};//end of class
inline const InterfaceID & ISCT_FillCabling::interfaceID(){
static const InterfaceID IID("ISCT_FillCabling",1,0);
return IID;
}
#endif
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef SCT_CablingSvc_h
#define SCT_CablingSvc_h
/**
* @file SCT_CablingSvc.h
* Header file for SCT cabling service
* @author Shaun Roe
* @date 20 October, 2008
**/
//STL includes
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
//uint32 in std: namespace
#include "boost/cstdint.hpp"
//fixed-size array
#include "boost/array.hpp"
//Gaudi includes
#include "AthenaBaseComps/AthService.h"
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/IIncidentListener.h"
//package includes
//these are in the baseclass:
//#include "SCT_Cabling/SCT_SerialNumber.h"
//#include "SCT_Cabling/SCT_OnlineId.h"
#include "Identifier/IdentifierHash.h"
#include "SCT_Cabling/ISCT_CablingSvc.h"
#include "SCT_Cabling/ISCT_FillCabling.h"
//fwd declarations
template <class TYPE> class SvcFactory;
class ISvcLocator;
class StatusCode;
class InterfaceID;
class Incident;
class SCT_ID;
class Identifier;
/**
* @class SCT_CablingSvc, providing mappings of online and offline identifiers and also serial numbers
**/
class SCT_CablingSvc: virtual public ISCT_CablingSvc, virtual public IIncidentListener, public AthService{
friend class SvcFactory<SCT_CablingSvc>;
public:
enum {MAX_HASH=8175, NUMBER_OF_HASHES=8176};
///Incident listener method
virtual void handle(const Incident& beginRunIncident);
//@name Service methods, reimplemented
//@{
SCT_CablingSvc(const std::string &name, ISvcLocator * svc);
virtual ~SCT_CablingSvc(){}
virtual StatusCode initialize();
virtual StatusCode finalize();
//interfaceID() implementation is in the baseclass
virtual StatusCode queryInterface(const InterfaceID & riid, void** ppvInterface );
//@}
//@name ISCT_CablingSvc methods implemented, these are visible to clients
//@{
/// return offline hash, given the online Id (used by decoders)
virtual IdentifierHash getHashFromOnlineId(const SCT_OnlineId & onlineId, const bool withWarnings=true);
/// return the online Id, given a hash (used by simulation encoders)
virtual SCT_OnlineId getOnlineIdFromHash(const IdentifierHash & hash);
/// return the online Id, given an offlineId
virtual SCT_OnlineId getOnlineIdFromOfflineId(const Identifier & offlineId);
/// return the rob/rod Id, given a hash (used by simulation encoders)
virtual boost::uint32_t getRobIdFromHash(const IdentifierHash & hash) {
return getOnlineIdFromHash(hash).rod();
}
/// return the rob/rod Id, given an offlineId (used by simulation encoders)
virtual boost::uint32_t getRobIdFromOfflineId(const Identifier & offlineId) {
return getOnlineIdFromOfflineId(offlineId).rod();
}
/// size of the data structure (for the SCT should be 8176, one for each module side)
virtual unsigned int size() const;
/// is the data structure empty?
virtual bool empty() const;
/// get hash from a module serial number, needed in the conditions service because configurations are stored by module s/n
virtual IdentifierHash getHashFromSerialNumber(const SCT_SerialNumber & sn) ;
/// get module serial number from hash, needed during filling of data structure
virtual SCT_SerialNumber getSerialNumberFromHash(const IdentifierHash & hash) ;
/// fill a users vector with all the RodIds
virtual void getAllRods(std::vector<boost::uint32_t> & usersVector) { std::copy(m_rodIdSet.begin(), m_rodIdSet.end(), std::back_inserter(usersVector)); }
/// fill a user's vector with all the hash ids which belong to a given rod
virtual void getHashesForRod(std::vector<IdentifierHash> & usersVector, const boost::uint32_t rodId);
//@}
/// insert the hashId, onlineId and serial number to the data, used only within this package to fill the data structure
bool insert(const IdentifierHash & hash, const SCT_OnlineId & onlineId, const SCT_SerialNumber & sn);
private:
/**
* The underlying data structure for IdHash vs. onlineId is a boost fixed size array of 9216 elements
* since the SCT crates have identifiers of the form 0x2X000Y and 0x2X010Y, where X is 1-4
* and X is 0-0xb (so there are 96 possibilities). Further, each crate can have a maximum of
* 96 fibres, so 96 * 96 = 9216 possibilities. In practice, there are 8176 modules so the crate
* cabling occupancy is 89%; this is probably still better than using a map.
**/
boost::array<IdentifierHash, SCT_OnlineId::NUMBER_OF_INDICES> m_onlineId2HashArray;
std::map<SCT_SerialNumber, IdentifierHash> m_sn2HashMap; //!<Data map for serial number to hash
boost::array<SCT_OnlineId, NUMBER_OF_HASHES> m_hash2OnlineIdArray; //!<Array for hash to onlineId; hash goes from 0-8175
std::set<boost::uint32_t> m_rodIdSet; //!<set of robIds
ServiceHandle<ISCT_FillCabling> m_cablingFiller; //!< The cabling filler by baseclass handle; the concrete class is decided by job options
StringProperty m_cablingDataSource; //!< the name of the data source
unsigned int m_hashEntries; //!< number of entries successfully entered in the data structures
const SCT_ID * m_idHelper; //!< helper for offlineId/hash conversions
bool m_usingDatabase;
};
#endif
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef SCT_OnlineId_h
#define SCT_OnlineId_h
/**
* @file SCT_OnlineId.h
* Header file for a utility class to hold the online id
**/
#include "boost/cstdint.hpp"
/**
* SCT_OnlineId is a class to hold an online id number and
* provide check on validity, and conversions between the different formats.
* In general, an SCT online id has 32 bits
* composed of the robId (0-23) and the fibre number (24-31)
**/
class SCT_OnlineId{
public:
///Default constructor produces an invalid serial number
SCT_OnlineId();
/// Construct from uint32
SCT_OnlineId(const boost::uint32_t onlineId);
/// Construct from robId and fibre; a cursory check is made on validity of the input
SCT_OnlineId(const boost::uint32_t rodId, const boost::uint32_t fibre);
///return the rod/rob Id
boost::uint32_t rod() const;
///return the fibre
boost::uint32_t fibre() const;
//@name conversions to other forms
//@{
///overload cast to uint
operator unsigned int() const;
//@}
/**
* Check whether the onlineId is valid, with flag to switch between validity from the database or text file cabling source
**/
bool is_valid(const bool usingDbCabling) const;
/**
* Check whether the onlineId is valid, without knowing the data source; this is a rough check
**/
bool is_valid() const;
///Return an index in the range 0-9215, calculated from parts of the onlineId
unsigned int index() const;
///Is the rod in range?
static bool rodIdInRange(boost::uint32_t r);
///constants for evaluating hash indices of the online id. The hashing formula is in 'index()'
enum {
FIRST_FIBRE=0, LAST_FIBRE=95, NUM_FIBRES=96, MAX_INDEX=19871, NUMBER_OF_INDICES=19872, INVALID_INDEX=0xFFFFFFFF, INVALID_ONLINE_ID=0xFFFFFFFF
};
///Implement pre-increment and post-increment for iterating over fibres in a rod
SCT_OnlineId &operator++();
SCT_OnlineId operator++(int);
private:
/// The underlying number
boost::uint32_t m_onlineId;
///simple range check
bool fibreInRange(boost::uint32_t f) const;
///rough check on validity
bool couldBeValid(boost::uint32_t r);
///
bool rodIdInRange(boost::uint32_t r, const bool usingDbCabling) const;
};
#endif
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef SCT_SerialNumber_h
#define SCT_SerialNumber_h
/**
* @file SCT_SerialNumber.h
* Header file for a utility class to hold the serial number
**/
#include <string>
#include <ostream>
/**
* SCT_SerialNumber is a class to hold a serial number and
* provide check on validity, and conversions between the different formats.
* In general, an SCT serial number is a unique 14 digit code assigned to each module
* and found on the module as a bar code. It always starts with 20220
**/
class SCT_SerialNumber{
public:
///Default constructor produces an invalid serial number
SCT_SerialNumber();
/**
* Construct from string of the full number
**/
SCT_SerialNumber(const std::string & snString);
/**
* Construct from full number (unsigned), which has to be a long long
**/
SCT_SerialNumber(const unsigned long long fullSerialNumber);
/**
* Construct from full number (signed), which has to be a long long
**/
SCT_SerialNumber(const long long fullSerialNumber);
/**
* Construct from unsigned int, which can only hold the truncated serial number
**/
SCT_SerialNumber(const unsigned int truncatedSerialNumber);
/**
* Construct from int, which can only hold the truncated serial number
**/
SCT_SerialNumber(const int truncatedSerialNumber);
//@name conversions to other forms
//@{
///Full serial number as a string
std::string str() const;
///truncated serial number as unsigned int
unsigned int to_uint() const;
///full serial number as long long
unsigned long long to_ulonglong() const;
///overload cast to uint
operator unsigned int() const;
//@}
/** Cursory check on whether the serial number is well formed
* N.B. this is deliberately not an 'is_valid' method since a check on validity would require
* more comprehensive validation.
**/
bool isWellFormed() const;
///until I make a better test, is_valid returns only whether its well formed
bool is_valid() const{ return isWellFormed(); }
private:
/// The truncated number holds the integer part after the '20220' of the serial number
unsigned int m_truncatedNumber;
};
#endif
package SCT_Cabling
author Shaun Roe <Shaun.Roe@cern.ch>
use AtlasPolicy AtlasPolicy-*
use AthenaBaseComps AthenaBaseComps-* Control
use AtlasBoost AtlasBoost-* External
use Identifier Identifier-* DetectorDescription
use GaudiInterface GaudiInterface-* External
private
use InDetIdentifier InDetIdentifier-* InnerDetector/InDetDetDescr
use AthenaPoolUtilities AthenaPoolUtilities-* Database/AthenaPOOL
use PathResolver PathResolver-* Tools
use EventInfo EventInfo-* Event
use StoreGate StoreGate-* Control
public
apply_pattern dual_use_library files="*.cxx
apply_pattern declare_runtime files="*.dat"
apply_pattern declare_joboptions files="*.py"
macro DOXYGEN_IMAGE_PATH "../doc/images"
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/**
@mainpage SCT_Cabling Package
@author shaun.roe@cern.ch
@section SCT_CablingIntro Introduction
This package is meant to provide the mapping between online and offline
identifiers for each detector element. By online identifier we mean the
way a detector element is uniquely identified in the bytestream (i.e.
the ROD number and the link of the ROD). It also provides the mapping
between a ROB and the offline identifiers which are included in that ROB.
The present clients are the BS converters and the Region Selector used in the
HLT.
@section SCT_CablingOverview Class Overview
SCT_Cabling contains the following classes:
- ISCT_CablingSvc: Pure Abstract Baseclass giving accessor methods for SCT_CablingSvc. This is
the main interface for clients.
- SCT_CablingSvc: Inheriting from ISCT_CablingSvc, IIncidentListener and Service: Provides both
accessor methods and filling methods for the data structures it holds.
- ISCT_FillCabling: Interface for the SCT_Fillxxxx methods which are used to fill the data structures
in SCT_CablingSvc.
- SCT_FillCablingFromText: Inheriting from ISCT_FillCabling and Service, this is used to fill the
cabling data from a text file.
- SCT_FillCablingFromCoraCool: Inheriting from ISCT_FillCabling and Service, this is used to fill the
caling from the database, in CoraCool format.
- SCT_OnlineId: A stand-alone class for the online id, which is an encoding of the rod and fibre used
to readout a particular module.
- SCT_SerialNumber: A stand-alone class for the serial number, which is a 14 digit code associated with
each SCT module at its manufactire.
- SCT_TestCablingAlg: A test algorithm which instantiates the cabling service and loops over all possible
modules, calling methods to show the online Id and serial number for each one.
@image html structureDiag.png
@section SCT_CablingSvcDetail SCT_CablingSvc in Detail
SCT_CablingSvc is accessed by clients through its ISCT_CablingSvc interface. This provides access only to the 'getter' methods. In addition, it inherits from the IIncidentListener so that it can fill data (if appropriate) at the BeginRun incident. The 'setter' method is only accessible to users of the full class, in this case the fillers: SCT_FillCablingFromText and SCT_FillCablingFromCoraCool. These share a common baseclass and they are passed a pointer to the full SCT_CablingSvc to enable them to fill it. The decision as to which filler is to be instantiated is made by job options: the property 'DataSource' may be set to CORACOOL, in which case the database filler is used, or to a text filename, in which case the text filler is used.
The filler classes may report whether they can fill during the initialize phase, or need to wait for 'BeginRun'.
**/
\ No newline at end of file
################################################################################
# Job options file to test the Cabling
################################################################################
#--------------------------------------------------------------
# use auditors
#--------------------------------------------------------------
from AthenaCommon.AppMgr import ServiceMgr
from GaudiSvc.GaudiSvcConf import AuditorSvc
from AthenaCommon.AppMgr import theApp
ServiceMgr += AuditorSvc()
theAuditorSvc = ServiceMgr.AuditorSvc
theAuditorSvc.Auditors += [ "ChronoAuditor"]
theAuditorSvc.Auditors += [ "MemStatAuditor" ]
theApp.AuditAlgorithms=True
#--------------------------------------------------------------
# Load Geometry
#--------------------------------------------------------------
from AthenaCommon.GlobalFlags import globalflags
#globalflags.DetDescrVersion="ATLAS-GEO-16-00-00"
globalflags.DetDescrVersion = "ATLAS-GEO-20-00-01"
globalflags.DetGeo="atlas"