double[] dataX = new double[this.numberOfDataPoints];
for(int i=0; i<this.numberOfDataPoints; i++)dataX[i]=i;
double incrI = ((double)(this.numberOfDataPoints-1))/(nInterp-1);
interpData = new double[nInterp];
CubicSpline cs = new CubicSpline(dataX, this.sortedData);
double interp = 0.0;
for(int i=0; i<nInterp-1; i++){
interpData[i]=cs.interpolate(interp);
interp += incrI;
}
interpData[nInterp-1] = (double)(this.numberOfDataPoints-1);
}
// Bin the data
int nBins = 100;
double[] binnedData = new double[nBins];
double[] bins = new double[nBins];
double binWidth = this.range/nBins;
double binLower = this.minimum;
double binUpper = binLower + binWidth;
int counter = 0;
for(int i=0; i<nBins; i++){
bins[i] = (binUpper + binLower)/2.0;
binnedData[i] = 0.0;
boolean test = true;
if(counter>=nInterp)test = false;
while(test){
if(interpData[counter]<binUpper){
binnedData[i] += 1.0;
}
else{
test = false;
}
counter++;
if(counter>=nInterp)test = false;
}
binLower = binUpper;
binUpper = binLower + binWidth;
}
if(counter<nInterp)binnedData[nBins-1] += (double)(nInterp-counter);
// Identify peak
ArrayMaths am = new ArrayMaths(binnedData);
double maxI = am.maximum();
int maxIindex = am.maximumIndex();
this.peakPoint = bins[maxIindex];
double halfHeight = maxI/2.0;
double widthLower = 0.0;
boolean lowerCheck = false;
double widthUpper = 0.0;
boolean upperCheck = false;
// lower limit
if(binnedData[0]==halfHeight){
widthLower = bins[0];
lowerCheck = true;
}
else{
if(binnedData[0]<halfHeight){
if(maxIindex>=2){
double[] interpLy = new double[maxIindex+1];
double[] interpLx = new double[maxIindex+1];
for(int i=0; i<=maxIindex; i++){
interpLy[i] = binnedData[i];
interpLx[i] = bins[i];
}
CubicSpline csl = new CubicSpline(interpLx, interpLy);
double[] tempx = new double[100];
double[] tempy = new double[100];
double incr = (interpLx[maxIindex]-interpLx[0])/99;
double intr = interpLx[0];
for(int i=0; i<99; i++){
tempx[i] = intr;
tempy[i] = csl.interpolate(intr);
intr += incr;
}
tempy[99] = interpLy[maxIindex];
tempx[99] = interpLx[maxIindex];
boolean testt = true;
int ii = 0;
while(testt){
if(halfHeight<=tempy[ii]){
if(ii==0){
widthLower = tempx[0];
testt = false;
lowerCheck = true;
}else{
if(ii==99){
widthLower = tempx[99];
testt = false;
lowerCheck = true;
}
else{
widthLower = (tempx[ii] + tempx[ii-1])/2.0;
testt = false;
lowerCheck = true;
}
}
}
ii++;
if(ii>=100)testt = false;
}
}
else{
if(maxIindex==2){
if(binnedData[1]>=halfHeight){
widthLower = bins[0] + (bins[1] - bins[0])*(halfHeight - binnedData[0])/(binnedData[1] - binnedData[0]);
lowerCheck = true;
}
else{
widthLower = bins[1] + (bins[2] - bins[1])*(halfHeight - binnedData[1])/(binnedData[2] - binnedData[1]);
lowerCheck = true;
}
}
else{
widthLower = bins[0] + (bins[1] - bins[0])*(halfHeight - binnedData[0])/(binnedData[1] - binnedData[0]);
lowerCheck = true;
}
}
}
else{
if(maxIindex>2){
if((binnedData[maxIindex]-binnedData[0])>halfHeight*0.5){
widthLower = bins[0] + (bins[1] - bins[0])*(halfHeight - binnedData[0])/(binnedData[1] - binnedData[0]);
lowerCheck = true;
}
}
}
}
// upper limit
int nTop = nBins - 1;
int nDif = nBins - maxIindex;
if(binnedData[nTop]==halfHeight){
widthUpper = bins[nTop];
upperCheck = true;
}
else{
if(binnedData[nTop]<halfHeight){
if(nDif>=3){
double[] interpLy = new double[nDif];
double[] interpLx = new double[nDif];
int ii = 0;
for(int i=maxIindex; i<nBins; i++){
interpLy[ii] = binnedData[i];
interpLx[ii] = bins[i];
ii++;
}
CubicSpline csl = new CubicSpline(interpLx, interpLy);
double[] tempx = new double[100];
double[] tempy = new double[100];
double incr = (interpLx[nDif-1]-interpLx[0])/99;
double intr = interpLx[0];
for(int i=0; i<99; i++){
tempx[i] = intr;
tempy[i] = csl.interpolate(intr);
intr += incr;
}
tempy[99] = interpLy[nDif-1];
tempx[99] = interpLx[nDif-1];
boolean testt = true;