Dear @bvonhall, @pkonopka, @shahoian, all,
in the CPV pedestal QC task I try to perform a parallel fitting of set of histograms.
Let’s say I have 23040 TH1 histos to 1) search peaks and 2) fit with gauss.
In the PedestalTask.h I have:
class PedestalTask:
...
private:
std::array<TH1F*, kNChannels> mHistAmplitudes;
In the PedestalTask.cxx I try to do following:
void PedestalTask::fillHistograms()
{
...
auto lambdaHistoFitter = [this] (int iStartChannel, int nChannels) {
TSpectrum* peakSearcher = new TSpectrum(5);
int numberOfPeaks;
double *xPeaks, yPeaks[5];
...
for (int channel = iStartChannel;
(channel < iStartChannel + nChannels) && (channel < kNChannels);
channel++) {
numberOfPeaks = peakSearcher->Search(mHistAmplitudes[channel], 10., "nobackground", 0.2);
xPeaks = peakSearcher->GetPositionX();
if (numberOfPeaks == 1) {
TF1* functionGaus = new TF1(Form("functionGaus%d",channel), "gaus", 0., 4095.);
yPeaks[0] = mHistAmplitudes[channel]
->GetBinContent(mHistAmplitudes[channel]->GetXaxis()->FindBin(xPeaks[0]));
functionGaus->SetParameters(yPeaks[0], xPeaks[0], 2.);
mHistAmplitudes[channel]->Fit(functionGaus, "WWQ0", "", xPeaks[0] - 20., xPeaks[0] + 20.);
}
...
};
//create fitting threads
std::vector<std::thread> fitThreads;
for (int iTh = 0; iTh < 3; iTh++) {
fitThreads.push_back(std::thread(lambdaHistoFitter, iTh * 7680, 7680));
}
//wait until all threads finished
for (auto& t : fitThreads) {
t.join();
}
}
and this code fails always with different errors like
*** Break *** segmentation violation
or like some other errors saying problems in TFormula or in fortran’s minuit or whatever you want.
If I run everything in 1 thread then all is fine. I assume that the program is not thread-safe and every time I obtain random error due to incorrect access of common memory by the threads.
Any tips how to prepare thread-safe code are very welcome.
The problem is not supercritical for me, and there are ways to overcome this problem without threading. It’s more for my curiosity.
Thank you!