58 ClassImp(TMVA::VariableGaussTransform);
65 TMVA::VariableGaussTransform::VariableGaussTransform( DataSetInfo& dsi, TString strcor )
66 : VariableTransformBase( dsi, Types::kGauss,
"Gauss" ),
67 fFlatNotGauss(kFALSE),
72 if (strcor==
"Uniform") {fFlatNotGauss = kTRUE;
80 TMVA::VariableGaussTransform::~VariableGaussTransform(
void )
82 CleanUpCumulativeArrays();
87 void TMVA::VariableGaussTransform::Initialize()
94 Bool_t TMVA::VariableGaussTransform::PrepareTransformation (
const std::vector<Event*>& events)
98 if (!IsEnabled() || IsCreated())
return kTRUE;
100 Log() << kINFO <<
"Preparing the Gaussian transformation..." << Endl;
102 UInt_t inputSize = fGet.size();
103 SetNVariables(inputSize);
105 if (inputSize > 200) {
106 Log() << kWARNING <<
"----------------------------------------------------------------------------"
109 <<
": More than 200 variables, I hope you have enough memory!!!!" << Endl;
110 Log() << kWARNING <<
"----------------------------------------------------------------------------"
115 GetCumulativeDist( events );
125 const TMVA::Event* TMVA::VariableGaussTransform::Transform(
const Event*
const ev, Int_t cls )
const
127 if (!IsCreated()) Log() << kFATAL <<
"Transformation not yet created" << Endl;
133 if (cls <0 || cls >= (
int) fCumulativePDF[0].size()) cls = fCumulativePDF[0].size()-1;
137 UInt_t inputSize = fGet.size();
139 std::vector<Float_t> input(0);
140 std::vector<Float_t> output(0);
142 std::vector<Char_t> mask;
143 GetInput( ev, input, mask );
145 std::vector<Char_t>::iterator itMask = mask.begin();
151 for (UInt_t ivar=0; ivar<inputSize; ivar++) {
158 if (0 != fCumulativePDF[ivar][cls]) {
160 if(fTMVAVersion>TMVA_VERSION(3,9,7))
161 cumulant = (fCumulativePDF[ivar][cls])->GetVal(input.at(ivar));
163 cumulant = OldCumulant(input.at(ivar), fCumulativePDF[ivar][cls]->GetOriginalHist() );
164 cumulant = TMath::Min(cumulant,1.-10e-10);
165 cumulant = TMath::Max(cumulant,0.+10e-10);
168 output.push_back( cumulant );
171 Double_t maxErfInvArgRange = 0.99999999;
172 Double_t arg = 2.0*cumulant - 1.0;
173 arg = TMath::Min(+maxErfInvArgRange,arg);
174 arg = TMath::Max(-maxErfInvArgRange,arg);
176 output.push_back( 1.414213562*TMath::ErfInverse(arg) );
181 if (fTransformedEvent==0 || fTransformedEvent->GetNVariables()!=ev->GetNVariables()) {
182 if (fTransformedEvent!=0) {
delete fTransformedEvent; fTransformedEvent = 0; }
183 fTransformedEvent =
new Event();
186 SetOutput( fTransformedEvent, output, mask, ev );
188 return fTransformedEvent;
194 const TMVA::Event* TMVA::VariableGaussTransform::InverseTransform(
const Event*
const ev, Int_t cls )
const
196 if (!IsCreated()) Log() << kFATAL <<
"Transformation not yet created" << Endl;
202 if (cls <0 || cls >= (
int) fCumulativePDF[0].size()) cls = fCumulativePDF[0].size()-1;
206 UInt_t inputSize = fGet.size();
208 std::vector<Float_t> input(0);
209 std::vector<Float_t> output(0);
211 std::vector<Char_t> mask;
212 GetInput( ev, input, mask, kTRUE );
214 std::vector<Char_t>::iterator itMask = mask.begin();
218 Double_t invCumulant;
220 for (UInt_t ivar=0; ivar<inputSize; ivar++) {
227 if (0 != fCumulativePDF[ivar][cls]) {
228 invCumulant = input.at(ivar);
232 invCumulant = (TMath::Erf(invCumulant/1.414213562)+1)/2.f;
235 if(fTMVAVersion>TMVA_VERSION(4,0,0))
236 invCumulant = (fCumulativePDF[ivar][cls])->GetValInverse(invCumulant,kTRUE);
238 Log() << kFATAL <<
"Inverse Uniform/Gauss transformation not implemented for TMVA versions before 4.1.0" << Endl;
240 output.push_back(invCumulant);
244 if (fBackTransformedEvent==0) fBackTransformedEvent =
new Event( *ev );
246 SetOutput( fBackTransformedEvent, output, mask, ev, kTRUE );
248 return fBackTransformedEvent;
254 void TMVA::VariableGaussTransform::GetCumulativeDist(
const std::vector< Event*>& events )
256 const UInt_t inputSize = fGet.size();
260 UInt_t nevt = events.size();
262 const UInt_t nClasses = GetNClasses();
263 UInt_t numDist = nClasses+1;
265 if (GetNClasses() == 1 ) numDist = nClasses;
267 UInt_t **nbins =
new UInt_t*[numDist];
269 std::list< TMVA::TMVAGaussPair > **listsForBinning =
new std::list<TMVA::TMVAGaussPair>* [numDist];
270 std::vector< Float_t > **vsForBinning =
new std::vector<Float_t>* [numDist];
271 for (UInt_t i=0; i < numDist; i++) {
272 listsForBinning[i] =
new std::list<TMVA::TMVAGaussPair> [inputSize];
273 vsForBinning[i] =
new std::vector<Float_t> [inputSize];
274 nbins[i] =
new UInt_t[inputSize];
277 std::vector<Float_t> input;
278 std::vector<Char_t> mask;
281 Float_t *sumOfWeights =
new Float_t[numDist];
282 Float_t *minWeight =
new Float_t[numDist];
283 Float_t *maxWeight =
new Float_t[numDist];
284 for (UInt_t i=0; i<numDist; i++) {
289 for (UInt_t ievt=0; ievt < nevt; ievt++) {
290 const Event* ev= events[ievt];
291 Int_t cls = ev->GetClass();
292 Float_t eventWeight = ev->GetWeight();
293 sumOfWeights[cls] += eventWeight;
294 if (minWeight[cls] > eventWeight) minWeight[cls]=eventWeight;
295 if (maxWeight[cls] < eventWeight) maxWeight[cls]=eventWeight;
296 if (numDist>1) sumOfWeights[numDist-1] += eventWeight;
298 Bool_t hasMaskedEntries = GetInput( ev, input, mask );
299 if( hasMaskedEntries ){
300 Log() << kWARNING <<
"Incomplete event" << Endl;
301 std::ostringstream oss;
304 Log() << kFATAL <<
"Targets or variables masked by transformation. Apparently (a) value(s) is/are missing in this event." << Endl;
309 for( std::vector<Float_t>::iterator itInput = input.begin(), itInputEnd = input.end(); itInput != itInputEnd; ++itInput ) {
310 Float_t value = (*itInput);
311 listsForBinning[cls][ivar].push_back(TMVA::TMVAGaussPair(value,eventWeight));
312 if (numDist>1)listsForBinning[numDist-1][ivar].push_back(TMVA::TMVAGaussPair(value,eventWeight));
317 for (UInt_t icl=0; icl<numDist-1; icl++){
318 minWeight[numDist-1] = TMath::Min(minWeight[icl],minWeight[numDist-1]);
319 maxWeight[numDist-1] = TMath::Max(maxWeight[icl],maxWeight[numDist-1]);
324 const UInt_t nevmin=10;
325 const UInt_t nbinsmax=2000;
327 for (UInt_t icl=0; icl< numDist; icl++){
328 for (UInt_t ivar=0; ivar<inputSize; ivar++) {
329 listsForBinning[icl][ivar].sort();
330 std::list< TMVA::TMVAGaussPair >::iterator it;
331 Float_t sumPerBin = sumOfWeights[icl]/nbinsmax;
332 sumPerBin=TMath::Max(minWeight[icl]*nevmin,sumPerBin);
334 Float_t ev_value=listsForBinning[icl][ivar].begin()->GetValue();
335 Float_t lastev_value=ev_value;
336 const Float_t eps = 1.e-4;
337 vsForBinning[icl][ivar].push_back(ev_value-eps);
338 vsForBinning[icl][ivar].push_back(ev_value);
340 for (it=listsForBinning[icl][ivar].begin(); it != listsForBinning[icl][ivar].end(); ++it){
341 sum+= it->GetWeight();
342 if (sum >= sumPerBin) {
343 ev_value=it->GetValue();
344 if (ev_value>lastev_value) {
345 vsForBinning[icl][ivar].push_back(ev_value);
347 lastev_value=ev_value;
351 if (sum!=0) vsForBinning[icl][ivar].push_back(listsForBinning[icl][ivar].back().GetValue());
352 nbins[icl][ivar] = vsForBinning[icl][ivar].size();
356 delete[] sumOfWeights;
361 fCumulativeDist.resize(inputSize);
362 for (UInt_t icls = 0; icls < numDist; icls++) {
363 for (UInt_t ivar=0; ivar < inputSize; ivar++){
364 Float_t* binnings =
new Float_t[nbins[icls][ivar]];
366 for (UInt_t k =0 ; k < nbins[icls][ivar]; k++){
367 binnings[k] = vsForBinning[icls][ivar][k];
369 fCumulativeDist[ivar].resize(numDist);
370 if (0 != fCumulativeDist[ivar][icls] ) {
371 delete fCumulativeDist[ivar][icls];
373 fCumulativeDist[ivar][icls] =
new TH1F(Form(
"Cumulative_Var%d_cls%d",ivar,icls),
374 Form(
"Cumulative_Var%d_cls%d",ivar,icls),
375 nbins[icls][ivar] -1,
377 fCumulativeDist[ivar][icls]->SetDirectory(0);
383 for (UInt_t i=0; i<numDist; i++) {
384 delete [] listsForBinning[numDist-i-1];
385 delete [] vsForBinning[numDist-i-1];
386 delete [] nbins[numDist-i-1];
388 delete [] listsForBinning;
389 delete [] vsForBinning;
393 std::vector<Int_t> ic(numDist);
394 for (UInt_t ievt=0; ievt<nevt; ievt++) {
396 const Event* ev= events[ievt];
397 Int_t cls = ev->GetClass();
398 Float_t eventWeight = ev->GetWeight();
400 GetInput( ev, input, mask );
403 for( std::vector<Float_t>::iterator itInput = input.begin(), itInputEnd = input.end(); itInput != itInputEnd; ++itInput ) {
404 Float_t value = (*itInput);
405 fCumulativeDist[ivar][cls]->Fill(value,eventWeight);
406 if (numDist>1) fCumulativeDist[ivar][numDist-1]->Fill(value,eventWeight);
413 CleanUpCumulativeArrays(
"PDF");
416 Double_t sum = 0, total=0;
417 fCumulativePDF.resize(inputSize);
418 for (UInt_t ivar=0; ivar<inputSize; ivar++) {
420 for (UInt_t icls=0; icls<numDist; icls++) {
421 (fCumulativeDist[ivar][icls])->Smooth();
424 for (Int_t ibin=1, ibinEnd=fCumulativeDist[ivar][icls]->GetNbinsX(); ibin <=ibinEnd ; ibin++){
425 Float_t val = (fCumulativeDist[ivar][icls])->GetBinContent(ibin);
426 if (val>0) total += val;
428 for (Int_t ibin=1, ibinEnd=fCumulativeDist[ivar][icls]->GetNbinsX(); ibin <=ibinEnd ; ibin++){
429 Float_t val = (fCumulativeDist[ivar][icls])->GetBinContent(ibin);
430 if (val>0) sum += val;
431 (fCumulativeDist[ivar][icls])->SetBinContent(ibin,sum/total);
434 fCumulativePDF[ivar].push_back(
new PDF( Form(
"GaussTransform var%d cls%d",ivar,icls), fCumulativeDist[ivar][icls], PDF::kSpline1, fPdfMinSmooth, fPdfMaxSmooth,kFALSE,kFALSE));
441 void TMVA::VariableGaussTransform::WriteTransformationToStream( std::ostream& )
const
443 Log() << kFATAL <<
"VariableGaussTransform::WriteTransformationToStream is obsolete" << Endl;
449 void TMVA::VariableGaussTransform::CleanUpCumulativeArrays(TString opt) {
450 if (opt ==
"ALL" || opt ==
"PDF"){
451 for (UInt_t ivar=0; ivar<fCumulativePDF.size(); ivar++) {
452 for (UInt_t icls=0; icls<fCumulativePDF[ivar].size(); icls++) {
453 if (0 != fCumulativePDF[ivar][icls])
delete fCumulativePDF[ivar][icls];
456 fCumulativePDF.clear();
458 if (opt ==
"ALL" || opt ==
"Dist"){
459 for (UInt_t ivar=0; ivar<fCumulativeDist.size(); ivar++) {
460 for (UInt_t icls=0; icls<fCumulativeDist[ivar].size(); icls++) {
461 if (0 != fCumulativeDist[ivar][icls])
delete fCumulativeDist[ivar][icls];
464 fCumulativeDist.clear();
470 void TMVA::VariableGaussTransform::AttachXMLTo(
void* parent) {
471 void* trfxml = gTools().AddChild(parent,
"Transform");
472 gTools().AddAttr(trfxml,
"Name",
"Gauss");
473 gTools().AddAttr(trfxml,
"FlatOrGauss", (fFlatNotGauss?
"Flat":
"Gauss") );
475 VariableTransformBase::AttachXMLTo( trfxml );
477 UInt_t nvar = fGet.size();
478 for (UInt_t ivar=0; ivar<nvar; ivar++) {
479 void* varxml = gTools().AddChild( trfxml,
"Variable");
481 gTools().AddAttr( varxml,
"VarIndex", ivar );
483 if ( fCumulativePDF[ivar][0]==0 ||
484 (fCumulativePDF[ivar].size()>1 && fCumulativePDF[ivar][1]==0 ))
485 Log() << kFATAL <<
"Cumulative histograms for variable " << ivar <<
" don't exist, can't write it to weight file" << Endl;
487 for (UInt_t icls=0; icls<fCumulativePDF[ivar].size(); icls++){
488 void* pdfxml = gTools().AddChild( varxml, Form(
"CumulativePDF_cls%d",icls));
489 (fCumulativePDF[ivar][icls])->AddXMLTo(pdfxml);
497 void TMVA::VariableGaussTransform::ReadFromXML(
void* trfnode ) {
499 CleanUpCumulativeArrays();
502 gTools().ReadAttr(trfnode,
"FlatOrGauss", FlatOrGauss );
504 if (FlatOrGauss ==
"Flat") fFlatNotGauss = kTRUE;
505 else fFlatNotGauss = kFALSE;
507 Bool_t newFormat = kFALSE;
509 void* inpnode = NULL;
511 inpnode = gTools().GetChild(trfnode,
"Selection");
515 void* varnode = NULL;
519 VariableTransformBase::ReadFromXML( inpnode );
521 varnode = gTools().GetNextChild(inpnode);
523 varnode = gTools().GetChild(trfnode);
527 TString varname, histname, classname;
530 if( gTools().HasAttr(varnode,
"Name") )
531 gTools().ReadAttr(varnode,
"Name", varname);
532 gTools().ReadAttr(varnode,
"VarIndex", ivar);
534 void* clsnode = gTools().GetChild( varnode);
537 void* pdfnode = gTools().GetChild( clsnode);
538 PDF* pdfToRead =
new PDF(TString(
"tempName"),kFALSE);
539 pdfToRead->ReadXML(pdfnode);
541 fCumulativePDF.resize( ivar+1 );
542 fCumulativePDF[ivar].push_back(pdfToRead);
543 clsnode = gTools().GetNextChild(clsnode);
546 varnode = gTools().GetNextChild(varnode);
554 void TMVA::VariableGaussTransform::ReadTransformationFromStream( std::istream& istr,
const TString& classname)
556 Bool_t addDirStatus = TH1::AddDirectoryStatus();
557 TH1::AddDirectory(0);
559 istr.getline(buf,512);
561 TString strvar, dummy;
563 while (!(buf[0]==
'#'&& buf[1]==
'#')) {
565 while (*p==
' ' || *p==
'\t') p++;
566 if (*p==
'#' || *p==
'\0') {
567 istr.getline(buf,512);
570 std::stringstream sstr(buf);
573 if (strvar==
"CumulativeHistogram") {
574 UInt_t type(0), ivar(0);
575 TString devnullS(
""),hname(
"");
579 sstr >> type >> ivar >> hname >> nbins >> fElementsperbin;
581 Float_t *Binnings =
new Float_t[nbins+1];
584 for (Int_t ibin=0; ibin<nbins+1; ibin++) {
589 if(ivar>=fCumulativeDist.size()) fCumulativeDist.resize(ivar+1);
590 if(type>=fCumulativeDist[ivar].size()) fCumulativeDist[ivar].resize(type+1);
592 TH1F * histToRead = fCumulativeDist[ivar][type];
593 if ( histToRead !=0 )
delete histToRead;
595 histToRead =
new TH1F( hname, hname, nbins, Binnings );
596 histToRead->SetDirectory(0);
597 fCumulativeDist[ivar][type]=histToRead;
600 for (Int_t ibin=0; ibin<nbins; ibin++) {
602 histToRead->SetBinContent(ibin+1,val);
605 PDF* pdf =
new PDF(hname,histToRead,PDF::kSpline0, 0, 0, kFALSE, kFALSE);
607 fCumulativePDF.resize(ivar+1);
608 fCumulativePDF[ivar].resize(type+1);
609 fCumulativePDF[ivar][type] = pdf;
614 if (strvar==
"Uniform") {
615 sstr >> fFlatNotGauss;
616 istr.getline(buf,512);
620 istr.getline(buf,512);
622 TH1::AddDirectory(addDirStatus);
624 UInt_t classIdx=(classname==
"signal")?0:1;
625 for(UInt_t ivar=0; ivar<fCumulativePDF.size(); ++ivar) {
626 PDF* src = fCumulativePDF[ivar][classIdx];
627 fCumulativePDF[ivar].push_back(
new PDF(src->GetName(),fCumulativeDist[ivar][classIdx],PDF::kSpline0, 0, 0, kFALSE, kFALSE) );
630 SetTMVAVersion(TMVA_VERSION(3,9,7));
637 Double_t TMVA::VariableGaussTransform::OldCumulant(Float_t x, TH1* h )
const {
639 Int_t bin = h->FindBin(x);
640 bin = TMath::Max(bin,1);
641 bin = TMath::Min(bin,h->GetNbinsX());
644 Double_t x0, x1, y0, y1;
645 Double_t total = h->GetNbinsX()*fElementsperbin;
646 Double_t supmin = 0.5/total;
648 x0 = h->GetBinLowEdge(TMath::Max(bin,1));
649 x1 = h->GetBinLowEdge(TMath::Min(bin,h->GetNbinsX())+1);
651 y0 = h->GetBinContent(TMath::Max(bin-1,0));
652 y1 = h->GetBinContent(TMath::Min(bin, h->GetNbinsX()+1));
661 if (bin > h->GetNbinsX()) {
665 if (bin == h->GetNbinsX()) {
672 cumulant = y0 + (y1-y0)*(x-x0)/(x1-x0);
675 if (x <= h->GetBinLowEdge(1)){
678 if (x >= h->GetBinLowEdge(h->GetNbinsX()+1)){
687 void TMVA::VariableGaussTransform::PrintTransformation( std::ostream& )
690 Log() << kINFO <<
"I do not know yet how to print this... look in the weight file " << cls <<
":" << Endl;
698 void TMVA::VariableGaussTransform::MakeFunction( std::ostream& fout,
const TString& fcncName,
699 Int_t part, UInt_t trCounter, Int_t )
701 const UInt_t nvar = fGet.size();
702 UInt_t numDist = GetNClasses() + 1;
704 for (UInt_t icls=0; icls<numDist; icls++) {
705 for (UInt_t ivar=0; ivar<nvar; ivar++) {
706 Int_t nbin=(fCumulativePDF[ivar][icls])->GetGraph()->GetN();
707 if (nbin > nBins) nBins=nbin;
714 fout <<
" int nvar;" << std::endl;
717 fout <<
" double cumulativeDist["<<nvar<<
"]["<<numDist<<
"]["<<nBins+1<<
"];"<<std::endl;
718 fout <<
" double X["<<nvar<<
"]["<<numDist<<
"]["<<nBins+1<<
"];"<<std::endl;
719 fout <<
" double xMin["<<nvar<<
"]["<<numDist<<
"];"<<std::endl;
720 fout <<
" double xMax["<<nvar<<
"]["<<numDist<<
"];"<<std::endl;
721 fout <<
" int nbins["<<nvar<<
"]["<<numDist<<
"];"<<std::endl;
725 fout <<
"#include \"math.h\"" << std::endl;
727 fout <<
"//_______________________________________________________________________" << std::endl;
728 fout <<
"inline void " << fcncName <<
"::InitTransform_"<<trCounter<<
"()" << std::endl;
729 fout <<
"{" << std::endl;
730 fout <<
" // Gauss/Uniform transformation, initialisation" << std::endl;
731 fout <<
" nvar=" << nvar <<
";" << std::endl;
732 for (UInt_t icls=0; icls<numDist; icls++) {
733 for (UInt_t ivar=0; ivar<nvar; ivar++) {
734 Int_t nbin=(fCumulativePDF[ivar][icls])->GetGraph()->GetN();
735 fout <<
" nbins["<<ivar<<
"]["<<icls<<
"]="<<nbin<<
";"<<std::endl;
742 for (UInt_t icls=0; icls<numDist; icls++) {
743 for (UInt_t ivar=0; ivar<nvar; ivar++) {
747 Char_t type = fGet.at(ivar).first;
749 Log() << kWARNING <<
"MakeClass for the Gauss transformation works only for the transformation of variables. The transformation of targets/spectators is not implemented." << Endl;
751 }
catch( std::out_of_range &){
752 Log() << kWARNING <<
"MakeClass for the Gauss transformation searched for a non existing variable index (" << ivar <<
")" << Endl;
757 Double_t xmn = (fCumulativePDF[ivar][icls])->GetGraph()->GetX()[0];
758 Double_t xmx = (fCumulativePDF[ivar][icls])->GetGraph()->GetX()[(fCumulativePDF[ivar][icls])->GetGraph()->GetN()-1];
760 fout <<
" xMin["<<ivar<<
"]["<<icls<<
"]="<< gTools().StringFromDouble(xmn)<<
";"<<std::endl;
761 fout <<
" xMax["<<ivar<<
"]["<<icls<<
"]="<<gTools().StringFromDouble(xmx)<<
";"<<std::endl;
762 for (Int_t ibin=0; ibin<(fCumulativePDF[ivar][icls])->GetGraph()->GetN(); ibin++) {
763 fout <<
" cumulativeDist[" << ivar <<
"]["<< icls<<
"]["<<ibin<<
"]="<< gTools().StringFromDouble((fCumulativePDF[ivar][icls])->GetGraph()->GetY()[ibin])<<
";"<<std::endl;
764 fout <<
" X[" << ivar <<
"]["<< icls<<
"]["<<ibin<<
"]="<< gTools().StringFromDouble((fCumulativePDF[ivar][icls])->GetGraph()->GetX()[ibin])<<
";"<<std::endl;
769 fout <<
"}" << std::endl;
771 fout <<
"//_______________________________________________________________________" << std::endl;
772 fout <<
"inline void " << fcncName <<
"::Transform_"<<trCounter<<
"( std::vector<double>& iv, int clsIn) const" << std::endl;
773 fout <<
"{" << std::endl;
774 fout <<
" // Gauss/Uniform transformation" << std::endl;
775 fout <<
" int cls=clsIn;" << std::endl;
776 fout <<
" if (cls < 0 || cls > "<<GetNClasses()<<
") {"<< std::endl;
777 fout <<
" if ("<<GetNClasses()<<
" > 1 ) cls = "<<GetNClasses()<<
";"<< std::endl;
778 fout <<
" else cls = "<<(fCumulativePDF[0].size()==1?0:2)<<
";"<< std::endl;
779 fout <<
" }"<< std::endl;
781 fout <<
" // copy the variables which are going to be transformed "<< std::endl;
782 VariableTransformBase::MakeFunction(fout, fcncName, 0, trCounter, 0 );
783 fout <<
" static std::vector<double> dv; "<< std::endl;
784 fout <<
" dv.resize(nvar); "<< std::endl;
785 fout <<
" for (int ivar=0; ivar<nvar; ivar++) dv[ivar] = iv[indicesGet.at(ivar)]; "<< std::endl;
786 fout <<
" "<< std::endl;
787 fout <<
" bool FlatNotGauss = "<< (fFlatNotGauss?
"true":
"false") <<
"; "<< std::endl;
788 fout <<
" double cumulant; "<< std::endl;
789 fout <<
" //const int nvar = "<<nvar<<
"; "<< std::endl;
790 fout <<
" for (int ivar=0; ivar<nvar; ivar++) { "<< std::endl;
791 fout <<
" int nbin = nbins[ivar][cls]; "<< std::endl;
792 fout <<
" int ibin=0; "<< std::endl;
793 fout <<
" while (dv[ivar] > X[ivar][cls][ibin]) ibin++; "<< std::endl;
794 fout <<
" "<< std::endl;
795 fout <<
" if (ibin<0) { ibin=0;} "<< std::endl;
796 fout <<
" if (ibin>=nbin) { ibin=nbin-1;} "<< std::endl;
797 fout <<
" int nextbin = ibin; "<< std::endl;
798 fout <<
" if ((dv[ivar] > X[ivar][cls][ibin] && ibin !=nbin-1) || ibin==0) "<< std::endl;
799 fout <<
" nextbin++; "<< std::endl;
800 fout <<
" else "<< std::endl;
801 fout <<
" nextbin--; "<< std::endl;
802 fout <<
" "<< std::endl;
803 fout <<
" double dx = X[ivar][cls][ibin]- X[ivar][cls][nextbin]; "<< std::endl;
804 fout <<
" double dy = cumulativeDist[ivar][cls][ibin] - cumulativeDist[ivar][cls][nextbin]; "<< std::endl;
805 fout <<
" cumulant = cumulativeDist[ivar][cls][ibin] + (dv[ivar] - X[ivar][cls][ibin])* dy/dx;"<< std::endl;
806 fout <<
" "<< std::endl;
807 fout <<
" "<< std::endl;
808 fout <<
" if (cumulant>1.-10e-10) cumulant = 1.-10e-10; "<< std::endl;
809 fout <<
" if (cumulant<10e-10) cumulant = 10e-10; "<< std::endl;
810 fout <<
" if (FlatNotGauss) dv[ivar] = cumulant; "<< std::endl;
811 fout <<
" else { "<< std::endl;
812 fout <<
" double maxErfInvArgRange = 0.99999999; "<< std::endl;
813 fout <<
" double arg = 2.0*cumulant - 1.0; "<< std::endl;
814 fout <<
" if (arg > maxErfInvArgRange) arg= maxErfInvArgRange; "<< std::endl;
815 fout <<
" if (arg < -maxErfInvArgRange) arg=-maxErfInvArgRange; "<< std::endl;
816 fout <<
" double inverf=0., stp=1. ; "<< std::endl;
817 fout <<
" while (stp >1.e-10){; "<< std::endl;
818 fout <<
" if (erf(inverf)>arg) inverf -=stp ; "<< std::endl;
819 fout <<
" else if (erf(inverf)<=arg && erf(inverf+stp)>=arg) stp=stp/5. ; "<< std::endl;
820 fout <<
" else inverf += stp; "<< std::endl;
821 fout <<
" } ; "<< std::endl;
822 fout <<
" //dv[ivar] = 1.414213562*TMath::ErfInverse(arg); "<< std::endl;
823 fout <<
" dv[ivar] = 1.414213562* inverf; "<< std::endl;
824 fout <<
" } "<< std::endl;
825 fout <<
" } "<< std::endl;
826 fout <<
" // copy the transformed variables back "<< std::endl;
827 fout <<
" for (int ivar=0; ivar<nvar; ivar++) iv[indicesPut.at(ivar)] = dv[ivar]; "<< std::endl;
828 fout <<
"} "<< std::endl;