| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

CheckGeometryOverlaps.cpp

Go to the documentation of this file.
00001 // $Id: CheckGeometryOverlaps.cpp,v 1.1 2007/12/19 09:49:26 ibelyaev Exp $
00002 // ============================================================================
00003 // Include files 
00004 // ============================================================================
00005 // STL & STD 
00006 // ============================================================================
00007 #include <set>
00008 #include <functional>
00009 #include <algorithm>
00010 // ============================================================================
00012 // ============================================================================
00013 #include "GaudiKernel/AlgFactory.h"
00014 #include "GaudiKernel/IRndmGenSvc.h"
00015 #include "GaudiKernel/RndmGenerators.h"
00016 #include "GaudiKernel/SystemOfUnits.h"
00017 #include "GaudiKernel/Vector3DTypes.h"
00018 // ============================================================================
00019 // GaudiAlg
00020 // ============================================================================
00021 #include "GaudiAlg/GaudiAlgorithm.h"
00022 // ============================================================================
00023 // DetDesc 
00024 // ============================================================================
00025 #include "DetDesc/ILVolume.h"
00026 #include "DetDesc/IPVolume.h"
00027 #include "DetDesc/ISolid.h"
00028 #include "DetDesc/Material.h"
00029 #include "DetDesc/SolidBox.h"
00030 #include "DetDesc/VolumeIntersectionIntervals.h"
00031 #include "DetDesc/IntersectionErrors.h"
00032 #include "DetDesc/ITransportSvc.h"
00033 // ============================================================================
00034 // Boost
00035 // ============================================================================
00036 #include "boost/progress.hpp"
00037 #include "boost/format.hpp"
00038 // ============================================================================
00039 // GSL 
00040 // ============================================================================
00041 #include "gsl/gsl_sys.h"
00042 // ============================================================================
00048 // ============================================================================
00049 namespace DetDesc
00050 {
00051   // ==========================================================================
00052   bool isOK ( const ILVolume::Intersections& cnt ) 
00053   {
00054     for ( ILVolume::Intersections::const_iterator i1 = cnt.begin() ; 
00055           cnt.end() != i1 ; ++i1 ) 
00056     {
00057       const double x1 = i1->first.first  ;
00058       const double x2 = i1->first.second ;
00059       for ( ILVolume::Intersections::const_iterator i2 = i1 + 1 ; 
00060             cnt.end() != i2 ; ++i2 ) 
00061       {
00062         if ( 0 == VolumeIntersectionIntervals::intersect ( *i1 , *i2 ) ) 
00063         { return false ; }
00064         
00065         const double y1 = i2->first.first  ;
00066         const double y2 = i2->first.second ;        
00067         if ( x2 < y1 || y2 < x1 ) { continue ; }
00068         const double z1 = std::max ( x1 , y1 ) ;
00069         const double z2 = std::min ( x2 , y2 ) ;
00070         //if ( 0 > gsl_fcmp ( z1 , z2  , 1.0e-8 ) ) { return false ; }
00071         if ( z1 < z2 ) { return false ; }
00072         //if ( 0 > gsl_fcmp ( z1 , z2  , 1.0e-10 ) ) { return false ; }
00073       } 
00074     }
00075     return true ;
00076   }              
00077   std::pair<std::pair<int,int>,double> 
00078   notOK ( const ILVolume::Intersections& cnt ) 
00079   {
00080     for ( ILVolume::Intersections::const_iterator i1 = cnt.begin() ; 
00081           cnt.end() != i1 ; ++i1 ) 
00082     {
00083       const double x1 = i1->first.first  ;
00084       const double x2 = i1->first.second ;
00085       for ( ILVolume::Intersections::const_iterator i2 = i1 + 1 ; 
00086             cnt.end() != i2 ; ++i2 ) 
00087       {
00088         const double y1 = i2->first.first  ;
00089         const double y2 = i2->first.second ;        
00090         if ( x2 < y1 || y2 < x1 ) { continue ; }
00091         const double z1 = std::max ( x1 , y1 ) ;
00092         const double z2 = std::min ( x2 , y2 ) ;        
00093         if ( z1 < z2 ) 
00094         { 
00095           std::pair<int,int> p = std::make_pair
00096             ( i1 - cnt.begin() , i2 - cnt.begin  () ) ;
00097           return std::make_pair ( p , z2 - z1 ) ;
00098         }   
00099       } 
00100     }
00101     return std::pair<std::pair<int,int>,double>() ;
00102   }              
00103   // ==========================================================================
00109   class CheckOverlap : public GaudiAlgorithm 
00110   {
00112     friend class AlgFactory<DetDesc::CheckOverlap> ;
00113   public:
00114     // ========================================================================
00119     virtual StatusCode initialize () ;
00120     // ========================================================================
00125     virtual StatusCode execute    () ;
00126     // ========================================================================
00131     virtual StatusCode finalize   () ;
00132     // ========================================================================
00133   protected:
00134     // ========================================================================
00139     CheckOverlap 
00140     ( const std::string& name   , 
00141       ISvcLocator*       svcloc ) ;
00143     virtual ~CheckOverlap(){}; 
00144     // ========================================================================
00145   private:
00147     StatusCode checkVolume 
00148     ( const ILVolume* volume , const unsigned int level ) const ;
00150     StatusCode makeShots   ( const ILVolume* volume ) const ;
00151   private:
00152     // volume name 
00153     std::string         m_volumeName     ; 
00154     // volume itself 
00155     const ILVolume*     m_volume         ; 
00156     
00157     // volume limits (for assemblies)
00158     double              m_minx           ;
00159     double              m_maxx           ;
00160     double              m_miny           ;
00161     double              m_maxy           ;
00162     double              m_minz           ;
00163     double              m_maxz           ;
00164     
00165     // number of shots  
00166     int                 m_shots          ; 
00167     
00168     // point of shooting for sphere 
00169     std::vector<double> m_vrtx           ;
00170     Gaudi::XYZPoint                   m_vertex   ;
00171     mutable std::set<const ILVolume*> m_checked  ;
00172   } ;
00173 } //end of namespace DetDesk
00174 // ============================================================================
00175 /*  Standard constructor
00176  *  @param name name of the algorithm
00177  *  @param svcloc pointer to Service Locator 
00178  */
00179 // ============================================================================
00180 DetDesc::CheckOverlap::CheckOverlap
00181 ( const std::string& name   ,
00182   ISvcLocator*       svcloc )
00183   : GaudiAlgorithm( name , svcloc ) 
00184   , m_volumeName   ( "Undefined Volume" )
00185   , m_volume       ( 0            )
00186   , m_minx         ( -10 * Gaudi::Units::m      ) 
00187   , m_maxx         (  10 * Gaudi::Units::m      ) 
00188   , m_miny         ( -10 * Gaudi::Units::m      ) 
00189   , m_maxy         (  10 * Gaudi::Units::m      ) 
00190   , m_minz         ( -10 * Gaudi::Units::m      ) 
00191   , m_maxz         (  10 * Gaudi::Units::m      )
00192   , m_shots        ( 10000 )
00193   , m_vrtx         ( 3 , 0 ) 
00194   , m_vertex       (  ) 
00195   , m_checked      ()
00196 {
00197   declareProperty ( "Volume"               , m_volumeName   ) ;
00198   declareProperty ( "MinX"                 , m_minx         ) ;
00199   declareProperty ( "MinY"                 , m_miny         ) ;
00200   declareProperty ( "MinZ"                 , m_minz         ) ;
00201   declareProperty ( "MaxX"                 , m_maxx         ) ;
00202   declareProperty ( "MaxY"                 , m_maxy         ) ;
00203   declareProperty ( "MaxZ"                 , m_maxz         ) ;
00204   declareProperty ( "Shots"                , m_shots        ) ;
00205   declareProperty ( "Null"                 , m_vrtx         ) ;
00206  }
00207 // ============================================================================
00208 /*  standard algorithm initialization
00209  *  @see IAlgorithm
00210  *  @return status code 
00211  */
00212 // ============================================================================
00213 StatusCode DetDesc::CheckOverlap::initialize() 
00214 {
00215   StatusCode sc = GaudiAlgorithm::initialize() ;
00216   if ( sc.isFailure() ) { return sc ; }
00217   
00218   Assert ( 0 != randSvc () , "randSvc() points to NULL!" ) ;
00219   Assert ( 0 != detSvc  () , "detSvc()  points to NULL!" ) ;
00220   
00221   if ( !exist<ILVolume> ( detSvc() , m_volumeName ) && 
00222        exist<ILVolume>  ( detSvc() , "/dd/Geometry/"+ m_volumeName ) )
00223   {
00224     m_volumeName = "/dd/Geometry/" + m_volumeName ;
00225   }
00226   
00227   m_volume = getDet<ILVolume> ( m_volumeName ) ;
00228   
00229   // activate the vertex
00230   if ( m_vrtx.size() <= 3 )
00231   { while ( 3 != m_vrtx.size() ) { m_vrtx.push_back( 0.0 ); } }
00232   else 
00233   {
00234     warning()  << " Ignore extra fields in 'ShootingPoint' "<< endreq ;
00235   }
00236   m_vertex.SetXYZ( m_vrtx[0], m_vrtx[1], m_vrtx[2] ) ;
00237   
00238   if ( !m_volume->isAssembly() && 0 != m_volume->solid() ) 
00239   {
00240     const ISolid* top = m_volume->solid()->coverTop();
00241     if( 0 == top ) 
00242     { return Error( "CoverTop* points to NULL!" ) ; }
00243     const SolidBox* box = dynamic_cast<const SolidBox*> ( top );
00244     if( 0 == box ) 
00245     { return Error("SolidBox* points to NULL!"); }
00246     
00247     m_minx = -1 * box->xHalfLength() * 1.05 ;
00248     m_maxx =      box->xHalfLength() * 1.05 ;
00249     m_miny = -1 * box->yHalfLength() * 1.05 ;
00250     m_maxy =      box->yHalfLength() * 1.05 ;
00251     m_minz = -1 * box->zHalfLength() * 1.05 ;
00252     m_maxz =      box->zHalfLength() * 1.05 ;
00253   }
00254   
00256   svc<ITransportSvc> ( "TransportSvc" , true ) ;
00257   
00258   always() << " ATTENTION! THIS ALGORITHM DOES DESTROY THE GEOMETRY TREE" << endreq ;
00259   always() << " ATTENTION! NEVER USED IT IN THE REAL JOB OR RELY ON THE " << endreq ;
00260   always() << " ATTENTION! RESULT OF ANY OTHER 'GEOMETRY' TOOL/ALGORITHM" << endreq ;
00261   
00262   return StatusCode::SUCCESS ;
00263 }
00264 // ============================================================================
00265 /*  standard execution of algorithm 
00266  *  @see IAlgorithm
00267  *  @return status code 
00268  */
00269 // ============================================================================
00270 StatusCode DetDesc::CheckOverlap::execute() 
00271 {
00272   StatusCode sc = checkVolume ( m_volume , 0 ) ;
00273   
00274   always() << " ATTENTION! THIS ALGORITHM DOES DESTROY THE GEOMETRY TREE" << endreq ;
00275   always() << " ATTENTION! NEVER USED IT IN THE REAL JOB OR RELY ON THE " << endreq ;
00276   always() << " ATTENTION! RESULT OF ANY OTHER 'GEOMETRY' TOOL/ALGORITHM" << endreq ;
00277   
00278   return sc ;
00279 }
00280 // ============================================================================
00281 // perform the actual checking of the volume 
00282 // ============================================================================
00283 StatusCode DetDesc::CheckOverlap::checkVolume 
00284 ( const ILVolume*    volume , 
00285   const unsigned int level  ) const 
00286 {
00287   if ( 0 == volume ) { return Error ( "Invalid pointer to ILVolume!" ) ; }
00288   
00289   boost::format fmt ( "%-3d") ;
00290   const std::string lev = ( fmt % level ).str() ;
00291   
00292   // not checked yet ? 
00293   if ( m_checked.end() != m_checked.find ( volume ) ) 
00294   { return StatusCode::SUCCESS ; }
00295   
00296   
00297   always() 
00298     << lev << std::string ( 2*level , ' ' ) 
00299     << "Checking: " << volume -> name () << endreq ;
00300   
00301   // ==========================================================================
00302   // loop over all daughter volumes and
00303   const ILVolume::PVolumes& pvs = volume->pvolumes() ;
00304   for ( ILVolume::PVolumes::const_iterator ipv = 
00305           pvs.begin() ; pvs.end() != ipv ; ++ipv )
00306   {
00307     const IPVolume* pv = *ipv ;
00308     if ( 0 == pv ) { return Error ( "IPVolume* points to NULL!" )  ; } // RETURN 
00309     const ILVolume* lv = pv->lvolume () ;
00310     if ( 0 == lv ) { return Error ( "ILVolume* points to NULL!" )  ; } // RETURN 
00311     // check the daughter volume
00312     StatusCode sc = checkVolume ( lv , level + 1) ;
00313     if ( sc.isFailure() ) { return sc ; }                              // RETURN 
00314   }
00315   // ==========================================================================
00316   /*  here all daughter volumes are OK and are CLEARED! 
00317    *  and one can start to make the own  shoots (MUST be efficient!)
00318    */
00319   const StatusCode result = makeShots ( volume ) ;
00320   //
00321   {
00322     // ATTENTION!!! 
00323     // clear daugher volumes :
00324     ILVolume* vol = const_cast<ILVolume*>( volume ) ;
00325     vol -> pvolumes().clear() ;
00326   }
00327   
00328   // ==========================================================================
00329   always() 
00330     << lev << std::string ( 2*level , ' ' ) 
00331     << "Checked:  " << volume -> name () << endreq ;
00332   
00333   counter ("#volumes") += 1 ;
00334   if ( volume->isAssembly() ) { counter ("#assembly") += 1 ; }
00335   
00336   m_checked.insert ( volume ) ;
00337   
00338   return result ;
00339 }
00340 // ============================================================================
00341 // make the random shoots 
00342 // ============================================================================
00343 StatusCode DetDesc::CheckOverlap::makeShots 
00344 ( const ILVolume* volume ) const 
00345 {
00346   
00347   if ( 0 == volume ) 
00348   { return Error ( "Invalid pointer to ILVolume!" ) ; }
00349   
00350   // reset the counter of errors 
00351   DetDesc::IntersectionErrors::setCode ( StatusCode::SUCCESS , volume ) ;
00352 
00353   typedef  std::vector<Gaudi::XYZVector> Vectors ;
00354   Vectors vcts ;
00355   
00356   //
00357   vcts.push_back ( Gaudi::XYZVector ( 0 , 0 , 1 ) ) ;
00358   vcts.push_back ( Gaudi::XYZVector ( 0 , 1 , 0 ) ) ;
00359   vcts.push_back ( Gaudi::XYZVector ( 1 , 0 , 0 ) ) ;
00360   
00361   vcts.push_back ( Gaudi::XYZVector ( 1 ,  1 , 0 ) ) ;
00362   vcts.push_back ( Gaudi::XYZVector ( 1 , -1 , 0 ) ) ;
00363   vcts.push_back ( Gaudi::XYZVector ( 0 ,  1 , 1 ) ) ;
00364   vcts.push_back ( Gaudi::XYZVector ( 0 , -1 , 1 ) ) ;
00365   
00366   
00367   double xmin = m_minx ;
00368   double xmax = m_maxx ;
00369   double ymin = m_miny ;
00370   double ymax = m_maxy ;
00371   double zmin = m_minz ;
00372   double zmax = m_maxz ;
00373   
00374   if ( !volume->isAssembly() && 0 != volume->solid() ) 
00375   {
00376     const ISolid* top = volume->solid()->coverTop();
00377     if( 0 == top ) { return Error ( "CoverTop* points to NULL!" ) ; }
00378     const SolidBox* box = dynamic_cast<const SolidBox*> ( top );
00379     if( 0 == box ) { return Error ("SolidBox* points to NULL!"  ) ; }
00380     
00381     xmin = -1 * box -> xHalfLength () * 1.01 ;
00382     xmax =      box -> xHalfLength () * 1.01 ;
00383     ymin = -1 * box -> yHalfLength () * 1.01 ;
00384     ymax =      box -> yHalfLength () * 1.01 ;
00385     zmin = -1 * box -> zHalfLength () * 1.01 ;
00386     zmax =      box -> zHalfLength () * 1.01 ;
00387   }
00388   
00389   // get the number of shoots 
00390   int nShots = m_shots ;
00391   
00392   // check the simplest cases 
00393   if ( !volume ->isAssembly() && volume  -> pvolumes().empty() ) 
00394   {
00395     const ISolid* solid = volume->solid() ;
00396     if ( 0 != solid && 0 != dynamic_cast<const SolidBox*> ( solid ) ) 
00397     {
00398       // nothing to check, the case is just trivial  
00399       nShots = 0 ;
00400       return StatusCode::SUCCESS ;                                   // RETURN 
00401     }  
00402   }
00403   
00404   { //   
00405     boost::format fmt ( "Shooting #%8d:") ;
00406     info () << ( fmt %  nShots ).str() 
00407             << volume -> name () 
00408             << " #pv=" << volume->pvolumes().size() 
00409             << endreq ;
00410   }
00411   
00412   // display the progress
00413   boost::progress_display progress ( nShots ) ;
00414   
00415   // get the random number generator 
00416   Rndm::Numbers flat  ( randSvc() , Rndm::Flat (  0.0 , 1.0 ) );
00417   Rndm::Numbers flat1 ( randSvc() , Rndm::Flat ( -1.0 , 1.0 ) );
00418   
00419   for ( int iShoot = 0 ; iShoot < nShots ; ++iShoot ) 
00420   {
00421     
00422     const double x1 = xmin + flat.shoot() * ( xmax - xmin ) ;
00423     const double y1 = ymin + flat.shoot() * ( ymax - ymin ) ;
00424     const double z1 = zmin + flat.shoot() * ( zmax - zmin ) ;
00425     
00426     const double x2 = xmin + flat.shoot() * ( xmax - xmin ) ;
00427     const double y2 = ymin + flat.shoot() * ( ymax - ymin ) ;
00428     const double z2 = zmin + flat.shoot() * ( zmax - zmin ) ;
00429     
00430     Gaudi::XYZPoint  point  ( x1 , y1 , z1 ) ;
00431     Gaudi::XYZPoint  p2     ( x2 , y2 , z2 ) ;
00432     
00433     vcts.push_back ( p2       - point  ) ;
00434     vcts.push_back ( m_vertex - point  ) ;
00435     vcts.push_back ( m_vertex - point  )  ;
00436     
00437     vcts.push_back ( Gaudi::XYZVector ( flat1() , flat1() , flat1() ) )  ;
00438     vcts.push_back ( Gaudi::XYZVector ( flat1() , flat1() , flat1() ) )  ;
00439     vcts.push_back ( Gaudi::XYZVector ( flat1() , flat1() , flat1() ) )  ;
00440     
00441     vcts.push_back ( Gaudi::XYZVector ( 0 , 0 , 1 + 0.1 * flat1()  ) ) ;
00442     vcts.push_back ( Gaudi::XYZVector ( 0 , 1 + 0.1 * flat1() , 0  ) ) ; 
00443     vcts.push_back ( Gaudi::XYZVector ( 1 + 0.1 * flat1() , 0  , 0 ) ) ; 
00444     
00445     vcts.push_back ( Gaudi::XYZVector ( 0 , 0 , 1 + 0.1 * flat1()  ) ) ;
00446     vcts.push_back ( Gaudi::XYZVector ( 0 , 1 + 0.1 * flat1() , 0  ) ) ; 
00447     vcts.push_back ( Gaudi::XYZVector ( 1 + 0.1 * flat1() , 0  , 0 ) ) ; 
00448     
00449     for ( Vectors::const_iterator iv = vcts.begin() ; vcts.end() != iv ; ++iv ) 
00450     {
00451       // reset the counter of errors 
00452       DetDesc::IntersectionErrors::setCode ( StatusCode::SUCCESS , volume ) ;
00453       
00454       ILVolume::Intersections intersections;
00455       volume -> intersectLine ( point , *iv , intersections , 0 );
00456       
00457       // get the status
00458       StatusCode sc = DetDesc::IntersectionErrors::code() ;
00459       
00460       if ( sc.isFailure() ) 
00461       {
00462         
00463         error() << "Problem is detected with volume " 
00464                 << volume->name () 
00465                 << " With P/V=" 
00466                 << point << "/" << (*iv) << endreq ;
00467         
00468         DetDesc::IntersectionErrors::inspect
00469           ( volume , point  , *iv ,  intersections ) ;
00470         
00471         return Error ( "Intersection problems with " + volume->name() , sc ) ;
00472       }
00473     } // vectors
00474     // remove last vectors 
00475     while ( 7 < vcts.size() ) { vcts.pop_back() ; }
00476     // show the progress  
00477     ++progress ;
00478   } // shoots
00479   
00480   return StatusCode::SUCCESS ;
00481 }
00482 // ========================================================================
00483 /*  standard finalization of algorithm 
00484  *  @see IAlgorithm
00485  *  @return status code 
00486  */
00487 // ========================================================================
00488 StatusCode DetDesc::CheckOverlap::finalize   () 
00489 {
00490   always () << " ATTENTION! THIS ALGORITHM DOES DESTROY THE GEOMETRY TREE" << endreq ;
00491   always () << " ATTENTION! NEVER USED IT IN THE REAL JOB OR RELY ON THE " << endreq ;
00492   always () << " ATTENTION! RESULT OF ANY OTHER 'GEOMETRY' TOOL/ALGORITHM" << endreq ;
00493   
00494   return GaudiAlgorithm::finalize () ;
00495 }
00496 // ============================================================================
00498 DECLARE_NAMESPACE_ALGORITHM_FACTORY(DetDesc,CheckOverlap);
00499 // ============================================================================
00500 
00501 // ============================================================================
00502 // The END 
00503 // ============================================================================
00504 
00505 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:05:13 2011 for DetDescChecks by doxygen 1.4.7