SFrame 3.6
plug-ins/include/SSummedVar.icc
Go to the documentation of this file.
00001 // Dear emacs, this is -*- c++ -*-
00002 // $Id: SSummedVar.icc 179 2010-06-30 09:36:19Z krasznaa $
00003 /***************************************************************************
00004  * @Project: SFrame - ROOT-based analysis framework for ATLAS
00005  * @Package: Plug-ins
00006  *
00007  * @author Stefan Ask       <Stefan.Ask@cern.ch>           - Manchester
00008  * @author David Berge      <David.Berge@cern.ch>          - CERN
00009  * @author Johannes Haller  <Johannes.Haller@cern.ch>      - Hamburg
00010  * @author A. Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN/Debrecen
00011  *
00012  ***************************************************************************/
00013 
00014 #ifndef SFRAME_PLUGINS_SSummedVar_ICC
00015 #define SFRAME_PLUGINS_SSummedVar_ICC
00016 
00017 // System include(s):
00018 #include <cxxabi.h>
00019 #include <cstdlib>
00020 
00021 // STL include(s):
00022 #include <vector>
00023 
00024 // ROOT include(s):
00025 #include <TCollection.h>
00026 #include <TList.h>
00027 
00028 // SFrame include(s):
00029 #include "core/include/ISCycleBaseHist.h"
00030 #include "core/include/SLogger.h"
00031 
00038 template< class Type >
00039 std::vector< Type > operator+( const std::vector< Type >& left,
00040                                const std::vector< Type >& right ) {
00041 
00042    // Create the result vector:
00043    std::vector< Type > result;
00044 
00045    // Check that the summation can be performed:
00046    if( left.size() != right.size() ) {
00047       const char* type_name = typeid( left ).name();
00048       int status;
00049       char* real_type_name = abi::__cxa_demangle( type_name, 0, 0, &status );
00050       if( status ) {
00051          SError error( SError::StopExecution );
00052          error << "Couldn't demangle type name: " << type_name;
00053          throw error;
00054       }
00055       SLogger m_logger( real_type_name ); // Name given like this on purpose...
00056       REPORT_ERROR( "Couldn't perform summation on type: " << real_type_name );
00057       REPORT_ERROR( "The results will not be correct!" );
00058       ::free( real_type_name );
00059       return result;
00060    }
00061 
00062    // Peform the summation:
00063    result.resize( left.size() );
00064    for( typename std::vector< Type >::size_type i = 0; i < left.size(); ++i ) {
00065       result[ i ] = left[ i ] + right[ i ];
00066    }
00067 
00068    return result;
00069 }
00070 
00077 template< class KeyType, class ValueType >
00078 std::map< KeyType, ValueType > operator+( const std::map< KeyType, ValueType >& left,
00079                                           const std::map< KeyType, ValueType >& right ) {
00080 
00081    // Create the result map:
00082    std::map< KeyType, ValueType > result;
00083 
00084    // Check that the summation can be performed:
00085    if( left.size() != right.size() ) {
00086       const char* type_name = typeid( left ).name();
00087       int status;
00088       char* real_type_name = abi::__cxa_demangle( type_name, 0, 0, &status );
00089       if( status ) {
00090          SError error( SError::StopExecution );
00091          error << "Couldn't demangle type name: " << type_name;
00092          throw error;
00093       }
00094       SLogger m_logger( real_type_name ); // Name given like this on purpose...
00095       REPORT_ERROR( "Couldn't perform summation on type: " << real_type_name );
00096       REPORT_ERROR( "The results will not be correct!" );
00097       ::free( real_type_name );
00098       return result;
00099    }
00100 
00101    // Perform the summation:
00102    typename std::map< KeyType, ValueType >::const_iterator left_itr = left.begin();
00103    typename std::map< KeyType, ValueType >::const_iterator left_end = left.end();
00104    typename std::map< KeyType, ValueType >::const_iterator right_itr = right.begin();
00105    typename std::map< KeyType, ValueType >::const_iterator right_end = right.end();
00106    for( ; left_itr != left_end && right_itr != right_end; ++left_itr, ++right_itr ) {
00107       // Check that we have the corresponding elements selected:
00108       if( left_itr->first != right_itr->first ) {
00109          const char* type_name = typeid( left ).name();
00110          int status;
00111          char* real_type_name = abi::__cxa_demangle( type_name, 0, 0, &status );
00112          if( status ) {
00113             SError error( SError::StopExecution );
00114             error << "Couldn't demangle type name: " << type_name;
00115             throw error;
00116          }
00117          SLogger m_logger( real_type_name );
00118          REPORT_ERROR( "Couldn't perform summation on type: " << real_type_name );
00119          REPORT_ERROR( "The results will not be correct!" );
00120          ::free( real_type_name );
00121          return result;
00122       }
00123       // Add the two values:
00124       result[ left_itr->first ] = left_itr->second + right_itr->second;
00125    }
00126 
00127    return result;
00128 }
00129 
00131 //                                                                //
00132 //          Implementation of the ProofSummedVar class            //
00133 //                                                                //
00135 
00136 template< class Type >
00137 ProofSummedVar< Type >::ProofSummedVar( const char* name,
00138                                         const char* title )
00139    : TNamed( name, title ), m_member() {
00140 
00141 }
00142 
00148 template< class Type >
00149 Int_t ProofSummedVar< Type >::Merge( TCollection* coll ) {
00150 
00151    SLogger m_logger( this->ClassName() );
00152 
00153    //
00154    // Return right away if the input is flawed:
00155    //
00156    if( ! coll ) return 0;
00157    if( coll->IsEmpty() ) return 0;
00158 
00159    //
00160    // Select the elements from the collection that can actually be merged:
00161    //
00162    TIter next( coll );
00163    TObject* obj = 0;
00164    while( ( obj = next() ) ) {
00165 
00166       //
00167       // See if it is an SCycleOutput object itself:
00168       //
00169       ProofSummedVar< Type >* pobj = dynamic_cast< ProofSummedVar< Type >* >( obj );
00170       if( ! pobj ) {
00171          REPORT_ERROR( "Trying to merge \"" << obj->ClassName()
00172                        << "\" object into \"" << this->ClassName() << "\"" );
00173          continue;
00174       }
00175 
00176       //
00177       // If everything is fine, add its contents to this object.
00178       // I perform the summation in this non-optimal way to be able to use
00179       // the overloaded operator defined at the top of this file...
00180       //
00181       m_member = m_member + pobj->m_member;
00182 
00183    }
00184 
00185    m_logger << DEBUG << "Merged objects with name \"" << GetName()
00186             << "\"" << SLogger::endmsg;
00187 
00188    return 1;
00189 }
00190 
00192 //                                                                //
00193 //            Implementation of the SSummedVar class              //
00194 //                                                                //
00196 
00197 template< class Type >
00198 SSummedVar< Type >::SSummedVar( const char* name, ISCycleBaseHist* parent )
00199    : m_objName( name ), m_parent( parent ), m_object( 0 ) {
00200 
00201 }
00202 
00203 template< class Type >
00204 SSummedVar< Type >::operator Type&() {
00205 
00206    return GetReference();
00207 }
00208 
00209 template< class Type >
00210 SSummedVar< Type >::operator const Type&() const {
00211 
00212    return GetReference();
00213 }
00214 
00215 template< class Type >
00216 Type& SSummedVar< Type >::operator*() {
00217 
00218    return GetReference();
00219 }
00220 
00221 template< class Type >
00222 Type* SSummedVar< Type >::operator->() {
00223 
00224    return GetPointer();
00225 }
00226 
00227 template< class Type >
00228 Type& SSummedVar< Type >::GetReference() {
00229 
00230    return GetObject()->m_member;
00231 }
00232 
00233 template< class Type >
00234 Type* SSummedVar< Type >::GetPointer() {
00235 
00236    return &( GetObject()->m_member );
00237 }
00238 
00239 template< class Type >
00240 const Type& SSummedVar< Type >::operator*() const {
00241 
00242    return GetReference();
00243 }
00244 
00245 template< class Type >
00246 const Type* SSummedVar< Type >::operator->() const {
00247 
00248    return GetPointer();
00249 }
00250 
00251 template< class Type >
00252 const Type& SSummedVar< Type >::GetReference() const {
00253 
00254    return GetObject()->m_member;
00255 }
00256 
00257 template< class Type >
00258 const Type* SSummedVar< Type >::GetPointer() const {
00259 
00260    return &( GetObject()->m_member );
00261 }
00262 
00268 template< class Type >
00269 ProofSummedVar< Type >* SSummedVar< Type >::GetObject() const throw( SError ) {
00270 
00271    //
00272    // Try to get an already existing object from the output list:
00273    //
00274    ProofSummedVar< Type >* pobj =
00275       dynamic_cast< ProofSummedVar< Type >* >( m_parent->GetHistOutput()->FindObject( m_objName ) );
00276 
00277    if( pobj ) {
00278       //
00279       // Check if we have this object cached already. If it's a different object, then
00280       // we delete the cached one.
00281       //
00282       if( m_object ) {
00283          if( m_object != pobj ) {
00284             delete m_object;
00285             m_object = pobj;
00286          }
00287       } else {
00288          m_object = pobj;
00289       }
00290    } else {
00291       //
00292       // Construct a logger with a meaningful source. It has to be this compilated
00293       // since SSummedVar does not inherit from TObject.
00294       //
00295       const char* type_name = typeid( *this ).name();
00296       int status;
00297       char* real_type_name = abi::__cxa_demangle( type_name, 0, 0, &status );
00298       if( status ) {
00299          SError error( SError::StopExecution );
00300          error << "Couldn't demangle type name: " << type_name;
00301          throw error;
00302       }
00303       SLogger m_logger( real_type_name );
00304       free( real_type_name );
00305 
00306       //
00307       // Create a new object and add it to the output list:
00308       //
00309       REPORT_VERBOSE( "Creating new object with name \""
00310                       << m_objName << "\"" );
00311       m_object = new ProofSummedVar< Type >( m_objName, "Internal SFrame object" );
00312       m_parent->GetHistOutput()->Add( m_object );
00313    }
00314 
00315    return m_object;
00316 
00317 }
00318 
00319 #endif // SFRAME_PLUGINS_SSummedVar_ICC