Crashes second time Fit function is called

I am trying to fit a Gaussian curves to multiple sets of points, creating separate fits in separate graphs in a for loop. The first iteration of the loop runs fine: the fit is performed and fit parameters are produced. However, on the second iteration of this loop, the program crashes with the error “A breakpoint instruction (__debugbreak() statement or a similar call) was executed in {program}.exe.”. Strangely, this happens AFTER the fit parameters are displayed in debug output the second time.

My code is below. Some sample data is manually entered, the same for each iteration, but this happens still when the data is different for each iteration.

struct GaussianResult
{
    double centroid;
    double amplitude;
    double width;
    double chisq;
};

GaussianResult GaussianFitErrorGraph(std::vector<double> xData, std::vector<double> yData, std::vector<double> yError, double resolution, int sequenceNumber)
{
    int nPoints = yData.size();
    std::string graphName = "hist" + std::to_string( sequenceNumber );
    TGraphErrors* graph = new TGraphErrors();
    for( int i = 0; i < nPoints; ++i )
    {
        graph->SetPoint( i, xData[ i ], yData[ i ] );
        graph->SetPointError( i, 1, yError[i] );
    }
    std::string fitFuncName = "fitFunc" + std::to_string( sequenceNumber );
    TF1* fitFunc = new TF1( fitFuncName.c_str(), "gaus", 0.0, xData.size() );
    graph->Fit( fitFunc );//Always crashes here the second time.
    double centroid = fitFunc->GetParameter( 1 );
    double width = fitFunc->GetParameter( 2 );
    double magnitude = fitFunc->GetParameter( 0 );
    double chiSquare = fitFunc->GetChisquare();
    double nDF = fitFunc->GetNDF();
    double reducedChiSquare = chiSquare / nDF;
    GaussianResult result { centroid, magnitude, width, reducedChiSquare };
    delete fitFunc;
    delete graph;
    return result;

}
int main()
{
    {
        int j = 0;
        while(j < 10)
        {
            std::vector<double> intensities1 { 34.000000000000000,	35.000000000000000,	38.000000000000000,	40.000000000000000,	35.000000000000000,	37.000000000000000,	41.000000000000000,	49.000000000000000,	56.000000000000000,	132.00000000000000,	179.00000000000000,	181.00000000000000,	187.00000000000000,	190.00000000000000,	193.00000000000000,	191.00000000000000,	193.00000000000000,	196.00000000000000,	192.00000000000000 };
            std::vector<double> contrasts1, contrasts2, xs, yErrors;
            for( int i = 0; i < intensities1.size() - 1; i++ )
            {
                contrasts1.push_back( intensities1[ i + 1 ] - intensities1[ i ] );
                yErrors.push_back( sqrt( intensities1[ i + 1 ] + intensities1[ i ] ) );
                xs.push_back( i );
            }
            GaussianResult oneResult = GaussianFitErrorGraph( xs, contrasts1, yErrors, 1.0, j );
            j++;
        }
    }
}

ROOT Version: root_v6.30.04.win64.vc17
Platform: Windows 10
Compiler: Visual Studio 2022


Hi, I cannot reproduce the problem with ROOT master:

C:\root-dev\rootdev>root test_main.C
   ------------------------------------------------------------------
  | Welcome to ROOT 6.31/01                        https://root.cern |
  | (c) 1995-2024, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for win64 on Mar 13 2024, 12:06:07                         |
  | From heads/master@v6-31-01-1412-gf134061a63                      |
  | With MSVC 19.39.33522.0                                          |
  | Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q'  |
   ------------------------------------------------------------------

root [0]
Processing test_main.C...
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
 FCN=1.38051 FROM MIGRAD    STATUS=CONVERGED      84 CALLS          85 TOTAL
                     EDM=6.15973e-08    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     7.66963e+01   1.72721e+01   1.21760e-02  -1.62001e-05
   2  Mean         8.08975e+00   6.25011e-01   3.94611e-04  -2.43275e-04
   3  Sigma        8.52397e-01   3.29593e-01   6.07814e-05   1.40279e-03
root [1]

Could it be a problem with the Windows/Visual Studio version?

I’ll try with v6.30.04 and I’ll let you know

When I try running TMinuit on its own in this loop in the same environment it works fine.

The following code works perfectly, performing a fit for each image loaded:

namespace TrendStatistics
{
//globals
    Int_t s_NPoints;
    std::vector<double> s_DataY, s_DataX, s_DataErrY;
  class TrendStatistics
  {
  public: 
      void Fit();
  };
    static Double_t Gauss( Double_t* x, Double_t* par )
    {
        return par[ 0 ] * exp( -0.5 * pow( ( x[ 0 ] - par[ 1 ] ) / par[ 2 ], 2 ) );
    }
    static void Chi2( Int_t& npar, Double_t* gin, Double_t& f, Double_t* par, Int_t flag )
    {
        Double_t chi2 = 0;
        for( Int_t i = 0; i < s_NPoints; ++i )
        {
            Double_t residual = ( s_DataY[ i ] - Gauss( &s_DataX[ i ], par ) ) / s_DataErrY[ i ];
            chi2 += residual * residual;
        }
        f = chi2;
    }

    std::vector<double> TrendStatistics::RowFromImage( int rowToExtract, int startCol, int endCol, cv::Mat& image )
    {
        std::vector<double> oneRow;
        cv::Rect roi( startCol, rowToExtract, endCol - startCol + 1, 1 );
        cv::Mat rowPortion = image( roi );
        for( int i = 0; i < rowPortion.cols; i++ )
        {
            double intensity = static_cast< double >( rowPortion.at<uchar>( 0, i ) );
            oneRow.push_back( intensity );
        }
        return oneRow;
    }

    void TrendStatistics::Fit()
    {
            std::string folder = "test_squares";
            int rowToExtract1 = 135;
            int rowToExtract2 = 608;
            int startCol = 182;
            int endCol = 200;
            int j = 0;
            
            for( auto& file : Utilities::DirectoryRecursiveIterator( folder ) )
            {

                    

                    std::string filename = file.path().filename().string();
                    cv::Mat image = cv::imread( file.path().string(), cv::IMREAD_GRAYSCALE );
                    std::vector<double> intensities1 = RowFromImage( rowToExtract1, startCol, endCol, image );
                    s_NPoints = 0;
                    for( int i = 0; i < intensities1.size() - 1; i++ )
                    {
                        s_DataY.push_back( intensities1[ i + 1 ] - intensities1[ i ] );
                        s_DataErrY.push_back( sqrt( intensities1[ i + 1 ] + intensities1[ i ] ) );
                        s_DataX.push_back( i );
                        s_NPoints++;
                    }
                    TMinuit* minuit = new TMinuit( 3 );
                    minuit->SetFCN( Chi2 );
                    std::vector<double>::iterator maxAmplitudeLocation = std::max_element( s_DataY.begin(), s_DataY.end() );
                    double meanGuess = std::distance( s_DataY.begin(), maxAmplitudeLocation );
                    double amplitudeGuess = *maxAmplitudeLocation;
                    minuit->DefineParameter( 0, "Amplitude", amplitudeGuess, 0.01, 0, 100 );
                    minuit->DefineParameter( 1, "Mean", meanGuess, 0.01, -100, 100 );
                    minuit->DefineParameter( 2, "Sigma", 5, 0.01, 0, 20 );
                    minuit->Command( "MIGRAD" );
                    delete minuit;
                    s_DataY.clear();
                    s_DataErrY.clear();
                    s_DataX.clear();
                    std::cout << std::endl << std::endl << std::endl;
             
                j++;


            }      
    }
}
int main()
{
    TrendStatistics trendStatistics;
    trendStatistics.Fit();
    return 0;
}

So I just tried with ROOT master and ROOT v6.30.04, with Visual Studio v17.9.3 (x64) and even Visual Studio v16.11.34 (x86), both interpreted and compiled, without any problem. So my question is: do you compile your code, and if yes, how? Can you make sure to use the proper compiler flags? E.g.:

cl -nologo -O2 -MD -GR -EHsc -Zc:__cplusplus -std:c++17 multivac.cxx -I %ROOTSYS%\include /link -LIBPATH:%ROOTSYS%\lib libCore.lib libHist.lib libGraf.lib

It works now!

It seems the problem is that I was linking to too many of ROOT’s dependencies, since I wasn’t able to find documentation about which lib files should be linked to. When I link to libCore.lib libHist.lib libGraf.lib libGpad.lib ONLY the program runs as expected.

Thank you for your help.

1 Like

That’s weird. Linking against all libraries should not matter, since the linker only use the required ones. Anyway, FYI, the library needed by a given class is mentioned at the bottom of the page of each class in the reference guide. E.g. look at the bottom of the TF1 Class Reference

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.