#include <iostream>
#include <TMap.h>
#include <TMath.h>
#include <TObjString.h>
#include <RVersion.h>
#include <cmath>
#include "TUnfoldSys.h"
ClassImp(TUnfoldSys)
TUnfoldSys::TUnfoldSys(void)
{
InitTUnfoldSys();
}
TUnfoldSys::TUnfoldSys
(const TH2 *hist_A, EHistMap histmap, ERegMode regmode,EConstraint constraint)
: TUnfold(hist_A,histmap,regmode,constraint)
{
InitTUnfoldSys();
fAoutside = new TMatrixD(GetNx(),2);
fDAinColRelSq = new TMatrixD(GetNx(),1);
Int_t nmax=GetNx()*GetNy();
Int_t *rowDAinRelSq = new Int_t[nmax];
Int_t *colDAinRelSq = new Int_t[nmax];
Double_t *dataDAinRelSq = new Double_t[nmax];
Int_t da_nonzero=0;
for (Int_t ix = 0; ix < GetNx(); ix++) {
Int_t ibinx = fXToHist[ix];
Double_t sum_sq= fSumOverY[ix]*fSumOverY[ix];
for (Int_t ibiny = 0; ibiny <= GetNy()+1; ibiny++) {
Double_t dz;
if (histmap == kHistMapOutputHoriz) {
dz = hist_A->GetBinError(ibinx, ibiny);
} else {
dz = hist_A->GetBinError(ibiny, ibinx);
}
Double_t normerr_sq=dz*dz/sum_sq;
(*fDAinColRelSq)(ix,0) += normerr_sq;
if(ibiny==0) {
if (histmap == kHistMapOutputHoriz) {
(*fAoutside)(ix,0)=hist_A->GetBinContent(ibinx, ibiny);
} else {
(*fAoutside)(ix,0)=hist_A->GetBinContent(ibiny, ibinx);
}
} else if(ibiny==GetNy()+1) {
if (histmap == kHistMapOutputHoriz) {
(*fAoutside)(ix,1)=hist_A->GetBinContent(ibinx, ibiny);
} else {
(*fAoutside)(ix,1)=hist_A->GetBinContent(ibiny, ibinx);
}
} else {
rowDAinRelSq[da_nonzero]=ibiny-1;
colDAinRelSq[da_nonzero] = ix;
dataDAinRelSq[da_nonzero] = normerr_sq;
if(dataDAinRelSq[da_nonzero]>0.0) da_nonzero++;
}
}
}
if(da_nonzero) {
fDAinRelSq = CreateSparseMatrix(GetNy(),GetNx(),da_nonzero,
rowDAinRelSq,colDAinRelSq,dataDAinRelSq);
} else {
DeleteMatrix(&fDAinColRelSq);
}
delete[] rowDAinRelSq;
delete[] colDAinRelSq;
delete[] dataDAinRelSq;
}
void TUnfoldSys::AddSysError
(const TH2 *sysError,const char *name,EHistMap histmap,ESysErrMode mode)
{
if(fSysIn->FindObject(name)) {
Error("AddSysError","Source %s given twice, ignoring 2nd call.\n",name);
} else {
TMatrixD aCopy(*fA);
Int_t nmax= GetNx()*GetNy();
Double_t *data=new Double_t[nmax];
Int_t *cols=new Int_t[nmax];
Int_t *rows=new Int_t[nmax];
nmax=0;
for (Int_t ix = 0; ix < GetNx(); ix++) {
Int_t ibinx = fXToHist[ix];
Double_t sum=0.0;
for(Int_t loop=0;loop<2;loop++) {
for (Int_t ibiny = 0; ibiny <= GetNy()+1; ibiny++) {
Double_t z;
if (histmap == kHistMapOutputHoriz) {
z = sysError->GetBinContent(ibinx, ibiny);
} else {
z = sysError->GetBinContent(ibiny, ibinx);
}
if(mode!=kSysErrModeMatrix) {
Double_t z0;
if((ibiny>0)&&(ibiny<=GetNy())) {
z0=aCopy(ibiny-1,ix)*fSumOverY[ix];
} else if(ibiny==0) {
z0=(*fAoutside)(ix,0);
} else {
z0=(*fAoutside)(ix,1);
}
if(mode==kSysErrModeShift) {
z += z0;
} else if(mode==kSysErrModeRelative) {
z = z0*(1.+z);
}
}
if(loop==0) {
sum += z;
} else {
if((ibiny>0)&&(ibiny<=GetNy())) {
rows[nmax]=ibiny-1;
cols[nmax]=ix;
if(sum>0.0) {
data[nmax]=z/sum-aCopy(ibiny-1,ix);
} else {
data[nmax]=0.0;
}
if(data[nmax] != 0.0) nmax++;
}
}
}
}
}
if(nmax==0) {
Error("AddSysError",
"source %s has no influence and has not been added.\n",name);
} else {
TMatrixDSparse *dsys=CreateSparseMatrix(GetNy(),GetNx(),
nmax,rows,cols,data);
fSysIn->Add(new TObjString(name),dsys);
}
delete[] data;
delete[] rows;
delete[] cols;
}
}
void TUnfoldSys::DoBackgroundSubtraction(void)
{
if(fYData) {
DeleteMatrix(&fY);
DeleteMatrix(&fVyy);
if(fBgrIn->GetEntries()<=0) {
fY=new TMatrixD(*fYData);
fVyy=new TMatrixDSparse(*fVyyData);
} else {
if(GetVyyInv()) {
Warning("DoBackgroundSubtraction",
"inverse error matrix from user input,"
" not corrected for background");
}
fY=new TMatrixD(*fYData);
const TObject *key;
{
TMapIter bgrPtr(fBgrIn);
for(key=bgrPtr.Next();key;key=bgrPtr.Next()) {
const TMatrixD *bgr=(const TMatrixD *)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
((const TPair *)*bgrPtr)->Value()
#else
fBgrIn->GetValue(((const TObjString *)key)->GetString())
#endif
;
for(Int_t i=0;i<GetNy();i++) {
(*fY)(i,0) -= (*bgr)(i,0);
}
}
}
TMatrixD vyy(*fVyyData);
Int_t ny=fVyyData->GetNrows();
const Int_t *vyydata_rows=fVyyData->GetRowIndexArray();
const Int_t *vyydata_cols=fVyyData->GetColIndexArray();
const Double_t *vyydata_data=fVyyData->GetMatrixArray();
Int_t *usedBin=new Int_t[ny];
for(Int_t i=0;i<ny;i++) {
usedBin[i]=0;
}
for(Int_t i=0;i<ny;i++) {
for(Int_t k=vyydata_rows[i];k<vyydata_rows[i+1];k++) {
if(vyydata_data[k]>0.0) {
usedBin[i]++;
usedBin[vyydata_cols[k]]++;
}
}
}
{
TMapIter bgrErrUncorrSqPtr(fBgrErrUncorrInSq);
for(key=bgrErrUncorrSqPtr.Next();key;
key=bgrErrUncorrSqPtr.Next()) {
const TMatrixD *bgrerruncorrSquared=(TMatrixD const *)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
((const TPair *)*bgrErrUncorrSqPtr)->Value()
#else
fBgrErrUncorrInSq->GetValue(((const TObjString *)key)
->GetString())
#endif
;
for(Int_t yi=0;yi<ny;yi++) {
if(!usedBin[yi]) continue;
vyy(yi,yi) +=(*bgrerruncorrSquared)(yi,0);
}
}
}
{
TMapIter bgrErrScalePtr(fBgrErrScaleIn);
for(key=bgrErrScalePtr.Next();key;key=bgrErrScalePtr.Next()) {
const TMatrixD *bgrerrscale=(const TMatrixD *)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
((const TPair *)*bgrErrScalePtr)->Value()
#else
fBgrErrScaleIn->GetValue(((const TObjString *)key)
->GetString())
#endif
;
for(Int_t yi=0;yi<ny;yi++) {
if(!usedBin[yi]) continue;
for(Int_t yj=0;yj<ny;yj++) {
if(!usedBin[yj]) continue;
vyy(yi,yj) +=(*bgrerrscale)(yi,0)* (*bgrerrscale)(yj,0);
}
}
}
}
delete[] usedBin;
usedBin=0;
fVyy=new TMatrixDSparse(vyy);
}
} else {
Fatal("DoBackgroundSubtraction","No input vector defined");
}
}
Int_t TUnfoldSys::SetInput(const TH1 *hist_y,Double_t scaleBias,
Double_t oneOverZeroError,const TH2 *hist_vyy,
const TH2 *hist_vyy_inv)
{
Int_t r=TUnfold::SetInput(hist_y,scaleBias,oneOverZeroError,hist_vyy,
hist_vyy_inv);
fYData=fY;
fY=0;
fVyyData=fVyy;
fVyy=0;
DoBackgroundSubtraction();
return r;
}
void TUnfoldSys::SubtractBackground
(const TH1 *bgr,const char *name,Double_t scale,Double_t scale_error)
{
if(fBgrIn->FindObject(name)) {
Error("SubtractBackground","Source %s given twice, ignoring 2nd call.\n",
name);
} else {
TMatrixD *bgrScaled=new TMatrixD(GetNy(),1);
TMatrixD *bgrErrUncSq=new TMatrixD(GetNy(),1);
TMatrixD *bgrErrCorr=new TMatrixD(GetNy(),1);
for(Int_t row=0;row<GetNy();row++) {
(*bgrScaled)(row,0) = scale*bgr->GetBinContent(row+1);
(*bgrErrUncSq)(row,0) =
TMath::Power(scale*bgr->GetBinError(row+1),2.);
(*bgrErrCorr)(row,0) = scale_error*bgr->GetBinContent(row+1);
}
fBgrIn->Add(new TObjString(name),bgrScaled);
fBgrErrUncorrInSq->Add(new TObjString(name),bgrErrUncSq);
fBgrErrScaleIn->Add(new TObjString(name),bgrErrCorr);
if(fYData) {
DoBackgroundSubtraction();
} else {
Info("SubtractBackground",
"Background subtraction prior to setting input data");
}
}
}
void TUnfoldSys::GetBackground
(TH1 *bgrHist,const char *bgrSource,const Int_t *binMap,
Int_t includeError,Bool_t clearHist) const
{
if(clearHist) {
ClearHistogram(bgrHist);
}
const TObject *key;
{
TMapIter bgrPtr(fBgrIn);
for(key=bgrPtr.Next();key;key=bgrPtr.Next()) {
TString bgrName=((const TObjString *)key)->GetString();
if(bgrSource && bgrName.CompareTo(bgrSource)) continue;
const TMatrixD *bgr=(const TMatrixD *)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
((const TPair *)*bgrPtr)->Value()
#else
fBgrIn->GetValue(bgrName)
#endif
;
for(Int_t i=0;i<GetNy();i++) {
Int_t destBin=binMap[i];
bgrHist->SetBinContent(destBin,bgrHist->GetBinContent(destBin)+
(*bgr)(i,0));
}
}
}
if(includeError &1) {
TMapIter bgrErrUncorrSqPtr(fBgrErrUncorrInSq);
for(key=bgrErrUncorrSqPtr.Next();key;key=bgrErrUncorrSqPtr.Next()) {
TString bgrName=((const TObjString *)key)->GetString();
if(bgrSource && bgrName.CompareTo(bgrSource)) continue;
const TMatrixD *bgrerruncorrSquared=(TMatrixD const *)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
((const TPair *)*bgrErrUncorrSqPtr)->Value()
#else
fBgrErrUncorrInSq->GetValue(((const TObjString *)key)
->GetString())
#endif
;
for(Int_t i=0;i<GetNy();i++) {
Int_t destBin=binMap[i];
bgrHist->SetBinError
(destBin,TMath::Sqrt
((*bgrerruncorrSquared)(i,0)+
TMath::Power(bgrHist->GetBinError(destBin),2.)));
}
}
}
if(includeError & 2) {
TMapIter bgrErrScalePtr(fBgrErrScaleIn);
for(key=bgrErrScalePtr.Next();key;key=bgrErrScalePtr.Next()) {
TString bgrName=((const TObjString *)key)->GetString();
if(bgrSource && bgrName.CompareTo(bgrSource)) continue;
const TMatrixD *bgrerrscale=(TMatrixD const *)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
((const TPair *)*bgrErrScalePtr)->Value()
#else
fBgrErrScaleIn->GetValue(((const TObjString *)key)->GetString())
#endif
;
for(Int_t i=0;i<GetNy();i++) {
Int_t destBin=binMap[i];
bgrHist->SetBinError(destBin,hypot((*bgrerrscale)(i,0),
bgrHist->GetBinError(destBin)));
}
}
}
}
void TUnfoldSys::InitTUnfoldSys(void)
{
fDAinRelSq = 0;
fDAinColRelSq = 0;
fAoutside = 0;
fBgrIn = new TMap();
fBgrErrUncorrInSq = new TMap();
fBgrErrScaleIn = new TMap();
fSysIn = new TMap();
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
fBgrIn->SetOwnerKeyValue();
fBgrErrUncorrInSq->SetOwnerKeyValue();
fBgrErrScaleIn->SetOwnerKeyValue();
fSysIn->SetOwnerKeyValue();
#else
fBgrIn->SetOwner();
fBgrErrUncorrInSq->SetOwner();
fBgrErrScaleIn->SetOwner();
fSysIn->SetOwner();
#endif
fEmatUncorrX = 0;
fEmatUncorrAx = 0;
fDeltaCorrX = new TMap();
fDeltaCorrAx = new TMap();
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
fDeltaCorrX->SetOwnerKeyValue();
fDeltaCorrAx->SetOwnerKeyValue();
#else
fDeltaCorrX->SetOwner();
fDeltaCorrAx->SetOwner();
#endif
fDeltaSysTau = 0;
fDtau=0.0;
fYData=0;
fVyyData=0;
}
TUnfoldSys::~TUnfoldSys(void)
{
DeleteMatrix(&fDAinRelSq);
DeleteMatrix(&fDAinColRelSq);
delete fBgrIn;
delete fBgrErrUncorrInSq;
delete fBgrErrScaleIn;
delete fSysIn;
ClearResults();
delete fDeltaCorrX;
delete fDeltaCorrAx;
DeleteMatrix(&fYData);
DeleteMatrix(&fVyyData);
}
void TUnfoldSys::ClearResults(void)
{
TUnfold::ClearResults();
DeleteMatrix(&fEmatUncorrX);
DeleteMatrix(&fEmatUncorrAx);
fDeltaCorrX->Clear();
fDeltaCorrAx->Clear();
DeleteMatrix(&fDeltaSysTau);
}
void TUnfoldSys::PrepareSysError(void)
{
if(!fEmatUncorrX) {
fEmatUncorrX=PrepareUncorrEmat(GetDXDAM(0),GetDXDAM(1));
}
TMatrixDSparse *AM0=0,*AM1=0;
if(!fEmatUncorrAx) {
if(!AM0) AM0=MultiplyMSparseMSparse(fA,GetDXDAM(0));
if(!AM1) {
AM1=MultiplyMSparseMSparse(fA,GetDXDAM(1));
Int_t *rows_cols=new Int_t[GetNy()];
Double_t *data=new Double_t[GetNy()];
for(Int_t i=0;i<GetNy();i++) {
rows_cols[i]=i;
data[i]=1.0;
}
TMatrixDSparse *one=CreateSparseMatrix
(GetNy(),GetNy(),GetNy(),rows_cols, rows_cols,data);
delete[] data;
delete[] rows_cols;
AddMSparse(AM1,-1.,one);
DeleteMatrix(&one);
fEmatUncorrAx=PrepareUncorrEmat(AM0,AM1);
}
}
if((!fDeltaSysTau )&&(fDtau>0.0)) {
fDeltaSysTau=new TMatrixDSparse(*GetDXDtauSquared());
Double_t scale=2.*TMath::Sqrt(fTauSquared)*fDtau;
Int_t n=fDeltaSysTau->GetRowIndexArray() [fDeltaSysTau->GetNrows()];
Double_t *data=fDeltaSysTau->GetMatrixArray();
for(Int_t i=0;i<n;i++) {
data[i] *= scale;
}
}
TMapIter sysErrIn(fSysIn);
const TObjString *key;
for(key=(const TObjString *)sysErrIn.Next();key;
key=(const TObjString *)sysErrIn.Next()) {
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
const TMatrixDSparse *dsys=
(const TMatrixDSparse *)((const TPair *)*sysErrIn)->Value();
#else
const TMatrixDSparse *dsys=
(const TMatrixDSparse *)(fSysIn->GetValue(key->GetString()));
#endif
const TPair *named_emat=(const TPair *)
fDeltaCorrX->FindObject(key->GetString());
if(!named_emat) {
TMatrixDSparse *emat=PrepareCorrEmat(GetDXDAM(0),GetDXDAM(1),dsys);
fDeltaCorrX->Add(new TObjString(*key),emat);
}
named_emat=(const TPair *)fDeltaCorrAx->FindObject(key->GetString());
if(!named_emat) {
if(!AM0) AM0=MultiplyMSparseMSparse(fA,GetDXDAM(0));
if(!AM1) {
AM1=MultiplyMSparseMSparse(fA,GetDXDAM(1));
Int_t *rows_cols=new Int_t[GetNy()];
Double_t *data=new Double_t[GetNy()];
for(Int_t i=0;i<GetNy();i++) {
rows_cols[i]=i;
data[i]=1.0;
}
TMatrixDSparse *one=CreateSparseMatrix
(GetNy(),GetNy(),GetNy(),rows_cols, rows_cols,data);
delete[] data;
delete[] rows_cols;
AddMSparse(AM1,-1.,one);
DeleteMatrix(&one);
fEmatUncorrAx=PrepareUncorrEmat(AM0,AM1);
}
TMatrixDSparse *emat=PrepareCorrEmat(AM0,AM1,dsys);
fDeltaCorrAx->Add(new TObjString(*key),emat);
}
}
DeleteMatrix(&AM0);
DeleteMatrix(&AM1);
}
void TUnfoldSys::GetEmatrixSysUncorr
(TH2 *ematrix,const Int_t *binMap,Bool_t clearEmat)
{
PrepareSysError();
ErrorMatrixToHist(ematrix,fEmatUncorrX,binMap,clearEmat);
}
TMatrixDSparse *TUnfoldSys::PrepareUncorrEmat
(const TMatrixDSparse *m_0,const TMatrixDSparse *m_1)
{
TMatrixDSparse *r=0;
if(fDAinColRelSq && fDAinRelSq) {
TMatrixDSparse *M1A_Z1=MultiplyMSparseMSparse(m_1,fA);
ScaleColumnsByVector(M1A_Z1,GetDXDAZ(1));
TMatrixDSparse *M1Rsq_Z1=MultiplyMSparseMSparse(m_1,fDAinRelSq);
ScaleColumnsByVector(M1Rsq_Z1,GetDXDAZ(1));
TMatrixDSparse *AtZ0 = MultiplyMSparseTranspMSparse(fA,GetDXDAZ(0));
TMatrixDSparse *RsqZ0=
MultiplyMSparseTranspMSparse(fDAinRelSq,GetDXDAZ(0));
TMatrixDSparse *F=new TMatrixDSparse(*m_0);
ScaleColumnsByVector(F,AtZ0);
AddMSparse(F,-1.0,M1A_Z1);
TMatrixDSparse *G=new TMatrixDSparse(*m_0);
ScaleColumnsByVector(G,RsqZ0);
AddMSparse(G,-1.0,M1Rsq_Z1);
DeleteMatrix(&M1A_Z1);
DeleteMatrix(&M1Rsq_Z1);
DeleteMatrix(&AtZ0);
DeleteMatrix(&RsqZ0);
r=MultiplyMSparseMSparseTranspVector(F,F,fDAinColRelSq);
TMatrixDSparse *r1=MultiplyMSparseMSparseTranspVector(F,G,0);
TMatrixDSparse *r2=MultiplyMSparseMSparseTranspVector(G,F,0);
AddMSparse(r,-1.0,r1);
AddMSparse(r,-1.0,r2);
DeleteMatrix(&r1);
DeleteMatrix(&r2);
DeleteMatrix(&F);
DeleteMatrix(&G);
}
if(fDAinRelSq) {
TMatrixDSparse Z0sq(*GetDXDAZ(0));
const Int_t *Z0sq_rows=Z0sq.GetRowIndexArray();
Double_t *Z0sq_data=Z0sq.GetMatrixArray();
for(int index=0;index<Z0sq_rows[Z0sq.GetNrows()];index++) {
Z0sq_data[index] *= Z0sq_data[index];
}
TMatrixDSparse *Z0sqRsq=MultiplyMSparseTranspMSparse(fDAinRelSq,&Z0sq);
TMatrixDSparse *r3=MultiplyMSparseMSparseTranspVector(m_0,m_0,Z0sqRsq);
DeleteMatrix(&Z0sqRsq);
TMatrixDSparse Z1sq(*GetDXDAZ(1));
const Int_t *Z1sq_rows=Z1sq.GetRowIndexArray();
Double_t *Z1sq_data=Z1sq.GetMatrixArray();
for(int index=0;index<Z1sq_rows[Z1sq.GetNrows()];index++) {
Z1sq_data[index] *= Z1sq_data[index];
}
TMatrixDSparse *Z1sqRsq=MultiplyMSparseMSparse(fDAinRelSq,&Z1sq);
TMatrixDSparse *r4=MultiplyMSparseMSparseTranspVector(m_1,m_1,Z1sqRsq);
DeleteMatrix(&Z1sqRsq);
TMatrixDSparse *H=MultiplyMSparseMSparseTranspVector
(m_0,fDAinRelSq,GetDXDAZ(1));
ScaleColumnsByVector(H,GetDXDAZ(0));
TMatrixDSparse *r5=MultiplyMSparseMSparseTranspVector(m_1,H,0);
TMatrixDSparse *r6=MultiplyMSparseMSparseTranspVector(H,m_1,0);
DeleteMatrix(&H);
if(r) {
AddMSparse(r,1.0,r3);
DeleteMatrix(&r3);
} else {
r=r3;
r3=0;
}
AddMSparse(r,1.0,r4);
AddMSparse(r,-1.0,r5);
AddMSparse(r,-1.0,r6);
DeleteMatrix(&r4);
DeleteMatrix(&r5);
DeleteMatrix(&r6);
}
return r;
}
TMatrixDSparse *TUnfoldSys::PrepareCorrEmat
(const TMatrixDSparse *m1,const TMatrixDSparse *m2,const TMatrixDSparse *dsys)
{
TMatrixDSparse *dsysT_VYAx = MultiplyMSparseTranspMSparse(dsys,GetDXDAZ(0));
TMatrixDSparse *delta = MultiplyMSparseMSparse(m1,dsysT_VYAx);
DeleteMatrix(&dsysT_VYAx);
TMatrixDSparse *dsys_X = MultiplyMSparseMSparse(dsys,GetDXDAZ(1));
TMatrixDSparse *delta2 = MultiplyMSparseMSparse(m2,dsys_X);
DeleteMatrix(&dsys_X);
AddMSparse(delta,-1.0,delta2);
DeleteMatrix(&delta2);
return delta;
}
void TUnfoldSys::SetTauError(Double_t delta_tau)
{
fDtau=delta_tau;
DeleteMatrix(&fDeltaSysTau);
}
Bool_t TUnfoldSys::GetDeltaSysSource(TH1 *hist_delta,const char *name,
const Int_t *binMap)
{
PrepareSysError();
const TPair *named_emat=(const TPair *)fDeltaCorrX->FindObject(name);
const TMatrixDSparse *delta=0;
if(named_emat) {
delta=(TMatrixDSparse *)named_emat->Value();
}
VectorMapToHist(hist_delta,delta,binMap);
return delta !=0;
}
Bool_t TUnfoldSys::GetDeltaSysBackgroundScale
(TH1 *hist_delta,const char *source,const Int_t *binMap)
{
PrepareSysError();
const TPair *named_err=(const TPair *)fBgrErrScaleIn->FindObject(source);
TMatrixDSparse *dx=0;
if(named_err) {
const TMatrixD *dy=(TMatrixD *)named_err->Value();
dx=MultiplyMSparseM(GetDXDY(),dy);
}
VectorMapToHist(hist_delta,dx,binMap);
if(dx!=0) {
DeleteMatrix(&dx);
return kTRUE;
}
return kFALSE;
}
Bool_t TUnfoldSys::GetDeltaSysTau(TH1 *hist_delta,const Int_t *binMap)
{
PrepareSysError();
VectorMapToHist(hist_delta,fDeltaSysTau,binMap);
return fDeltaSysTau !=0;
}
void TUnfoldSys::GetEmatrixSysSource
(TH2 *ematrix,const char *name,const Int_t *binMap,Bool_t clearEmat)
{
PrepareSysError();
const TPair *named_emat=(const TPair *)fDeltaCorrX->FindObject(name);
TMatrixDSparse *emat=0;
if(named_emat) {
const TMatrixDSparse *delta=(TMatrixDSparse *)named_emat->Value();
emat=MultiplyMSparseMSparseTranspVector(delta,delta,0);
}
ErrorMatrixToHist(ematrix,emat,binMap,clearEmat);
DeleteMatrix(&emat);
}
void TUnfoldSys::GetEmatrixSysBackgroundScale
(TH2 *ematrix,const char *name,const Int_t *binMap,Bool_t clearEmat)
{
PrepareSysError();
const TPair *named_err=(const TPair *)fBgrErrScaleIn->FindObject(name);
TMatrixDSparse *emat=0;
if(named_err) {
const TMatrixD *dy=(TMatrixD *)named_err->Value();
TMatrixDSparse *dx=MultiplyMSparseM(GetDXDY(),dy);
emat=MultiplyMSparseMSparseTranspVector(dx,dx,0);
DeleteMatrix(&dx);
}
ErrorMatrixToHist(ematrix,emat,binMap,clearEmat);
DeleteMatrix(&emat);
}
void TUnfoldSys::GetEmatrixSysTau
(TH2 *ematrix,const Int_t *binMap,Bool_t clearEmat)
{
PrepareSysError();
TMatrixDSparse *emat=0;
if(fDeltaSysTau) {
emat=MultiplyMSparseMSparseTranspVector(fDeltaSysTau,fDeltaSysTau,0);
}
ErrorMatrixToHist(ematrix,emat,binMap,clearEmat);
DeleteMatrix(&emat);
}
void TUnfoldSys::GetEmatrixInput
(TH2 *ematrix,const Int_t *binMap,Bool_t clearEmat)
{
GetEmatrixFromVyy(fVyyData,ematrix,binMap,clearEmat);
}
void TUnfoldSys::GetEmatrixSysBackgroundUncorr
(TH2 *ematrix,const char *source,const Int_t *binMap,Bool_t clearEmat)
{
const TPair *named_err=(const TPair *)fBgrErrUncorrInSq->FindObject(source);
TMatrixDSparse *emat=0;
if(named_err) {
TMatrixD const *dySquared=(TMatrixD const *)named_err->Value();
emat=MultiplyMSparseMSparseTranspVector(GetDXDY(),GetDXDY(),dySquared);
}
ErrorMatrixToHist(ematrix,emat,binMap,clearEmat);
DeleteMatrix(&emat);
}
void TUnfoldSys::GetEmatrixFromVyy
(const TMatrixDSparse *vyy,TH2 *ematrix,const Int_t *binMap,Bool_t clearEmat)
{
PrepareSysError();
TMatrixDSparse *em=0;
if(vyy) {
TMatrixDSparse *dxdyVyy=MultiplyMSparseMSparse(GetDXDY(),vyy);
em=MultiplyMSparseMSparseTranspVector(dxdyVyy,GetDXDY(),0);
DeleteMatrix(&dxdyVyy);
}
ErrorMatrixToHist(ematrix,em,binMap,clearEmat);
DeleteMatrix(&em);
}
void TUnfoldSys::GetEmatrixTotal(TH2 *ematrix,const Int_t *binMap)
{
GetEmatrix(ematrix,binMap);
GetEmatrixSysUncorr(ematrix,binMap,kFALSE);
TMapIter sysErrPtr(fDeltaCorrX);
const TObject *key;
for(key=sysErrPtr.Next();key;key=sysErrPtr.Next()) {
GetEmatrixSysSource(ematrix,
((const TObjString *)key)->GetString(),
binMap,kFALSE);
}
GetEmatrixSysTau(ematrix,binMap,kFALSE);
}
TMatrixDSparse *TUnfoldSys::GetSummedErrorMatrixYY(void)
{
PrepareSysError();
TMatrixDSparse *emat_sum=new TMatrixDSparse(*fVyy);
AddMSparse(emat_sum,1.0,fEmatUncorrAx);
TMapIter sysErrPtr(fDeltaCorrAx);
const TObject *key;
for(key=sysErrPtr.Next();key;key=sysErrPtr.Next()) {
const TMatrixDSparse *delta=(TMatrixDSparse *)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
((const TPair *)*sysErrPtr)->Value()
#else
fDeltaCorrAx->GetValue(((const TObjString *)key)
->GetString())
#endif
;
TMatrixDSparse *emat=MultiplyMSparseMSparseTranspVector(delta,delta,0);
AddMSparse(emat_sum,1.0,emat);
DeleteMatrix(&emat);
}
if(fDeltaSysTau) {
TMatrixDSparse *Adx_tau=MultiplyMSparseMSparse(fA,fDeltaSysTau);
TMatrixDSparse *emat_tau=
MultiplyMSparseMSparseTranspVector(Adx_tau,Adx_tau,0);
DeleteMatrix(&Adx_tau);
AddMSparse(emat_sum,1.0,emat_tau);
DeleteMatrix(&emat_tau);
}
return emat_sum;
}
TMatrixDSparse *TUnfoldSys::GetSummedErrorMatrixXX(void)
{
PrepareSysError();
TMatrixDSparse *emat_sum=new TMatrixDSparse(*GetVxx());
AddMSparse(emat_sum,1.0,fEmatUncorrX);
TMapIter sysErrPtr(fDeltaCorrX);
const TObject *key;
for(key=sysErrPtr.Next();key;key=sysErrPtr.Next()) {
const TMatrixDSparse *delta=(TMatrixDSparse *)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
((const TPair *)*sysErrPtr)->Value()
#else
fDeltaCorrX->GetValue(((const TObjString *)key)
->GetString())
#endif
;
TMatrixDSparse *emat=MultiplyMSparseMSparseTranspVector(delta,delta,0);
AddMSparse(emat_sum,1.0,emat);
DeleteMatrix(&emat);
}
if(fDeltaSysTau) {
TMatrixDSparse *emat_tau=
MultiplyMSparseMSparseTranspVector(fDeltaSysTau,fDeltaSysTau,0);
AddMSparse(emat_sum,1.0,emat_tau);
DeleteMatrix(&emat_tau);
}
return emat_sum;
}
Double_t TUnfoldSys::GetChi2Sys(void)
{
TMatrixDSparse *emat_sum=GetSummedErrorMatrixYY();
Int_t rank=0;
TMatrixDSparse *v=InvertMSparseSymmPos(emat_sum,&rank);
TMatrixD dy(*fY, TMatrixD::kMinus, *GetAx());
TMatrixDSparse *vdy=MultiplyMSparseM(v,&dy);
DeleteMatrix(&v);
Double_t r=0.0;
const Int_t *vdy_rows=vdy->GetRowIndexArray();
const Double_t *vdy_data=vdy->GetMatrixArray();
for(Int_t i=0;i<vdy->GetNrows();i++) {
if(vdy_rows[i+1]>vdy_rows[i]) {
r += vdy_data[vdy_rows[i]] * dy(i,0);
}
}
DeleteMatrix(&vdy);
DeleteMatrix(&emat_sum);
return r;
}
void TUnfoldSys::GetRhoItotal(TH1 *rhoi,const Int_t *binMap,TH2 *invEmat)
{
ClearHistogram(rhoi,-1.);
TMatrixDSparse *emat_sum=GetSummedErrorMatrixXX();
GetRhoIFromMatrix(rhoi,emat_sum,binMap,invEmat);
DeleteMatrix(&emat_sum);
}
void TUnfoldSys::ScaleColumnsByVector
(TMatrixDSparse *m,const TMatrixTBase<Double_t> *v) const
{
if((m->GetNcols() != v->GetNrows())||(v->GetNcols()!=1)) {
Fatal("ScaleColumnsByVector error",
"matrix cols/vector rows %d!=%d OR vector cols %d !=1\n",
m->GetNcols(),v->GetNrows(),v->GetNcols());
}
const Int_t *rows_m=m->GetRowIndexArray();
const Int_t *cols_m=m->GetColIndexArray();
Double_t *data_m=m->GetMatrixArray();
const TMatrixDSparse *v_sparse=dynamic_cast<const TMatrixDSparse *>(v);
if(v_sparse) {
const Int_t *rows_v=v_sparse->GetRowIndexArray();
const Double_t *data_v=v_sparse->GetMatrixArray();
for(Int_t i=0;i<m->GetNrows();i++) {
for(Int_t index_m=rows_m[i];index_m<rows_m[i+1];index_m++) {
Int_t j=cols_m[index_m];
Int_t index_v=rows_v[j];
if(index_v<rows_v[j+1]) {
data_m[index_m] *= data_v[index_v];
} else {
data_m[index_m] =0.0;
}
}
}
} else {
for(Int_t i=0;i<m->GetNrows();i++) {
for(Int_t index=rows_m[i];index<rows_m[i+1];index++) {
data_m[index] *= (*v)(cols_m[index],0);
}
}
}
}
void TUnfoldSys::VectorMapToHist
(TH1 *hist_delta,const TMatrixDSparse *delta,const Int_t *binMap)
{
Int_t nbin=hist_delta->GetNbinsX();
Double_t *c=new Double_t[nbin+2];
for(Int_t i=0;i<nbin+2;i++) {
c[i]=0.0;
}
if(delta) {
Int_t binMapSize = fHistToX.GetSize();
const Double_t *delta_data=delta->GetMatrixArray();
const Int_t *delta_rows=delta->GetRowIndexArray();
for(Int_t i=0;i<binMapSize;i++) {
Int_t destBinI=binMap ? binMap[i] : i;
Int_t srcBinI=fHistToX[i];
if((destBinI>=0)&&(destBinI<nbin+2)&&(srcBinI>=0)) {
Int_t index=delta_rows[srcBinI];
if(index<delta_rows[srcBinI+1]) {
c[destBinI]+=delta_data[index];
}
}
}
}
for(Int_t i=0;i<nbin+2;i++) {
hist_delta->SetBinContent(i,c[i]);
hist_delta->SetBinError(i,0.0);
}
delete[] c;
}