| # Gaudi Framework, version v21r8 |

Home |  | Generated: 17 Mar 2010

# GaudiHistos.icpp

Go to the documentation of this file.

    00001 // $Id: GaudiHistos.icpp,v 1.17 2008/10/10 12:39:04 marcocle Exp $
    00002 // ============================================================================
    00003 #ifndef GAUDIALG_GAUDIHISTOS_ICPP
    00004 #define GAUDIALG_GAUDIHISTOS_ICPP 1
    00005 // ============================================================================
    00006 /* @file
    00007  *
    00008  *  Implementation file for class : GaudiHistos
    00009  *
    00010  *  @author Chris Jones   Christopher.Rob.Jones@cern.ch
    00011  *  @author Vanya BELYAEV Ivan.Belyaev@itep.ru
    00012  *  @date   2005-08-08
    00013  */
    00014 // ============================================================================
    00015 // STD & STL
    00016 // ============================================================================
    00017 #include <algorithm>
    00018 #include <string>
    00019 #include <vector>
    00020 #include <set>
    00021 // ============================================================================
    00022 // GaudiKernel
    00023 // ============================================================================
    00024 #include "GaudiKernel/MsgStream.h"
    00025 #include "GaudiKernel/IHistogramSvc.h"
    00026 // ============================================================================
    00027 // GaudiUtils
    00028 // ============================================================================
    00029 #include "GaudiUtils/HistoTableFormat.h"
    00030 // ============================================================================
    00031 // GaudiAlg
    00032 // ============================================================================
    00033 #include "GaudiAlg/GaudiHistos.h"
    00034 #include "GaudiAlg/CheckForNaN.h"
    00035 #include "GaudiAlg/Print.h"
    00036 #include "GaudiAlg/Fill.h"
    00037 // ============================================================================
    00038 // forward declarations from AIDA
    00039 // ============================================================================
    00040 namespace AIDA
    00041 {
    00042   class IBaseHistogram ;
    00043   class IHistogram     ;
    00044   class IHistogram1D   ;
    00045   class IHistogram2D   ;
    00046   class IHistogram3D   ;
    00047   class IProfile       ;
    00048   class IProfile1D     ;
    00049   class IProfile2D     ;
    00050 }
    00051 // =============================================================================
    00052 // Constructor initialisation and job options
    00053 // =============================================================================
    00054 template <class PBASE>
    00055 void GaudiHistos<PBASE>::initGaudiHistosConstructor()
    00056 {
    00057   // SWITCH ON/OFF the histograms
    00058   this->declareProperty
    00059     ( "HistoProduce"          ,
    00060       m_produceHistos = true  ,
    00061       "Swith on/off the production of histograms "   ) ;
    00062   // print the histograms at finalization
    00063   this->declareProperty
    00064     ( "HistoPrint"            ,
    00065       m_histosPrint   = false ,
    00066       "Switch on/off the printout of histograms at finalization"    )
    00067     -> declareUpdateHandler ( &GaudiHistos<PBASE>::printHistoHandler, this ) ;
    00068   // check for NaN/Finite
    00069   this->declareProperty
    00070     ( "HistoCheckForNaN"      ,
    00071       m_checkForNaN   = true  ,
    00072       "Swicth on/off the checks for NaN and Infinity for histogram fill" ) ;
    00073   // for HBOOK persistency, 'true' can be useful
    00074   this->declareProperty
    00075     ( "HistoSplitDir"         ,
    00076       m_splitHistoDir = false ,
    00077       "Split long directory names into short pieces (suitable for HBOOK)" );
    00078   // general OffSet for histogram ID
    00079   this->declareProperty
    00080     ( "HistoOffSet"           ,
    00081       m_histoOffSet   =   0   ,
    00082       "OffSet for automatically assigned histogram numerical identifiers " ) ;
    00083   // top level histogram directory
    00084   this->declareProperty
    00085     ( "HistoTopDir"           ,
    00086       m_histoTopDir   =   ""  ,
    00087       "Top level histogram directory (take care that it ends with '/')" ) ;
    00088   // histogram directory
    00089   this->declareProperty
    00090     ( "HistoDir"             ,
    00091       m_histoDir      = this->name() ,
    00092       "Histogram Directory" ) ;
    00093   // control output level of histograms
    00094   this->declareProperty ( "FullDetail"            , m_fullDetail    = false ) ;
    00095   // monitor histograms
    00096   this->declareProperty ( "MonitorHistograms"     , m_declareMoniHists = true ) ;
    00097   // format for 1D-histograms printout
    00098   this->declareProperty
    00099     ( "FormatFor1DHistoTable" ,
    00100       m_histo1DTableFormat   = Gaudi::Utils::Histos::Formats::format () ,
    00101       "Format string for printout of 1D histograms"      ) ;
    00102   // "short" format for 1D-histograms printout
    00103   this->declareProperty
    00104     ( "ShortFormatFor1DHistoTable" ,
    00105       m_histo1DTableFormatShort   = " | %1$-25.25s %2%"  ,
    00106       "Format string for printout of 1D histograms"      ) ;
    00107   // the header for 1D-histogram tabkle
    00108   this->declareProperty
    00109     ( "HeaderFor1DHistoTable" ,
    00110       m_histo1DTableHeader   = Gaudi::Utils::Histos::Formats::header () ,
    00111       "The table header for printout of 1D histograms "  ) ;
    00112   this->declareProperty
    00113     ( "UseSequencialNumericAutoIDs", m_useNumericAutoIDs = false,
    00114       "Flag to allow users to switch back to the old style of creating numerical automatic IDs" );
    00115   m_idReplaceInfo.clear();
    00116   m_idReplaceInfo["/"] = "=SLASH=";
    00117   this->declareProperty
    00118     ( "AutoStringIDPurgeMap", m_idReplaceInfo,
    00119       "Map of strings to search and replace when using the title as the basis of automatically generated literal IDs" );
    00120 }
    00121 // ============================================================================
    00122 // Initialise Histogramming
    00123 // ============================================================================
    00124 template <class PBASE>
    00125 StatusCode GaudiHistos<PBASE>::
    00126 #ifdef __ICC
    00127   i_ghInitialize
    00128 #else
    00129   initialize
    00130 #endif
    00131   ()
    00132 {
    00133   // initialize base class
    00134   const StatusCode sc = PBASE::initialize();
    00135   if ( sc.isFailure() ) return sc;
    00136
    00137   // produce histograms?
    00138   if ( !produceHistos() )
    00139   {
    00140     this->debug() << "Histogram production is switched OFF" << endmsg;
    00141     return sc;
    00142   }
    00143
    00144   // check the validity of histogram service
    00145   if ( this->histoSvc() == NULL )
    00146   { return this->Error("initialize():: IHistogramSvc* is invalid"); }
    00147
    00148   // Warn if the user has decided to use numerical automatic IDs
    00149   if ( useNumericAutoIDs() )
    00150   {
    00151     this ->
    00152       Warning( "Using numerical automatic IDs. These are not guaranteed to be totally deterministic. Use with care...",
    00153                StatusCode::SUCCESS );
    00154   }
    00155
    00156   // Finally, print the location histogram will be written to
    00157   this->Print
    00158     ( "The histogram path is set to be '" + histoPath() + "'",
    00159       StatusCode( StatusCode::SUCCESS, true )  , MSG::DEBUG );
    00160
    00161   return sc;
    00162 }
    00163 // ============================================================================
    00164 // Finalise Histogramming
    00165 // ============================================================================
    00166 template <class PBASE>
    00167 StatusCode GaudiHistos<PBASE>::
    00168 #ifdef __ICC
    00169   i_ghFinalize
    00170 #else
    00171   finalize
    00172 #endif
    00173   ()
    00174 {
    00175
    00176   if ( produceHistos() )
    00177   {
    00178
    00179     // Count how many histos of each type
    00180     if ( !noHistos() )
    00181     {
    00182       const unsigned int n1D  = histo1DMapID   () . size () ;
    00183       const unsigned int n2D  = histo2DMapID   () . size () ;
    00184       const unsigned int n3D  = histo3DMapID   () . size () ;
    00185       const unsigned int n1DP = profile1DMapID () . size () ;
    00186       const unsigned int n2DP = profile2DMapID () . size () ;
    00187       const unsigned int total = n1D+n2D+n3D+n1DP+n2DP;
    00188       if ( total>0 )
    00189       {
    00190         this->always() << "Booked " << total << " Histogram(s) : ";
    00191         if ( n1D>0  ) this->always() << "1D=" << n1D << " ";
    00192         if ( n2D>0  ) this->always() << "2D=" << n2D << " ";
    00193         if ( n3D>0  ) this->always() << "3D=" << n3D << " ";
    00194         if ( n1DP>0 ) this->always() << "1DProf=" << n1DP << " ";
    00195         if ( n2DP>0 ) this->always() << "2DProf=" << n2DP << " ";
    00196         this->always() << endmsg;
    00197       }
    00198     }
    00199
    00200     // detailed printing
    00201     if ( histosPrint() ) { printHistos() ; }
    00202
    00203   }
    00204
    00205   // clear all maps
    00206   m_histo1DMapTitle   . clear () ;
    00207   m_histo2DMapTitle   . clear () ;
    00208   m_histo3DMapTitle   . clear () ;
    00209   m_histo1DMapID      . clear () ;
    00210   m_histo2DMapID      . clear () ;
    00211   m_histo3DMapID      . clear () ;
    00212   m_profile1DMapTitle . clear () ;
    00213   m_profile2DMapTitle . clear () ;
    00214   m_profile1DMapID    . clear () ;
    00215   m_profile2DMapID    . clear () ;
    00216
    00217   // finalize base class
    00218   return PBASE::finalize();
    00219 }
    00220 // ============================================================================
    00221 // perform the actual detailed printout of histograms
    00222 // ============================================================================
    00223 template <class PBASE>
    00224 int GaudiHistos<PBASE>::printHistos ( const MSG::Level level ) const
    00225 {
    00226   using namespace Gaudi::Utils::Histos ;
    00227
    00228   if ( noHistos() )
    00229   {
    00230     if ( this->msgLevel(MSG::DEBUG) )
    00231     { this->msgStream(level) << "No histograms are booked" << endmsg ; }
    00232     return 0 ;                                                        // RETURN
    00233   }
    00234
    00235   MsgStream & msg = this->msgStream(level);
    00236
    00237   // Printout all histograms
    00238
    00239   Gaudi::Utils::Histos::Table table
    00240     ( m_histo1DTableFormat ,
    00241       m_histo1DTableHeader ) ;
    00242
    00243   if ( !histo1DMapID().empty() )
    00244   {
    00245     msg << "List of booked 1D histograms in directory         "
    00246         << "\"" << histoPath() << "\" :-"  ;
    00247
    00248     if ( !table.header().empty() )
    00249     {
    00250       msg << std::endl << Gaudi::Utils::Histos::format
    00251         ( "ID" , table.header() , m_histo1DTableFormatShort ) ;
    00252     }
    00253     // temporary map to keep ordered IDs
    00254     typedef std::map<HistoID,const AIDA::IHistogram1D*> OrderedMapType;
    00255     OrderedMapType OrderedMap ( histo1DMapID().begin() , histo1DMapID().end() );
    00256     //
    00257     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
    00258           OrderedMap.end() != entry ; ++entry )
    00259     {
    00260       const AIDA::IHistogram1D* aida = entry->second ;
    00261       if ( NULL == aida )
    00262       { this->error() << "IHistogram1D points to NULL" << endmsg ; continue ; }
    00263       // format and print the row
    00264       msg << std::endl << table.toString
    00265         ( aida                      ,
    00266           HistoID ( entry->first )  ,
    00267           m_histo1DTableFormatShort ) ;
    00268     }
    00269     msg << endmsg ;
    00270   }
    00271   // ==========================================================================
    00272   if ( !histo2DMapID().empty() )
    00273   {
    00274     msg << "List of booked 2D histograms in directory         "
    00275         << "\"" << histoPath() << "\" :-" ;
    00276
    00277     // temporary map to keep ordered IDs
    00278     typedef std::map<HistoID,const AIDA::IHistogram2D*> OrderedMapType;
    00279     OrderedMapType OrderedMap ( histo2DMapID().begin() , histo2DMapID().end() ) ;
    00280     //
    00281     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
    00282           OrderedMap.end() != entry ; ++entry )
    00283     {
    00284       const AIDA::IHistogram2D* aida = entry->second ;
    00285       if ( NULL == aida )
    00286       { this->error() << "IHistogram2D points to NULL" << endmsg ; continue ; }
    00287       msg << std::endl
    00288           << GaudiAlg::Print2D::toString ( aida , entry->first );
    00289     }
    00290     msg << endmsg ;
    00291   }
    00292   // ==========================================================================
    00293   if ( !histo3DMapID().empty() )
    00294   {
    00295     msg << "List of booked 3D histograms in directory         "
    00296         << "\"" << histoPath() << "\" :-" ;
    00297     // temporary map to keep ordered IDs
    00298     typedef std::map<HistoID,const AIDA::IHistogram3D*> OrderedMapType;
    00299     OrderedMapType OrderedMap ( histo3DMapID().begin() , histo3DMapID().end() ) ;
    00300     //
    00301     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
    00302           OrderedMap.end() != entry ; ++entry )
    00303     {
    00304       const AIDA::IHistogram3D* aida = entry->second ;
    00305       if ( NULL == aida )
    00306       { this->error() << "IHistogram3D points to NULL" << endmsg ; continue ; }
    00307       msg << std::endl << GaudiAlg::Print3D::toString ( aida , entry->first );
    00308     }
    00309     msg << endmsg ;
    00310   }
    00311   // ==========================================================================
    00312   if ( !profile1DMapID().empty() )
    00313   {
    00314     msg << "List of booked 1D profile histograms in directory "
    00315         << "\"" << histoPath() << "\" :-" ;
    00316     // temporary map to keep ordered IDs
    00317     typedef std::map<HistoID,const AIDA::IProfile1D*> OrderedMapType;
    00318     OrderedMapType OrderedMap ( profile1DMapID().begin() , profile1DMapID().end() ) ;
    00319     //
    00320     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
    00321           OrderedMap.end() != entry ; ++entry )
    00322     {
    00323       const AIDA::IProfile1D*   aida = entry->second ;
    00324       if ( NULL == aida )
    00325       { this->error() << "IProfile1D points to NULL" << endmsg ; continue ; }
    00326       msg << std::endl << GaudiAlg::Print1DProf::toString  ( aida , entry->first );
    00327     }
    00328     msg << endmsg ;
    00329   }
    00330   // ==========================================================================
    00331   if ( !profile2DMapID().empty() )
    00332   {
    00333     msg << "List of booked 2D profile histograms in directory "
    00334         << "\"" << histoPath() << "\" :-" ;
    00335     // temporary map to keep ordered IDs
    00336     typedef std::map<HistoID,const AIDA::IProfile2D*> OrderedMapType;
    00337     OrderedMapType OrderedMap ( profile2DMapID().begin() , profile2DMapID().end() ) ;
    00338     //
    00339     for ( OrderedMapType::const_iterator entry = OrderedMap.begin() ;
    00340           OrderedMap.end() != entry ; ++entry )
    00341     {
    00342       const AIDA::IProfile2D*   aida = entry->second ;
    00343       if ( NULL == aida )
    00344       { this->error() << "IProfile2D points to NULL" << endmsg ; continue ; }
    00345       msg << std::endl << GaudiAlg::Print2DProf::toString ( aida , entry->first );
    00346     }
    00347     msg << endmsg ;
    00348   }
    00349   //
    00350   return this->totalNumberOfHistos() ;
    00351 }
    00352 // ============================================================================
    00353 // Check if all histogram maps are empty
    00354 // ============================================================================
    00355 template <class PBASE>
    00356 bool GaudiHistos<PBASE>::noHistos() const
    00357 {
    00358   return ( histo1DMapTitle   () . empty() &&
    00359            histo2DMapTitle   () . empty() &&
    00360            histo3DMapTitle   () . empty() &&
    00361            profile1DMapTitle () . empty() &&
    00362            profile2DMapTitle () . empty() &&
    00363            histo1DMapID      () . empty() &&
    00364            histo2DMapID      () . empty() &&
    00365            histo3DMapID      () . empty() &&
    00366            profile1DMapID    () . empty() &&
    00367            profile2DMapID    () . empty() );
    00368 }
    00369 // ============================================================================
    00370 // Declare a histogram to the monitor service
    00371 // ============================================================================
    00372 template <class PBASE>
    00373 void GaudiHistos<PBASE>::monitorHisto
    00374 ( const AIDA::IBaseHistogram* hist,
    00375   const HistoID& ID ) const
    00376 {
    00377   if ( hist && m_declareMoniHists )
    00378   {
    00379     if ( this->msgLevel(MSG::DEBUG) )
    00380     {
    00381       this->debug() << "Monitoring histogram '"
    00382                     << ID.idAsString() << "' desc = '"
    00383                     << Gaudi::Utils::Histos::htitle(hist) << "'" << endmsg;
    00384     }
    00385     this->declareInfo ( histoPath()+"/"+ID.idAsString() ,
    00386                         hist            ,
    00387                         Gaudi::Utils::Histos::htitle(hist) ) ;
    00388   }
    00389 }
    00390 // ============================================================================
    00391 // access the EXISTING 1D histogram by ID
    00392 // ============================================================================
    00393 template <class PBASE>
    00394 AIDA::IHistogram1D* GaudiHistos<PBASE>::histo1D ( const HistoID& ID )  const
    00395 {
    00396   AIDA::IHistogram1D * h(NULL);
    00397   //
    00398   Histo1DMapID::const_iterator found = histo1DMapID().find( ID ) ;
    00399   //
    00400   h = ( histo1DMapID().end() == found ? NULL : found->second );
    00401   //
    00402   return h ;
    00403 }
    00404 // ============================================================================
    00405 // access the EXISTING 2D histogram by ID
    00406 // ============================================================================
    00407 template <class PBASE>
    00408 AIDA::IHistogram2D* GaudiHistos<PBASE>::histo2D ( const HistoID& ID )  const
    00409 {
    00410   AIDA::IHistogram2D * h(NULL);
    00411   //
    00412   Histo2DMapID::const_iterator found = histo2DMapID().find( ID ) ;
    00413   //
    00414   h = ( histo2DMapID().end() == found ? NULL : found->second );
    00415   //
    00416   return h;
    00417 }
    00418 // ============================================================================
    00419 // access the EXISTING 3D histogram by ID
    00420 // ============================================================================
    00421 template <class PBASE>
    00422 AIDA::IHistogram3D* GaudiHistos<PBASE>::histo3D ( const HistoID& ID )  const
    00423 {
    00424   AIDA::IHistogram3D * h(NULL);
    00425   //
    00426   Histo3DMapID::const_iterator found = histo3DMapID().find( ID ) ;
    00427   h = ( histo3DMapID().end() == found ? NULL : found->second );
    00428   //
    00429   return h;
    00430 }
    00431 // ============================================================================
    00432 // access the EXISTING 1D profile histogram by ID
    00433 // ============================================================================
    00434 template <class PBASE>
    00435 AIDA::IProfile1D* GaudiHistos<PBASE>::profile1D ( const HistoID& ID )  const
    00436 {
    00437   AIDA::IProfile1D * h(NULL);
    00438   //
    00439   Profile1DMapID::const_iterator found = profile1DMapID().find( ID ) ;
    00440   //
    00441   h = ( profile1DMapID().end() == found ? NULL : found->second );
    00442   //
    00443   return h;
    00444 }
    00445 // ============================================================================
    00446 // access the EXISTING 2D profile histogram by ID
    00447 // ============================================================================
    00448 template <class PBASE>
    00449 AIDA::IProfile2D* GaudiHistos<PBASE>::profile2D ( const HistoID& ID )  const
    00450 {
    00451   AIDA::IProfile2D * h(NULL);
    00452   //
    00453   Profile2DMapID::const_iterator found = profile2DMapID().find( ID ) ;
    00454   //
    00455   h = ( profile2DMapID().end() == found ? NULL : found->second );
    00456   //
    00457   return h;
    00458 }
    00459 // ============================================================================
    00460 // Returns the total number of histograms (of all types) currently booked
    00461 // ============================================================================
    00462 template <class PBASE>
    00463 unsigned int GaudiHistos<PBASE>::totalNumberOfHistos() const
    00464 {
    00465   return
    00466     histo1DMapID   () . size () +
    00467     histo2DMapID   () . size () +
    00468     histo3DMapID   () . size () +
    00469     profile1DMapID () . size () +
    00470     profile2DMapID () . size () ;
    00471 }
    00472 // ============================================================================
    00473 // Create a new histogram ID using the given title
    00474 // ============================================================================
    00475 template <class PBASE>
    00476 void GaudiHistos<PBASE>::newHistoID
    00477 ( const std::string & title ,
    00478   HistoID&            ID    ) const
    00479 {
    00480   if ( useNumericAutoIDs() || title.empty() )
    00481   {
    00482     if ( !useNumericAutoIDs() )
    00483     {
    00484       this -> Warning( "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for histogram ID",
    00485                        StatusCode::SUCCESS );
    00486     }
    00487     // propose the histogram ID (always numeric)
    00488     ID = HistoID( totalNumberOfHistos() + 1 + histoOffSet() );
    00489     // adjust the proposed ID
    00490     while ( histoExists( ID ) ) { ID = HistoID ( ID.numeric() + 1 ) ; }
    00491   }
    00492   else
    00493   {
    00494     // use the title to create a unique literal ID
    00495     ID = HistoID( this->convertTitleToID(title) );
    00496     // Just in case ...
    00497     while ( histoExists( ID ) ) { ID = HistoID(ID.idAsString()+"_"); }
    00498   }
    00499 }
    00500 // ============================================================================
    00501 // Create an ID string from a title string
    00502 // ============================================================================
    00503 template <class PBASE>
    00504 std::string GaudiHistos<PBASE>::convertTitleToID( const std::string & title ) const
    00505 {
    00506   // clean up the ID string for all unwanted characters
    00507   std::string tmp_id = title;
    00508   for ( std::map<std::string,std::string>::const_iterator i =
    00509           m_idReplaceInfo.begin() ; i != m_idReplaceInfo.end(); ++i )
    00510   {
    00511     stringSearchReplace( tmp_id, i->first, i->second );
    00512   }
    00513   return tmp_id;
    00514 }
    00515 // ============================================================================
    00516 // Searches 'title' for all instancies of 'A' and replaces them with 'B'
    00517 // ============================================================================
    00518 template <class PBASE>
    00519 void GaudiHistos<PBASE>::stringSearchReplace
    00520 ( std::string       & title ,
    00521   const std::string & A     ,
    00522   const std::string & B     ) const
    00523 {
    00524   std::string::size_type slash = title.find_first_of ( A ) ;
    00525   while ( std::string::npos != slash )
    00526   {
    00527     title = title.substr(0,slash) + B + title.substr(slash+A.size());
    00528     slash = title.find_first_of( A );
    00529   }
    00530 }
    00531 // ============================================================================
    00532 // the handler for "HistoPrint" property
    00533 // ============================================================================
    00534 template < class PBASE >
    00535 void GaudiHistos<PBASE>::printHistoHandler( Property& )
    00536 {
    00537   // no action if not yet initialized
    00538   if ( this -> FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
    00539   if ( this -> histosPrint() ) { this -> printHistos ( MSG::ALWAYS ) ; }
    00540 }
    00541 // ============================================================================
    00542 // 1D
    00543 #include "GaudiAlg/GaudiHistos_1DFixedBinning.icpp"
    00544 #include "GaudiAlg/GaudiHistos_1DVariableBinning.icpp"
    00545 // 2D
    00546 #include "GaudiAlg/GaudiHistos_2DFixedBinning.icpp"
    00547 #include "GaudiAlg/GaudiHistos_2DVariableBinning.icpp"
    00548 // 3D
    00549 #include "GaudiAlg/GaudiHistos_3DFixedBinning.icpp"
    00550 #include "GaudiAlg/GaudiHistos_3DVariableBinning.icpp"
    00551 // 1D Profile
    00552 #include "GaudiAlg/GaudiHistos_1DProfFixedBinning.icpp"
    00553 #include "GaudiAlg/GaudiHistos_1DProfVariableBinning.icpp"
    00554 // 2D Profile
    00555 #include "GaudiAlg/GaudiHistos_2DProfFixedBinning.icpp"
    00556 #include "GaudiAlg/GaudiHistos_2DProfVariableBinning.icpp"
    00557 // ============================================================================
    00558 // The END
    00559 // ============================================================================
    00560 #endif // GAUDIALG_GAUDIHISTOS_ICPP
    00561 // ============================================================================