Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:38:18

0001 // -*- C++ -*-
0002 //
0003 // DataPointSet.h is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 1999-2019 Leif Lonnblad
0005 //
0006 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 #ifndef LWH_DataPointSet_H
0010 #define LWH_DataPointSet_H
0011 //
0012 // This is the declaration of the DataPointSet class representing
0013 //
0014 
0015 
0016 #include <vector>
0017 #include <limits>
0018 #include <cmath>
0019 #include <algorithm>
0020 #include "AIDataPointSet.h"
0021 #include "ManagedObject.h"
0022 #include "DataPoint.h"
0023 
0024 namespace LWH {
0025 
0026 using namespace AIDA;
0027 
0028 /**
0029  * An DataPointSet represents a binned histogram axis. A 1D Histogram would have
0030  * one DataPointSet representing the X axis, while a 2D Histogram would have two
0031  * axes representing the X and Y DataPointSet.
0032  */
0033 class DataPointSet: public IDataPointSet, public ManagedObject {
0034 
0035 public:
0036 
0037   /**
0038    * Standard constructor takes the dimension, \a D, of the data
0039    * points as argument.
0040    */
0041   DataPointSet(int D): dim(D) {}
0042 
0043   /**
0044    * Destructor.
0045    */
0046   virtual ~DataPointSet() {}
0047 
0048   /**
0049    * Not implemented in LWH. will throw an exception.
0050    */
0051   IAnnotation & annotation() {
0052     throw std::runtime_error("LWH cannot handle annotations");
0053   }
0054 
0055   /**
0056    * Not implemented in LWH. will throw an exception.
0057    */
0058   const IAnnotation & annotation() const {
0059     throw std::runtime_error("LWH cannot handle annotations");
0060   }
0061 
0062   /**
0063    * Get the data set's title.
0064    * @return The data set's title.
0065    */
0066   std::string title() const {
0067     return theTitle;
0068   }
0069 
0070   /**
0071    * Get the data set's title.
0072    * @return The data set's title.
0073    */
0074   std::string name() const {
0075     return theTitle;
0076   }
0077 
0078   /**
0079    * Set the data set's title.
0080    * @param title The title.
0081    * @return false If title cannot be changed.
0082    */
0083   bool setTitle(const std::string & title) {
0084     theTitle = title;
0085     return true;
0086   }
0087 
0088   /**
0089    * Get the dimension of the IDataPoints that can be stored in the set.
0090    * @return The dimension of the IDataPoints storable in the set.
0091    *
0092    */
0093   int dimension() const {
0094     return dim;
0095   }
0096 
0097   /**
0098    * Remove all the IDataPoints in the set.
0099    * After this the IDataPointSet is as just created.
0100    */
0101   void clear() {
0102     dset.clear();
0103   }
0104 
0105   /**
0106    * Get the current size of the IDataPointSet, i.e. the number
0107    * of IDataPoints contained in the set.
0108    * @return The size of the IDataPointSet.
0109    */
0110   int size() const {
0111     return dset.size();
0112   }
0113 
0114   /**
0115    * Get the IDataPoint at a give index in the set.
0116    * @param index The IDataPoint index.
0117    * @return      The corresponding IDataPoint.
0118    */
0119   IDataPoint * point(int index) {
0120     return &(dset[index]);
0121   }
0122 
0123   /**
0124    * Set the values and errors of a given coordinate all at once.  If
0125    * this method is called on an empty IDataPointSet, a number of
0126    * points equal to the size of the arrays provided is created; if
0127    * the IDataPointSet is not empty the dimension of the array must
0128    * match with the size of the IDataPointSet.
0129    * @param coord The coordinate's index
0130    * @param val   The array of the values for the given coordinate
0131    * @param err   The array with the symmetric errors.
0132    * @return false if an illegal coordinate is provided or if there is
0133    *      a mismatch between the size of the array and the size of the
0134    *      IDataPointSet.
0135    */
0136   bool setCoordinate(int coord,
0137              const std::vector<double>  & val,
0138              const std::vector<double>  & err) {
0139     return setCoordinate(coord, val, err, err);
0140   }
0141 
0142   /**
0143    * Set the values and errors of a given coordinate all at once.  If
0144    * this method is called on an empty IDataPointSet, a number of
0145    * points equal to the size of the arrays provided is created; if
0146    * the IDataPointSet is not empty the dimension of the array must
0147    * match with the size of the IDataPointSet.
0148    * @param coord The coordinate's index
0149    * @param val   The array of the values for the given coordinate
0150    * @param errp  The array with the plus errors.
0151    * @param errm  The array with the minus errors.
0152    * @return false if an illegal coordinate is provided or if there is
0153    *     a mismatch between the size of the array and the size of the
0154    *     IDataPointSet.
0155    *
0156    */
0157   bool setCoordinate(int coord,
0158              const std::vector<double>  & val,
0159              const std::vector<double>  & errp,
0160              const std::vector<double>  & errm) {
0161     if ( coord < 0 || coord >= dimension() ) return false;
0162     if ( val.size() != dset.size() || errp.size() != dset.size() ||
0163      errm.size() != dset.size() ) return false;
0164     for ( int i = 0, N = val.size(); i < N; ++i ) {
0165       dset[i].coordinate(coord)->setValue(val[i]);
0166       dset[i].coordinate(coord)->setErrorPlus(errp[i]);
0167       dset[i].coordinate(coord)->setErrorMinus(errm[i]);
0168     }
0169     return true;
0170   }
0171 
0172   /**
0173    * Return the data point at the given index.
0174    * @return 0 if index is out of range.
0175    */
0176   const IDataPoint * point(int index) const {
0177     if ( index < 0 || unsigned(index) >= dset.size() ) return 0;
0178     return &(dset[index]);
0179   }
0180 
0181   /**
0182    * Add a new empty IDataPoint at the end of the set.
0183    * @return The newly added point.
0184    */
0185   IDataPoint * addPoint() {
0186     dset.push_back(DataPoint(dimension()));
0187     return &(dset.back());
0188   }
0189 
0190   /**
0191    * Add a copy of an IDataPoint at the end of the set.
0192    * @param point The IDataPoint to be added.
0193    * @return false If the point has the wrong dimension or
0194    *                                       if the point cannot be added.
0195    */
0196   bool addPoint(const IDataPoint & point) {
0197     if ( dimension() && dimension() != point.dimension() ) return false;
0198     dset.push_back(DataPoint(point));
0199     return true;
0200   }
0201 
0202   /**
0203    * Remove the IDataPoint at a given index.
0204    * @param index The index of the IDataPoint to be removed.
0205    * @return false If the index is < 0 or >= size().
0206    */
0207   bool removePoint(int index) {
0208     if ( index < 0 || unsigned(index) >= dset.size() ) return false;
0209     dset.erase(dset.begin() + index);
0210     return true;
0211   }
0212 
0213   /**
0214    * Get the lower value for a give axis.
0215    * @param coord The coordinate of the axis.
0216    * @return      The lower edge of the corresponding axis.
0217    *              If coord < 0 or coord >= dimension(), or if the
0218    *              set is empty NaN is returned.
0219    */
0220   double lowerExtent(int coord) const {
0221     if ( dset.empty() ) return std::numeric_limits<double>::quiet_NaN();
0222     if ( coord < 0 || coord >= dimension() )
0223       return std::numeric_limits<double>::quiet_NaN();
0224     double low = dset[0].coordinate(coord)->value();
0225     for ( int i = 1, N = dset.size(); i < N; ++i )
0226       low = std::min(low, dset[i].coordinate(coord)->value());
0227     return low;
0228   }
0229 
0230   /**
0231    * Get the upper value for a give axis.
0232    * @param coord The coordinate of the axis.
0233    * @return      The upper edge of the corresponding axis.
0234    *              If coord < 0 or coord >= dimension(), or if the set
0235    *              is empty NaN is returned.
0236    */
0237   double upperExtent(int coord) const {
0238     if ( dset.empty() ) return std::numeric_limits<double>::quiet_NaN();
0239     if ( coord < 0 || coord >= dimension() )
0240       return std::numeric_limits<double>::quiet_NaN();
0241     double upp = dset[0].coordinate(coord)->value();
0242     for ( int i = 1, N = dset.size(); i < N; ++i )
0243       upp = std::max(upp, dset[i].coordinate(coord)->value());
0244     return upp;
0245   }
0246 
0247   /**
0248    * Scales the values and the errors of all the measurements
0249    * of each point by a given factor.
0250    * @param scale The scale factor.
0251    * @return false If an illegal scaleFactor is provided.
0252    */
0253   bool scale(double scale) {
0254     for ( int i = 0, N = dset.size(); i < N; ++i )
0255       for ( int j = 0, M = dset[i].dimension(); j < M; ++j ) {
0256     IMeasurement * m = dset[i].coordinate(j);
0257     m->setValue(m->value()*scale);
0258     m->setErrorPlus(m->errorPlus()*scale);
0259     m->setErrorMinus(m->errorPlus()*scale);
0260       }
0261     return true;
0262   }
0263     
0264   /**
0265    * Scales the values of all the measurements
0266    * of each point by a given factor.
0267    * @param scale The scale factor.
0268    * @return false If an illegal scaleFactor is provided.
0269    */
0270   bool scaleValues(double scale) {
0271     for ( int i = 0, N = dset.size(); i < N; ++i )
0272       for ( int j = 0, M = dset[i].dimension(); j < M; ++j ) {
0273     IMeasurement * m = dset[i].coordinate(j);
0274     m->setValue(m->value()*scale);
0275       }
0276     return true;
0277   }
0278 
0279   /**
0280    * Scales the errors of all the measurements
0281    * of each point by a given factor.
0282    * @param scale The scale factor.
0283    * @return false If an illegal scaleFactor is provided.
0284    */
0285   bool scaleErrors(double scale) {
0286     for ( int i = 0, N = dset.size(); i < N; ++i )
0287       for ( int j = 0, M = dset[i].dimension(); j < M; ++j ) {
0288     IMeasurement * m = dset[i].coordinate(j);
0289     m->setErrorPlus(m->errorPlus()*scale);
0290     m->setErrorMinus(m->errorPlus()*scale);
0291       }
0292     return true;
0293   }
0294 
0295   /**
0296    * Not implemented in LWH.
0297    * @return null pointer always.
0298    */ 
0299   void * cast(const std::string &) const {
0300     return 0;
0301   }
0302 
0303   /**
0304    * Write out the data set in the AIDA xml format.
0305    */
0306   bool writeXML(std::ostream & os, std::string path, std::string name) {
0307     os << "  <dataPointSet name=\"" << name
0308        << "\"\n    title=\"" << title()
0309        << "\" path=\"" << path
0310        << "\" dimension=\"" << dimension() << "\">\n";
0311     for ( int d = 0; d < dimension(); ++d )
0312       os << "    <dimension dim=\"" << d << "\" title=\"unknown\" />\n";
0313     for ( int i = 0, N = size(); i < N; ++i ) {
0314       os << "    <dataPoint>\n";
0315       for ( int j = 0, M = dimension(); j < M; ++j )
0316     os << "      <measurement value=\""
0317        << point(i)->coordinate(j)->value()
0318        << "\" errorPlus=\""
0319        << point(i)->coordinate(j)->errorPlus()
0320        << "\" errorMinus=\""
0321        << point(i)->coordinate(j)->errorMinus()
0322        << "\"/>\n";
0323       os << "    </dataPoint>\n";
0324     }
0325     os << "  </dataPointSet>" << std::endl;
0326     return true;
0327   }
0328 
0329   /**
0330    * Write out the data set in a flat text file suitable for
0331    * eg. gnuplot to read. The coloums are layed out as 'x1 x2 ... xn
0332    * dx1+ dx2+ ... dxn+ dx1- dx2- ... dxn-'.
0333    */
0334   bool writeFLAT(std::ostream & os, std::string path, std::string name) {
0335     os << "# " << path << "/" << name << " " << size()
0336        << " \"" << title() << " \" dimension " << dimension() << std::endl;
0337     for ( int i = 0, N = size(); i < N; ++i ) {
0338       for ( int j = 0, M = dimension(); j < M; ++j )
0339     os << point(i)->coordinate(j)->value() << " ";
0340       for ( int j = 0, M = dimension(); j < M; ++j )
0341     os << point(i)->coordinate(j)->errorPlus() << " ";
0342       for ( int j = 0, M = dimension(); j < M; ++j )
0343     os << point(i)->coordinate(j)->errorMinus() << " ";
0344       os << std::endl;
0345     }
0346     os << std::endl;
0347     return true;
0348   }
0349 
0350 private:
0351 
0352   /** The title */
0353   std::string theTitle;
0354 
0355   /**
0356    * The included data points.
0357    */
0358   std::vector<DataPoint> dset;
0359 
0360   /**
0361    * The dimension of the points in this set.
0362    */
0363   unsigned int dim;
0364 
0365 
0366 };
0367 
0368 }
0369 
0370 #endif /* LWH_DataPointSet_H */