SFrame 3.6
|
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