Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

AIDA_Cloud2D.cpp

Go to the documentation of this file.
00001 #include "AIDA_Cloud2D.h"
00002 #include "AIDA_Histogram2D.h"
00003 #include "AIDA/IAnnotation.h"
00004 #include "AIDA/IAxis.h"
00005 #include <cmath>
00006 #include <set>
00007 #include "AnnotationNumberFormater.h"
00008 #include "EdgeCalculator.h"
00009 
00010 static const std::string meanXKey = "MeanX";
00011 static const std::string rmsXKey = "RmsX";
00012 static const std::string meanYKey = "MeanY";
00013 static const std::string rmsYKey = "RmsY";
00014 static const std::string emptyString = "";
00015 
00016 
00017 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::AIDA_Cloud2D( const std::string& title ):
00018   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( title, "ICloud2D", 2 ),
00019   m_cacheSize( Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::defaultCacheSize ),
00020   m_elements(),
00021   m_sumOfWeights( 0 ),
00022   m_sumOfWeightTimesValueX( 0 ),
00023   m_sumOfWeightTimesValueY( 0 ),
00024   m_sumOfWeightTimesSquaredValueX( 0 ),
00025   m_sumOfWeightTimesSquaredValueY( 0 ),
00026   m_lowEdgeX( 0 ),
00027   m_lowEdgeY( 0 ),
00028   m_highEdgeX( 0 ),
00029   m_highEdgeY( 0 ),
00030   m_histo( 0 )
00031 {
00032   setCacheSize( m_cacheSize );
00033 
00035   AIDA::IAnnotation& annotation = annotationNoUpdate();
00036   annotation.addItem( meanXKey, emptyString, false );
00037   annotation.addItem( rmsXKey, emptyString, false );
00038   annotation.addItem( meanYKey, emptyString, false );
00039   annotation.addItem( rmsYKey, emptyString, false );
00040 }
00041 
00042 
00043 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::AIDA_Cloud2D( const AIDA_Cloud2D& h ):
00044   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( h.title(), "ICloud2D", 2 ),
00045   m_cacheSize( h.m_cacheSize ),
00046   m_elements( h.m_elements ),
00047   m_sumOfWeights( h.m_sumOfWeights ),
00048   m_sumOfWeightTimesValueX( h.m_sumOfWeightTimesValueX ),
00049   m_sumOfWeightTimesValueY( h.m_sumOfWeightTimesValueY ),
00050   m_sumOfWeightTimesSquaredValueX( h.m_sumOfWeightTimesSquaredValueX ),
00051   m_sumOfWeightTimesSquaredValueY( h.m_sumOfWeightTimesSquaredValueY ),
00052   m_lowEdgeX( h.m_lowEdgeX ),
00053   m_lowEdgeY( h.m_lowEdgeY ),
00054   m_highEdgeX( h.m_highEdgeX ),
00055   m_highEdgeY( h.m_highEdgeY ),
00056   m_histo( 0 )
00057 {
00058   if ( h.m_histo ) {
00059     m_histo = new Anaphe::AIDA_Histogram_native::AIDA_Histogram2D( * ( dynamic_cast<const Anaphe::AIDA_Histogram_native::AIDA_Histogram2D*>( h.m_histo ) ) );
00060   }
00061 
00063   AIDA::IAnnotation& annotation = annotationNoUpdate();
00064   std::set< std::string > existingAnnotationItems;
00065   for ( int item = 0; item < annotation.size(); ++item ) {
00066       existingAnnotationItems.insert( annotation.key( item ) );
00067   }
00068   const AIDA::IAnnotation& otherAnnotation = h.annotation();
00069   for ( int itemNew = 0; itemNew < otherAnnotation.size(); ++itemNew ) {
00070       const std::string& key = otherAnnotation.key( itemNew );
00071       if ( existingAnnotationItems.find( key ) == existingAnnotationItems.end() ) {
00072           annotation.addItem( key, otherAnnotation.value( itemNew ), false );
00073       }
00074   }
00075 }
00076 
00077 
00078 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::AIDA_Cloud2D( const AIDA::ICloud2D& h ):
00079   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram( h.title(), "ICloud2D", 2 ),
00080   m_cacheSize( Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::defaultCacheSize ),
00081   m_elements(),
00082   m_sumOfWeights( 0 ),
00083   m_sumOfWeightTimesValueX( 0 ),
00084   m_sumOfWeightTimesValueY( 0 ),
00085   m_sumOfWeightTimesSquaredValueX( 0 ),
00086   m_sumOfWeightTimesSquaredValueY( 0 ),
00087   m_lowEdgeX( 0 ),
00088   m_lowEdgeY( 0 ),
00089   m_highEdgeX( 0 ),
00090   m_highEdgeY( 0 ),
00091   m_histo( 0 )
00092 {
00093   if ( h.isConverted() ) {
00094     AIDA::ICloud2D& c = const_cast<AIDA::ICloud2D&>( h );
00095     const AIDA::IHistogram2D& histo = c.histogram();
00096     m_histo = new Anaphe::AIDA_Histogram_native::AIDA_Histogram2D( histo );
00097   }
00098   else {
00099     setCacheSize( m_cacheSize );    
00100     for ( int i = 0; i < h.entries(); ++i ) this->fill( h.valueX( i ), h.valueY( i ), h.weight( i ) );
00101   }
00102 
00104   AIDA::IAnnotation& annotation = annotationNoUpdate();
00105   std::set< std::string > existingAnnotationItems;
00106   for ( int item = 0; item < annotation.size(); ++item ) {
00107       existingAnnotationItems.insert( annotation.key( item ) );
00108   }
00109   const AIDA::IAnnotation& otherAnnotation = h.annotation();
00110   for ( int itemNew = 0; itemNew < otherAnnotation.size(); ++itemNew ) {
00111       const std::string& key = otherAnnotation.key( itemNew );
00112       if ( existingAnnotationItems.find( key ) == existingAnnotationItems.end() ) {
00113           annotation.addItem( key, otherAnnotation.value( itemNew ), false );
00114       }
00115   }
00116 }
00117 
00118 
00119 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::~AIDA_Cloud2D()
00120 {
00121   if ( m_histo ) delete m_histo;
00122 }
00123 
00124 
00125 void
00126 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::updateAnnotation() const
00127 {
00128   Anaphe::AIDA_Histogram_native::AIDA_BaseHistogram::updateAnnotation();
00129   const AIDA::IAnnotation& anno = annotationNoUpdate();
00130   AIDA::IAnnotation& annotation = const_cast< AIDA::IAnnotation& >( anno );
00131 
00132   annotation.setValue( meanXKey, anaphe_annotationNumberFormater.formatDouble( meanX() ) );
00133   annotation.setValue( rmsXKey, anaphe_annotationNumberFormater.formatDouble( rmsX() ) );
00134   annotation.setValue( meanYKey, anaphe_annotationNumberFormater.formatDouble( meanY() ) );
00135   annotation.setValue( rmsYKey, anaphe_annotationNumberFormater.formatDouble( rmsY() ) );
00136 }
00137 
00138 
00139 bool
00140 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::reset()
00141 {
00142   if ( m_histo ) {
00143     delete m_histo;
00144     m_histo = 0;
00145   }
00146   m_elements.clear();
00147   setCacheSize( m_cacheSize );
00148   m_sumOfWeights = 0;
00149   m_sumOfWeightTimesValueX = m_sumOfWeightTimesValueY = 0;
00150   m_sumOfWeightTimesSquaredValueX = m_sumOfWeightTimesSquaredValueY = 0;
00151   m_lowEdgeX = m_lowEdgeY = 0;
00152   m_highEdgeX = m_highEdgeY = 0;
00153   return true;
00154 }
00155 
00156 
00157 int
00158 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::entries() const
00159 {
00160   if ( m_histo ) {
00161     return m_histo->entries();
00162   }
00163   else {
00164     return m_elements.size();
00165   }
00166 }
00167 
00168 
00169 double
00170 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::sumOfWeights() const
00171 {
00172   if ( m_histo ) {
00173     return m_histo->sumBinHeights();
00174   }
00175   else {
00176     return m_sumOfWeights;
00177   }
00178 }
00179 
00180 
00181 bool
00182 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::convertToHistogram()
00183 {
00184   if ( m_histo || m_elements.size() < 2 ) return false;
00185   double lowEdgeX, highEdgeX;
00186   edgeCalculator.calculateEdges( m_lowEdgeX, m_highEdgeX, Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::defaultNumberOfBins, lowEdgeX, highEdgeX );
00187   double lowEdgeY, highEdgeY;
00188   edgeCalculator.calculateEdges( m_lowEdgeY, m_highEdgeY, Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::defaultNumberOfBins, lowEdgeY, highEdgeY );
00189   Anaphe::AIDA_Histogram_native::AIDA_Histogram2D* p =
00190     new Anaphe::AIDA_Histogram_native::AIDA_Histogram2D( title() + " (supporting histogram)",
00191                                                          Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::defaultNumberOfBins,
00192                                                          lowEdgeX, highEdgeX,
00193                                                          Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::defaultNumberOfBins,
00194                                                          lowEdgeY, highEdgeY );
00195   p->setName( name() + "_supportingHistogram" );
00196   m_histo = p;
00197   for ( unsigned int i = 0; i < m_elements.size(); ++i ) m_histo->fill( m_elements[i].x, m_elements[i].y, m_elements[i].w );
00198   m_elements.clear();
00199   return true;
00200 }
00201 
00202 
00203 bool
00204 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::isConverted() const
00205 {
00206   return ( m_histo != 0 );
00207 }
00208 
00209 
00210 bool
00211 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::scale( double scaleFactor )
00212 {
00213   if ( m_histo ) return m_histo->scale( scaleFactor );
00214   else {
00215     for ( unsigned int i = 0; i < m_elements.size(); ++i ) {
00216       m_elements[i].w *= scaleFactor;
00217     }
00218     m_sumOfWeights *= scaleFactor;
00219     m_sumOfWeightTimesValueX *= scaleFactor;
00220     m_sumOfWeightTimesValueY *= scaleFactor;
00221     m_sumOfWeightTimesSquaredValueX *= scaleFactor;
00222     m_sumOfWeightTimesSquaredValueY *= scaleFactor;
00223     return true;
00224   }
00225 }
00226 
00227 
00228 bool
00229 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::fill( double x, double y, double weight )
00230 {
00231   if ( m_histo ) return m_histo->fill( x, y, weight );
00232   else {
00233     if ( m_elements.empty() ) {
00234       m_lowEdgeX = m_highEdgeX = x;
00235       m_lowEdgeY = m_highEdgeY = y;
00236     }
00237     else {
00238       if ( m_lowEdgeX > x ) m_lowEdgeX = x;
00239       if ( m_highEdgeX < x ) m_highEdgeX = x;
00240       if ( m_lowEdgeY > y ) m_lowEdgeY = y;
00241       if ( m_highEdgeY < y ) m_highEdgeY = y;
00242     }
00243     m_elements.push_back( Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::Cloud2DElement( x, y, weight ) );
00244     m_sumOfWeights += weight;
00245     m_sumOfWeightTimesValueX += weight * x;
00246     m_sumOfWeightTimesValueY += weight * y;
00247     m_sumOfWeightTimesSquaredValueX += weight * x * x;
00248     m_sumOfWeightTimesSquaredValueY += weight * y * y;
00249     if ( m_elements.size() >= m_cacheSize ) convertToHistogram();
00250     return true;
00251   }
00252 }
00253 
00254 
00255 double
00256 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::lowerEdgeX() const
00257 {
00258   if ( m_histo ) return m_histo->xAxis().lowerEdge();
00259   else return m_lowEdgeX;
00260 }
00261 
00262 
00263 double
00264 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::lowerEdgeY() const
00265 {
00266   if ( m_histo ) return m_histo->yAxis().lowerEdge();
00267   else return m_lowEdgeY;
00268 }
00269 
00270 
00271 double
00272 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::upperEdgeX() const
00273 {
00274   if ( m_histo ) return m_histo->xAxis().upperEdge();
00275   else return m_highEdgeX;
00276 }
00277 
00278 
00279 double
00280 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::upperEdgeY() const
00281 {
00282   if ( m_histo ) return m_histo->yAxis().upperEdge();
00283   else return m_highEdgeY;
00284 }
00285 
00286 
00287 double
00288 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::valueX( int index ) const
00289 {
00290   if ( m_histo || index < 0 ) return 0;
00291   if ( static_cast< unsigned int >( index ) >= m_elements.size() ) return 0;
00292   return m_elements[index].x;
00293 }
00294 
00295 
00296 double
00297 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::valueY( int index ) const
00298 {
00299   if ( m_histo || index < 0 ) return 0;
00300   if ( static_cast< unsigned int >( index ) >= m_elements.size() ) return 0;
00301   return m_elements[index].y;
00302 }
00303 
00304 
00305 double
00306 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::weight( int index ) const
00307 {
00308   if ( m_histo || index < 0 ) return 0;
00309   if ( static_cast< unsigned int >( index ) >= m_elements.size() ) return 0;
00310   return m_elements[index].w;
00311 }
00312 
00313 
00314 double
00315 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::meanX() const
00316 {
00317   if ( m_histo ) return m_histo->meanX();
00318   else if ( m_sumOfWeights ) {
00319     return ( m_sumOfWeightTimesValueX / m_sumOfWeights );
00320   }
00321   else return 0;
00322 }
00323 
00324 
00325 double
00326 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::meanY() const
00327 {
00328   if ( m_histo ) return m_histo->meanY();
00329   else if ( m_sumOfWeights ) {
00330     return ( m_sumOfWeightTimesValueY / m_sumOfWeights );
00331   }
00332   else return 0;
00333 }
00334 
00335 
00336 double
00337 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::rmsX() const
00338 {
00339   if ( m_histo ) return m_histo->rmsX();
00340   else if ( m_sumOfWeights ) {
00341     return std::sqrt(std::abs( m_sumOfWeightTimesSquaredValueX * m_sumOfWeights - m_sumOfWeightTimesValueX*m_sumOfWeightTimesValueX))/std::abs(m_sumOfWeights);
00342   }
00343   else return 0;
00344 }
00345 
00346 
00347 double
00348 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::rmsY() const
00349 {
00350   if ( m_histo ) return m_histo->rmsY();
00351   else if ( m_sumOfWeights ) {
00352     return std::sqrt(std::abs( m_sumOfWeightTimesSquaredValueY * m_sumOfWeights - m_sumOfWeightTimesValueY*m_sumOfWeightTimesValueY))/std::abs(m_sumOfWeights);
00353   }
00354   else return 0;
00355 }
00356 
00357 
00358 bool
00359 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::convert( int nBinsX, double lowerEdgeX, double upperEdgeX,
00360                               int nBinsY, double lowerEdgeY, double upperEdgeY )
00361 {
00362   if ( m_histo ) return false;
00363   Anaphe::AIDA_Histogram_native::AIDA_Histogram2D* p = new Anaphe::AIDA_Histogram_native::AIDA_Histogram2D( title() + " (supporting histogram)",
00364                                                                                                             nBinsX, lowerEdgeX, upperEdgeX,
00365                                                                                                             nBinsY, lowerEdgeY, upperEdgeY );
00366   p->setName( name() + "_supportingHistogram" );
00367   m_histo = p;
00368   for ( unsigned int i = 0; i < m_elements.size(); ++i ) m_histo->fill( m_elements[i].x, m_elements[i].y, m_elements[i].w );
00369   m_elements.clear();
00370   return true;
00371 }
00372 
00373 
00374 bool
00375 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::convert( const std::vector< double >& binEdgeX, const std::vector< double >& binEdgeY )
00376 {
00377   if ( m_histo ) return false;
00378   Anaphe::AIDA_Histogram_native::AIDA_Histogram2D* p = new Anaphe::AIDA_Histogram_native::AIDA_Histogram2D( title() + " (supporting histogram)", binEdgeX, binEdgeY );
00379   p->setName( name() + "_supportingHistogram" );
00380   m_histo = p;
00381   for ( unsigned int i = 0; i < m_elements.size(); ++i ) m_histo->fill( m_elements[i].x, m_elements[i].y, m_elements[i].w );
00382   m_elements.clear();
00383   return true;
00384 }
00385 
00386 
00387 bool
00388 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::fillHistogram( AIDA::IHistogram2D& hist ) const
00389 {
00390   if ( m_histo ) {
00391     AIDA::IHistogram2D& h = *m_histo;
00392     for ( int ib = -2; ib < h.yAxis().bins(); ++ib ) {
00393       int i = ib;
00394       if ( ib == -2 ) i = static_cast<int>( AIDA::IAxis::OVERFLOW_BIN );
00395       else if ( ib == -1 ) i = static_cast<int>( AIDA::IAxis::UNDERFLOW_BIN );
00396 
00397       for ( int jb = -2; jb < h.yAxis().bins(); ++jb ) {
00398         int j = ib;
00399         if ( jb == -2 ) j = static_cast<int>( AIDA::IAxis::OVERFLOW_BIN );
00400         else if ( jb == -1 ) j = static_cast<int>( AIDA::IAxis::UNDERFLOW_BIN );
00401 
00402         const int entries = h.binEntries( i, j );
00403         if ( entries == 0 ) continue;
00404         const double newCentreX = h.binMeanX( i, j );
00405         const double newCentreY = h.binMeanY( i, j );
00406         const double newValue = h.binHeight( i, j );
00407         if ( entries == 1 ) hist.fill( newCentreX, newCentreY, newValue );
00408         else {
00409           double newError = h.binError( i, j );
00410           const double w1 =
00411             ( 2 * newValue - std::sqrt( ( 4 * entries * newError * newError - newValue * newValue ) / ( entries - 1 ) ) ) / ( 2 * entries );
00412           const double w2 = newValue - ( entries - 1 ) * w1;
00413           for ( int ie = 0; ie < entries - 1; ++ie ) {
00414             hist.fill( newCentreX, newCentreY, w1 );
00415           }
00416           hist.fill( newCentreX, newCentreY, w2 );
00417         }
00418       }
00419     }
00420   }
00421   else {
00422     for ( std::vector< Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::Cloud2DElement >::const_iterator iElement = m_elements.begin();
00423           iElement != m_elements.end(); ++iElement ) {
00424       hist.fill( iElement->x, iElement->y, iElement->w );
00425     }
00426   }
00427   return true;
00428 }
00429 
00430 
00431 const AIDA::IHistogram2D&
00432 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::histogram() const
00433 {
00434   if ( ! m_histo ) const_cast<Anaphe::AIDA_Histogram_native::AIDA_Cloud2D*>(this)->convertToHistogram();
00435   return *m_histo;
00436 }
00437 
00438 
00439 bool
00440 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::setCacheSize( unsigned int newCacheSize )
00441 {
00442   m_cacheSize = newCacheSize;
00443   if ( m_cacheSize != static_cast<unsigned int>( -1 ) ) m_elements.reserve( newCacheSize );
00444   return true;
00445 }
00446 
00447 
00448 unsigned int
00449 Anaphe::AIDA_Histogram_native::AIDA_Cloud2D::cacheSize() const
00450 {
00451   return m_cacheSize;
00452 }

Generated on Tue Nov 19 12:32:15 2002 for AIDA_Histogram_native by doxygen1.2.16