00001 #include "ScanPoints.h"
00002 #include "TAxis.h"
00003 #include "Sct/LogicErrors.h"
00004 #include <algorithm>
00005
00006 using Sct::LogicError;
00007 using Sct::IllegalStateError;
00008
00009 namespace SctData {
00010
00011 ScanPoints::ScanPoints(const unsigned nPoints, const float* points,
00012 const unsigned* nEvents, const unsigned* nErrorEvents) throw() : points("ScanPoints::points") {
00013 for (unsigned i=0; i<nPoints; ++i) {
00014 addPoint(points[i], nEvents[i], nErrorEvents[i]);
00015 }
00016 }
00017
00018 ScanPoints::ScanPoints() throw() : points("ScanPoints::points") {}
00019
00020 string ScanPoints::getClassName() const throw() {
00021 return "SctData::ScanPoints";
00022 }
00023
00024 unsigned ScanPoints::getNPoints() const throw() {
00025 return points.size();
00026 }
00027
00028 double ScanPoints::getPoint(const unsigned i) const throw(LogicError) {
00029 return points[i];
00030 }
00031
00032 double ScanPoints::operator[] (const unsigned i) const throw(LogicError) {
00033 return points[i];
00034 }
00035
00036 double& ScanPoints::operator[] (const unsigned i) throw(LogicError) {
00037 return points[i].point;
00038 }
00039
00040 unsigned int ScanPoints::getNEvents(const unsigned i) const throw(LogicError) {
00041 return points[i].nEvents;
00042 }
00043
00044 unsigned int ScanPoints::getNErrorEvents(const unsigned i) const throw(LogicError) {
00045 return points[i].nErrorEvents;
00046 }
00047
00048 void ScanPoints::addPoint(const double point, const unsigned events, const unsigned errorEvents) throw() {
00049 points.push_back( ScanPoint(point, events, errorEvents) );
00050 }
00051
00052 double ScanPoints::getMin() const{
00053 return ascending() ? getPoint(0) : getPoint(getNPoints()-1);
00054 }
00055
00056 double ScanPoints::getMax() const{
00057 return ascending() ? getPoint(getNPoints()-1) : getPoint(0);
00058 }
00059
00060 bool ScanPoints::ascending() const {
00061 if (getNPoints()<2) return true;
00062 bool up=false, down=false;
00063 double lastPoint=getPoint(0);
00064
00065 #ifndef NDEBUG
00066
00067 for (unsigned ipoint=1; ipoint<getNPoints(); ++ipoint){
00068 double point=getPoint(ipoint);
00069 if (point<lastPoint) down=true;
00070 if (point>lastPoint) up=true;
00071 if (point==lastPoint || (up && down)) throw LogicError("ScanPoints not in ascending or descending order, or has repeated points", __FILE__, __LINE__);
00072 lastPoint=point;
00073 }
00074 return up;
00075 #else
00076 return getPoint(getNPoints()-1) > getPoint(0);
00077 #endif
00078 }
00079
00080
00081 double* ScanPoints::getEdgesAscending() const throw(LogicError) {
00082 if (points.size()<2) throw IllegalStateError("ScanPoints::getEdges() must have two points", __FILE__, __LINE__) ;
00083
00084 double* bins = new double[points.size()+1];
00085
00086 if (ascending()){
00087 double lowedge = points[0] + 0.5 * (points[0]- points[1]);
00088 bins[0] = lowedge;
00089 for (unsigned int i=1; i<=points.size(); i++) {
00090 bins[i] = 2*points[i-1] - bins[i-1];
00091 }
00092 } else {
00093 double lowedge = points[points.size()-1] + 0.5 * (points[points.size()-1] - points[points.size()-2]);
00094 bins[0] = lowedge;
00095 for (unsigned int i=1; i<=points.size(); i++) {
00096 bins[i] = 2*points[ points.size()-i] - bins[i-1];
00097 }
00098 }
00099 return bins;
00100 }
00101
00102 void ScanPoints::setAxis(TAxis& axis) const throw(LogicError) {
00103 double* bins = getEdgesAscending();
00104 axis.Set(points.size(), bins);
00105 delete [] bins;
00106 }
00107
00108 }