Gaussian::Gaussian(const fracfloat_t* trueData, const fracfloat_t* predictedData, unsigned count){ fracfloat_t differences[count]; for(unsigned i = 0; i < count; i++){ differences[i] = predictedData[i] - trueData[i]; } fitGaussian(Array<fracfloat_t>(differences, count)); }
void fitGaussian( TH1D* hist, double& mean, double& sigma, bool display) { double max = 0; double background = 0; fitGaussian(hist, mean, sigma, max, background, display); }
void fitPSF(DataParams ¶ms, MultiArray<2, double> &ps) { double minval=9999999, maxval = 0; int size = 2*ps.shape(0)*ps.shape(1); std::vector<double> data2(2*ps.shape(0)*ps.shape(1)); for(int i=0, counter = 0;i<ps.shape(0);++i) { for(int j=0;j<ps.shape(1);++j,++counter) { //std::cout<<i<<" "<<j<<" "<<counter<<std::endl; data2[2*counter] = std::sqrt(std::abs(std::pow(i-ps.shape(0)/2,2)+std::pow(j-ps.shape(1)/2,2))); data2[2*counter+1] = ps(i,j); if (ps(i,j)< minval){minval = ps(i,j);} if (ps(i,j)> maxval){maxval = ps(i,j);} } } double sigma = 2.0, scale = maxval - minval, offset = minval; //std::cout<<sigma<<" "<<scale<<" "<<offset<<std::endl; fitGaussian(&data2[0], size/2, sigma, scale, offset); params.setSigma(sigma); }
void SimpleFeatureComparator::initialize() { fitGaussian(); initialized = true; }
Gaussian::Gaussian(const fracfloat_t *errors, unsigned n){ fitGaussian(Array<fracfloat_t>(n, (fracfloat_t*) errors)); //Remove const on errors via cast (we don't modify it, don't worry!) }
void residualAlignment(TH2D* residualX, TH2D* residualY, double& offsetX, double& offsetY, double& rotation, double relaxation, bool display) { assert(residualX && residualY && "Processors: can't perform residual alignment without histograms"); rotation = 0; offsetX = 0; offsetY = 0; double angleWeights = 0; double fitChi2 = 0; for (int axis = 0; axis < 2; axis++) { TH2D* hist = 0; if (axis) hist = residualX; else hist = residualY; // Project the histogram and fit with a gaussian to center the sensor TH1D* project = hist->ProjectionX("ResidualProjetion", 1, hist->GetNbinsY()); project->SetDirectory(0); double sigma = project->GetBinWidth(1); double mean = 0; fitGaussian(project, mean, sigma, false); if (axis) offsetX = mean; else offsetY = mean; delete project; std::vector<double> ptsX; std::vector<double> ptsY; std::vector<double> ptsErr; const unsigned int numSlices = hist->GetNbinsY(); for (Int_t row = 1; row <= (int)numSlices; row++) { TH1D* slice = hist->ProjectionX("ResidualSlice", row, row); slice->SetDirectory(0); double mean = 0; double sigma = 0; double factor = 0; double background = 0; if (slice->Integral() < 1) { delete slice; continue; } fitGaussian(slice, mean, sigma, factor, background, false); const double sliceMin = slice->GetBinCenter(1); const double sliceMax = slice->GetBinCenter(slice->GetNbinsX()); delete slice; // Quality assurance // Sigma is contained in the slice's range if (sigma > (sliceMax - sliceMin)) continue; // Mean is contained in the slice's range if (mean > sliceMax || mean < sliceMin) continue; // Peak is contains sufficient events if (factor < 100) continue; // Sufficient signal to noise ratio if (factor / background < 10) continue; // Get the total number of events in the gaussian 1 sigma Int_t sigRangeLow = hist->FindBin(mean - sigma); Int_t sigRangeHigh = hist->FindBin(mean + sigma); double sigRangeTotal = 0; for (Int_t bin = sigRangeLow; bin <= sigRangeHigh; bin++) sigRangeTotal += hist->GetBinContent(bin); // 2 * 1 sigma integral shoudl give ~ area under gaussian sigma /= sqrt(2 * sigRangeTotal); ptsX.push_back(hist->GetYaxis()->GetBinCenter(row)); ptsY.push_back(mean); ptsErr.push_back(sigma); } if (ptsX.size() < 3) continue; std::vector<double> yvals = ptsY; std::sort(yvals.begin(), yvals.end()); const double median = yvals[yvals.size()/2]; double avgDeviation = 0; for (unsigned int i = 0; i < yvals.size(); i++) avgDeviation += fabs(yvals[i] - median); avgDeviation /= (double)yvals.size(); std::vector<double> ptsXGood; std::vector<double> ptsYGood; std::vector<double> ptsErrGood; for (unsigned int i = 0; i < ptsX.size(); i++) { if (fabs(ptsY[i] - median) > 1.5*avgDeviation) continue; ptsXGood.push_back(ptsX[i]); ptsYGood.push_back(ptsY[i]); ptsErrGood.push_back(ptsErr[i]); } if (ptsXGood.size() < 3) continue; TGraphErrors* graph = new TGraphErrors(ptsXGood.size(), &(ptsXGood.at(0)), &(ptsYGood.at(0)), 0, &(ptsErrGood.at(0))); TF1* fitFunc = new TF1("f1", "1 ++ x"); TF1* result = 0; graph->Fit(fitFunc, "Q0E").Get(); result = graph->GetFunction(fitFunc->GetName()); // Weight the angle by the slope uncertainty and the inverse of the chi2 normalized double weight = result->GetParError(1); const double chi2 = result->GetChisquare() / (double)result->GetNDF(); fitChi2 += chi2; weight *= chi2; if (weight > 10 * DBL_MIN) weight = 1.0 / weight; else weight = 1.0; if (axis) { rotation -= weight * atan(result->GetParameter(1)); offsetX = result->GetParameter(0); } else { rotation += weight * atan(result->GetParameter(1)); offsetY = result->GetParameter(0); } angleWeights += weight; if (display) { TCanvas* can = new TCanvas("ResidualAlignment", "Residual Alignment", 900, 600); can->Divide(2); can->cd(1); hist->Draw("COLZ"); can->cd(2); result->SetLineColor(46); result->SetLineWidth(2); graph->Draw("ap"); result->Draw("SAME"); can->Update(); can->WaitPrimitive(); } delete fitFunc; delete graph; } if (angleWeights > 10 * DBL_MIN) rotation /= angleWeights; std::cout << "relaxation: " << relaxation << std::endl; rotation *= relaxation; offsetX *= relaxation; offsetY *= relaxation; }
void fitBox( TH1D* hist, double& mean, double& sigma, double& max, double& background, double sensorWidth, bool display) { TF1 *errorfunc = new TF1("errorfunc","[0]*(1+TMath::Erf([1]*([2]-x)))*(1-TMath::Erf([3]*([4]-x)))"); errorfunc->SetParNames("Height", "FallSlope","Fall", "RiseSlope", "Rise"); //fit a gaussian for first approximation fitGaussian(hist, mean, sigma, max, background, display); //first order approximations // double maxBin = hist->GetMaximumBin(); double rise = mean - sensorWidth/2; double fall = mean + sensorWidth/2; double height = max/4; double riseSlope = height*10; double fallSlope = height*10; // double maxBin = 0; // double rise = -1000; // double fall = 3000; // double maxHeight = 40; // double riseSlope = 400; // double fallSlope = 400; errorfunc->SetParameter("Height",height); errorfunc->SetParameter("Rise",rise); errorfunc->SetParameter("Fall",fall); errorfunc->SetParameter("RiseSlope",riseSlope); errorfunc->SetParameter("FallSlope",fallSlope); errorfunc->SetParLimits(0, height-abs(0.5*height), height+abs(0.5*height)); errorfunc->SetParLimits(4, rise-abs(1*rise), rise+abs(1*rise)); errorfunc->SetParLimits(2, fall-abs(1*fall), fall+abs(1*fall)); errorfunc->SetParLimits(3, 0.01*riseSlope, 100*riseSlope); errorfunc->SetParLimits(1, 0.01*fallSlope, 100*fallSlope); hist->Fit("errorfunc", ""); //max = gauss->GetParameter(0); mean = ( errorfunc->GetParameter(2) + errorfunc->GetParameter(4) ) / 2 ; sigma = abs ( errorfunc->GetParameter(4) - errorfunc->GetParameter(2) ); //background = gauss->GetParameter(3); if (display) { TCanvas* can = new TCanvas(); errorfunc->SetLineColor(46); errorfunc->SetLineWidth(1); hist->Draw(); errorfunc->Draw("SAME"); can->Update(); can->WaitPrimitive(); } delete errorfunc; // int maxPos = 1; // max = 0; // int risePos = 1; // double rise = 0; // int fallPos = 1; // double fall = 0; // // for (int bin = 1; bin <= hist->GetNbinsX(); bin++) // { // const double value = hist->GetBinContent(bin); // if (value > max) // { // max = value; // maxPos = bin; // } // // const double valuePrev = hist->GetBinContent(bin > 1 ? bin-1 : bin); // if (value - valuePrev > rise) { // rise = value - valuePrev; // risePos = bin; // } // // const double valueNext = hist->GetBinContent( // bin < hist->GetNbinsX() ? bin+1 : bin); // if (value - valueNext > fall) { // fall = value - valueNext; // fallPos = bin; // } // } // // mean = hist->GetXaxis()->GetBinCenter(maxPos); // sigma = hist->GetXaxis()->GetBinUpEdge(fallPos) - // hist->GetXaxis()->GetBinLowEdge(risePos); // // const unsigned int initialWidth = 5; // // Int_t bgBin1 = hist->FindBin(mean - initialWidth * sigma); // Int_t bgBin2 = hist->FindBin(mean + initialWidth * sigma); // if (bgBin1 < 1) bgBin1 = 1; // if (bgBin2 > hist->GetNbinsX()) bgBin2 = hist->GetNbinsX(); // background = hist->GetBinContent(bgBin1) + hist->GetBinContent(bgBin2); // background /= 2.0; // // max -= background; // // // If sigma is very small, try to calculate using FWHM // // if (sigma < 10 * DBL_MIN) // // { // // double pt1 = 0; // // for (Int_t bin = 1; bin <= hist->GetNbinsX(); bin++) // // { // // if (bin >= max / 2.0) // // { // // pt1 = hist->GetBinCenter(bin); // // break; // // } // // } // // // double pt2 = 0; // // for (Int_t bin = hist->GetNbinsX(); bin >= 1; bin--) // // { // // if (bin >= max / 2.0) // // { // // pt2 = hist->GetBinCenter(bin); // // break; // // } // // } // // // sigma = pt2 - pt1; // // } // // gauss->SetRange(mean - initialWidth * sigma, mean + initialWidth * sigma); // gauss->SetParameters(max, mean, sigma, background); // gauss->SetParLimits(2, 0, 10 * sigma); // hist->Fit("g1", "QR0"); // // max = gauss->GetParameter(0); // mean = gauss->GetParameter(1); // sigma = gauss->GetParameter(2); // background = gauss->GetParameter(3); // // gauss->SetRange(mean - 5 * sigma, mean + 5 * sigma); // gauss->SetParameters(max, mean, sigma, background); // hist->Fit("g1", "QR0"); // // max = gauss->GetParameter(0); // mean = gauss->GetParameter(1); // sigma = gauss->GetParameter(2); // background = gauss->GetParameter(3); // // if (display) // { // TCanvas* can = new TCanvas(); // gauss->SetLineColor(46); // gauss->SetLineWidth(1); // hist->Draw(); // gauss->Draw("SAME"); // can->Update(); // can->WaitPrimitive(); // } // // delete gauss; }