00001
00002
00003
00004
00006
00007 #include "GaudiKernel/SvcFactory.h"
00008 #include "GaudiKernel/IDataProviderSvc.h"
00009 #include "GaudiKernel/IMessageSvc.h"
00010 #include "GaudiKernel/SmartDataPtr.h"
00011 #include "GaudiKernel/MsgStream.h"
00012
00013
00014
00015 #include "DetDesc/IGeometryInfo.h"
00016 #include "DetDesc/IDetectorElement.h"
00017 #include "DetDesc/IntersectionErrors.h"
00018
00019
00020
00021 #include "TransportSvc.h"
00022
00023
00024
00025 #include "boost/format.hpp"
00026
00033
00034 namespace
00035 {
00036 inline
00037 std::string
00038 logVol
00039 ( const std::string& name ,
00040 const unsigned int len ,
00041 const std::string& prefix = "/dd/Geometry/" )
00042 {
00043 std::string::size_type pos = name.find ( prefix ) ;
00044 if ( 0 == pos )
00045 { return logVol ( std::string ( name , pos + prefix.size() ) , len , prefix ) ; }
00046 if ( len < name.size () )
00047 {
00048 const unsigned int p = name.size() - len ;
00049 return std::string ( name , p ) ;
00050 }
00051 return name ;
00052 }
00053 }
00054
00055
00056
00057 TransportSvc::TransportSvc
00058 ( const std::string& name ,
00059 ISvcLocator* ServiceLocator )
00060 : Service ( name , ServiceLocator )
00061
00062 , m_detDataSvc_name ( "DetectorDataSvc" )
00064 , m_detDataSvc ( 0 )
00065
00066 , m_standardGeometry_address ( "/dd/Structure/LHCb" )
00067 , m_standardGeometry ( 0 )
00068
00069 , m_previousGeometry ( 0 )
00071 , m_prevPoint1 ( )
00072 , m_prevPoint2 ( )
00073 , m_previousThreshold ( -10000 )
00074 , m_previousGuess ( 0 )
00075 , m_previousTopGeometry ( 0 )
00076 , m_localIntersections ( )
00078 , m_local_intersects ( )
00080 , m_skip ()
00081 , m_recover ()
00082 , m_recovery ( true )
00083 , m_protocol ( true )
00085 {
00087 declareProperty ( "DetectorDataService" , m_detDataSvc_name ) ;
00088 declareProperty ( "StandardGeometryTop" , m_standardGeometry_address ) ;
00089 declareProperty
00090 ( "Recovery" , m_recovery ,
00091 "The flag to allow the recovery of geometry errors" ) ;
00092 declareProperty
00093 ( "Protocol" , m_protocol ,
00094 "The flag to allow protocol for the geometry problems" ) ;
00095 }
00096
00097
00098
00099 TransportSvc::~TransportSvc(){}
00100
00101
00102
00103 StatusCode TransportSvc::queryInterface
00104 ( const InterfaceID& iid, void** ppi )
00105 {
00107 if ( ITransportSvc ::interfaceID () == iid )
00108 { *ppi = static_cast<ITransportSvc*> ( this ) ; }
00109 else if ( DetDesc::IGeometryErrorSvc::interfaceID () == iid )
00110 { *ppi = static_cast<DetDesc::IGeometryErrorSvc*> ( this ) ; }
00111 else
00112 { return Service::queryInterface ( iid , ppi ) ; }
00114 addRef();
00116 return StatusCode::SUCCESS;
00118 }
00119
00120
00121
00122 StatusCode TransportSvc::initialize()
00123 {
00125 StatusCode statusCode = Service::initialize();
00126 if( statusCode.isFailure() ) return statusCode;
00127
00128 MsgStream log( msgSvc() , name() );
00129
00131 statusCode = serviceLocator()->service(m_detDataSvc_name, m_detDataSvc, true);
00132 if ( statusCode.isSuccess() && 0 != m_detDataSvc ) {
00133 detSvc() -> addRef();
00134 }
00135 else {
00136 log << MSG::FATAL
00137 << " Unable to locate Detector Data Service="
00138 << m_detDataSvc_name << endreq;
00139 m_detDataSvc = 0 ;
00140 return StatusCode::FAILURE ;
00141 }
00142
00143 if ( MSG::DEBUG >= outputLevel() && !m_protocol )
00144 {
00145 log << MSG::WARNING
00146 << "Protocol property is always 'true' when in DEBUG" << endmsg ;
00147 m_protocol = true ;
00148 }
00149
00150 if ( 0 == DetDesc::IntersectionErrors::service() )
00151 {
00152 log << MSG::INFO
00153 << "Initialize the static pointer to DetDesc::IGeometryErrorSvc" << endreq ;
00154 DetDesc::IntersectionErrors::setService ( this ) ;
00155 }
00156
00157 if ( !m_protocol )
00158 {
00159 log << MSG::WARNING
00160 << "The protocol of geometry errors is DISABLED" << endmsg;
00161 DetDesc::IntersectionErrors::setService ( 0 ) ;
00162 }
00163
00164
00165 DetDesc::IntersectionErrors::setRecovery ( m_recovery ) ;
00166 if ( DetDesc::IntersectionErrors::recovery() ) {
00167 log << MSG::INFO << "Recovery of geometry errors is ENABLED" << endmsg; }
00168 else {
00169 log << MSG::INFO << "Recovery of geometry errors is DISABLED" << endmsg; }
00170
00171 return StatusCode::SUCCESS;
00172 }
00173
00174
00175
00176 StatusCode TransportSvc::finalize()
00177 {
00178
00179 MsgStream log ( msgSvc() , name() );
00180
00181 {
00182 log << MSG::ALWAYS
00183 << " GEOMETRY ERRORS: 'Skip' map has the size " << m_skip.size() << std::endl ;
00184 if ( !m_skip.empty() )
00185 {
00186 boost::format fmt1 ( " | %1$=55.55s | | %2$-65.65s |" ) ;
00187 fmt1 % " Logical Volume " ;
00188 fmt1 % " # mean RMS min max" ;
00189 log << fmt1.str() << std::endl ;
00190 for ( Map::const_iterator i = m_skip.begin() ; m_skip.end() != i ; ++i )
00191 {
00192 {
00193 boost::format fmt2 ( " | %1$-55.55s | mm | %2$-65.65s |" ) ;
00194 fmt2 % logVol ( i->first , 55 ) ;
00195 fmt2 % Gaudi::Utils::formatAsTableRow
00196 ( i->second.first , false ,
00197 "%1$-7d %3$-14.8g %4$14.8g %5$-14.8g %6$14.8g" ) ;
00198 log << fmt2.str() << std::endl ;
00199 }
00200 {
00201 boost::format fmt2 ( " | %1$-55.55s | X0 | %2$-65.65s |" ) ;
00202 fmt2 % logVol ( i->first , 55 ) ;
00203 fmt2 % Gaudi::Utils::formatAsTableRow
00204 ( i->second.second , false ,
00205 "%1$-7d %3$-14.8g %4$14.8g %5$-14.8g %6$14.8g" ) ;
00206 log << fmt2.str() << std::endl ;
00207 }
00208 }
00209 }
00210 }
00211 log << endmsg;
00212
00213
00214 {
00215 log << MSG::ALWAYS
00216 << " GEOMETRY ERRORS: 'Recover' map has the size " << m_recover.size() << std::endl ;
00217 if ( !m_recover.empty() )
00218 {
00219 boost::format fmt1 ( " | %1$=55.55s | | %2$-65.65s |" ) ;
00220 fmt1 % " Logical Volume " ;
00221 fmt1 % " # mean RMS min max" ;
00222 log << fmt1.str() << std::endl ;
00223 for ( Map::const_iterator i = m_recover.begin() ; m_recover.end() != i ; ++i )
00224 {
00225 {
00226 boost::format fmt2 ( " | %1$-55.55s | mm | %2$-65.65s |" ) ;
00227 fmt2 % logVol ( i->first , 55 ) ;
00228 fmt2 % Gaudi::Utils::formatAsTableRow
00229 ( i->second.first , false ,
00230 "%1$-7d %3$-14.8g %4$14.8g %5$-14.8g %6$14.8g" ) ;
00231 log << fmt2.str() << std::endl ;
00232 }
00233 {
00234 boost::format fmt2 ( " | %1$-55.55s | X0 | %2$-65.65s |" ) ;
00235 fmt2 % logVol ( i->first , 55 ) ;
00236 fmt2 % Gaudi::Utils::formatAsTableRow
00237 ( i->second.second , false ,
00238 "%1$-7d %3$-14.8g %4$14.8g %5$-14.8g %6$14.8g" ) ;
00239 log << fmt2.str() << std::endl ;
00240 }
00241 }
00242 }
00243 }
00244 log << endmsg;
00245
00246
00247 {
00248 log << MSG::ALWAYS
00249 << " GEOMETRY ERRORS: 'Codes' map has the size " << m_codes.size() << std::endl ;
00250 if ( !m_codes .empty() )
00251 {
00252 boost::format fmt1 ( " | %1$=55.55s | %2$=10.10s |" ) ;
00253 fmt1 % " Logical Volume " ;
00254 fmt1 % "#errors" ;
00255 log << fmt1.str() << std::endl ;
00256 for ( Map1::const_iterator i = m_codes.begin() ; m_codes.end() != i ; ++i )
00257 {
00258 {
00259 boost::format fmt2 ( " | %1$-55.55s | %2$=10d |" ) ;
00260 fmt2 % logVol ( i->first , 55 ) ;
00261 fmt2 % i->second ;
00262 log << fmt2.str() << std::endl ;
00263 }
00264 }
00265 }
00266 }
00267 log << endmsg;
00268
00269 if ( this == DetDesc::IntersectionErrors::service() )
00270 {
00271 log << MSG::INFO
00272 << "Reset the static pointer to DetDesc::IGeometyrErrorSvc" << endreq ;
00273 DetDesc::IntersectionErrors::setService ( 0 ) ;
00274 }
00276 {
00277 const unsigned long nErrors = DetDesc::IntersectionErrors::errors () ;
00278 if ( 0 != nErrors )
00279 {
00280 log << MSG::ERROR
00281 << "DetDesc::IntersectionErrors has "
00282 << nErrors << " errors " << endreq ;
00283 log << MSG::ERROR
00284 << "Rerun the job with activated error handling!" << endreq ;
00285 }
00286 }
00288 {
00290 MsgStream log ( msgSvc() , name() );
00292 if ( 0 != detSvc () )
00293 { detSvc () -> release() ; m_detDataSvc = 0 ; }
00294 }
00296 log << MSG::DEBUG << "Service finalised successfully" << endreq;
00298 return Service::finalize();
00300 }
00301
00302 IGeometryInfo* TransportSvc::findGeometry
00303 ( const std::string& address ) const
00304 {
00306 IGeometryInfo* gi = 0 ;
00308 try
00309 {
00310 SmartDataPtr<IDetectorElement> detelem( detSvc() , address );
00311 if( 0 != detelem ) { gi = detelem->geometry() ; }
00312 }
00313 catch(...)
00314 { Assert( false ,
00315 "TransportSvc::findGeometry(), unknown exception caught!" ); }
00317 if( 0 == gi )
00318 throw TransportSvcException(
00319 "TransportSvc::unable to locate geometry address="+address,
00320 StatusCode::FAILURE );
00322 return gi;
00323 }
00324
00325
00326
00327 #include "TransportSvcDistanceInRadUnits.h"
00328 #include "TransportSvcFindLocalGI.h"
00329 #include "TransportSvcGoodLocalGI.h"
00330 #include "TransportSvcIntersections.h"
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 void TransportSvc::setCode
00343 ( const StatusCode& sc ,
00344 const ILVolume* volume )
00345 {
00346 if ( sc.isSuccess() ) { return ; }
00347 if ( !m_protocol && MSG::DEBUG > outputLevel() ) { return ; }
00348
00349 if ( 0 != volume ) { ++m_codes [ volume->name() ] ; }
00350 else { ++m_codes [ "" ] ; }
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 void TransportSvc::inspect
00363 ( const ILVolume* volume ,
00364 const Gaudi::XYZPoint& pnt ,
00365 const Gaudi::XYZVector& vect ,
00366 const ILVolume::Intersections& cnt )
00367 {
00368
00369 MsgStream log ( msgSvc () , name () );
00370
00371 log << MSG::ERROR
00372 << " DetDesc::IntersectionError for LV='" << volume->name() <<"'" << endreq ;
00373 log << MSG::ERROR
00374 << " Local Frame: "
00375 << " point=" << pnt
00376 << "/vector=" << vect
00377 << " Tick Length=" << vect.R() << endreq ;
00378
00379 boost::format fmt1
00380 ( "| %1$1.1s |%2$=15.15s %3$=15.15s|%4$=27.27s %5$=27.27s|%6$=3s %7$=16.16s | %8$=16.16s |" ) ;
00381 fmt1 % "?" ;
00382 fmt1 % "tickMin" ;
00383 fmt1 % "tickMax" ;
00384 fmt1 % "point1" ;
00385 fmt1 % "point2" ;
00386 fmt1 % "#" ;
00387 fmt1 % "phys.volume" ;
00388 fmt1 % "material" ;
00389 log << MSG::ERROR << fmt1.str() << endreq ;
00390
00391 for ( ILVolume::Intersections::const_iterator i =
00392 cnt.begin() ; cnt.end() != i ; ++i )
00393 {
00394
00395 bool ok = true ;
00396 for ( ILVolume::Intersections::const_iterator i2 = cnt.begin() ;
00397 ok && cnt.end() != i2 ; ++i2 )
00398 {
00399 if ( i2 == i ) { continue ; }
00400 ok = ( 0 != VolumeIntersectionIntervals::intersect ( *i , *i2 ) ) ;
00401 }
00402 boost::format fmt
00403 ( "| %1$1.1s |%2$15.9g %3$-15.9g|%4$27.27s %5$-27.27s|%6$=3d %7$16.16s | %8$16.16s |" ) ;
00404 fmt % ( ok ? " " : "*" ) ;
00405 fmt % i -> first.first ;
00406 fmt % i -> first.second ;
00407 fmt % ( pnt + i -> first.first * vect ) ;
00408 fmt % ( pnt + i -> first.second * vect ) ;
00409
00410
00411 Gaudi::XYZPoint c = pnt + 0.5 * ( i -> first.first + i -> first.second ) * vect ;
00412 ILVolume::PVolumePath pvs ;
00413 volume -> belongsTo ( c , 1 , pvs ) ;
00414 if ( pvs.empty() || 0 == pvs.front() )
00415 {
00416 fmt % -1 ;
00417 fmt % "<mother>" ;
00418 }
00419 else
00420 {
00421 const ILVolume::PVolumes& volumes = volume->pvolumes() ;
00422 ILVolume::PVolumes::const_iterator ipv =
00423 std::find ( volumes.begin() , volumes.end() , pvs.front() ) ;
00424 if ( volumes.end() == ipv ) { fmt % -1 ; }
00425 else { fmt % ( ipv - volumes.begin() ) ; }
00426 fmt % pvs.front()->name() ;
00427 }
00428 const std::string& n = i->second->name() ;
00429 if ( 16 >= n.size() ) { fmt % n ; }
00430 else { fmt % std::string ( n , n.size() - 16 ) ; }
00431
00432
00433 log << MSG::ERROR << fmt.str() << endreq ;
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 void TransportSvc::recovered
00447 ( const ILVolume* volume ,
00448 const Material* material1 ,
00449 const Material* material2 ,
00450 const double delta )
00451 {
00452 if ( !m_protocol && MSG::DEBUG > outputLevel() ) { return ; }
00453
00454 Map::mapped_type& p = m_recover [ volume->name() ] ;
00455
00456 p.first += delta ;
00457 p.second +=
00458 std::fabs
00459 ( delta / material1 -> radiationLength () -
00460 delta / material2 -> radiationLength () ) ;
00461
00462 return ;
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 void TransportSvc::skip
00474 ( const ILVolume* volume ,
00475 const Material* material ,
00476 const double delta )
00477 {
00478 if ( !m_protocol && MSG::DEBUG > outputLevel() ) { return ; }
00479
00480 Map::mapped_type& p = m_skip [ volume->name() ] ;
00481
00482 p.first += delta ;
00483 p.second += delta / material->radiationLength() ;
00484
00485 return ;
00486 }
00487
00488
00489
00490
00491 DECLARE_SERVICE_FACTORY( TransportSvc )
00492
00493
00494
00495
00496