00001
00002
00003
00004 #include "GaudiKernel/SvcFactory.h"
00005 #include "GaudiKernel/ISvcLocator.h"
00006 #include "GaudiKernel/MsgStream.h"
00007 #include "GaudiKernel/SystemOfUnits.h"
00008
00009 #include "MagneticFieldSvc.h"
00010 #include "MagnetCondLocations.h"
00011 #include "IMagFieldTool.h"
00012
00013 #include "GaudiKernel/Vector3DTypes.h"
00014 #include "GaudiKernel/Point3DTypes.h"
00015 #include "GaudiKernel/IUpdateManagerSvc.h"
00016 #include "GaudiKernel/IToolSvc.h"
00017
00018 #include <cstdlib>
00019 #include <fstream>
00020
00030 DECLARE_SERVICE_FACTORY( MagneticFieldSvc );
00031
00032
00033
00034
00035 MagneticFieldSvc::MagneticFieldSvc( const std::string& name,
00036 ISvcLocator* svc ) : Service( name, svc ),
00037 m_mapFromOptions(false),
00038 m_scaleFromOptions(false),
00039 m_mapFilesUpPtr(0),
00040 m_mapFilesDownPtr(0),
00041 m_scaleUpPtr(0),
00042 m_scaleDownPtr(0),
00043 m_currentPtr(0),
00044 m_fieldTool(0),
00045 m_DC06FieldUp(0),
00046 m_DC06FieldDown(0),
00047 m_RealFieldUp(0),
00048 m_RealFieldDown(0),
00049 m_updMgrSvc(0),
00050 m_toolSvc(0)
00051 {
00052
00053 m_constFieldVector.push_back( 0. );
00054 m_constFieldVector.push_back( 0. );
00055 m_constFieldVector.push_back( 0. );
00056
00057 if( std::getenv("FIELDMAPROOT") != NULL ) {
00058 m_mapFilePath = getenv("FIELDMAPROOT");
00059 m_mapFilePath += "/cdf/";
00060 }
00061 else
00062 m_mapFilePath = "";
00063
00064 declareProperty( "NominalCurrent", m_nominalCurrent = 5850,
00065 "Nominal magnet current in Amps" );
00066 declareProperty( "FieldMapPath", m_mapFilePath,
00067 "Directory where field map files are located, including trailing separator" );
00068 declareProperty( "UseConditions", m_UseConditions = true );
00069 declareProperty( "UseSetCurrent", m_UseSetCurrent = false );
00070 declareProperty( "FieldMapFiles", m_mapFileNames,
00071 "Vector of file names for the field map. If set, over-rides CondDB value" );
00072 declareProperty( "ScaleFactor", m_scaleFactor = 9999.,
00073 "Factor by which to rescale the field map. If set, over-rides CondDB value" );
00074 declareProperty( "Polarity", m_polarity = 0,
00075 "Polarity of the magnet. If set, over-rides CondDB value" );
00076
00077 declareProperty( "UseConstantField", m_useConstField = false );
00078 declareProperty( "ConstantFieldVector", m_constFieldVector );
00079
00080
00081 declareProperty( "UseRealMap", m_useRealMap = false );
00082 declareProperty( "FieldMapFile", m_filename = "" );
00083 declareProperty( "FieldMapFileQ1",m_qfilename[0] = "" );
00084 declareProperty( "FieldMapFileQ2",m_qfilename[1] = "" );
00085 declareProperty( "FieldMapFileQ3",m_qfilename[2] = "" );
00086 declareProperty( "FieldMapFileQ4",m_qfilename[3] = "" );
00087 declareProperty( "CondPath", m_condPath = "" );
00088
00089 }
00090
00091
00092
00093 MagneticFieldSvc::~MagneticFieldSvc()
00094 {
00095 }
00096
00097
00098
00099
00100 StatusCode MagneticFieldSvc::initialize()
00101 {
00102
00103 MsgStream log(msgSvc(), name());
00104 StatusCode status = Service::initialize();
00105 if( status.isFailure() ) return status;
00106
00107
00108 if( m_filename != "" || m_qfilename[0] != "" || m_qfilename[1] != ""
00109 || m_qfilename[2] != "" || m_qfilename[3] != "") {
00110 if( m_mapFileNames.size() > 0 ) {
00111 log << MSG::ERROR << "Both old and new style FieldMapFile options set, don't know what to do!" << endmsg;
00112 return StatusCode::FAILURE;
00113 }
00114 else if( m_filename != "" && m_qfilename[0] == "" && m_qfilename[1] == ""
00115 && m_qfilename[2] == "" && m_qfilename[3] == "") {
00116 log << MSG::WARNING << "Using obsolete DC06 option FieldMapFile, please change to FieldMapFiles" << endmsg;
00117 m_mapFileNames.push_back( m_filename );
00118 }
00119 else if( m_filename == "" && m_qfilename[0] != "" && m_qfilename[1] != ""
00120 && m_qfilename[2] != "" && m_qfilename[3] != "") {
00121 log << MSG::WARNING << "Using obsolete real map options FieldMapFileQ*, please change to FieldMapFiles" << endmsg;
00122 m_mapFileNames.push_back( m_qfilename[0] );
00123 m_mapFileNames.push_back( m_qfilename[1] );
00124 m_mapFileNames.push_back( m_qfilename[2] );
00125 m_mapFileNames.push_back( m_qfilename[3] );
00126 }
00127 else {
00128 log << MSG::ERROR << "Using invalid combination of FieldMapFile and FieldMapfileQ* options" << endmsg;
00129 return StatusCode::FAILURE;
00130 }
00131 }
00132 if( m_condPath != "" )
00133 log << MSG::WARNING << "Obsolete property CondPath given but has no effect" << endmsg;
00134
00135
00136 status = service("ToolSvc", m_toolSvc );
00137 if ( status.isFailure() ) {
00138 log << MSG::ERROR << "Cannot find the ToolSvc" << endmsg;
00139 return status;
00140 }
00141
00142 if( m_useConstField ) {
00143
00144 log << MSG::WARNING << "using constant magnetic field with field vector "
00145 << m_constFieldVector << " (Tesla)" << endmsg;
00146 return StatusCode::SUCCESS;
00147 }
00148
00149 if( m_UseConditions ) {
00150
00151 status = initializeWithCondDB();
00152 }
00153 else {
00154 status = initializeWithoutCondDB();
00155 }
00156
00157 return status;
00158 }
00159
00160
00161
00162
00163 StatusCode MagneticFieldSvc::finalize()
00164 {
00165 StatusCode sc = StatusCode::SUCCESS;
00166
00167 if ( m_DC06FieldUp ) { sc = sc && m_toolSvc->releaseTool(m_DC06FieldUp); }
00168 if ( m_DC06FieldDown ) { sc = sc && m_toolSvc->releaseTool(m_DC06FieldDown); }
00169 if ( m_RealFieldUp ) { sc = sc && m_toolSvc->releaseTool(m_RealFieldUp); }
00170 if ( m_RealFieldDown ) { sc = sc && m_toolSvc->releaseTool(m_RealFieldDown); }
00171
00172 return sc && Service::finalize();
00173 }
00174
00175
00176 bool MagneticFieldSvc::useRealMap() const
00177
00178 {
00179 if( m_mapFileNames.size() == 4 )
00180 return true;
00181 else
00182 return false;
00183 }
00184
00185
00186 StatusCode MagneticFieldSvc::initializeWithCondDB()
00187
00188 {
00189 MsgStream log(msgSvc(), name());
00190
00191 StatusCode status = service("UpdateManagerSvc",m_updMgrSvc);
00192 if ( status.isFailure() ) {
00193 log << MSG::ERROR << "Cannot find the UpdateManagerSvc" << endmsg;
00194 return status;
00195 }
00196
00197
00198 if( m_UseSetCurrent ) {
00199 m_updMgrSvc->registerCondition( this, MagnetCondLocations::Set,
00200 &MagneticFieldSvc::i_updateConditions, m_currentPtr );
00201 }
00202 else {
00203 m_updMgrSvc->registerCondition( this, MagnetCondLocations::Measured,
00204 &MagneticFieldSvc::i_updateConditions, m_currentPtr );
00205 }
00206
00207
00208 m_mapFromOptions = false;
00209 if( m_mapFileNames.size() != 0 ) {
00210 log << MSG::WARNING
00211 << "Requested condDB but using manually set field map file name(s) = "
00212 << m_mapFileNames << endmsg;
00213 m_mapFromOptions = true;
00214 }
00215 else {
00216 m_updMgrSvc->registerCondition( this, MagnetCondLocations::FieldMapFilesUp,
00217 &MagneticFieldSvc::i_updateConditions, m_mapFilesUpPtr );
00218
00219 m_updMgrSvc->registerCondition( this, MagnetCondLocations::FieldMapFilesDown,
00220 &MagneticFieldSvc::i_updateConditions, m_mapFilesDownPtr );
00221 }
00222
00223
00224
00225 m_scaleFromOptions = false;
00226 if( m_scaleFactor < 9998. ) {
00227 log << MSG::WARNING
00228 << "Requested condDB but using manually set scale factor = "
00229 << m_scaleFactor << endmsg;
00230 m_scaleFromOptions = true;
00231 }
00232 else {
00233 m_updMgrSvc->registerCondition( this, MagnetCondLocations::ScaleUp,
00234 &MagneticFieldSvc::i_updateConditions, m_scaleUpPtr );
00235
00236 m_updMgrSvc->registerCondition( this, MagnetCondLocations::ScaleDown,
00237 &MagneticFieldSvc::i_updateConditions, m_scaleDownPtr );
00238 }
00239
00240
00241 return m_updMgrSvc->update(this);
00242
00243 }
00244
00245
00246 StatusCode MagneticFieldSvc::initializeWithoutCondDB()
00247
00248 {
00249
00250 MsgStream log(msgSvc(), name());
00251 log << MSG::WARNING << "Not using CondDB, entirely steered by options" << endmsg;
00252
00253 if( m_mapFileNames.size() == 0 ) {
00254 log << MSG::ERROR << "Field Map filename(s) not set" << endmsg;
00255 return StatusCode::FAILURE;
00256 }
00257 m_mapFromOptions = true;
00258
00259 if( m_scaleFactor > 9998. ) {
00260 m_scaleFactor = 1.;
00261 log << MSG::DEBUG << "Scale factor set to default = " << m_scaleFactor << endmsg;
00262 }
00263 m_scaleFromOptions = true;
00264
00265
00266
00267 return updateTool( 1 );
00268 }
00269
00270
00271
00272
00273 StatusCode MagneticFieldSvc::queryInterface( const InterfaceID& riid,
00274 void** ppvInterface )
00275 {
00276 if ( IMagneticFieldSvc::interfaceID().versionMatch(riid) ) {
00277 *ppvInterface = (IMagneticFieldSvc*)this;
00278 addRef();
00279 return StatusCode::SUCCESS;
00280 } else if ( ILHCbMagnetSvc::interfaceID().versionMatch(riid) ) {
00281 *ppvInterface = (ILHCbMagnetSvc*)this;
00282 addRef();
00283 return StatusCode::SUCCESS;
00284 }
00285 return Service::queryInterface(riid,ppvInterface);
00286 }
00287
00288
00289
00290
00291 StatusCode MagneticFieldSvc::fieldVector(const Gaudi::XYZPoint& r,
00292 Gaudi::XYZVector& bf ) const {
00293
00294 if( m_useConstField ) {
00295 bf.SetXYZ( m_constFieldVector[0]*Gaudi::Units::tesla,
00296 m_constFieldVector[1]*Gaudi::Units::tesla,
00297 m_constFieldVector[2]*Gaudi::Units::tesla );
00298 return StatusCode::SUCCESS;
00299 }
00300
00301
00302 m_fieldTool->fieldVector( r, bf );
00303 return StatusCode::SUCCESS;
00304
00305 }
00306
00307
00308 StatusCode MagneticFieldSvc::i_updateConditions()
00309
00310 {
00311 MsgStream log(msgSvc(), name());
00312 log << MSG::DEBUG << "updateConditions called" << endmsg;
00313
00314 int polarity;
00315 if( m_polarity != 0 ) {
00316 log << MSG::WARNING
00317 << "Requested condDB but using manually set polarity = " << m_polarity << endmsg;
00318 polarity = m_polarity;
00319 }
00320 else
00321 polarity = m_currentPtr->param<int>("Polarity");
00322
00323
00324 if( !m_scaleFromOptions ) {
00325 double current = m_currentPtr->param<double>("Current");
00326
00327
00328 std::vector<double> coeffs;
00329 if( polarity > 0 )
00330 coeffs = m_scaleUpPtr->param<std::vector<double> >("Coeffs");
00331 else
00332 coeffs = m_scaleDownPtr->param<std::vector<double> >("Coeffs");
00333
00334 m_scaleFactor = coeffs[0] + ( coeffs[1]*(current/m_nominalCurrent) );
00335 }
00336
00337
00338 if( !m_mapFromOptions ) {
00339 m_mapFileNames.clear();
00340
00341
00342 std::vector<std::string> files;
00343 if( polarity > 0 )
00344 files = m_mapFilesUpPtr->param<std::vector<std::string> >("Files");
00345 else
00346 files = m_mapFilesDownPtr->param<std::vector<std::string> >("Files");
00347
00348 for ( std::vector<std::string>::const_iterator iF = files.begin(); iF != files.end(); ++iF ) {
00349 m_mapFileNames.push_back( m_mapFilePath + *iF );
00350 }
00351 }
00352
00353 log << MSG::DEBUG << "Field map files updated: " << m_mapFileNames << endmsg;
00354 log << MSG::DEBUG << "Scale factor updated: " << m_scaleFactor << endmsg;
00355
00356
00357 return updateTool( polarity );
00358 }
00359
00360
00361 StatusCode MagneticFieldSvc::updateTool( int polarity )
00362
00363 {
00364
00365 MsgStream log(msgSvc(), name());
00366
00367 if( polarity == 0 ) {
00368 polarity = 1;
00369 log << MSG::INFO << "Polarity not set, using default = 1 (UP) " << endmsg;
00370 }
00371
00372 if( m_mapFileNames.size() == 1 ) {
00373
00374 if( polarity > 0 ) {
00375 if( 0 == m_DC06FieldUp ) {
00376 StatusCode sc = m_toolSvc->retrieveTool( "MagFieldToolDC06",
00377 "MagToolDC06Up",
00378 m_DC06FieldUp, this );
00379 if( sc.isFailure() ) {
00380 log << MSG::ERROR << "Could not retrieve MagToolDC06Up" << endmsg;
00381 return sc;
00382 }
00383 }
00384 m_fieldTool = m_DC06FieldUp;
00385 }
00386 else {
00387 if( 0 == m_DC06FieldDown ) {
00388 StatusCode sc = m_toolSvc->retrieveTool( "MagFieldToolDC06",
00389 "MagToolDC06Down",
00390 m_DC06FieldDown, this );
00391 if( sc.isFailure() ) {
00392 log << MSG::ERROR << "Could not retrieve MagToolDC06Down" << endmsg;
00393 return sc;
00394 }
00395 }
00396 m_fieldTool = m_DC06FieldDown;
00397 }
00398 }
00399 else if( m_mapFileNames.size() == 4 ) {
00400
00401 if( polarity > 0 ) {
00402 if( 0 == m_RealFieldUp ) {
00403 StatusCode sc = m_toolSvc->retrieveTool( "MagFieldTool",
00404 "MagToolRealUp",
00405 m_RealFieldUp, this );
00406 if( sc.isFailure() ) {
00407 log << MSG::ERROR << "Could not retrieve MagToolRealUp" << endmsg;
00408 return sc;
00409 }
00410 }
00411 m_fieldTool = m_RealFieldUp;
00412 }
00413 else {
00414 if( 0 == m_RealFieldDown ) {
00415 StatusCode sc = m_toolSvc->retrieveTool( "MagFieldTool",
00416 "MagToolRealDown",
00417 m_RealFieldDown, this );
00418 if( sc.isFailure() ) {
00419 log << MSG::ERROR << "Could not retrieve MagToolRealDown" << endmsg;
00420 return sc;
00421 }
00422 }
00423 m_fieldTool = m_RealFieldDown;
00424 }
00425 }
00426 else {
00427 log << MSG::ERROR
00428 << "Wrong number of field map files, don't know what to do" << endmsg;
00429 return StatusCode::FAILURE;
00430 }
00431
00432 if ( !m_fieldTool )
00433 {
00434 log << MSG::ERROR
00435 << "Null FieldTool pointer | polarity = " << polarity
00436 << ", # FieldMap Files = " << m_mapFileNames.size()
00437 << endmsg;
00438 return StatusCode::FAILURE;
00439 }
00440
00441
00442 return m_fieldTool->updateMap( m_mapFileNames, m_scaleFactor );
00443 }