145 size_t numberOfTests;
164 "douplets of signal and background histograms and doublets of signal and background nuisances, \n"
165 <<
"\teach of which defined by <file name>:<histogram name> and <type> (values), respectively, \n"
166 <<
"\twhere <type> can be:" << get_keys(nuisance_helper));
169 zap[
'b'] =
make_field(Fb,
"background strength") = 1.0;
170 zap[
'n'] =
make_field(numberOfTests,
"number of tests");
171 zap[
'M'] =
make_field(M,
"lookup table for CDFs") = 0;
172 zap[
'R'] =
make_field(SNR,
"signal-to-noise ratio") = 0.0;
173 zap[
'A'] =
make_field(add,
"add remnant signal and noise");
174 zap[
'x'] =
make_field(X,
"x-axis likelihood histogram") = histogram_type(110, -10.0, +100.0);
175 zap[
'Q'] =
make_field(Q,
"minimal likelihood ratio") = 0.0;
176 zap[
'P'] =
make_field(P,
"maximal probability") = 0.0;
182 catch(
const exception& error) {
183 FATAL(error.what() << endl);
189 JExperiment::setSNR(SNR);
194 for (
const auto& i : setup) {
196 const TObject* pS = getObject(i.HS);
197 const TObject* pB = getObject(i.HB);
198 const TObject* ps = getObject(i.Hs);
199 const TObject* pb = getObject(i.Hb);
205 STATUS(printer(
"Signal for generation: ", pS) << endl);
206 STATUS(printer(
"Background for generation:", pB) << endl);
207 STATUS(printer(
"Signal for evaluation: ", ps) << endl);
208 STATUS(printer(
"Background for evaluation:", pb) << endl);
225 STATUS(
"Number of tests: " << setw(10) << numberOfTests << endl);
227 if (
debug >= debug_t) {
228 for (
size_t i = 0; i != px.size(); ++i) {
229 cout << setw(2) << i <<
' ' << px[i].nuisance.signal <<
' ' << px[i].nuisance.background << endl;
237 TH1D hl(
"hl", NULL, X.getNumberOfBins(), X.getLowerLimit(), X.getUpperLimit());
238 TH1D hn(
"hn", NULL, 100, -15.0, +15.0);
241 if (P > 0.0 && Q > 0.0) {
243 const chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
245 const double signal = discovery<float, 100>(px, Q, P, numberOfTests);
247 const chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
249 STATUS(
"Total time: " << setw(8) << (t1 - t0) / chrono::milliseconds(1) <<
" [ms]" << endl);
251 cout <<
"Signal strength: " <<
FIXED(9,5) << signal << endl;
253 }
else if (P > 0.0 || Q > 0.0) {
258 const chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
260 for (
size_t i = 0; i != numberOfTests; ++i) {
261 storage.
put(px().likelihood);
264 const chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
266 STATUS(
"Average time: " << setw(6) << (t1 - t0) / chrono::nanoseconds(numberOfTests) <<
" [ns]" << endl);
269 storage([&hl](
const data_type x) { hl.Fill(x); });
275 const chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
287 const chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
289 STATUS(
"Time to result: " << setw(6) << (t1 - t0) / chrono::microseconds(1) <<
" [us]" << endl);
292 if (P > 0.0) { cout <<
"Minimal likelihood ratio: " <<
FIXED(9,5) << x <<
' ' <<
SCIENTIFIC(12,3) << p << endl; }
293 if (Q > 0.0) { cout <<
"Maximal probability: " <<
SCIENTIFIC(12,3) << p <<
' ' <<
FIXED(9,5) << x << endl; }
295 }
else if (numberOfTests != 0) {
299 const chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
303 const chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
305 STATUS(
"Average time: " << setw(6) << (t1 - t0) / chrono::nanoseconds(storage.size()) <<
" [ns]" << endl);
307 for (
const auto& result : storage) {
310 << setw(3) << result.ns <<
' '
311 << setw(3) << result.nb <<
' '
312 <<
FIXED(12,5) << result.likelihood <<
' '
313 <<
FIXED(12,5) << result.signal << endl);
315 hl.Fill(result.likelihood);
316 hn.Fill(result.signal - result.ns);