164 ClassImp(TUnfoldDensity);
 
  166 TUnfoldDensity::~TUnfoldDensity(
void)
 
  169    if(fOwnedOutputBins) 
delete fOwnedOutputBins;
 
  170    if(fOwnedInputBins) 
delete fOwnedInputBins;
 
  171    if(fRegularisationConditions) 
delete fRegularisationConditions;
 
  177 TUnfoldDensity::TUnfoldDensity(
void)
 
  183    fRegularisationConditions=0;
 
  217 TUnfoldDensity::TUnfoldDensity
 
  218 (
const TH2 *hist_A, EHistMap histmap,ERegMode regmode,EConstraint constraint,
 
  219  EDensityMode densityMode,
const TUnfoldBinning *outputBins,
 
  220  const TUnfoldBinning *inputBins,
const char *regularisationDistribution,
 
  221  const char *regularisationAxisSteering) :
 
  222    TUnfoldSys(hist_A,histmap,kRegModeNone,constraint)
 
  224    fRegularisationConditions=0;
 
  226    fConstOutputBins = outputBins;
 
  227    fOwnedOutputBins = 0;
 
  228    TAxis 
const *genAxis,*detAxis;
 
  229    if(histmap==kHistMapOutputHoriz) {
 
  230       genAxis=hist_A->GetXaxis();
 
  231       detAxis=hist_A->GetYaxis();
 
  233       genAxis=hist_A->GetYaxis();
 
  234       detAxis=hist_A->GetXaxis();
 
  236    if(!fConstOutputBins) {
 
  240          new TUnfoldBinning(*genAxis,1,1);
 
  241       fConstOutputBins = fOwnedOutputBins;
 
  244    if(fConstOutputBins->GetParentNode()) {
 
  245       Error(
"TUnfoldDensity",
 
  246             "Invalid output binning scheme (node is not the root node)");
 
  248    fConstInputBins = inputBins;
 
  250    if(!fConstInputBins) {
 
  254          new TUnfoldBinning(*detAxis,0,0);
 
  255       fConstInputBins = fOwnedInputBins;
 
  257    if(fConstInputBins->GetParentNode()) {
 
  258       Error(
"TUnfoldDensity",
 
  259             "Invalid input binning scheme (node is not the root node)");
 
  263    Int_t nOut=genAxis->GetNbins();
 
  264    Int_t nOutMappedT=TMath::Abs(fConstOutputBins->GetTH1xNumberOfBins(kTRUE));
 
  265    Int_t nOutMappedF=TMath::Abs(fConstOutputBins->GetTH1xNumberOfBins
 
  267    if((nOutMappedT!= nOut)&&(nOutMappedF!=nOut)) {
 
  268       Error(
"TUnfoldDensity",
 
  269             "Output binning incompatible number of bins: axis %d binning scheme %d (%d)",
 
  270             nOut,nOutMappedT,nOutMappedF);
 
  273    Int_t nInput=detAxis->GetNbins();
 
  274    Int_t nInputMappedT=TMath::Abs(fConstInputBins->GetTH1xNumberOfBins(kTRUE));
 
  275    Int_t nInputMappedF=TMath::Abs(fConstInputBins->GetTH1xNumberOfBins
 
  277    if((nInputMappedT!= nInput)&&(nInputMappedF!= nInput)) {
 
  278       Error(
"TUnfoldDensity",
 
  279             "Input binning incompatible number of bins:axis %d binning scheme %d (%d) ",
 
  280             nInput,nInputMappedT,nInputMappedF);
 
  284    for (Int_t ix = 0; ix <= nOut+1; ix++) {
 
  286    Info(
"TUnfold",
"*NOT* unfolding bin %s",(
char const *)GetOutputBinName(ix));
 
  291    if(regmode !=kRegModeNone) {
 
  292       RegularizeDistribution
 
  293    (regmode,densityMode,regularisationDistribution,
 
  294     regularisationAxisSteering);
 
  307 TString TUnfoldDensity::GetOutputBinName(Int_t iBinX)
 const {
 
  308    if(!fConstOutputBins) 
return TUnfold::GetOutputBinName(iBinX);
 
  309    else return fConstOutputBins->GetBinName(iBinX);
 
  332 Double_t TUnfoldDensity::GetDensityFactor
 
  333 (EDensityMode densityMode,Int_t iBin)
 const 
  336    if((densityMode == kDensityModeBinWidth)||
 
  337       (densityMode == kDensityModeBinWidthAndUser)) {
 
  338       Double_t binSize=fConstOutputBins->GetBinSize(iBin);
 
  339       if(binSize>0.0) factor /= binSize;
 
  342    if((densityMode == kDensityModeUser)||
 
  343       (densityMode == kDensityModeBinWidthAndUser)) {
 
  344       factor *= fConstOutputBins->GetBinFactor(iBin);
 
  383 void TUnfoldDensity::RegularizeDistribution
 
  384 (ERegMode regmode,EDensityMode densityMode,
const char *distribution,
 
  385  const char *axisSteering)
 
  388    RegularizeDistributionRecursive(GetOutputBinning(),regmode,densityMode,
 
  389                                    distribution,axisSteering);
 
  401 void TUnfoldDensity::RegularizeDistributionRecursive
 
  402 (
const TUnfoldBinning *binning,ERegMode regmode,
 
  403  EDensityMode densityMode,
const char *distribution,
const char *axisSteering) {
 
  404    if((!distribution)|| !TString(distribution).CompareTo(binning->GetName())) {
 
  405       RegularizeOneDistribution(binning,regmode,densityMode,axisSteering);
 
  407    for(
const TUnfoldBinning *child=binning->GetChildNode();child;
 
  408        child=child->GetNextNode()) {
 
  409       RegularizeDistributionRecursive(child,regmode,densityMode,distribution,
 
  422 void TUnfoldDensity::RegularizeOneDistribution
 
  423 (
const TUnfoldBinning *binning,ERegMode regmode,
 
  424  EDensityMode densityMode,
const char *axisSteering)
 
  427    cout<<
"TUnfoldDensity::RegularizeOneDistribution node=" 
  428        <<binning->GetName()<<
" "<<regmode<<
" "<<densityMode
 
  429        <<
" "<<(axisSteering ? axisSteering : 
"")<<
"\n";
 
  431    if(!fRegularisationConditions)
 
  432       fRegularisationConditions=
new TUnfoldBinning(
"regularisation");
 
  434    TUnfoldBinning *thisRegularisationBinning=
 
  435       fRegularisationConditions->AddBinning(binning->GetName());
 
  438    Int_t isOptionGiven[8];
 
  439    binning->DecodeAxisSteering(axisSteering,
"uUoObBpN",isOptionGiven);
 
  441    isOptionGiven[0] |= isOptionGiven[1];
 
  443    isOptionGiven[2] |= isOptionGiven[3];
 
  445    isOptionGiven[4] |= isOptionGiven[5];
 
  447    for(Int_t i=0;i<7;i++) {
 
  448       isOptionGiven[7] &= ~isOptionGiven[i];
 
  451    if(isOptionGiven[6] & (isOptionGiven[0]|isOptionGiven[2]) ) {
 
  452       Error(
"RegularizeOneDistribution",
 
  453             "axis steering %s is not valid",axisSteering);
 
  456    cout<<
" "<<isOptionGiven[0]
 
  457        <<
" "<<isOptionGiven[1]
 
  458        <<
" "<<isOptionGiven[2]
 
  459        <<
" "<<isOptionGiven[3]
 
  460        <<
" "<<isOptionGiven[4]
 
  461        <<
" "<<isOptionGiven[5]
 
  462        <<
" "<<isOptionGiven[6]
 
  463        <<
" "<<isOptionGiven[7]
 
  466    Info(
"RegularizeOneDistribution",
"regularizing %s regMode=%d" 
  467    " densityMode=%d axisSteering=%s",
 
  468    binning->GetName(),(Int_t) regmode,(Int_t)densityMode,
 
  469    axisSteering ? axisSteering : 
"");
 
  470    Int_t startBin=binning->GetStartBin();
 
  471    Int_t endBin=startBin+ binning->GetDistributionNumberOfBins();
 
  472    std::vector<Double_t> factor(endBin-startBin);
 
  474    for(Int_t bin=startBin;bin<endBin;bin++) {
 
  475       factor[bin-startBin]=GetDensityFactor(densityMode,bin);
 
  476       if(factor[bin-startBin] !=0.0) nbin++;
 
  479    cout<<
"initial number of bins "<<nbin<<
"\n";
 
  481    Int_t dimension=binning->GetDistributionDimension();
 
  485    for(Int_t bin=startBin;bin<endBin;bin++) {
 
  486       Int_t uStatus,oStatus;
 
  487       binning->GetBinUnderflowOverflowStatus(bin,&uStatus,&oStatus);
 
  488       if(uStatus & isOptionGiven[1]) factor[bin-startBin]=0.;
 
  489       if(oStatus & isOptionGiven[3]) factor[bin-startBin]=0.;
 
  490       if(factor[bin-startBin] !=0.0) nbin++;
 
  493    cout<<
"after underflow/overflow bin removal "<<nbin<<
"\n";
 
  495    if(regmode==kRegModeSize) {
 
  499       for(Int_t bin=startBin;bin<endBin;bin++) {
 
  500          if(factor[bin-startBin]==0.0) 
continue;
 
  501          if(AddRegularisationCondition(bin,factor[bin-startBin])) {
 
  506          thisRegularisationBinning->AddBinning(
"size",nRegBins);
 
  508    } 
else if((regmode==kRegModeDerivative)||(regmode==kRegModeCurvature)) {
 
  509       for(Int_t direction=0;direction<dimension;direction++) {
 
  512          Int_t directionMask=(1<<direction);
 
  513          if(isOptionGiven[7] & directionMask) {
 
  515             cout<<
"skip direction "<<direction<<
"\n";
 
  519          Double_t binDistanceNormalisation=
 
  520             (isOptionGiven[5] & directionMask)  ?
 
  521             binning->GetDistributionAverageBinSize
 
  522             (direction,isOptionGiven[0] & directionMask,
 
  523              isOptionGiven[2] & directionMask) : 1.0;
 
  524          for(Int_t bin=startBin;bin<endBin;bin++) {
 
  526             if(factor[bin-startBin]==0.0) 
continue;
 
  529             Double_t distPrev,distNext;
 
  530             Int_t error=binning->GetBinNeighbours
 
  531                (bin,direction,&iPrev,&distPrev,&iNext,&distNext,
 
  532                 isOptionGiven[6] & directionMask);
 
  534                Error(
"RegularizeOneDistribution",
 
  535                      "invalid option %s (isPeriodic) for axis %s" 
  536                      " (has underflow or overflow)",axisSteering,
 
  537                      binning->GetDistributionAxisLabel(direction).Data());
 
  539             if((regmode==kRegModeDerivative)&&(iNext>=0)) {
 
  540                Double_t f0 = -factor[bin-startBin];
 
  541                Double_t f1 = factor[iNext-startBin];
 
  542                if(isOptionGiven[4] & directionMask) {
 
  544                      f0 *= binDistanceNormalisation/distNext;
 
  545                      f1 *= binDistanceNormalisation/distNext;
 
  551                if((f0==0.0)||(f1==0.0)) 
continue;
 
  552                if(AddRegularisationCondition(bin,f0,iNext,f1)) {
 
  555                   std::cout<<
"Added Reg: bin "<<bin<<
" "<<f0
 
  556                            <<
" next: "<<iNext<<
" "<<f1<<
"\n";
 
  559             } 
else if((regmode==kRegModeCurvature)&&(iPrev>=0)&&(iNext>=0)) {
 
  560                Double_t f0 = factor[iPrev-startBin];
 
  561                Double_t f1 = -factor[bin-startBin];
 
  562                Double_t f2 = factor[iNext-startBin];
 
  563                if(isOptionGiven[4] & directionMask) {
 
  564                   if((distPrev<0.)&&(distNext>0.)) {
 
  566                      Double_t f=TMath::Power(binDistanceNormalisation,2.)/
 
  569                      f1 *= f*(1./distPrev+1./distNext);
 
  577                if((f0==0.0)||(f1==0.0)||(f2==0.0)) 
continue;
 
  578                if(AddRegularisationCondition(iPrev,f0,bin,f1,iNext,f2)) {
 
  581                   std::cout<<
"Added Reg: prev "<<iPrev<<
" "<<f0
 
  582                            <<
" bin: "<<bin<<
" "<<f1
 
  583                            <<
" next: "<<iNext<<
" "<<f2<<
"\n";
 
  590             if(regmode==kRegModeDerivative) {
 
  592             } 
else if(regmode==kRegModeCurvature) {
 
  595             name +=  binning->GetDistributionAxisLabel(direction);
 
  596             thisRegularisationBinning->AddBinning(name,nRegBins);
 
  650 TH1 *TUnfoldDensity::GetOutput
 
  651 (
const char *histogramName,
const char *histogramTitle,
 
  652  const char *distributionName,
const char *axisSteering,
 
  653  Bool_t useAxisBinning)
 const 
  655    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
  657    TH1 *r=binning->CreateHistogram
 
  658       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  660      TUnfoldSys::GetOutput(r,binMap);
 
  682 TH1 *TUnfoldDensity::GetBias
 
  683 (
const char *histogramName,
const char *histogramTitle,
 
  684  const char *distributionName,
const char *axisSteering,
 
  685  Bool_t useAxisBinning)
 const 
  687   TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
  689    TH1 *r=binning->CreateHistogram
 
  690       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  692       TUnfoldSys::GetBias(r,binMap);
 
  694    if(binMap) 
delete [] binMap;
 
  714 TH1 *TUnfoldDensity::GetFoldedOutput
 
  715 (
const char *histogramName,
const char *histogramTitle,
 
  716  const char *distributionName,
const char *axisSteering,
 
  717  Bool_t useAxisBinning,Bool_t addBgr)
 const 
  719    TUnfoldBinning 
const *binning=fConstInputBins->FindNode(distributionName);
 
  721    TH1 *r=binning->CreateHistogram
 
  722       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  724       TUnfoldSys::GetFoldedOutput(r,binMap);
 
  726          TUnfoldSys::GetBackground(r,0,binMap,0,kFALSE);
 
  729    if(binMap) 
delete [] binMap;
 
  750 TH1 *TUnfoldDensity::GetBackground
 
  751 (
const char *histogramName,
const char *bgrSource,
const char *histogramTitle,
 
  752  const char *distributionName,
const char *axisSteering,Bool_t useAxisBinning,
 
  753  Int_t includeError)
 const 
  755    TUnfoldBinning 
const *binning=fConstInputBins->FindNode(distributionName);
 
  757    TH1 *r=binning->CreateHistogram
 
  758       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  760       TUnfoldSys::GetBackground(r,bgrSource,binMap,includeError,kTRUE);
 
  762    if(binMap) 
delete [] binMap;
 
  780 TH1 *TUnfoldDensity::GetInput
 
  781 (
const char *histogramName,
const char *histogramTitle,
 
  782  const char *distributionName,
const char *axisSteering,
 
  783  Bool_t useAxisBinning)
 const 
  785    TUnfoldBinning 
const *binning=fConstInputBins->FindNode(distributionName);
 
  787    TH1 *r=binning->CreateHistogram
 
  788       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  790       TUnfoldSys::GetInput(r,binMap);
 
  792    if(binMap) 
delete [] binMap;
 
  813 TH1 *TUnfoldDensity::GetRhoItotal
 
  814 (
const char *histogramName,
const char *histogramTitle,
 
  815  const char *distributionName,
const char *axisSteering,
 
  816  Bool_t useAxisBinning,TH2 **ematInv) {
 
  817    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
  819    TH1 *r=binning->CreateHistogram
 
  820       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  824          if(r->GetDimension()==1) {
 
  825             TString ematName(histogramName);
 
  826             ematName += 
"_inverseEMAT";
 
  828             invEmat=binning->CreateErrorMatrixHistogram
 
  829                (ematName,useAxisBinning,&binMap2D,histogramTitle,
 
  831             if(binMap2D) 
delete [] binMap2D;
 
  833             Error(
"GetRhoItotal",
 
  834                   "can not return inverse of error matrix for this binning");
 
  837       TUnfoldSys::GetRhoItotal(r,binMap,invEmat);
 
  842    if(binMap) 
delete [] binMap;
 
  864 TH1 *TUnfoldDensity::GetRhoIstatbgr
 
  865 (
const char *histogramName,
const char *histogramTitle,
 
  866  const char *distributionName,
const char *axisSteering,
 
  867  Bool_t useAxisBinning,TH2 **ematInv) {
 
  868    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
  870    TH1 *r=binning->CreateHistogram
 
  871       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  875          if(r->GetDimension()==1) {
 
  876             TString ematName(histogramName);
 
  877             ematName += 
"_inverseEMAT";
 
  879             invEmat=binning->CreateErrorMatrixHistogram
 
  880                (ematName,useAxisBinning,&binMap2D,histogramTitle,
 
  882             if(binMap2D) 
delete [] binMap2D;
 
  884             Error(
"GetRhoItotal",
 
  885                   "can not return inverse of error matrix for this binning");
 
  888       TUnfoldSys::GetRhoI(r,binMap,invEmat);
 
  893    if(binMap) 
delete [] binMap;
 
  912 TH1 *TUnfoldDensity::GetDeltaSysSource
 
  913 (
const char *source,
const char *histogramName,
 
  914  const char *histogramTitle,
const char *distributionName,
 
  915  const char *axisSteering,Bool_t useAxisBinning) {
 
  916    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
  918    TH1 *r=binning->CreateHistogram
 
  919       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  921       if(!TUnfoldSys::GetDeltaSysSource(r,source,binMap)) {
 
  926    if(binMap) 
delete [] binMap;
 
  946 TH1 *TUnfoldDensity::GetDeltaSysBackgroundScale
 
  947 (
const char *bgrSource,
const char *histogramName,
 
  948  const char *histogramTitle,
const char *distributionName,
 
  949  const char *axisSteering,Bool_t useAxisBinning) {
 
  950    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
  952    TH1 *r=binning->CreateHistogram
 
  953       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  955       if(!TUnfoldSys::GetDeltaSysBackgroundScale(r,bgrSource,binMap)) {
 
  960    if(binMap) 
delete [] binMap;
 
  979 TH1 *TUnfoldDensity::GetDeltaSysTau
 
  980 (
const char *histogramName,
const char *histogramTitle,
 
  981  const char *distributionName,
const char *axisSteering,Bool_t useAxisBinning)
 
  983    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
  985    TH1 *r=binning->CreateHistogram
 
  986       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
  988       if(!TUnfoldSys::GetDeltaSysTau(r,binMap)) {
 
  993    if(binMap) 
delete [] binMap;
 
 1011 TH2 *TUnfoldDensity::GetRhoIJtotal
 
 1012 (
const char *histogramName,
const char *histogramTitle,
 
 1013  const char *distributionName,
const char *axisSteering,
 
 1014  Bool_t useAxisBinning)
 
 1016    TH2 *r=GetEmatrixTotal
 
 1017       (histogramName,histogramTitle,distributionName,
 
 1018        axisSteering,useAxisBinning);
 
 1020       for(Int_t i=0;i<=r->GetNbinsX()+1;i++) {
 
 1021          Double_t e_i=r->GetBinContent(i,i);
 
 1022          if(e_i>0.0) e_i=TMath::Sqrt(e_i);
 
 1024          for(Int_t j=0;j<=r->GetNbinsY()+1;j++) {
 
 1026             Double_t e_j=r->GetBinContent(j,j);
 
 1027             if(e_j>0.0) e_j=TMath::Sqrt(e_j);
 
 1029             Double_t e_ij=r->GetBinContent(i,j);
 
 1030             if((e_i>0.0)&&(e_j>0.0)) {
 
 1031                r->SetBinContent(i,j,e_ij/e_i/e_j);
 
 1033                r->SetBinContent(i,j,0.0);
 
 1037       for(Int_t i=0;i<=r->GetNbinsX()+1;i++) {
 
 1038    if(r->GetBinContent(i,i)>0.0) {
 
 1039      r->SetBinContent(i,i,1.0);
 
 1041      r->SetBinContent(i,i,0.0);
 
 1063 TH2 *TUnfoldDensity::GetEmatrixSysUncorr
 
 1064 (
const char *histogramName,
const char *histogramTitle,
 
 1065  const char *distributionName,
const char *axisSteering,
 
 1066  Bool_t useAxisBinning)
 
 1068    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
 1070    TH2 *r=binning->CreateErrorMatrixHistogram
 
 1071       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
 1073       TUnfoldSys::GetEmatrixSysUncorr(r,binMap);
 
 1075    if(binMap) 
delete [] binMap;
 
 1094 TH2 *TUnfoldDensity::GetEmatrixSysBackgroundUncorr
 
 1095 (
const char *bgrSource,
const char *histogramName,
 
 1096  const char *histogramTitle,
const char *distributionName,
 
 1097  const char *axisSteering,Bool_t useAxisBinning)
 
 1099    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
 1101    TH2 *r=binning->CreateErrorMatrixHistogram
 
 1102       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
 1104       TUnfoldSys::GetEmatrixSysBackgroundUncorr(r,bgrSource,binMap,kFALSE);
 
 1106    if(binMap) 
delete [] binMap;
 
 1125 TH2 *TUnfoldDensity::GetEmatrixInput
 
 1126 (
const char *histogramName,
const char *histogramTitle,
 
 1127  const char *distributionName,
const char *axisSteering,
 
 1128  Bool_t useAxisBinning)
 
 1130    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
 1132    TH2 *r=binning->CreateErrorMatrixHistogram
 
 1133       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
 1135       TUnfoldSys::GetEmatrixInput(r,binMap);
 
 1137    if(binMap) 
delete [] binMap;
 
 1152 TH2 *TUnfoldDensity::GetProbabilityMatrix
 
 1153 (
const char *histogramName,
const char *histogramTitle,
 
 1154  Bool_t useAxisBinning)
 const 
 1156    TH2 *r=TUnfoldBinning::CreateHistogramOfMigrations
 
 1157       (fConstOutputBins,fConstInputBins,histogramName,
 
 1158        useAxisBinning,useAxisBinning,histogramTitle);
 
 1159    TUnfold::GetProbabilityMatrix(r,kHistMapOutputHoriz);
 
 1177 TH2 *TUnfoldDensity::GetEmatrixTotal
 
 1178 (
const char *histogramName,
const char *histogramTitle,
 
 1179  const char *distributionName,
const char *axisSteering,
 
 1180  Bool_t useAxisBinning)
 
 1182    TUnfoldBinning 
const *binning=fConstOutputBins->FindNode(distributionName);
 
 1184    TH2 *r=binning->CreateErrorMatrixHistogram
 
 1185       (histogramName,useAxisBinning,&binMap,histogramTitle,axisSteering);
 
 1187       TUnfoldSys::GetEmatrixTotal(r,binMap);
 
 1189    if(binMap) 
delete [] binMap;
 
 1204 TH2 *TUnfoldDensity::GetL
 
 1205 (
const char *histogramName,
const char *histogramTitle,Bool_t useAxisBinning)
 
 1207    if(fRegularisationConditions &&
 
 1208       (fRegularisationConditions->GetEndBin()-
 
 1209        fRegularisationConditions->GetStartBin()!= fL->GetNrows())) {
 
 1211               "remove invalid scheme of regularisation conditions %d %d",
 
 1212               fRegularisationConditions->GetEndBin(),fL->GetNrows());
 
 1213       delete fRegularisationConditions;
 
 1214       fRegularisationConditions=0;
 
 1216    if(!fRegularisationConditions) {
 
 1217       fRegularisationConditions=
new TUnfoldBinning(
"regularisation",fL->GetNrows());
 
 1218       Warning(
"GetL",
"create flat regularisation conditions scheme");
 
 1220    TH2 *r=TUnfoldBinning::CreateHistogramOfMigrations
 
 1221       (fConstOutputBins,fRegularisationConditions,histogramName,
 
 1222        useAxisBinning,useAxisBinning,histogramTitle);
 
 1242 TH1 *TUnfoldDensity::GetLxMinusBias
 
 1243 (
const char *histogramName,
const char *histogramTitle)
 
 1245    TMatrixD dx(*GetX(), TMatrixD::kMinus, fBiasScale * (*fX0));
 
 1246    TMatrixDSparse *Ldx=MultiplyMSparseM(fL,&dx);
 
 1247    if(fRegularisationConditions &&
 
 1248       (fRegularisationConditions->GetEndBin()-
 
 1249        fRegularisationConditions->GetStartBin()!= fL->GetNrows())) {
 
 1250       Warning(
"GetLxMinusBias",
 
 1251               "remove invalid scheme of regularisation conditions %d %d",
 
 1252               fRegularisationConditions->GetEndBin(),fL->GetNrows());
 
 1253       delete fRegularisationConditions;
 
 1254       fRegularisationConditions=0;
 
 1256    if(!fRegularisationConditions) {
 
 1257       fRegularisationConditions=
new TUnfoldBinning(
"regularisation",fL->GetNrows());
 
 1258       Warning(
"GetLxMinusBias",
"create flat regularisation conditions scheme");
 
 1260    TH1 *r=fRegularisationConditions->CreateHistogram
 
 1261       (histogramName,kFALSE,0,histogramTitle);
 
 1262    const Int_t *Ldx_rows=Ldx->GetRowIndexArray();
 
 1263    const Double_t *Ldx_data=Ldx->GetMatrixArray();
 
 1264    for(Int_t row=0;row<Ldx->GetNrows();row++) {
 
 1265       if(Ldx_rows[row]<Ldx_rows[row+1]) {
 
 1266          r->SetBinContent(row+1,Ldx_data[Ldx_rows[row]]);
 
 1281 const TUnfoldBinning *TUnfoldDensity::GetInputBinning
 
 1282 (
const char *distributionName)
 const 
 1286    return fConstInputBins->FindNode(distributionName);
 
 1297 const TUnfoldBinning *TUnfoldDensity::GetOutputBinning
 
 1298 (
const char *distributionName)
 const 
 1302    return fConstOutputBins->FindNode(distributionName);
 
 1343 Int_t TUnfoldDensity::ScanTau
 
 1344 (Int_t nPoint,Double_t tauMin,Double_t tauMax,TSpline **scanResult,
 
 1345  Int_t mode,
const char *distribution,
const char *axisSteering,
 
 1346  TGraph **lCurvePlot,TSpline **logTauXPlot,TSpline **logTauYPlot)
 
 1348    typedef std::map<Double_t,Double_t> TauScan_t;
 
 1349    typedef std::map<Double_t,std::pair<Double_t,Double_t> > LCurve_t;
 
 1374    if((tauMin<=0)||(tauMax<=0.0)||(tauMin>=tauMax)) {
 
 1384          Error(
"ScanTau",
"too few input bins, NDF<=0 %d",GetNdf());
 
 1386       Double_t X0=GetLcurveX();
 
 1387       Double_t Y0=GetLcurveY();
 
 1388       Double_t y0=GetScanVariable(mode,distribution,axisSteering);
 
 1389       Info(
"ScanTau",
"logtau=-Infinity y=%lf X=%lf Y=%lf",y0,X0,Y0);
 
 1393             0.5*(TMath::Log10(GetChi2A()+3.*TMath::Sqrt(GetNdf()+1.0))
 
 1395          DoUnfold(TMath::Power(10.,logTau));
 
 1396          if((!TMath::Finite(GetLcurveX())) ||(!TMath::Finite(GetLcurveY()))) {
 
 1397             Fatal(
"ScanTau",
"problem (missing regularisation?) X=%f Y=%f",
 
 1398                   GetLcurveX(),GetLcurveY());
 
 1400          Double_t y=GetScanVariable(mode,distribution,axisSteering);
 
 1402          lcurve[logTau]=std::make_pair(GetLcurveX(),GetLcurveY());
 
 1403          Info(
"ScanTau",
"logtau=%lf y=%lf X=%lf Y=%lf",logTau,y,
 
 1404               GetLcurveX(),GetLcurveY());
 
 1409       while(((
int)curve.size()<nPoint-1)&&
 
 1410             ((TMath::Abs(GetLcurveX()-X0)>0.00432)||
 
 1411              (TMath::Abs(GetLcurveY()-Y0)>0.00432))) {
 
 1412          Double_t logTau=(*curve.begin()).first-0.5;
 
 1413          DoUnfold(TMath::Power(10.,logTau));
 
 1414          Double_t y=GetScanVariable(mode,distribution,axisSteering);
 
 1416          lcurve[logTau]=std::make_pair(GetLcurveX(),GetLcurveY());
 
 1417          Info(
"ScanTay",
"logtau=%lf y=%lf X=%lf Y=%lf",logTau,y,
 
 1418               GetLcurveX(),GetLcurveY());
 
 1421       Double_t logTauMin=TMath::Log10(tauMin);
 
 1422       Double_t logTauMax=TMath::Log10(tauMax);
 
 1425          DoUnfold(TMath::Power(10.,logTauMax));
 
 1426          Double_t y=GetScanVariable(mode,distribution,axisSteering);
 
 1428          lcurve[logTauMax]=std::make_pair(GetLcurveX(),GetLcurveY());
 
 1429          Info(
"ScanTau",
"logtau=%lf y=%lf X=%lf Y=%lf",logTauMax,y,
 
 1430               GetLcurveX(),GetLcurveY());
 
 1433       DoUnfold(TMath::Power(10.,logTauMin));
 
 1434       Double_t y=GetScanVariable(mode,distribution,axisSteering);
 
 1436       lcurve[logTauMin]=std::make_pair(GetLcurveX(),GetLcurveY());
 
 1437       Info(
"ScanTau",
"logtau=%lf y=%lf X=%lf Y=%lf",logTauMin,y,
 
 1438            GetLcurveX(),GetLcurveY());
 
 1444    while((
int)curve.size()<nPoint-1) {
 
 1450       TauScan_t::const_iterator i0,i1;
 
 1453       Double_t logTauYMin=(*i0).first;
 
 1454       Double_t yMin=(*i0).second;
 
 1455       for (; i0 != curve.end(); ++i0) {
 
 1456          if((*i0).second<yMin) {
 
 1458             logTauYMin=(*i0).first;
 
 1465       Double_t distMax=0.0;
 
 1466       Double_t logTau=0.0;
 
 1467       for (++i1; i1 != curve.end(); ++i1) {
 
 1470          dist=TMath::Abs((*i0).first-(*i1).first)
 
 1472             +0.25*TMath::Power(0.5*((*i0).first+(*i1).first)-logTauYMin,2.)/
 
 1473             ((*curve.rbegin()).first-(*curve.begin()).first)/nPoint;
 
 1474          if((dist<=0.0)||(dist>distMax)) {
 
 1476             logTau=0.5*((*i0).first+(*i1).first);
 
 1480       DoUnfold(TMath::Power(10.,logTau));
 
 1481       Double_t y=GetScanVariable(mode,distribution,axisSteering);
 
 1483       lcurve[logTau]=std::make_pair(GetLcurveX(),GetLcurveY());
 
 1484       Info(
"ScanTau",
"logtau=%lf y=%lf X=%lf Y=%lf",logTau,y,
 
 1485            GetLcurveX(),GetLcurveY());
 
 1496    Double_t *cTi=
new Double_t[curve.size()];
 
 1497    Double_t *cCi=
new Double_t[curve.size()];
 
 1499    for (TauScan_t::const_iterator i = curve.begin(); i != curve.end(); ++i) {
 
 1505    TSpline3 *splineC=
new TSpline3(
"L curve curvature",cTi,cCi,n);
 
 1514    Double_t cCmin=cCi[iskip];
 
 1516    for(Int_t i=iskip;i<n-1-iskip;i++) {
 
 1519       Double_t xMin=cTi[i+1];
 
 1520       Double_t yMin=cCi[i+1];
 
 1529       splineC->GetCoeff(i,x,y,b,c,d);
 
 1531       Double_t m_p_half=-c/(3.*d);
 
 1532       Double_t q=b/(3.*d);
 
 1533       Double_t discr=m_p_half*m_p_half-q;
 
 1536          discr=TMath::Sqrt(discr);
 
 1539             xx = m_p_half + discr;
 
 1541             xx = m_p_half - discr;
 
 1543          Double_t dx=cTi[i+1]-x;
 
 1545          if((xx>0.0)&&(xx<dx)) {
 
 1546             y=splineC->Eval(x+xx);
 
 1559          if((xx>0.0)&&(xx<dx)) {
 
 1560             y=splineC->Eval(x+xx);
 
 1577    Double_t logTauFin=cTmin;
 
 1578    DoUnfold(TMath::Power(10.,logTauFin));
 
 1580       Double_t y=GetScanVariable(mode,distribution,axisSteering);
 
 1582       lcurve[logTauFin]=std::make_pair(GetLcurveX(),GetLcurveY());
 
 1583       Info(
"ScanTau",
"Result logtau=%lf y=%lf X=%lf Y=%lf",logTauFin,y,
 
 1584            GetLcurveX(),GetLcurveY());
 
 1590    Int_t bestChoice=-1;
 
 1591    if(curve.size()>0) {
 
 1592       Double_t *y=
new Double_t[curve.size()];
 
 1593       Double_t *logT=
new Double_t[curve.size()];
 
 1595       for (TauScan_t::const_iterator i = curve.begin(); i != curve.end(); ++i) {
 
 1596          if(logTauFin==(*i).first) {
 
 1605          name = TString::Format(
"scan(%d,",mode);
 
 1606          if(distribution) name+= distribution;
 
 1608          if(axisSteering) name += axisSteering;
 
 1610          (*scanResult)=
new TSpline3(name+
"%log(tau)",logT,y,n);
 
 1616       Double_t *logT=
new Double_t[lcurve.size()];
 
 1617       Double_t *x=
new Double_t[lcurve.size()];
 
 1618       Double_t *y=
new Double_t[lcurve.size()];
 
 1620       for (LCurve_t::const_iterator i = lcurve.begin(); i != lcurve.end(); ++i) {
 
 1622          x[n]=(*i).second.first;
 
 1623          y[n]=(*i).second.second;
 
 1628          *lCurvePlot=
new TGraph(n,x,y);
 
 1629          (*lCurvePlot)->SetTitle(
"L curve");
 
 1632          *logTauXPlot=
new TSpline3(
"log(chi**2)%log(tau)",logT,x,n);
 
 1634          *logTauYPlot=
new TSpline3(
"log(reg.cond)%log(tau)",logT,y,n);
 
 1667 Double_t TUnfoldDensity::GetScanVariable
 
 1668 (Int_t mode,
const char *distribution,
const char *axisSteering)
 
 1671    TString name(
"GetScanVariable(");
 
 1672    name += TString::Format(
"%d,",mode);
 
 1673    if(distribution) name += distribution;
 
 1675    if(axisSteering) name += axisSteering;
 
 1678    if((mode==kEScanTauRhoAvg)||(mode==kEScanTauRhoMax)||
 
 1679       (mode==kEScanTauRhoSquareAvg)) {
 
 1680       rhoi=GetRhoIstatbgr(name,0,distribution,axisSteering,kFALSE);
 
 1681    } 
else if((mode==kEScanTauRhoAvgSys)||(mode==kEScanTauRhoMaxSys)||
 
 1682              (mode==kEScanTauRhoSquareAvgSys)) {
 
 1683       rhoi=GetRhoItotal(name,0,distribution,axisSteering,kFALSE);
 
 1687       Double_t sumSquare=0.0;
 
 1688       Double_t rhoMax=0.0;
 
 1690       for(Int_t i=0;i<=rhoi->GetNbinsX()+1;i++) {
 
 1691          Double_t c=rhoi->GetBinContent(i);
 
 1693             if(c>rhoMax) rhoMax=c;
 
 1699       if((mode==kEScanTauRhoAvg)||(mode==kEScanTauRhoAvgSys)) {
 
 1701       } 
else if((mode==kEScanTauRhoSquareAvg)||
 
 1702                 (mode==kEScanTauRhoSquareAvgSys)) {
 
 1710       Fatal(
"GetScanVariable",
"mode %d not implemented",mode);