00001 #include "histogram1d.h"
00002 #include "message.h"
00003 #include "linalg.h"
00004
00005 void CHistogram1d::setFixedWidthBins(double dx, double xoffset){
00006 Array1D<double> tmp(ndata+1,0.);
00007 for (int i=0;i<ndata+1;++i) {tmp[i]=dx*i+xoffset-dx/2.;}
00008 knots=tmp;
00009 fixed_width_bins=true;
00010 xmin = getLeftSupport( 0 );
00011 xmax = getRightSupport( ndata - 1 );
00012 }
00013
00014 bool CHistogram1d::inThisBin(int i, double xx) const
00015 {return ((xx<knots[i+1])&&(xx>=knots[i]));}
00016
00023 int CHistogram1d::whatBin(double x, bool graceful) const{
00024 for (int i=0;i<ndata;++i){if (inThisBin(i,x)) return i;}
00025 if (x<knots[0]) {
00026 MESSAGE << "x = "<<x<<" is off scale, "<< "min x="<<knots[0];
00027 if (graceful) MESSAGE<<ENDM_WARN; else
00028 MESSAGE<<ENDM_INFO;
00029 if (graceful) return 0; else return -1;
00030 } else {
00031 MESSAGE << "x = "<<x<<" is off scale, "<< "max x="<<knots[ndata];
00032
00033 MESSAGE<<ENDM_INFO;
00034 if (graceful) return ndata-1; else return ndata;
00035 }
00036 }
00037
00038 double CHistogram1d::basisFunction(double x, int i, int jderiv) const{
00039 switch (jderiv){
00040 case 0: return double(inThisBin(i,x));
00041 case -1: return x*double(inThisBin(i,x));
00042 default: return 0.0;
00043 }
00044 return 0.0;
00045 }
00046
00047
00048 bool CHistogram1d::Read(const parameterMap& m){
00049 bool found_bins=false, found_data=false;
00050
00051 vector< double > empty_vec(0);
00052 vector< vector< double > > empty_mat(0);
00053
00054 CObject1d::Read(m);
00055
00056 fixed_width_bins=parameter::getB(m,"fixed_width_bins",fixed_width_bins);
00057 if (fixed_width_bins){
00058 found_bins=true;
00059 CDataSet::Read(m);
00060 if ( m.hasKey("dx") && m.hasKey("xoffset") ) setFixedWidthBins(parameter::getD(m,"dx"),parameter::getD(m,"xoffset"));
00061 else if ( m.hasKey("xmin") && m.hasKey("xmax") ) {
00062 double binWidth = ( parameter::getD(m,"xmax") - parameter::getD(m,"xmin") )/ndata;
00063 setFixedWidthBins(binWidth,binWidth/2.0+m.hasKey("xmin"));
00064 }
00065 else throw MESSAGE << "Cannot find dx or xoffset keys or xmax and xmin keys"<<ENDM_FATAL;
00066 } else if(m.find("left_bin_edges")!=m.end()){
00067 found_bins=true;
00068 CDataSet::Read(m);
00069 knots = stl2tntVec(parameter::getV(m,"knots",empty_vec));
00070 xmin = getLeftSupport( 0 );
00071 xmax = getRightSupport( ndata - 1 );
00072 }
00073
00074 found_data=CDataSet::Read(m);
00075
00076 if(m.find("xy_datablock")!=m.end()) {
00077 found_bins=true;
00078 found_data=true;
00079 vector< vector<double> > tmp;
00080 tmp=parameter::getM(m,"xy_datablock",empty_mat);
00081 ndata = tmp.size();
00082 Array1D<double> xtmp(ndata+1,0.);
00083 Array1D<double> ytmp(ndata,0.);
00084 for (int i=0;i<ndata;++i){
00085 xtmp[i+1]=2.*tmp[0][i]-xtmp[i];
00086 ytmp[i]=tmp[1][i];
00087 }
00088 data = ytmp;
00089 if (!fixed_width_bins) knots = xtmp;
00090 xmin = getLeftSupport( 0 );
00091 xmax = getRightSupport( ndata - 1 );
00092 } else if(m.find("xydy_datablock")!=m.end()) {
00093 found_bins=true;
00094 found_data=true;
00095 vector< vector<double> > tmp;
00096 tmp=parameter::getM(m,"xydy_datablock",empty_mat);
00097 ndata = tmp.size();
00098 Array1D<double> xtmp(ndata+1,0.);
00099 Array1D<double> ytmp(ndata,0.);
00100 Array1D<double> dytmp(ndata,0.);
00101 for (int i=0;i<ndata;++i){
00102 xtmp[i+1]=2.*tmp[0][i]-xtmp[i];
00103 ytmp[i]=tmp[1][i];
00104 dytmp[i]=tmp[2][i];
00105 }
00106 data = ytmp;
00107 uncert=dytmp;
00108 if (!fixed_width_bins) knots = xtmp;
00109 xmin = getLeftSupport( 0 );
00110 xmax = getRightSupport( ndata - 1 );
00111 }
00112 if (!found_bins) {
00113 MESSAGE << "Bin edges not found, setting to zero!"<<ENDM_INFO;
00114 Array1D<double> xtmp(ndata+1,0.);
00115 knots=xtmp;
00116 }
00117 if (!found_data) {
00118 MESSAGE << "Data set not found, setting to zero!" <<ENDM_INFO;
00119 Array1D<double> ytmp(ndata,0.), dytmp(ndata,0.);
00120 data=ytmp;
00121 uncert=dytmp;
00122 }
00123 return true;
00124 }
00125
00126 bool CHistogram1d::Write(parameterMap& m){
00127 CObject1d::Write(m);
00128 if (fixed_width_bins) {
00129 parameter::set(m,"fixed_width_bins",true);
00130 parameter::set(m,"dx",(knots[1]-knots[0]));
00131 parameter::set(m,"xoffset",(knots[1]-knots[0])/2.);
00132 } else {
00133 parameter::set(m,"left_bin_edges",tnt2stlVec(knots));
00134 }
00135 return CDataSet::Write(m);
00136 }
00137
00138 bool CHistogram1d::setDefaultKnots( void ){
00139 double dx=(xmax-xmin)/(double)ndata;
00140 setFixedWidthBins(dx,dx/2.0);
00141 return true;
00142 }