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 bool ScanPoints::ascending() const {
00053 if (getNPoints()<2) return true;
00054 bool up=false, down=false;
00055 double lastPoint=getPoint(0);
00056
00057 for (unsigned ipoint=1; ipoint<getNPoints(); ++ipoint){
00058 double point=getPoint(ipoint);
00059 if (point<lastPoint) down=true;
00060 if (point>lastPoint) up=true;
00061 if (point==lastPoint || (up && down)) throw LogicError("ScanPoints not in ascending or descending order, or has repeated points", __FILE__, __LINE__);
00062 lastPoint=point;
00063 }
00064 return up;
00065 }
00066
00067
00068 double* ScanPoints::getEdgesAscending() const throw(LogicError) {
00069 if (points.size()<2) throw IllegalStateError("ScanPoints::getEdges() must have two points", __FILE__, __LINE__) ;
00070
00071 double* bins = new double[points.size()+1];
00072
00073 if (ascending()){
00074 double lowedge = points[0] + 0.5 * (points[0]- points[1]);
00075 bins[0] = lowedge;
00076 for (unsigned int i=1; i<=points.size(); i++) {
00077 bins[i] = 2*points[i-1] - bins[i-1];
00078 }
00079 } else {
00080 double lowedge = points[points.size()-1] + 0.5 * (points[points.size()-1] - points[points.size()-2]);
00081 bins[0] = lowedge;
00082 for (unsigned int i=1; i<=points.size(); i++) {
00083 bins[i] = 2*points[ points.size()-i] - bins[i-1];
00084 }
00085 }
00086 return bins;
00087 }
00088
00089 void ScanPoints::setAxis(TAxis& axis) const throw(LogicError) {
00090 double* bins = getEdgesAscending();
00091 axis.Set(points.size(), bins);
00092 delete [] bins;
00093 }
00094
00095 }