Skip to content
Snippets Groups Projects
Commit a538ff88 authored by Sebastien Ponce's avatar Sebastien Ponce
Browse files

Made DeCaloTiming functional

Also dropped its header file
parent 283bcbbc
No related branches found
No related tags found
1 merge request!3001Towards dropping GaudiAlgorithm from LHCb
......@@ -8,138 +8,126 @@
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
// Include files
// from Gaudi
#include "CaloDet/DeCalorimeter.h"
#include "DetDesc/GenericConditionAccessorHolder.h"
#include "GaudiAlg/Consumer.h"
#include "GaudiAlg/GaudiTupleAlg.h"
#include "GaudiKernel/IRndmGenSvc.h"
#include "GaudiKernel/RndmGenerators.h"
#include "GaudiKernel/StdArrayAsProperty.h"
// local
#include "DeCaloTiming.h"
//-----------------------------------------------------------------------------
// Implementation file for class : DeCaloTiming
//
// Simple algorithm to add time shift (user-defined or Gaussian or flat randomly
// distributed) at the DeCalorimeter initialisation level
// Useful to produce time misalignment (in Gauss) and check/develop alignment procedure
//
// 2007-08-22 : Olivier DESCHAMPS
//-----------------------------------------------------------------------------
// Declaration of the Algorithm Factory
DECLARE_COMPONENT( DeCaloTiming )
//=============================================================================
// Standard constructor, initializes variables
//=============================================================================
DeCaloTiming::DeCaloTiming( const std::string& name, ISvcLocator* pSvcLocator ) : GaudiTupleAlg( name, pSvcLocator ) {
declareProperty( "Method", m_method = "Flat" ); // Flat/Gauss/User
declareProperty( "Params", m_params = {0, 0} );
declareProperty( "Key", m_key = "CellID" );
declareProperty( "deltaTime", m_deltas );
/**
* Simple algorithm to add time shift (user-defined or Gaussian or flat randomly
* distributed) at the DeCalorimeter initialisation level
* Useful to produce time misalignment (in Gauss) and check/develop alignment procedure
*
* @author Olivier DESCHAMPS
* @date 2007-08-22
*/
class DeCaloTiming
: public Gaudi::Functional::Consumer<void( const DeCalorimeter& ),
LHCb::DetDesc::usesBaseAndConditions<GaudiTupleAlg, DeCalorimeter>> {
public:
/// Standard constructor
DeCaloTiming( const std::string& name, ISvcLocator* pSvcLocator );
StatusCode initialize() override;
void operator()( const DeCalorimeter& ) const override;
m_deltas["Default"] = 0.0 * Gaudi::Units::ns;
private:
double delta( long id ) const {
auto delta = m_deltas.find( std::to_string( id ) );
return delta != m_deltas.end() ? delta->second : m_deltas.value().at( "Default" );
}
// set default detectorName
auto idx = name.find_last_of( "." );
if ( idx == std::string::npos )
idx = 0;
else
++idx;
m_detectorName = name.substr( idx, 4 );
if ( name.substr( idx, 3 ) == "Prs" ) m_detectorName = "Prs";
if ( name.substr( idx, 3 ) == "Spd" ) m_detectorName = "Spd";
// Note that thread safety depends on the thread safety of the underlying random generator
mutable Rndm::Numbers m_shoot;
declareProperty( "DetectorName", m_detectorName );
}
//=============================================================================
// Initialization
//=============================================================================
StatusCode DeCaloTiming::initialize() {
StatusCode sc = GaudiTupleAlg::initialize(); // must be executed first
if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm
ServiceHandle<IRndmGenSvc> m_rndmSvc{this, "RndmGenSvc", "RndmGenSvc"};
if ( UNLIKELY( msgLevel( MSG::DEBUG ) ) ) debug() << "==> Initialize" << endmsg;
Gaudi::Property<std::string> m_method{this, "Method", "Flat", "Flat/Gauss/User"};
Gaudi::Property<std::array<double, 2>> m_params{this, "Params", {0, 0}};
Gaudi::Property<std::map<std::string, double>> m_deltas{this, "deltaTime", {{"Default", 0.0 * Gaudi::Units::ns}}};
Gaudi::Property<std::string> m_key{this, "Key", "CellID"};
// get DeCalorimeter
if ( "Ecal" == m_detectorName ) {
m_calo = getDet<DeCalorimeter>( DeCalorimeterLocation::Ecal );
} else if ( "Hcal" == m_detectorName ) {
m_calo = getDet<DeCalorimeter>( DeCalorimeterLocation::Hcal );
} else if ( "Prs" == m_detectorName ) {
m_calo = getDet<DeCalorimeter>( DeCalorimeterLocation::Prs );
} else if ( "Spd" == m_detectorName ) {
m_calo = getDet<DeCalorimeter>( DeCalorimeterLocation::Spd );
} else {
error() << "Unknown Calo detector name " << m_detectorName << endmsg;
return StatusCode::FAILURE;
}
// used to run only one first event
mutable std::once_flag m_onlyFirstEvent;
};
info() << " ======= SIMULATING THE MISALIGNMENT of " << m_detectorName << " TIMING ======= " << endmsg;
// Declaration of the Algorithm Factory
DECLARE_COMPONENT( DeCaloTiming )
// Params
auto rndmSvc = service<IRndmGenSvc>( "RndmGenSvc", true );
Rndm::Numbers shoot;
DeCaloTiming::DeCaloTiming( const std::string& name, ISvcLocator* pSvcLocator )
: Consumer( name, pSvcLocator, {KeyValue{"DetectorName", ""}} ) {}
if ( m_method == "Gauss" ) {
// Gaussian random (mean, rms)
info() << "---- Method : gaussian random timing values " << endmsg;
double a = m_params[0];
double b = m_params[1];
info() << " mean/sigma = " << a << "/" << b << endmsg;
sc = shoot.initialize( rndmSvc, Rndm::Gauss( a, b ) );
if ( !sc.isSuccess() ) return sc;
} else if ( m_method == "Flat" ) {
// Flat random (min, max)
info() << "---- Method : flat random timing values " << endmsg;
double a = m_params[0];
double b = m_params[1];
info() << " min/max = " << a << "/" << b << endmsg;
sc = shoot.initialize( rndmSvc, Rndm::Flat( a, b ) );
if ( !sc.isSuccess() ) return sc;
} else if ( m_method == "User" ) {
info() << "---- Method : user-defined timing values " << endmsg;
info() << "Timing value have been defined for " << m_deltas.size() << " cells " << endmsg;
info() << "Default value [" << m_deltas["Default"] << "] will be applied to "
<< m_calo->numberOfCells() - m_deltas.size() << " other cells." << endmsg;
if ( m_key == "CellID" ) {
info() << "The timing values are mapped with KEY = CellID " << endmsg;
} else if ( m_key == "Index" ) {
info() << "The timing values are are mapped with KEY = Index" << endmsg;
StatusCode DeCaloTiming::initialize() {
return GaudiTupleAlg::initialize().andThen( [&]() -> StatusCode {
info() << " ======= SIMULATING THE MISALIGNMENT of " << inputLocation<DeCalorimeter>()
<< " TIMING ======= " << endmsg;
if ( m_method == "Gauss" ) {
// Gaussian random (mean, rms)
info() << "---- Method : gaussian random timing values " << endmsg;
double a = m_params[0];
double b = m_params[1];
info() << " mean/sigma = " << a << "/" << b << endmsg;
auto sc = m_shoot.initialize( m_rndmSvc.get(), Rndm::Gauss( a, b ) );
if ( !sc.isSuccess() ) return sc;
} else if ( m_method == "Flat" ) {
// Flat random (min, max)
info() << "---- Method : flat random timing values " << endmsg;
double a = m_params[0];
double b = m_params[1];
info() << " min/max = " << a << "/" << b << endmsg;
auto sc = m_shoot.initialize( m_rndmSvc.get(), Rndm::Flat( a, b ) );
if ( !sc.isSuccess() ) return sc;
} else if ( m_method == "User" ) {
info() << "---- Method : user-defined timing values " << endmsg;
info() << "Timing value have been defined for " << m_deltas.size() << " cells " << endmsg;
info() << "Default value [" << m_deltas["Default"] << "] will be applied to other cells." << endmsg;
if ( m_key == "CellID" ) {
info() << "The timing values are mapped with KEY = CellID " << endmsg;
} else if ( m_key == "Index" ) {
info() << "The timing values are are mapped with KEY = Index" << endmsg;
} else {
error() << "undefined deltaKey : must be either 'CellID' or 'Index' " << endmsg;
return StatusCode::FAILURE;
}
} else {
error() << "undefined deltaKey : must be either 'CellID' or 'Index' " << endmsg;
error() << "Method " << m_method << " unknown - should be 'Flat', 'Gauss' or 'User'" << endmsg;
return StatusCode::FAILURE;
}
} else {
error() << "Method " << m_method << " unknown - should be 'Flat', 'Gauss' or 'User'" << endmsg;
return StatusCode::FAILURE;
}
// update cellParams
return StatusCode::SUCCESS;
} );
}
auto& cells = const_cast<CaloVector<CellParam>&>( m_calo->cellParams() ); // no-const conversion
std::vector<int> cellids, cellind;
std::vector<double> times, dtimes;
for ( auto& icell : cells ) {
LHCb::CaloCellID id = icell.cellID();
if ( !m_calo->valid( id ) || m_calo->isPinId( id ) ) continue;
long num = m_calo->cellIndex( id );
double dt = ( m_method != "User" ? shoot() : delta( m_key != "Index" ? id.index() : num ) );
if ( UNLIKELY( msgLevel( MSG::DEBUG ) ) )
debug() << num << " Delta time for cellID " << id << " : " << dt << endmsg;
icell.setDeltaTime( dt ); // add delta time (ns)
cellids.push_back( id.index() );
cellind.push_back( num );
times.push_back( icell.time() );
dtimes.push_back( icell.deltaTime() );
}
void DeCaloTiming::operator()( const DeCalorimeter& deCalo ) const {
std::call_once( m_onlyFirstEvent, [&]() {
// update cellParams
auto& cells = const_cast<CaloVector<CellParam>&>( deCalo.cellParams() ); // no-const conversion
std::vector<int> cellids, cellind;
std::vector<double> times, dtimes;
for ( auto& icell : cells ) {
LHCb::CaloCellID id = icell.cellID();
if ( !deCalo.valid( id ) || deCalo.isPinId( id ) ) continue;
long num = deCalo.cellIndex( id );
double dt = ( m_method != "User" ? m_shoot() : delta( m_key != "Index" ? id.index() : num ) );
if ( UNLIKELY( msgLevel( MSG::DEBUG ) ) )
debug() << num << " Delta time for cellID " << id << " : " << dt << endmsg;
icell.setDeltaTime( dt ); // add delta time (ns)
cellids.push_back( id.index() );
cellind.push_back( num );
times.push_back( icell.time() );
dtimes.push_back( icell.deltaTime() );
}
// Ntupling
Tuple ntp = nTuple( 500, m_detectorName + "DeTiming", CLID_ColumnWiseTuple );
auto max = m_calo->numberOfCells();
ntp->farray( "cellID", cellids, "Nchannels", max ).ignore();
ntp->farray( "index", cellind, "Nchannels", max ).ignore();
ntp->farray( "time", times, "Nchannels", max ).ignore();
ntp->farray( "dtime", dtimes, "Nchannels", max ).ignore();
return ntp->write();
// Ntupling
Tuple ntp = nTuple( 500, inputLocation<DeCalorimeter>() + "DeTiming", CLID_ColumnWiseTuple );
auto max = deCalo.numberOfCells();
ntp->farray( "cellID", cellids, "Nchannels", max ).ignore();
ntp->farray( "index", cellind, "Nchannels", max ).ignore();
ntp->farray( "time", times, "Nchannels", max ).ignore();
ntp->farray( "dtime", dtimes, "Nchannels", max ).ignore();
ntp->write().ignore();
} );
}
/*****************************************************************************\
* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the GNU General Public *
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
#ifndef COMPONENT_DECALOTIMING_H
#define COMPONENT_DECALOTIMING_H
// Include files
// from Gaudi
#include "CaloDet/DeCalorimeter.h"
#include "GaudiAlg/GaudiTupleAlg.h"
/** @class DeCaloTiming DeCaloTiming.h component/DeCaloTiming.h
*
*
* @author Olivier DESCHAMPS
* @date 2007-08-22
*/
class DeCaloTiming : public GaudiTupleAlg {
public:
/// Standard constructor
DeCaloTiming( const std::string& name, ISvcLocator* pSvcLocator );
StatusCode initialize() override; ///< Algorithm initialization
private:
double delta( long id ) {
auto i = m_deltas.find( std::to_string( id ) );
if ( i == m_deltas.end() ) i = m_deltas.find( "Default" );
return i->second;
}
std::string m_detectorName;
std::string m_method;
std::array<double, 2> m_params{};
std::map<std::string, double> m_deltas;
std::string m_key;
DeCalorimeter* m_calo = nullptr;
};
#endif // COMPONENT_DECALOTIMING_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment