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);