134 const
Double_t TMVA::MethodCuts::fgMaxAbsCutVal = 1.0e30;
139 TMVA::MethodCuts::MethodCuts( const
TString& jobName,
141 DataSetInfo& theData,
144 MethodBase( jobName, Types::kCuts, methodTitle, theData, theOption, theTargetDir ),
145 fFitMethod ( kUseGeneticAlgorithm ),
146 fEffMethod ( kUseEventSelection ),
171 fVarHistS_smooth( 0 ),
172 fVarHistB_smooth( 0 ),
186 fFitMethod ( kUseGeneticAlgorithm ),
187 fEffMethod ( kUseEventSelection ),
212 fVarHistS_smooth( 0 ),
213 fVarHistB_smooth( 0 ),
234 fVarHistS = fVarHistB = 0;
235 fVarHistS_smooth = fVarHistB_smooth = 0;
236 fVarPdfS = fVarPdfB = 0;
238 fBinaryTreeS = fBinaryTreeB = 0;
244 fRangeSign =
new std::vector<Int_t> ( GetNvar() );
245 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) (*fRangeSign)[ivar] = +1;
247 fMeanS =
new std::vector<Double_t>( GetNvar() );
248 fMeanB =
new std::vector<Double_t>( GetNvar() );
249 fRmsS =
new std::vector<Double_t>( GetNvar() );
250 fRmsB =
new std::vector<Double_t>( GetNvar() );
253 fFitParams =
new std::vector<EFitParameters>( GetNvar() );
254 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) (*fFitParams)[ivar] = kNotEnforced;
256 fFitMethod = kUseMonteCarlo;
262 for (
UInt_t i=0; i<GetNvar(); i++) {
268 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
269 for (
Int_t ibin=0; ibin<fNbins; ibin++) {
270 fCutMin[ivar][ibin] = 0;
271 fCutMax[ivar][ibin] = 0;
275 fTmpCutMin =
new Double_t[GetNvar()];
276 fTmpCutMax =
new Double_t[GetNvar()];
290 delete fEffBvsSLocal;
292 if (
NULL != fCutRangeMin)
delete [] fCutRangeMin;
293 if (
NULL != fCutRangeMax)
delete [] fCutRangeMax;
294 if (
NULL != fAllVarsI)
delete [] fAllVarsI;
296 for (
UInt_t i=0;i<GetNvar();i++) {
297 if (
NULL != fCutMin[i] )
delete [] fCutMin[i];
298 if (
NULL != fCutMax[i] )
delete [] fCutMax[i];
299 if (
NULL != fCutRange[i])
delete fCutRange[i];
302 if (
NULL != fCutMin)
delete [] fCutMin;
303 if (
NULL != fCutMax)
delete [] fCutMax;
305 if (
NULL != fTmpCutMin)
delete [] fTmpCutMin;
306 if (
NULL != fTmpCutMax)
delete [] fTmpCutMax;
308 if (
NULL != fBinaryTreeS)
delete fBinaryTreeS;
309 if (
NULL != fBinaryTreeB)
delete fBinaryTreeB;
332 DeclareOptionRef(fFitMethodS =
"GA",
"FitMethod",
"Minimisation Method (GA, SA, and MC are the primary methods to be used; the others have been introduced for testing purposes and are depreciated)");
336 AddPreDefVal(
TString(
"MCEvents"));
337 AddPreDefVal(
TString(
"MINUIT"));
338 AddPreDefVal(
TString(
"EventScan"));
341 DeclareOptionRef(fEffMethodS =
"EffSel",
"EffMethod",
"Selection Method");
342 AddPreDefVal(
TString(
"EffSel"));
343 AddPreDefVal(
TString(
"EffPDF"));
346 fCutRange.resize(GetNvar());
347 fCutRangeMin =
new Double_t[GetNvar()];
348 fCutRangeMax =
new Double_t[GetNvar()];
349 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
351 fCutRangeMin[ivar] = fCutRangeMax[ivar] = -1;
354 DeclareOptionRef( fCutRangeMin, GetNvar(),
"CutRangeMin",
"Minimum of allowed cut range (set per variable)" );
355 DeclareOptionRef( fCutRangeMax, GetNvar(),
"CutRangeMax",
"Maximum of allowed cut range (set per variable)" );
357 fAllVarsI =
new TString[GetNvar()];
359 for (
UInt_t i=0; i<GetNvar(); i++) fAllVarsI[i] =
"NotEnforced";
361 DeclareOptionRef(fAllVarsI, GetNvar(),
"VarProp",
"Categorisation of cuts");
362 AddPreDefVal(
TString(
"NotEnforced"));
365 AddPreDefVal(
TString(
"FSmart"));
375 if (IsNormalised()) {
376 Log() <<
kWARNING <<
"Normalisation of the input variables for cut optimisation is not" <<
Endl;
377 Log() <<
kWARNING <<
"supported because this provides intransparent cut values, and no" <<
Endl;
378 Log() <<
kWARNING <<
"improvement in the performance of the algorithm." <<
Endl;
379 Log() <<
kWARNING <<
"Please remove \"Normalise\" option from booking option string" <<
Endl;
380 Log() <<
kWARNING <<
"==> Will reset normalisation flag to \"False\"" <<
Endl;
384 if (IgnoreEventsWithNegWeightsInTraining()) {
385 Log() <<
kFATAL <<
"Mechanism to ignore events with negative weights in training not yet available for method: "
386 << GetMethodTypeName()
387 <<
" --> Please remove \"IgnoreNegWeightsInTraining\" option from booking string."
391 if (fFitMethodS ==
"MC" ) fFitMethod = kUseMonteCarlo;
392 else if (fFitMethodS ==
"MCEvents") fFitMethod = kUseMonteCarloEvents;
393 else if (fFitMethodS ==
"GA" ) fFitMethod = kUseGeneticAlgorithm;
394 else if (fFitMethodS ==
"SA" ) fFitMethod = kUseSimulatedAnnealing;
395 else if (fFitMethodS ==
"MINUIT" ) {
396 fFitMethod = kUseMinuit;
397 Log() <<
kWARNING <<
"poor performance of MINUIT in MethodCuts; preferred fit method: GA" <<
Endl;
399 else if (fFitMethodS ==
"EventScan" ) fFitMethod = kUseEventScan;
400 else Log() <<
kFATAL <<
"unknown minimisation method: " << fFitMethodS <<
Endl;
402 if (fEffMethodS ==
"EFFSEL" ) fEffMethod = kUseEventSelection;
403 else if (fEffMethodS ==
"EFFPDF" ) fEffMethod = kUsePDFs;
404 else fEffMethod = kUseEventSelection;
407 Log() <<
kINFO <<
Form(
"Use optimization method: \"%s\"",
408 (fFitMethod == kUseMonteCarlo) ?
"Monte Carlo" :
409 (fFitMethod == kUseMonteCarlo) ?
"Monte-Carlo-Event sampling" :
410 (fFitMethod == kUseEventScan) ?
"Full Event Scan (slow)" :
411 (fFitMethod == kUseMinuit) ?
"MINUIT" :
"Genetic Algorithm" ) <<
Endl;
412 Log() <<
kINFO <<
Form(
"Use efficiency computation method: \"%s\"",
413 (fEffMethod == kUseEventSelection) ?
"Event Selection" :
"PDF" ) <<
Endl;
416 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
417 fCutRange[ivar] =
new Interval( fCutRangeMin[ivar], fCutRangeMax[ivar] );
421 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
423 if (fAllVarsI[ivar] ==
"" || fAllVarsI[ivar] ==
"NotEnforced") theFitP = kNotEnforced;
424 else if (fAllVarsI[ivar] ==
"FMax" ) theFitP = kForceMax;
425 else if (fAllVarsI[ivar] ==
"FMin" ) theFitP = kForceMin;
426 else if (fAllVarsI[ivar] ==
"FSmart" ) theFitP = kForceSmart;
428 Log() <<
kFATAL <<
"unknown value \'" << fAllVarsI[ivar]
429 <<
"\' for fit parameter option " <<
Form(
"VarProp[%i]",ivar) <<
Endl;
431 (*fFitParams)[ivar] = theFitP;
433 if (theFitP != kNotEnforced)
434 Log() <<
kINFO <<
"Use \"" << fAllVarsI[ivar]
435 <<
"\" cuts for variable: " <<
"'" << (*fInputVars)[ivar] <<
"'" <<
Endl;
445 NoErrorCalc(err, errUpper);
448 if (fCutMin ==
NULL || fCutMax ==
NULL || fNbins == 0) {
449 Log() <<
kFATAL <<
"<Eval_Cuts> fCutMin/Max have zero pointer. "
450 <<
"Did you book Cuts ?" <<
Endl;
453 const Event* ev = GetEvent();
456 if (fTestSignalEff > 0) {
458 Int_t ibin = fEffBvsSLocal->FindBin( fTestSignalEff );
459 if (ibin < 0 ) ibin = 0;
460 else if (ibin >= fNbins) ibin = fNbins - 1;
463 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++)
464 passed &= ( (ev->
GetValue(ivar) > fCutMin[ivar][ibin]) &&
465 (ev->
GetValue(ivar) <= fCutMax[ivar][ibin]) );
467 return passed ? 1. : 0. ;
477 std::vector<Double_t> cutsMin;
478 std::vector<Double_t> cutsMax;
479 Int_t ibin = fEffBvsSLocal->FindBin( effS );
481 Double_t trueEffS = GetCuts( effS, cutsMin, cutsMax );
484 std::vector<TString>* varVec = 0;
485 if (GetTransformationHandler().GetNumOfTransformations() == 0) {
487 varVec =
new std::vector<TString>;
488 for (
UInt_t ivar=0; ivar<cutsMin.size(); ivar++) {
489 varVec->push_back( DataInfo().GetVariableInfo(ivar).GetLabel() );
492 else if (GetTransformationHandler().GetNumOfTransformations() == 1) {
494 varVec = GetTransformationHandler().GetTransformationStringsOfLastTransform();
498 varVec =
new std::vector<TString>;
499 for (
UInt_t ivar=0; ivar<cutsMin.size(); ivar++) {
500 varVec->push_back( DataInfo().GetVariableInfo(ivar).GetLabel() +
" [transformed]" );
505 for (
UInt_t ivar=0; ivar<cutsMin.size(); ivar++) {
506 if ((
UInt_t)(*varVec)[ivar].Length() > maxL) maxL = (*varVec)[ivar].Length();
508 UInt_t maxLine = 20+maxL+16;
510 for (
UInt_t i=0; i<maxLine; i++)
Log() <<
"-";
512 Log() <<
kINFO <<
"Cut values for requested signal efficiency: " << trueEffS <<
Endl;
513 Log() <<
kINFO <<
"Corresponding background efficiency : " << fEffBvsSLocal->GetBinContent( ibin ) <<
Endl;
514 if (GetTransformationHandler().GetNumOfTransformations() == 1) {
515 Log() <<
kINFO <<
"Transformation applied to input variables : \""
516 << GetTransformationHandler().GetNameOfLastTransform() <<
"\"" <<
Endl;
518 else if (GetTransformationHandler().GetNumOfTransformations() > 1) {
519 Log() <<
kINFO <<
"[ More than one (=" << GetTransformationHandler().GetNumOfTransformations() <<
") "
520 <<
" transformations applied in transformation chain; cuts applied on transformed quantities ] " <<
Endl;
523 Log() <<
kINFO <<
"Transformation applied to input variables : None" <<
Endl;
525 for (
UInt_t i=0; i<maxLine; i++)
Log() <<
"-";
527 for (
UInt_t ivar=0; ivar<cutsMin.size(); ivar++) {
529 <<
"Cut[" << std::setw(2) << ivar <<
"]: "
530 << std::setw(10) << cutsMin[ivar]
532 << std::setw(maxL) << (*varVec)[ivar]
534 << std::setw(10) << cutsMax[ivar] <<
Endl;
536 for (
UInt_t i=0; i<maxLine; i++)
Log() <<
"-";
548 std::vector<Double_t> cMin( GetNvar() );
549 std::vector<Double_t> cMax( GetNvar() );
550 Double_t trueEffS = GetCuts( effS, cMin, cMax );
551 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
552 cutMin[ivar] = cMin[ivar];
553 cutMax[ivar] = cMax[ivar];
562 std::vector<Double_t>& cutMin,
563 std::vector<Double_t>& cutMax )
const
566 Int_t ibin = fEffBvsSLocal->FindBin( effS );
569 Double_t trueEffS = fEffBvsSLocal->GetBinLowEdge( ibin );
572 if (ibin < 0 ) ibin = 0;
573 else if (ibin >= fNbins) ibin = fNbins - 1;
577 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
578 cutMin.push_back( fCutMin[ivar][ibin] );
579 cutMax.push_back( fCutMax[ivar][ibin] );
590 if (fEffMethod == kUsePDFs) CreateVariablePDFs();
593 if (fBinaryTreeS != 0) {
delete fBinaryTreeS; fBinaryTreeS = 0; }
594 if (fBinaryTreeB != 0) {
delete fBinaryTreeB; fBinaryTreeB = 0; }
603 fBinaryTreeB->Fill( GetEventCollection(
Types::kTraining), fBackgroundClass );
605 for (
UInt_t ivar =0; ivar <
Data()->GetNVariables(); ivar++) {
622 if (
TMath::Abs(fCutRange[ivar]->GetMin() - fCutRange[ivar]->GetMax()) < 1.0e-300 ) {
623 fCutRange[ivar]->SetMin( xmin );
624 fCutRange[ivar]->SetMax( xmax );
626 else if (xmin > fCutRange[ivar]->GetMin()) fCutRange[ivar]->SetMin( xmin );
627 else if (xmax < fCutRange[ivar]->GetMax()) fCutRange[ivar]->SetMax( xmax );
630 std::vector<TH1F*> signalDist, bkgDist;
633 delete fEffBvsSLocal;
634 fEffBvsSLocal =
new TH1F( GetTestvarName() +
"_effBvsSLocal",
635 TString(GetName()) +
" efficiency of B vs S", fNbins, 0.0, 1.0 );
636 fEffBvsSLocal->SetDirectory(0);
639 for (
Int_t ibin=1; ibin<=fNbins; ibin++) fEffBvsSLocal->SetBinContent( ibin, -0.1 );
642 if (fFitMethod == kUseGeneticAlgorithm ||
643 fFitMethod == kUseMonteCarlo ||
644 fFitMethod == kUseMinuit ||
645 fFitMethod == kUseSimulatedAnnealing) {
648 std::vector<Interval*> ranges;
650 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
653 if (DataInfo().GetVariableInfo(ivar).GetVarType() ==
'I') {
654 nbins =
Int_t(fCutRange[ivar]->GetMax() - fCutRange[ivar]->GetMin()) + 1;
657 if ((*fFitParams)[ivar] == kForceSmart) {
658 if ((*fMeanS)[ivar] > (*fMeanB)[ivar]) (*fFitParams)[ivar] = kForceMax;
659 else (*fFitParams)[ivar] = kForceMin;
662 if ((*fFitParams)[ivar] == kForceMin) {
663 ranges.push_back(
new Interval( fCutRange[ivar]->GetMin(), fCutRange[ivar]->GetMin(), nbins ) );
664 ranges.push_back(
new Interval( 0, fCutRange[ivar]->GetMax() - fCutRange[ivar]->GetMin(), nbins ) );
666 else if ((*fFitParams)[ivar] == kForceMax) {
667 ranges.push_back(
new Interval( fCutRange[ivar]->GetMin(), fCutRange[ivar]->GetMax(), nbins ) );
668 ranges.push_back(
new Interval( fCutRange[ivar]->GetMax() - fCutRange[ivar]->GetMin(),
669 fCutRange[ivar]->GetMax() - fCutRange[ivar]->GetMin(), nbins ) );
672 ranges.push_back(
new Interval( fCutRange[ivar]->GetMin(), fCutRange[ivar]->GetMax(), nbins ) );
673 ranges.push_back(
new Interval( 0, fCutRange[ivar]->GetMax() - fCutRange[ivar]->GetMin(), nbins ) );
680 switch (fFitMethod) {
681 case kUseGeneticAlgorithm:
682 fitter =
new GeneticFitter( *
this,
Form(
"%sFitter_GA", GetName()), ranges, GetOptions() );
685 fitter =
new MCFitter ( *
this,
Form(
"%sFitter_MC", GetName()), ranges, GetOptions() );
688 fitter =
new MinuitFitter ( *
this,
Form(
"%sFitter_MINUIT", GetName()), ranges, GetOptions() );
690 case kUseSimulatedAnnealing:
694 Log() <<
kFATAL <<
"Wrong fit method: " << fFitMethod <<
Endl;
703 for (
UInt_t ivar=0; ivar<ranges.size(); ivar++)
delete ranges[ivar];
708 else if (fFitMethod == kUseEventScan) {
714 Int_t nsamples =
Int_t(0.5*nevents*(nevents - 1));
718 for (
Int_t ievt1=0; ievt1<nevents; ievt1++) {
719 for (
Int_t ievt2=ievt1+1; ievt2<nevents; ievt2++) {
721 EstimatorFunction( ievt1, ievt2 );
730 else if (fFitMethod == kUseMonteCarloEvents) {
732 Int_t nsamples = 200000;
734 DeclareOptionRef( nsamples,
"SampleSize",
"Number of Monte-Carlo-Event samples" );
735 DeclareOptionRef( seed,
"Seed",
"Seed for the random generator (0 takes random seeds)" );
747 Log() <<
kINFO <<
"Running Monte-Carlo-Event sampling over " << nsamples <<
" events" <<
Endl;
748 std::vector<Double_t> pars( 2*GetNvar() );
750 for (
Int_t itoy=0; itoy<nsamples; itoy++) {
752 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
765 const Event *ev1 = GetEvent(ievt1);
766 isSignal = DataInfo().IsSignal(ev1);
767 evt1 = ev1->GetValue( ivar );
769 const Event *ev2 = GetEvent(ievt2);
770 isSignal &= DataInfo().IsSignal(ev2);
773 if (nbreak++ > 10000)
Log() <<
kFATAL <<
"<MCEvents>: could not find signal events"
774 <<
" after 10000 trials - do you have signal events in your sample ?"
780 if (evt1 > evt2) {
Double_t z = evt1; evt1 = evt2; evt2 =
z; }
782 pars[2*ivar+1] = evt2 - evt1;
786 EstimatorFunction( pars );
796 else Log() <<
kFATAL <<
"Unknown minimisation method: " << fFitMethod <<
Endl;
798 if (fBinaryTreeS != 0) {
delete fBinaryTreeS; fBinaryTreeS = 0; }
799 if (fBinaryTreeB != 0) {
delete fBinaryTreeB; fBinaryTreeB = 0; }
802 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
803 for (
Int_t ibin=0; ibin<fNbins; ibin++) {
805 if ((*fFitParams)[ivar] == kForceMin && fCutMin[ivar][ibin] > -fgMaxAbsCutVal) {
806 fCutMin[ivar][ibin] = -fgMaxAbsCutVal;
808 if ((*fFitParams)[ivar] == kForceMax && fCutMax[ivar][ibin] < fgMaxAbsCutVal) {
809 fCutMax[ivar][ibin] = fgMaxAbsCutVal;
818 for (
Double_t eff=0.1; eff<0.95; eff += 0.1) PrintCuts( eff+epsilon );
833 const Event *ev1 = GetEvent(ievt1);
834 if (!DataInfo().IsSignal(ev1))
return -1;
836 const Event *ev2 = GetEvent(ievt2);
837 if (!DataInfo().IsSignal(ev2))
return -1;
839 const Int_t nvar = GetNvar();
843 for (
Int_t ivar=0; ivar<nvar; ivar++) {
849 std::vector<Double_t> pars;
850 for (
Int_t ivar=0; ivar<nvar; ivar++) {
853 if (evt1[ivar] < evt2[ivar]) {
862 pars.push_back( cutMin );
863 pars.push_back( cutMax - cutMin );
869 return ComputeEstimator( pars );
877 return ComputeEstimator( pars );
895 this->MatchParsToCuts( pars, &fTmpCutMin[0], &fTmpCutMax[0] );
898 switch (fEffMethod) {
900 this->GetEffsfromPDFs (&fTmpCutMin[0], &fTmpCutMax[0], effS, effB);
902 case kUseEventSelection:
903 this->GetEffsfromSelection (&fTmpCutMin[0], &fTmpCutMax[0], effS, effB);
906 this->GetEffsfromSelection (&fTmpCutMin[0], &fTmpCutMax[0], effS, effB);
917 Int_t ibinS = fEffBvsSLocal->FindBin( effS );
919 Double_t effBH = fEffBvsSLocal->GetBinContent( ibinS );
920 Double_t effBH_left = (ibinS > 1 ) ? fEffBvsSLocal->GetBinContent( ibinS-1 ) : effBH;
921 Double_t effBH_right = (ibinS < fNbins) ? fEffBvsSLocal->GetBinContent( ibinS+1 ) : effBH;
923 Double_t average = 0.5*(effBH_left + effBH_right);
924 if (effBH < effB) average = effBH;
928 eta = ( -
TMath::Abs(effBH-average) + (1.0 - (effBH - effB))) / (1.0 + effS);
935 if (effBH < 0 || effBH > effB) {
936 fEffBvsSLocal->SetBinContent( ibinS, effB );
937 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
938 fCutMin[ivar][ibinS-1] = fTmpCutMin[ivar];
939 fCutMax[ivar][ibinS-1] = fTmpCutMax[ivar];
953 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
954 diff=(fCutRange[ivar]->GetMax()-fTmpCutMax[ivar])/(fCutRange[ivar]->GetMax()-fCutRange[ivar]->GetMin());
956 diff=(fCutRange[ivar]->GetMin()-fTmpCutMin[ivar])/(fCutRange[ivar]->GetMax()-fCutRange[ivar]->GetMin());
957 penalty+=4.*diff*diff;
960 if (effS<1.e-4)
return 10.0+penalty;
961 else return 10.*(1.-10.*effS);
972 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
974 cutMin[ivar] = ((*fRangeSign)[ivar] > 0) ? pars[ipar] : pars[ipar] - pars[ipar+1];
975 cutMax[ivar] = ((*fRangeSign)[ivar] > 0) ? pars[ipar] + pars[ipar+1] : pars[ipar];
985 if (ibin < 1 || ibin > fNbins)
Log() <<
kFATAL <<
"::MatchCutsToPars: bin error: "
988 const UInt_t nvar = GetNvar();
991 for (
UInt_t ivar=0; ivar<nvar; ivar++) {
992 cutMin[ivar] = cutMinAll[ivar][ibin-1];
993 cutMax[ivar] = cutMaxAll[ivar][ibin-1];
996 MatchCutsToPars( pars, cutMin, cutMax );
1007 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
1008 Int_t ipar = 2*ivar;
1009 pars[ipar] = ((*fRangeSign)[ivar] > 0) ? cutMin[ivar] : cutMax[ivar];
1010 pars[ipar+1] = cutMax[ivar] - cutMin[ivar];
1023 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
1024 effS *= (*fVarPdfS)[ivar]->GetIntegral( cutMin[ivar], cutMax[ivar] );
1025 effB *= (*fVarPdfB)[ivar]->GetIntegral( cutMin[ivar], cutMax[ivar] );
1031 if( !fNegEffWarning )
Log() <<
kWARNING <<
"Negative signal efficiency found and set to 0. This is probably due to many events with negative weights in a certain cut-region." <<
Endl;
1032 fNegEffWarning =
kTRUE;
1036 if( !fNegEffWarning )
Log() <<
kWARNING <<
"Negative background efficiency found and set to 0. This is probably due to many events with negative weights in a certain cut-region." <<
Endl;
1037 fNegEffWarning =
kTRUE;
1051 Volume* volume =
new Volume( cutMin, cutMax, GetNvar() );
1054 nSelS = fBinaryTreeS->SearchVolume( volume );
1055 nSelB = fBinaryTreeB->SearchVolume( volume );
1060 nTotS = fBinaryTreeS->GetSumOfWeights();
1061 nTotB = fBinaryTreeB->GetSumOfWeights();
1064 if (nTotS == 0 && nTotB == 0) {
1065 Log() <<
kFATAL <<
"<GetEffsfromSelection> fatal error in zero total number of events:"
1066 <<
" nTotS, nTotB: " << nTotS <<
" " << nTotB <<
" ***" <<
Endl;
1073 Log() <<
kWARNING <<
"<ComputeEstimator> zero number of signal events" <<
Endl;
1075 else if (nTotB == 0) {
1078 Log() <<
kWARNING <<
"<ComputeEstimator> zero number of background events" <<
Endl;
1088 if( !fNegEffWarning )
Log() <<
kWARNING <<
"Negative signal efficiency found and set to 0. This is probably due to many events with negative weights in a certain cut-region." <<
Endl;
1089 fNegEffWarning =
kTRUE;
1093 if( !fNegEffWarning )
Log() <<
kWARNING <<
"Negative background efficiency found and set to 0. This is probably due to many events with negative weights in a certain cut-region." <<
Endl;
1094 fNegEffWarning =
kTRUE;
1104 fVarHistS =
new std::vector<TH1*>( GetNvar() );
1105 fVarHistB =
new std::vector<TH1*>( GetNvar() );
1106 fVarHistS_smooth =
new std::vector<TH1*>( GetNvar() );
1107 fVarHistB_smooth =
new std::vector<TH1*>( GetNvar() );
1108 fVarPdfS =
new std::vector<PDF*>( GetNvar() );
1109 fVarPdfB =
new std::vector<PDF*>( GetNvar() );
1116 for(
UInt_t ievt=0; ievt<
Data()->GetNEvents(); ievt++ ){
1117 const Event *ev = GetEvent(ievt);
1119 if( val > minVal ) minVal = val;
1120 if( val < maxVal ) maxVal = val;
1123 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
1126 TString histTitle = (*fInputVars)[ivar] +
" signal training";
1127 TString histName = (*fInputVars)[ivar] +
"_sig";
1138 (*fVarHistS)[ivar] =
new TH1F(histName.
Data(), histTitle.
Data(), fNbins, minVal, maxVal );
1141 histTitle = (*fInputVars)[ivar] +
" background training";
1142 histName = (*fInputVars)[ivar] +
"_bgd";
1153 (*fVarHistB)[ivar] =
new TH1F(histName.
Data(), histTitle.Data(), fNbins, minVal, maxVal );
1155 for(
UInt_t ievt=0; ievt<
Data()->GetNEvents(); ievt++ ){
1156 const Event *ev = GetEvent(ievt);
1158 if( DataInfo().IsSignal(ev) ){
1159 (*fVarHistS)[ivar]->Fill( val );
1161 (*fVarHistB)[ivar]->Fill( val );
1168 (*fVarHistS_smooth)[ivar] = (
TH1F*)(*fVarHistS)[ivar]->Clone();
1169 histTitle = (*fInputVars)[ivar] +
" signal training smoothed ";
1170 histTitle += nsmooth;
1171 histTitle +=
" times";
1172 histName = (*fInputVars)[ivar] +
"_sig_smooth";
1173 (*fVarHistS_smooth)[ivar]->SetName(histName);
1174 (*fVarHistS_smooth)[ivar]->SetTitle(histTitle);
1177 (*fVarHistS_smooth)[ivar]->Smooth(nsmooth);
1192 (*fVarHistB_smooth)[ivar] = (
TH1F*)(*fVarHistB)[ivar]->
Clone();
1193 histTitle = (*fInputVars)[ivar]+
" background training smoothed ";
1194 histTitle += nsmooth;
1195 histTitle +=
" times";
1196 histName = (*fInputVars)[ivar]+
"_bgd_smooth";
1197 (*fVarHistB_smooth)[ivar]->SetName(histName);
1198 (*fVarHistB_smooth)[ivar]->SetTitle(histTitle);
1201 (*fVarHistB_smooth)[ivar]->Smooth(nsmooth);
1204 (*fVarPdfS)[ivar] =
new PDF(
TString(GetName()) +
" PDF Var Sig " + GetInputVar( ivar ), (*fVarHistS_smooth)[ivar],
PDF::kSpline2 );
1205 (*fVarPdfB)[ivar] =
new PDF(
TString(GetName()) +
" PDF Var Bkg " + GetInputVar( ivar ), (*fVarHistB_smooth)[ivar],
PDF::kSpline2 );
1218 istr >> dummy >>
dummy;
1220 istr >> dummy >> fNbins;
1223 istr >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> dummyInt >>
dummy ;
1226 if (dummyInt !=
Data()->GetNVariables()) {
1227 Log() <<
kFATAL <<
"<ReadWeightsFromStream> fatal error: mismatch "
1228 <<
"in number of variables: " << dummyInt <<
" != " <<
Data()->GetNVariables() <<
Endl;
1233 if (fFitMethod == kUseMonteCarlo) {
1234 Log() <<
kINFO <<
"Read cuts optimised using sample of MC events" <<
Endl;
1236 else if (fFitMethod == kUseMonteCarloEvents) {
1237 Log() <<
kINFO <<
"Read cuts optimised using sample of MC events" <<
Endl;
1239 else if (fFitMethod == kUseGeneticAlgorithm) {
1240 Log() <<
kINFO <<
"Read cuts optimised using Genetic Algorithm" <<
Endl;
1242 else if (fFitMethod == kUseSimulatedAnnealing) {
1243 Log() <<
kINFO <<
"Read cuts optimised using Simulated Annealing algorithm" <<
Endl;
1245 else if (fFitMethod == kUseEventScan) {
1246 Log() <<
kINFO <<
"Read cuts optimised using Full Event Scan" <<
Endl;
1251 Log() <<
kINFO <<
"in " << fNbins <<
" signal efficiency bins and for " << GetNvar() <<
" variables" <<
Endl;
1255 istr.getline(buffer,200);
1256 istr.getline(buffer,200);
1260 if (fEffBvsSLocal != 0)
delete fEffBvsSLocal;
1261 fEffBvsSLocal =
new TH1F( GetTestvarName() +
"_effBvsSLocal",
1262 TString(GetName()) +
" efficiency of B vs S", fNbins, 0.0, 1.0 );
1263 fEffBvsSLocal->SetDirectory(0);
1265 for (
Int_t ibin=0; ibin<fNbins; ibin++) {
1266 istr >> tmpbin >> tmpeffS >> tmpeffB;
1267 fEffBvsSLocal->SetBinContent( ibin+1, tmpeffB );
1269 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
1270 istr >> fCutMin[ivar][ibin] >> fCutMax[ivar][ibin];
1274 fEffSMin = fEffBvsSLocal->GetBinCenter(1);
1275 fEffSMax = fEffBvsSLocal->GetBinCenter(fNbins);
1285 std::vector<Double_t> cutsMin;
1286 std::vector<Double_t> cutsMax;
1292 gTools().
AddComment( wght,
Form(
"Below are the optimised cuts for %i variables: Format: ibin(hist) effS effB cutMin[ivar=0] cutMax[ivar=0] ... cutMin[ivar=n-1] cutMax[ivar=n-1]", GetNvar() ) );
1302 for (
Int_t ibin=0; ibin<fNbins; ibin++) {
1303 Double_t effS = fEffBvsSLocal->GetBinCenter ( ibin + 1 );
1304 Double_t trueEffS = GetCuts( effS, cutsMin, cutsMax );
1305 if (
TMath::Abs(trueEffS) < 1e-10) trueEffS = 0;
1310 gTools().
AddAttr( binxml,
"effB", fEffBvsSLocal->GetBinContent( ibin + 1 ) );
1312 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
1325 for (
UInt_t i=0; i<GetNvar(); i++) {
1326 if (fCutMin[i] != 0)
delete [] fCutMin[i];
1327 if (fCutMax[i] != 0)
delete [] fCutMax[i];
1329 if (fCutMin != 0)
delete [] fCutMin;
1330 if (fCutMax != 0)
delete [] fCutMax;
1332 Int_t tmpEffMethod, tmpFitMethod;
1333 gTools().
ReadAttr( wghtnode,
"OptimisationMethod", tmpEffMethod );
1341 if (fFitMethod == kUseMonteCarlo) {
1342 Log() <<
kINFO <<
"Read cuts optimised using sample of MC events" <<
Endl;
1344 else if (fFitMethod == kUseMonteCarloEvents) {
1345 Log() <<
kINFO <<
"Read cuts optimised using sample of MC-Event events" <<
Endl;
1347 else if (fFitMethod == kUseGeneticAlgorithm) {
1348 Log() <<
kINFO <<
"Read cuts optimised using Genetic Algorithm" <<
Endl;
1350 else if (fFitMethod == kUseSimulatedAnnealing) {
1351 Log() <<
kINFO <<
"Read cuts optimised using Simulated Annealing algorithm" <<
Endl;
1353 else if (fFitMethod == kUseEventScan) {
1354 Log() <<
kINFO <<
"Read cuts optimised using Full Event Scan" <<
Endl;
1359 Log() <<
kINFO <<
"Reading " << fNbins <<
" signal efficiency bins for " << GetNvar() <<
" variables" <<
Endl;
1361 delete fEffBvsSLocal;
1362 fEffBvsSLocal =
new TH1F( GetTestvarName() +
"_effBvsSLocal",
1363 TString(GetName()) +
" efficiency of B vs S", fNbins, 0.0, 1.0 );
1364 fEffBvsSLocal->SetDirectory(0);
1365 for (
Int_t ibin=1; ibin<=fNbins; ibin++) fEffBvsSLocal->SetBinContent( ibin, -0.1 );
1367 fCutMin =
new Double_t*[GetNvar()];
1368 fCutMax =
new Double_t*[GetNvar()];
1369 for (
UInt_t i=0;i<GetNvar();i++) {
1389 if (tmpbin-1 >= fNbins || tmpbin-1 < 0) {
1390 Log() <<
kFATAL <<
"Mismatch in bins: " << tmpbin-1 <<
" >= " << fNbins <<
Endl;
1393 fEffBvsSLocal->SetBinContent( tmpbin, tmpeffB );
1395 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
1408 Log() <<
kINFO <<
"Write monitoring histograms to file: " << BaseDir()->GetPath() <<
Endl;
1410 fEffBvsSLocal->
Write();
1413 if (fEffMethod == kUsePDFs) {
1414 for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
1415 (*fVarHistS)[ivar]->Write();
1416 (*fVarHistB)[ivar]->Write();
1417 (*fVarHistS_smooth)[ivar]->Write();
1418 (*fVarHistB_smooth)[ivar]->Write();
1419 (*fVarPdfS)[ivar]->GetPDFHist()->Write();
1420 (*fVarPdfB)[ivar]->GetPDFHist()->Write();
1442 Log() <<
kFATAL <<
"<GetTrainingEfficiency> wrong number of arguments"
1443 <<
" in string: " << theString
1444 <<
" | required format, e.g., Efficiency:0.05" <<
Endl;
1457 if (results->
GetHist(
"EFF_BVSS_TR")==0) {
1459 if (fBinaryTreeS != 0) {
delete fBinaryTreeS; fBinaryTreeS = 0; }
1460 if (fBinaryTreeB != 0) {
delete fBinaryTreeB; fBinaryTreeB = 0; }
1465 fBinaryTreeB->Fill( GetEventCollection(
Types::kTraining), fBackgroundClass );
1473 TH1* eff_bvss_tr =
new TH1F( GetTestvarName() +
"_trainingEffBvsS", GetTestvarName() +
"", fNbins, 0, 1 );
1475 TH1* rej_bvss_tr =
new TH1F( GetTestvarName() +
"_trainingRejBvsS", GetTestvarName() +
"", fNbins, 0, 1 );
1477 results->
Store(eff_bvss_tr,
"EFF_BVSS_TR");
1478 results->
Store(rej_bvss_tr,
"REJ_BVSS_TR");
1485 Int_t nFailedBins=0;
1486 for (
Int_t bini=1; bini<=fNbins; bini++) {
1487 for (
UInt_t ivar=0; ivar <GetNvar(); ivar++){
1488 tmpCutMin[ivar] = fCutMin[ivar][bini-1];
1489 tmpCutMax[ivar] = fCutMax[ivar][bini-1];
1493 this->GetEffsfromSelection( &tmpCutMin[0], &tmpCutMax[0], effS, effB);
1496 if (effBin != bini){
1497 Log()<<
kVERBOSE <<
"unable to fill efficiency bin " << bini<<
" " << effBin <<
Endl;
1506 if (nFailedBins>0)
Log()<<
kWARNING <<
" unable to fill "<< nFailedBins <<
" efficiency bins " <<
Endl;
1508 delete [] tmpCutMin;
1509 delete [] tmpCutMax;
1512 fSplTrainEffBvsS =
new TSpline1(
"trainEffBvsS",
new TGraph( eff_bvss_tr ) );
1516 if (
NULL == fSplTrainEffBvsS)
return 0.0;
1519 Double_t effS = 0., effB, effS_ = 0., effB_ = 0.;
1520 Int_t nbins_ = 1000;
1523 for (
Int_t bini=1; bini<=nbins_; bini++) {
1525 effS = (bini - 0.5)/
Float_t(nbins_);
1526 effB = fSplTrainEffBvsS->Eval( effS );
1529 if ((effB - effBref)*(effB_ - effBref) < 0)
break;
1534 return 0.5*(effS + effS_);
1550 Data()->SetCurrentType(type);
1559 Log() <<
kFATAL <<
"<GetEfficiency> wrong number of arguments"
1560 <<
" in string: " << theString
1561 <<
" | required format, e.g., Efficiency:0.05, or empty string" <<
Endl;
1576 if (results->
GetHist(
"MVA_EFF_BvsS")==0) {
1578 if (fBinaryTreeS!=0) {
delete fBinaryTreeS; fBinaryTreeS = 0; }
1579 if (fBinaryTreeB!=0) {
delete fBinaryTreeB; fBinaryTreeB = 0; }
1585 fBinaryTreeS->Fill( GetEventCollection(
Types::kTesting), fSignalClass );
1587 fBinaryTreeB->Fill( GetEventCollection(
Types::kTesting), fBackgroundClass );
1596 TH1* eff_BvsS =
new TH1F( GetTestvarName() +
"_effBvsS", GetTestvarName() +
"", fNbins, 0, 1 );
1598 TH1* rej_BvsS =
new TH1F( GetTestvarName() +
"_rejBvsS", GetTestvarName() +
"", fNbins, 0, 1 );
1600 results->
Store(eff_BvsS,
"MVA_EFF_BvsS");
1601 results->
Store(rej_BvsS);
1606 TH1* eff_s =
new TH1F( GetTestvarName() +
"_effS", GetTestvarName() +
" (signal)", fNbins, xmin, xmax);
1608 TH1* eff_b =
new TH1F( GetTestvarName() +
"_effB", GetTestvarName() +
" (background)", fNbins, xmin, xmax);
1610 results->
Store(eff_s,
"MVA_S");
1611 results->
Store(eff_b,
"MVA_B");
1621 for (
Int_t bini=1; bini<=fNbins; bini++) {
1622 for (
UInt_t ivar=0; ivar <GetNvar(); ivar++) {
1623 tmpCutMin[ivar] = fCutMin[ivar][bini-1];
1624 tmpCutMax[ivar] = fCutMax[ivar][bini-1];
1628 this->GetEffsfromSelection( &tmpCutMin[0], &tmpCutMax[0], effS, effB);
1629 tmpBvsS->
SetPoint(bini, effS, effB);
1634 tmpBvsS->
SetPoint(fNbins+1, 1., 1.);
1636 delete [] tmpCutMin;
1637 delete [] tmpCutMax;
1640 fSpleffBvsS =
new TSpline1(
"effBvsS", tmpBvsS );
1641 for (
Int_t bini=1; bini<=fNbins; bini++) {
1643 Double_t effB = fSpleffBvsS->Eval( effS );
1650 if (
NULL == fSpleffBvsS)
return 0.0;
1653 Double_t effS = 0, effB = 0, effS_ = 0, effB_ = 0;
1654 Int_t nbins_ = 1000;
1660 for (
Int_t bini=1; bini<=nbins_; bini++) {
1663 effS = (bini - 0.5)/
Float_t(nbins_);
1664 effB = fSpleffBvsS->Eval( effS );
1665 integral += (1.0 - effB);
1674 for (
Int_t bini=1; bini<=nbins_; bini++) {
1676 effS = (bini - 0.5)/
Float_t(nbins_);
1677 effB = fSpleffBvsS->Eval( effS );
1680 if ((effB - effBref)*(effB_ - effBref) < 0)
break;
1685 effS = 0.5*(effS + effS_);
1687 if (
Data()->GetNEvtSigTest() > 0)
1702 fout <<
" // not implemented for class: \"" << className <<
"\"" << std::endl;
1703 fout <<
"};" << std::endl;
1721 Log() <<
"The optimisation of rectangular cuts performed by TMVA maximises " <<
Endl;
1722 Log() <<
"the background rejection at given signal efficiency, and scans " <<
Endl;
1723 Log() <<
"over the full range of the latter quantity. Three optimisation" <<
Endl;
1724 Log() <<
"methods are optional: Monte Carlo sampling (MC), a Genetics" <<
Endl;
1725 Log() <<
"Algorithm (GA), and Simulated Annealing (SA). GA and SA are" <<
Endl;
1726 Log() <<
"expected to perform best." <<
Endl;
1728 Log() <<
"The difficulty to find the optimal cuts strongly increases with" <<
Endl;
1729 Log() <<
"the dimensionality (number of input variables) of the problem." <<
Endl;
1730 Log() <<
"This behavior is due to the non-uniqueness of the solution space."<<
Endl;
1734 Log() <<
"If the dimensionality exceeds, say, 4 input variables, it is " <<
Endl;
1735 Log() <<
"advisable to scrutinize the separation power of the variables," <<
Endl;
1736 Log() <<
"and to remove the weakest ones. If some among the input variables" <<
Endl;
1737 Log() <<
"can be described by a single cut (e.g., because signal tends to be" <<
Endl;
1738 Log() <<
"larger than background), this can be indicated to MethodCuts via" <<
Endl;
1739 Log() <<
"the \"Fsmart\" options (see option string). Choosing this option" <<
Endl;
1740 Log() <<
"reduces the number of requirements for the variable from 2 (min/max)" <<
Endl;
1741 Log() <<
"to a single one (TMVA finds out whether it is to be interpreted as" <<
Endl;
1742 Log() <<
"min or max)." <<
Endl;
1746 Log() << bold <<
"Monte Carlo sampling:" << resbold <<
Endl;
1748 Log() <<
"Apart form the \"Fsmart\" option for the variables, the only way" <<
Endl;
1749 Log() <<
"to improve the MC sampling is to increase the sampling rate. This" <<
Endl;
1750 Log() <<
"is done via the configuration option \"MC_NRandCuts\". The execution" <<
Endl;
1751 Log() <<
"time scales linearly with the sampling rate." <<
Endl;
1753 Log() << bold <<
"Genetic Algorithm:" << resbold <<
Endl;
1755 Log() <<
"The algorithm terminates if no significant fitness increase has" <<
Endl;
1756 Log() <<
"been achieved within the last \"nsteps\" steps of the calculation." <<
Endl;
1757 Log() <<
"Wiggles in the ROC curve or constant background rejection of 1" <<
Endl;
1758 Log() <<
"indicate that the GA failed to always converge at the true maximum" <<
Endl;
1759 Log() <<
"fitness. In such a case, it is recommended to broaden the search " <<
Endl;
1760 Log() <<
"by increasing the population size (\"popSize\") and to give the GA " <<
Endl;
1761 Log() <<
"more time to find improvements by increasing the number of steps" <<
Endl;
1762 Log() <<
"(\"nsteps\")" <<
Endl;
1763 Log() <<
" -> increase \"popSize\" (at least >10 * number of variables)" <<
Endl;
1764 Log() <<
" -> increase \"nsteps\"" <<
Endl;
1766 Log() << bold <<
"Simulated Annealing (SA) algorithm:" << resbold <<
Endl;
1768 Log() <<
"\"Increasing Adaptive\" approach:" <<
Endl;
1770 Log() <<
"The algorithm seeks local minima and explores their neighborhood, while" <<
Endl;
1771 Log() <<
"changing the ambient temperature depending on the number of failures" <<
Endl;
1772 Log() <<
"in the previous steps. The performance can be improved by increasing" <<
Endl;
1773 Log() <<
"the number of iteration steps (\"MaxCalls\"), or by adjusting the" <<
Endl;
1774 Log() <<
"minimal temperature (\"MinTemperature\"). Manual adjustments of the" <<
Endl;
1775 Log() <<
"speed of the temperature increase (\"TemperatureScale\" and \"AdaptiveSpeed\")" <<
Endl;
1776 Log() <<
"to individual data sets should also help. Summary:" << brk <<
Endl;
1777 Log() <<
" -> increase \"MaxCalls\"" << brk <<
Endl;
1778 Log() <<
" -> adjust \"MinTemperature\"" << brk <<
Endl;
1779 Log() <<
" -> adjust \"TemperatureScale\"" << brk <<
Endl;
1780 Log() <<
" -> adjust \"AdaptiveSpeed\"" <<
Endl;
1782 Log() <<
"\"Decreasing Adaptive\" approach:" <<
Endl;
1784 Log() <<
"The algorithm calculates the initial temperature (based on the effect-" <<
Endl;
1785 Log() <<
"iveness of large steps) and the multiplier that ensures to reach the" <<
Endl;
1786 Log() <<
"minimal temperature with the requested number of iteration steps." <<
Endl;
1787 Log() <<
"The performance can be improved by adjusting the minimal temperature" <<
Endl;
1788 Log() <<
" (\"MinTemperature\") and by increasing number of steps (\"MaxCalls\"):" << brk <<
Endl;
1789 Log() <<
" -> increase \"MaxCalls\"" << brk <<
Endl;
1790 Log() <<
" -> adjust \"MinTemperature\"" <<
Endl;
1792 Log() <<
"Other kernels:" <<
Endl;
1794 Log() <<
"Alternative ways of counting the temperature change are implemented. " <<
Endl;
1795 Log() <<
"Each of them starts with the maximum temperature (\"MaxTemperature\")" <<
Endl;
1796 Log() <<
"and descreases while changing the temperature according to a given" <<
Endl;
1797 Log() <<
"prescription:" << brk <<
Endl;
1798 Log() <<
"CurrentTemperature =" << brk <<
Endl;
1799 Log() <<
" - Sqrt: InitialTemperature / Sqrt(StepNumber+2) * TemperatureScale" << brk <<
Endl;
1800 Log() <<
" - Log: InitialTemperature / Log(StepNumber+2) * TemperatureScale" << brk <<
Endl;
1801 Log() <<
" - Homo: InitialTemperature / (StepNumber+2) * TemperatureScale" << brk <<
Endl;
1802 Log() <<
" - Sin: (Sin(StepNumber / TemperatureScale) + 1) / (StepNumber + 1)*InitialTemperature + Eps" << brk <<
Endl;
1803 Log() <<
" - Geo: CurrentTemperature * TemperatureScale" <<
Endl;
1805 Log() <<
"Their performance can be improved by adjusting initial temperature" <<
Endl;
1806 Log() <<
"(\"InitialTemperature\"), the number of iteration steps (\"MaxCalls\")," <<
Endl;
1807 Log() <<
"and the multiplier that scales the termperature descrease" <<
Endl;
1808 Log() <<
"(\"TemperatureScale\")" << brk <<
Endl;
1809 Log() <<
" -> increase \"MaxCalls\"" << brk <<
Endl;
1810 Log() <<
" -> adjust \"InitialTemperature\"" << brk <<
Endl;
1811 Log() <<
" -> adjust \"TemperatureScale\"" << brk <<
Endl;
1812 Log() <<
" -> adjust \"KernelTemperature\"" <<
Endl;
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Double_t GetMvaValue(Double_t *err=0, Double_t *errUpper=0)
cut evaluation: returns 1.0 if event passed, 0.0 otherwise
Random number generator class based on M.
MsgLogger & Endl(MsgLogger &ml)
TH1 * GetHist(const TString &alias) const
Double_t ComputeEstimator(std::vector< Double_t > &)
returns estimator for "cut fitness" used by GA there are two requirements: 1) the signal efficiency m...
void TestClassification()
nothing to test
Collectable string class.
void CheckForUnusedOptions() const
checks for unused options in option string
void MatchParsToCuts(const std::vector< Double_t > &, Double_t *, Double_t *)
translates parameters into cuts
void Clone(Ssiz_t nc)
Make self a distinct copy with capacity of at least tot, where tot cannot be smaller than the current...
1-D histogram with a float per channel (see TH1 documentation)}
Short_t Min(Short_t a, Short_t b)
void AddWeightsXMLTo(void *parent) const
create XML description for LD classification and regression (for arbitrary number of output classes/t...
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
const char * Data() const
Double_t EstimatorFunction(std::vector< Double_t > &)
returns estimator for "cut fitness" used by GA
Double_t Run()
estimator function interface for fitting
void Init(void)
default initialisation called by all constructors
void CreateVariablePDFs(void)
for PDF method: create efficiency reference histograms and PDFs
Double_t GetCuts(Double_t effS, std::vector< Double_t > &cutMin, std::vector< Double_t > &cutMax) const
retrieve cut values for given signal efficiency
void GetEffsfromSelection(Double_t *cutMin, Double_t *cutMax, Double_t &effS, Double_t &effB)
compute signal and background efficiencies from event counting for given cut sample ...
std::vector< std::vector< double > > Data
void MatchCutsToPars(std::vector< Double_t > &, Double_t *, Double_t *)
translates cuts into parameters
void Train(void)
training method: here the cuts are optimised for the training sample
std::string GetMethodName(TCppMethod_t)
MethodCuts(const TString &jobName, const TString &methodTitle, DataSetInfo &theData, const TString &theOption="MC:150:10000:", TDirectory *theTargetFile=0)
void PrintCuts(Double_t effS) const
print cuts
void MakeClassSpecific(std::ostream &, const TString &) const
write specific classifier response
void ReadWeightsFromXML(void *wghtnode)
read coefficients from xml weight file
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
char * Form(const char *fmt,...)
void GetEffsfromPDFs(Double_t *cutMin, Double_t *cutMax, Double_t &effS, Double_t &effB)
compute signal and background efficiencies from PDFs for given cut sample
void DeclareOptions()
define the options (their key words) that can be set in the option string know options: Method <strin...
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
virtual Int_t GetSize() const
void WriteMonitoringHistosToFile(void) const
write histograms and PDFs to file for monitoring purposes
Describe directory structure in memory.
void ReadWeightsFromStream(std::istream &i)
read the cuts from stream
static RooMathCoreReg dummy
Float_t GetValue(UInt_t ivar) const
return value of i'th variable
Double_t GetEfficiency(const TString &, Types::ETreeType, Double_t &)
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
void GetHelpMessage() const
get help message text
#define REGISTER_METHOD(CLASS)
for example
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
virtual ~MethodCuts(void)
destructor
Short_t Max(Short_t a, Short_t b)
A Graph is a graphics object made of two arrays X and Y with npoints each.
void ProcessOptions()
process user options sanity check, do not allow the input variables to be normalised, because this only creates problems when interpreting the cuts
void DrawProgressBar(Int_t, const TString &comment="")
draws progress bar in color or B&W caution:
Bool_t WriteOptionsReference() const
void Store(TObject *obj, const char *alias=0)
Double_t Sqrt(Double_t x)
Double_t GetTrainingEfficiency(const TString &)
virtual Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets)
Cuts can only handle classification with 2 classes.