// Author: Stefan Schmitt
// DESY, 13/10/08

//  Version 17.1, bug fixes in GetFoldedOutput, GetOutput
//
//  History:
//    Version 17.0, option to specify an error matrix with SetInput(), new ScanRho() method
//    Version 16.2, in parallel to bug-fix in TUnfoldSys
//    Version 16.1, fix bug with error matrix in case kEConstraintArea is used
//    Version 16.0, fix calculation of global correlations, improved error messages
//    Version 15, simplified L-curve scan, new tau definition, new error calc., area preservation
//    Version 14, with changes in TUnfoldSys.cxx
//    Version 13, new methods for derived classes and small bug fix
//    Version 12, report singular matrices
//    Version 11, reduce the amount of printout
//    Version 10, more correct definition of the L curve, update references
//    Version 9, faster matrix inversion and skip edge points for L-curve scan
//    Version 8, replace all TMatrixSparse matrix operations by private code
//    Version 7, fix problem with TMatrixDSparse,TMatrixD multiplication
//    Version 6, replace class XY by std::pair
//    Version 5, replace run-time dynamic arrays by new and delete[]
//    Version 4, fix new bug from V3 with initial regularisation condition
//    Version 3, fix bug with initial regularisation condition
//    Version 2, with improved ScanLcurve() algorithm
//    Version 1, added ScanLcurve() method
//    Version 0, stable version of basic unfolding algorithm

////////////////////////////////////////////////////////////////////////
//
//  TUnfold is used to decompose a measurement y into several sources x
//  given the measurement uncertainties and a matrix of migrations A
//
//  *************************************************************
//  * For most applications, it is better to use TUnfoldDensity *
//  * instead of using TUnfoldSys or TUnfold                    *
//  *************************************************************
//
//  If you use this software, please consider the following citation
//       S.Schmitt, JINST 7 (2012) T10003 [arXiv:1205.6201]
//
//  More documentation and updates are available on
//      http://www.desy.de/~sschmitt
//
//
//  A short summary of the algorithm is given in the following:
//
//  the "best" x matching the measurement y within errors
//  is determined by minimizing the function
//    L1+L2+L3
//
//  where
//   L1 = (y-Ax)# Vyy^-1 (y-Ax)
//   L2 = tau^2 (L(x-x0))# L(x-x0)
//   L3 = lambda sum_i(y_i -(Ax)_i)
//
//  [the notation # means that the matrix is transposed ]
//
//  The term L1 is familiar from a least-square minimisation
//  The term L2 defines the regularisation (smootheness condition on x),
//    where the parameter tau^2 gives the strength of teh regularisation
//  The term L3 is an optional area constraint with Lagrangian parameter
//    lambda, ensuring that that the normalisation of x is consistent with the
//    normalisation of y
//
//  The method can be applied to a very large number of problems,
//  where the measured distribution y is a linear superposition
//  of several Monte Carlo shapes
//
// Input from measurement:
// -----------------------
//   y: vector of measured quantities  (dimension ny)
//   Vyy: covariance matrix for y (dimension ny x ny)
//        in many cases V is diagonal and calculated from the errors of y
//
// From simulation:
// ----------------
//   A: migration matrix               (dimension ny x nx)
//
// Result
// ------
//   x: unknown underlying distribution (dimension nx)
//      The error matrix of x, V_xx, is also determined
//
// Regularisation
// --------------
//   tau: parameter, defining the regularisation strength
//   L: matrix of regularisation conditions (dimension nl x nx)
//        depends on the structure of the input data
//   x0: bias distribution, from simulation
//
// Preservation of the area
// ------------------------
//   lambda: lagrangian multiplier
//   y_i: one component of the vector y
//   (Ax)_i: one component of the vector Ax
//
//
// Determination of the unfolding result x:
//
//   (a) not constrained: minimisation is performed as a function of x
//         for fixed lambda=0
//  or
//   (b) constrained: stationary point is found as a function of x and lambda
//
// The constraint can be useful to reduce biases on the result x
// in cases where the vector y follows non-Gaussian probability densities
// (example: Poisson statistics at counting experiments in particle physics)
//
// Some random examples:
// ======================
//   (1) measure a cross-section as a function of, say, E_T(detector)
//        and unfold it to obtain the underlying distribution E_T(generator)
//   (2) measure a lifetime distribution and unfold the contributions from
//        different flavours
//   (3) measure the transverse mass and decay angle
//        and unfold for the true mass distribution plus background
//
// Documentation
// =============
// Some technical documentation is available here:
//   http://www.desy.de/~sschmitt
//
// Note:
//   For most applications it is better to use the derived class
//     TUnfoldSys or even better TUnfoldDensity
//
//  TUnfoldSys extends the functionality of TUnfold
//             such that systematic errors are propagated to teh result
//             and that the unfolding can be done with proper background
//             subtraction
//
//  TUnfoldDensity extends further the functionality of TUnfoldSys
//                 complex binning schemes are supported
//                 The binning of input histograms is handeld consistently:
//                  (1) the regularisation may be done by density,
//                      i.e respecting the bin widths
//                  (2) methods are provided which preserve the proper binning
//                      of the result histograms
//
// Implementation
// ==============
// The result of the unfolding is calculated as follows:
//
//    Lsquared = L#L            regularisation conditions squared
//
//    epsilon_j = sum_i A_ij    vector of efficiencies
//
//    E^-1  = ((A# Vyy^-1 A)+tau^2 Lsquared)
//
//    x = E (A# Vyy^-1 y + tau^2 Lsquared x0 +lambda/2 * epsilon) is the result
//
// The derivatives
//    dx_k/dy_i
//    dx_k/dA_ij
//    dx_k/d(tau^2)
// are calculated for further usage.
//
// The covariance matrix V_xx is calculated as:
//    Vxx_ij = sum_kl dx_i/dy_k Vyy_kl dx_j/dy_l
//
// Warning:
// ========
//  The algorithm is based on "standard" matrix inversion, with the
//  known limitations in numerical accuracy and computing cost for
//  matrices with large dimensions.
//
//  Thus the algorithm should not used for large dimensions of x and y
//    nx should not be much larger than 200
//    ny should not be much larger than 1000
//
//
// Proper choice of tau
// ====================
// One of the difficult questions is about the choice of tau.
// The method implemented in TUnfold is the L-curve method:
// a two-dimensional curve is plotted
//   x-axis: log10(chisquare)
//   y-axis: log10(regularisation condition)
// In many cases this curve has an L-shape. The best choice of tau is in the
// kink of the L
//
// Within TUnfold a simple version of the L-curve analysis is available.
// It tests a given number of points in a predefined tau-range and searches
// for the maximum of the curvature in the L-curve (kink position).
// if no tau range is given, the range of the scan is determined automatically
//
//  A nice overview of the L-curve method is given in:
//   The L-curve and Its Use in the Numerical Treatment of Inverse Problems
//   (2000) by P. C. Hansen, in Computational Inverse Problems in
//   Electrocardiology, ed. P. Johnston,
//   Advances in Computational Bioengineering
//   http://www.imm.dtu.dk/~pch/TR/Lcurve.ps
//
// Alternative Regularisation conditions
// =====================================
// Regularisation is needed for most unfolding problems, in order to avoid
// large oscillations and large correlations on the output bins.
// It means that some extra conditions are applied on the output bins
//
// Within TUnfold these conditions are posed on the difference (x-x0), where
//    x:  unfolding output
//    x0: the bias distribution, by default calculated from
//        the input matrix A. There is a method SetBias() to change the
//        bias distribution.
//        The 3rd argument to DoUnfold() is a scale factor applied to the bias
//          bias_default[j] = sum_i A[i][j]
//          x0[j] = scaleBias*bias[j]
//        The scale factor can be used to
//         (a) completely suppress the bias by setting it to zero
//         (b) compensate differences in the normalisation between data
//             and Monte Carlo
//
// If the regularisation is strong, i.e. large parameter tau,
// then the distribution x or its derivatives will look like the bias
// distribution. If the parameter tau is small, the distribution x is
// independent of the bias.
//
// Three basic types of regularisation are implemented in TUnfold
//
//    condition            regularisation
//  ------------------------------------------------------
//    kRegModeNone         none
//    kRegModeSize         minimize the size of (x-x0)
//    kRegModeDerivative   minimize the 1st derivative of (x-x0)
//    kRegModeCurvature    minimize the 2nd derivative of (x-x0)
//
// kRegModeSize is the regularisation scheme which often is found in
// literature. The second derivative is often named curvature.
// Sometimes the bias is not discussed,  equivalent to a bias scale factor
// of zero.
//
// The regularisation schemes kRegModeDerivative and
// kRegModeCurvature have the nice feature that they create correlations
// between x-bins, whereas the non-regularized unfolding tends to create
// negative correlations between bins. For these regularisation schemes the
// parameter tau could be tuned such that the correlations are smallest,
// as an alternative to the L-curve method.
//
// If kRegModeSize is chosen or if x is a smooth function through all bins,
// the regularisation condition can be set on all bins together by giving
// the appropriate argument in the constructor (see examples above).
//
// If x is composed of independent groups of bins (for example,
// signal and background binning in two variables), it may be necessary to
// set regularisation conditions for the individual groups of bins.
// In this case,  give  kRegModeNone  in the constructor and specify
// the bin grouping with calls to
//          RegularizeBins()   specify a 1-dimensional group of bins
//          RegularizeBins2D() specify a 2-dimensional group of bins
//
// Note, the class TUnfoldDensity provides an automatic setup of complex
// regularisation schemes
//
// For ultimate flexibility, the regularisation condition can be set on each
// bin individually
//  -> give  kRegModeNone  in the constructor and use
//      RegularizeSize()        regularize one bin
//      RegularizeDerivative()  regularize the slope given by two bins
//      RegularizeCurvature()   regularize the curvature given by three bins
//      AddRegularisationCondition()
//                              define an arbitrary regulatisation condition
//
///////////////////////////////////////////////////////////////////////////

/*
 This file is part of TUnfold.

 TUnfold is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 TUnfold is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with TUnfold.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <TMatrixD.h>
#include <TMatrixDSparse.h>
#include <TMatrixDSym.h>
#include <TMatrixDSymEigen.h>
#include <TMath.h>
#include "TUnfold.h"

#include <map>
#include <vector>

// this option saves the spline of the L curve curvature to a file
// named splinec.ps for debugging

//#define DEBUG
//#define DEBUG_DETAIL
//#define DEBUG_LCURVE
//#define FORCE_EIGENVALUE_DECOMPOSITION

#ifdef DEBUG_LCURVE
#include <TCanvas.h>
#endif

ClassImp(TUnfold)
//______________________________________________________________________________

const char *TUnfold::GetTUnfoldVersion(void)
{
   return TUnfold_VERSION;
}


void TUnfold::InitTUnfold(void)
{
   // reset all data members
   fXToHist.Set(0);
   fHistToX.Set(0);
   fSumOverY.Set(0);
   fA = 0;
   fL = 0;
   fVyy = 0;
   fY = 0;
   fX0 = 0;
   fTauSquared = 0.0;
   fBiasScale = 0.0;
   fNdf = 0;
   fConstraint = kEConstraintNone;
   fRegMode = kRegModeNone;
   // output
   fVyyInv = 0;
   fVxx = 0;
   fX = 0;
   fAx = 0;
   fChi2A = 0.0;
   fLXsquared = 0.0;
   fRhoMax = 999.0;
   fRhoAvg = -1.0;
   fDXDAM[0] = 0;
   fDXDAZ[0] = 0;
   fDXDAM[1] = 0;
   fDXDAZ[1] = 0;
   fDXDtauSquared = 0;
   fDXDY = 0;
   fEinv = 0;
   fE = 0;
   fVxxInv = 0;
   fEpsMatrix=1.E-13;
   fIgnoredBins=0;
}

void TUnfold::DeleteMatrix(TMatrixD **m)
{
   if(*m) delete *m;
   *m=0;
}

void TUnfold::DeleteMatrix(TMatrixDSparse **m)
{
   if(*m) delete *m;
   *m=0;
}

void TUnfold::ClearResults(void)
{
   // delete old results (if any)
   // this function is virtual, so derived classes may implement their own
   // method to flag results as non-valid

   // note: the inverse of the input covariance is not cleared
   //       because it does not change until the input is changed

   DeleteMatrix(&fVxx);
   DeleteMatrix(&fX);
   DeleteMatrix(&fAx);
   for(Int_t i=0;i<2;i++) {
      DeleteMatrix(fDXDAM+i);
      DeleteMatrix(fDXDAZ+i);
   }
   DeleteMatrix(&fDXDtauSquared);
   DeleteMatrix(&fDXDY);
   DeleteMatrix(&fEinv);
   DeleteMatrix(&fE);
   DeleteMatrix(&fVxxInv);
   fChi2A = 0.0;
   fLXsquared = 0.0;
   fRhoMax = 999.0;
   fRhoAvg = -1.0;
}

TUnfold::TUnfold(void)
{
   // set all matrix pointers to zero
   InitTUnfold();
}

Double_t TUnfold::DoUnfold(void)
{
   // main unfolding algorithm. Declared virtual, because other algorithms
   // could be implemented
   //
   // Purpose: unfold y -> x
   // Data members required:
   //     fA:  matrix to relate x and y
   //     fY:  measured data points
   //     fX0: bias on x
   //     fBiasScale: scale factor for fX0
   //     fVyy:  covariance matrix for y
   //     fL: regularisation conditions
   //     fTauSquared: regularisation strength
   //     fConstraint: whether the constraint is applied
   // Data members modified:
   //     fVyyInv: inverse of input data covariance matrix
   //     fNdf: number of dgerres of freedom
   //     fEinv: inverse of the matrix needed for unfolding calculations
   //     fE:    the matrix needed for unfolding calculations
   //     fX:    unfolded data points
   //     fDXDY: derivative of x wrt y (for error propagation)
   //     fVxx:  error matrix (covariance matrix) on x
   //     fAx:   estimate of distribution y from unfolded data
   //     fChi2A:  contribution to chi**2 from y-Ax
   //     fChi2L:  contribution to chi**2 from L*(x-x0)
   //     fDXDtauSquared: derivative of x wrt tau
   //     fDXDAM[0,1]: matrix parts of derivative x wrt A
   //     fDXDAZ[0,1]: vector parts of derivative x wrt A
   //     fRhoMax: maximum global correlation coefficient
   //     fRhoAvg: average global correlation coefficient
   // return code:
   //     fRhoMax   if(fRhoMax>=1.0) then the unfolding has failed!

   ClearResults();

   // get pseudo-inverse matrix Vyyinv and NDF
   if(!fVyyInv) {
      GetInputInverseEmatrix(0);
      if(fConstraint != kEConstraintNone) {
         fNdf--;
      }
   }
   //
   // get matrix
   //              T
   //            fA fV  = mAt_V
   //
   TMatrixDSparse *AtVyyinv=MultiplyMSparseTranspMSparse(fA,fVyyInv);
   //
   // get
   //       T
   //     fA fVyyinv fY + fTauSquared fBiasScale Lsquared fX0 = rhs
   //
   TMatrixDSparse *rhs=MultiplyMSparseM(AtVyyinv,fY);
   TMatrixDSparse *lSquared=MultiplyMSparseTranspMSparse(fL,fL);
   if (fBiasScale != 0.0) {
      TMatrixDSparse *rhs2=MultiplyMSparseM(lSquared,fX0);
      AddMSparse(rhs, fTauSquared * fBiasScale ,rhs2);
      DeleteMatrix(&rhs2);
   }

   //
   // get matrix
   //              T
   //           (fA fV)fA + fTauSquared*fLsquared  = fEinv
   fEinv=MultiplyMSparseMSparse(AtVyyinv,fA);
   AddMSparse(fEinv,fTauSquared,lSquared);

   //
   // get matrix
   //             -1
   //        fEinv    = fE
   //
   Int_t rank=0;
   fE = InvertMSparseSymmPos(fEinv,&rank);
   if(rank != GetNx()) {
      Warning("DoUnfold","rank of matrix E %d expect %d",rank,GetNx());
   }

   //
   // get result
   //        fE rhs  = x
   //
   TMatrixDSparse *xSparse=MultiplyMSparseMSparse(fE,rhs);
   fX = new TMatrixD(*xSparse);
   DeleteMatrix(&rhs);
   DeleteMatrix(&xSparse);

   // additional correction for constraint
   Double_t lambda_half=0.0;
   Double_t one_over_epsEeps=0.0;
   TMatrixDSparse *epsilon=0;
   TMatrixDSparse *Eepsilon=0;
   if(fConstraint != kEConstraintNone) {
      // calculate epsilon: verctor of efficiencies
      const Int_t *A_rows=fA->GetRowIndexArray();
      const Int_t *A_cols=fA->GetColIndexArray();
      const Double_t *A_data=fA->GetMatrixArray();
      TMatrixD epsilonNosparse(fA->GetNcols(),1);
      for(Int_t i=0;i<A_rows[fA->GetNrows()];i++) {
         epsilonNosparse(A_cols[i],0) += A_data[i];
      }
      epsilon=new TMatrixDSparse(epsilonNosparse);
      // calculate vector EE*epsilon
      Eepsilon=MultiplyMSparseMSparse(fE,epsilon);
      // calculate scalar product epsilon#*Eepsilon
      TMatrixDSparse *epsilonEepsilon=MultiplyMSparseTranspMSparse(epsilon,
                                                                   Eepsilon);
      // if epsilonEepsilon is zero, nothing works...
      if(epsilonEepsilon->GetRowIndexArray()[1]==1) {
         one_over_epsEeps=1./epsilonEepsilon->GetMatrixArray()[0];
      } else {
         Fatal("Unfold","epsilon#Eepsilon has dimension %d != 1",
               epsilonEepsilon->GetRowIndexArray()[1]);
      }
      DeleteMatrix(&epsilonEepsilon);
      // calculate sum(Y)
      Double_t y_minus_epsx=0.0;
      for(Int_t iy=0;iy<fY->GetNrows();iy++) {
         y_minus_epsx += (*fY)(iy,0);
      }
      // calculate sum(Y)-epsilon#*X
      for(Int_t ix=0;ix<epsilonNosparse.GetNrows();ix++) {
         y_minus_epsx -=  epsilonNosparse(ix,0) * (*fX)(ix,0);
      }
      // calculate lambda_half
      lambda_half=y_minus_epsx*one_over_epsEeps;
      // calculate final vector X
      const Int_t *EEpsilon_rows=Eepsilon->GetRowIndexArray();
      const Double_t *EEpsilon_data=Eepsilon->GetMatrixArray();
      for(Int_t ix=0;ix<Eepsilon->GetNrows();ix++) {
         if(EEpsilon_rows[ix]<EEpsilon_rows[ix+1]) {
            (*fX)(ix,0) += lambda_half * EEpsilon_data[EEpsilon_rows[ix]];
         }
      }
   }
   //
   // get derivative dx/dy
   // for error propagation
   //     dx/dy = E A# Vyy^-1  ( = B )
   fDXDY = MultiplyMSparseMSparse(fE,AtVyyinv);

   // additional correction for constraint
   if(fConstraint != kEConstraintNone) {
      // transposed vector of dimension GetNy() all elements equal 1/epseEeps
      Int_t *rows=new Int_t[GetNy()];
      Int_t *cols=new Int_t[GetNy()];
      Double_t *data=new Double_t[GetNy()];
      for(Int_t i=0;i<GetNy();i++) {
         rows[i]=0;
         cols[i]=i;
         data[i]=one_over_epsEeps;
      }
      TMatrixDSparse *temp=CreateSparseMatrix
      (1,GetNy(),GetNy(),rows,cols,data);
      delete[] data;
      delete[] rows;
      delete[] cols;
      // B# * epsilon
      TMatrixDSparse *epsilonB=MultiplyMSparseTranspMSparse(epsilon,fDXDY);
      // temp- one_over_epsEeps*Bepsilon
      AddMSparse(temp, -one_over_epsEeps, epsilonB);
      DeleteMatrix(&epsilonB);
      // correction matrix
      TMatrixDSparse *corr=MultiplyMSparseMSparse(Eepsilon,temp);
      DeleteMatrix(&temp);
      // determine new derivative
      AddMSparse(fDXDY,1.0,corr);
      DeleteMatrix(&corr);
   }

   DeleteMatrix(&AtVyyinv);

   //
   // get error matrix on x
   //   fDXDY * Vyy * fDXDY#
   TMatrixDSparse *fDXDYVyy = MultiplyMSparseMSparse(fDXDY,fVyy);
   fVxx = MultiplyMSparseMSparseTranspVector(fDXDYVyy,fDXDY,0);

   DeleteMatrix(&fDXDYVyy);

   //
   // get result
   //        fA x  =  fAx
   //
   fAx = MultiplyMSparseM(fA,fX);

   //
   // calculate chi**2 etc

   // chi**2 contribution from (y-Ax)V(y-Ax)
   TMatrixD dy(*fY, TMatrixD::kMinus, *fAx);
   TMatrixDSparse *VyyinvDy=MultiplyMSparseM(fVyyInv,&dy);

   const Int_t *VyyinvDy_rows=VyyinvDy->GetRowIndexArray();
   const Double_t *VyyinvDy_data=VyyinvDy->GetMatrixArray();
   fChi2A=0.0;
   for(Int_t iy=0;iy<VyyinvDy->GetNrows();iy++) {
      if(VyyinvDy_rows[iy]<VyyinvDy_rows[iy+1]) {
         fChi2A += VyyinvDy_data[VyyinvDy_rows[iy]]*dy(iy,0);
      }
   }
   TMatrixD dx( fBiasScale * (*fX0), TMatrixD::kMinus,(*fX));
   TMatrixDSparse *LsquaredDx=MultiplyMSparseM(lSquared,&dx);
   const Int_t *LsquaredDx_rows=LsquaredDx->GetRowIndexArray();
   const Double_t *LsquaredDx_data=LsquaredDx->GetMatrixArray();
   fLXsquared = 0.0;
   for(Int_t ix=0;ix<LsquaredDx->GetNrows();ix++) {
      if(LsquaredDx_rows[ix]<LsquaredDx_rows[ix+1]) {
         fLXsquared += LsquaredDx_data[LsquaredDx_rows[ix]]*dx(ix,0);
      }
   }

   //
   // get derivative dx/dtau
   fDXDtauSquared=MultiplyMSparseMSparse(fE,LsquaredDx);

   if(fConstraint != kEConstraintNone) {
      TMatrixDSparse *temp=MultiplyMSparseTranspMSparse(epsilon,fDXDtauSquared);
      Double_t f=0.0;
      if(temp->GetRowIndexArray()[1]==1) {
         f=temp->GetMatrixArray()[0]*one_over_epsEeps;
      } else if(temp->GetRowIndexArray()[1]>1) {
         Fatal("Unfold",
               "epsilon#fDXDtauSquared has dimension %d != 1",
               temp->GetRowIndexArray()[1]);
      }
      if(f!=0.0) {
         AddMSparse(fDXDtauSquared, -f,Eepsilon);
      }
      DeleteMatrix(&temp);
   }
   DeleteMatrix(&epsilon);

   DeleteMatrix(&LsquaredDx);
   DeleteMatrix(&lSquared);

   // calculate/store matrices defining the derivatives dx/dA
   fDXDAM[0]=new TMatrixDSparse(*fE);
   fDXDAM[1]=new TMatrixDSparse(*fDXDY); // create a copy
   fDXDAZ[0]=VyyinvDy; // instead of deleting VyyinvDy
   VyyinvDy=0;
   fDXDAZ[1]=new TMatrixDSparse(*fX); // create a copy

   if(fConstraint != kEConstraintNone) {
      // add correction to fDXDAM[0]
      TMatrixDSparse *temp1=MultiplyMSparseMSparseTranspVector
      (Eepsilon,Eepsilon,0);
      AddMSparse(fDXDAM[0], -one_over_epsEeps,temp1);
      DeleteMatrix(&temp1);
      // add correction to fDXDAZ[0]
      Int_t *rows=new Int_t[GetNy()];
      Int_t *cols=new Int_t[GetNy()];
      Double_t *data=new Double_t[GetNy()];
      for(Int_t i=0;i<GetNy();i++) {
         rows[i]=i;
         cols[i]=0;
         data[i]=lambda_half;
      }
      TMatrixDSparse *temp2=CreateSparseMatrix
      (GetNy(),1,GetNy(),rows,cols,data);
      delete[] data;
      delete[] rows;
      delete[] cols;
      AddMSparse(fDXDAZ[0],1.0,temp2);
      DeleteMatrix(&temp2);
   }

   DeleteMatrix(&Eepsilon);

   rank=0;
   fVxxInv = InvertMSparseSymmPos(fVxx,&rank);
   if(rank != GetNx()) {
      Warning("DoUnfold","rank of output covariance is %d expect %d",
              rank,GetNx());
   }

   TVectorD VxxInvDiag(fVxxInv->GetNrows());
   const Int_t *VxxInv_rows=fVxxInv->GetRowIndexArray();
   const Int_t *VxxInv_cols=fVxxInv->GetColIndexArray();
   const Double_t *VxxInv_data=fVxxInv->GetMatrixArray();
   for (int ix = 0; ix < fVxxInv->GetNrows(); ix++) {
      for(int ik=VxxInv_rows[ix];ik<VxxInv_rows[ix+1];ik++) {
         if(ix==VxxInv_cols[ik]) {
            VxxInvDiag(ix)=VxxInv_data[ik];
         }
      }
   }

   // maximum global correlation coefficient
   const Int_t *Vxx_rows=fVxx->GetRowIndexArray();
   const Int_t *Vxx_cols=fVxx->GetColIndexArray();
   const Double_t *Vxx_data=fVxx->GetMatrixArray();

   Double_t rho_squared_max = 0.0;
   Double_t rho_sum = 0.0;
   Int_t n_rho=0;
   for (int ix = 0; ix < fVxx->GetNrows(); ix++) {
      for(int ik=Vxx_rows[ix];ik<Vxx_rows[ix+1];ik++) {
         if(ix==Vxx_cols[ik]) {
            Double_t rho_squared =
            1. - 1. / (VxxInvDiag(ix) * Vxx_data[ik]);
            if (rho_squared > rho_squared_max)
               rho_squared_max = rho_squared;
            if(rho_squared>0.0) {
               rho_sum += TMath::Sqrt(rho_squared);
               n_rho++;
            }
            break;
         }
      }
   }
   fRhoMax = TMath::Sqrt(rho_squared_max);
   fRhoAvg = (n_rho>0) ? (rho_sum/n_rho) : -1.0;

   return fRhoMax;
}

TMatrixDSparse *TUnfold::CreateSparseMatrix
(Int_t nrow,Int_t ncol,Int_t nel,Int_t *row,Int_t *col,Double_t *data) const
{
   // create a sparse matri
   //   nrow,ncol : dimension of the matrix
   //   nel: number of non-zero elements
   //   row[nel],col[nel],data[nel] : indices and data of the non-zero elements
   TMatrixDSparse *A=new TMatrixDSparse(nrow,ncol);
   if(nel>0) {
      A->SetMatrixArray(nel,row,col,data);
   }
   return A;
}

TMatrixDSparse *TUnfold::MultiplyMSparseMSparse(const TMatrixDSparse *a,
                                                const TMatrixDSparse *b) const
{
   // calculate the product of two sparse matrices
   //    a,b: pointers to sparse matrices, where a->GetNcols()==b->GetNrows()
   // this is a replacement for the call
   //    new TMatrixDSparse(*a,TMatrixDSparse::kMult,*b);
   if(a->GetNcols()!=b->GetNrows()) {
      Fatal("MultiplyMSparseMSparse",
            "inconsistent matrix col/ matrix row %d !=%d",
            a->GetNcols(),b->GetNrows());
   }

   TMatrixDSparse *r=new TMatrixDSparse(a->GetNrows(),b->GetNcols());
   const Int_t *a_rows=a->GetRowIndexArray();
   const Int_t *a_cols=a->GetColIndexArray();
   const Double_t *a_data=a->GetMatrixArray();
   const Int_t *b_rows=b->GetRowIndexArray();
   const Int_t *b_cols=b->GetColIndexArray();
   const Double_t *b_data=b->GetMatrixArray();
   // maximum size of the output matrix
   int nMax=0;
   for (Int_t irow = 0; irow < a->GetNrows(); irow++) {
      if(a_rows[irow+1]>a_rows[irow]) nMax += b->GetNcols();
   }
   if((nMax>0)&&(a_cols)&&(b_cols)) {
      Int_t *r_rows=new Int_t[nMax];
      Int_t *r_cols=new Int_t[nMax];
      Double_t *r_data=new Double_t[nMax];
      Double_t *row_data=new Double_t[b->GetNcols()];
      Int_t n=0;
      for (Int_t irow = 0; irow < a->GetNrows(); irow++) {
         if(a_rows[irow+1]<=a_rows[irow]) continue;
         // clear row data
         for(Int_t icol=0;icol<b->GetNcols();icol++) {
            row_data[icol]=0.0;
         }
         // loop over a-columns in this a-row
         for(Int_t ia=a_rows[irow];ia<a_rows[irow+1];ia++) {
            Int_t k=a_cols[ia];
            // loop over b-columns in b-row k
            for(Int_t ib=b_rows[k];ib<b_rows[k+1];ib++) {
               row_data[b_cols[ib]] += a_data[ia]*b_data[ib];
            }
         }
         // store nonzero elements
         for(Int_t icol=0;icol<b->GetNcols();icol++) {
            if(row_data[icol] != 0.0) {
               r_rows[n]=irow;
               r_cols[n]=icol;
               r_data[n]=row_data[icol];
               n++;
            }
         }
      }
      if(n>0) {
         r->SetMatrixArray(n,r_rows,r_cols,r_data);
      }
      delete[] r_rows;
      delete[] r_cols;
      delete[] r_data;
      delete[] row_data;
   }

   return r;
}


TMatrixDSparse *TUnfold::MultiplyMSparseTranspMSparse
(const TMatrixDSparse *a,const TMatrixDSparse *b) const
{
   // multiply a transposed Sparse matrix with another Sparse matrix
   //    a:  pointer to sparse matrix (to be transposed)
   //    b:  pointer to sparse matrix
   // this is a replacement for the call
   //    new TMatrixDSparse(TMatrixDSparse(TMatrixDSparse::kTransposed,*a),
   //                       TMatrixDSparse::kMult,*b)
   if(a->GetNrows() != b->GetNrows()) {
      Fatal("MultiplyMSparseTranspMSparse",
            "inconsistent matrix row numbers %d!=%d",
            a->GetNrows(),b->GetNrows());
   }

   TMatrixDSparse *r=new TMatrixDSparse(a->GetNcols(),b->GetNcols());
   const Int_t *a_rows=a->GetRowIndexArray();
   const Int_t *a_cols=a->GetColIndexArray();
   const Double_t *a_data=a->GetMatrixArray();
   const Int_t *b_rows=b->GetRowIndexArray();
   const Int_t *b_cols=b->GetColIndexArray();
   const Double_t *b_data=b->GetMatrixArray();
   // maximum size of the output matrix

   // matrix multiplication
   typedef std::map<Int_t,Double_t> MMatrixRow_t;
   typedef std::map<Int_t, MMatrixRow_t > MMatrix_t;
   MMatrix_t matrix;

   for(Int_t iRowAB=0;iRowAB<a->GetNrows();iRowAB++) {
      for(Int_t ia=a_rows[iRowAB];ia<a_rows[iRowAB+1];ia++) {
         for(Int_t ib=b_rows[iRowAB];ib<b_rows[iRowAB+1];ib++) {
            // this creates a new row if necessary
            MMatrixRow_t &row=matrix[a_cols[ia]];
            MMatrixRow_t::iterator icol=row.find(b_cols[ib]);
            if(icol!=row.end()) {
               // update existing row
               (*icol).second += a_data[ia]*b_data[ib];
            } else {
               // create new row
               row[b_cols[ib]] = a_data[ia]*b_data[ib];
            }
         }
      }
   }

   Int_t n=0;
   for(MMatrix_t::const_iterator irow=matrix.begin();
       irow!=matrix.end();irow++) {
      n += (*irow).second.size();
   }
   if(n>0) {
      // pack matrix into arrays
      Int_t *r_rows=new Int_t[n];
      Int_t *r_cols=new Int_t[n];
      Double_t *r_data=new Double_t[n];
      n=0;
      for(MMatrix_t::const_iterator irow=matrix.begin();
          irow!=matrix.end();irow++) {
         for(MMatrixRow_t::const_iterator icol=(*irow).second.begin();
             icol!=(*irow).second.end();icol++) {
            r_rows[n]=(*irow).first;
            r_cols[n]=(*icol).first;
            r_data[n]=(*icol).second;
            n++;
         }
      }
      // pack arrays into TMatrixDSparse
      if(n>0) {
         r->SetMatrixArray(n,r_rows,r_cols,r_data);
      }
      delete[] r_rows;
      delete[] r_cols;
      delete[] r_data;
   }

   return r;
}

TMatrixDSparse *TUnfold::MultiplyMSparseM(const TMatrixDSparse *a,
                                          const TMatrixD *b) const
{
   // multiply a Sparse matrix with a non-sparse matrix
   //    a:  pointer to sparse matrix
   //    b:  pointer to non-sparse matrix
   // this is a replacement for the call
   //    new TMatrixDSparse(*a,TMatrixDSparse::kMult,*b);
   if(a->GetNcols()!=b->GetNrows()) {
      Fatal("MultiplyMSparseM","inconsistent matrix col /matrix row %d!=%d",
            a->GetNcols(),b->GetNrows());
   }

   TMatrixDSparse *r=new TMatrixDSparse(a->GetNrows(),b->GetNcols());
   const Int_t *a_rows=a->GetRowIndexArray();
   const Int_t *a_cols=a->GetColIndexArray();
   const Double_t *a_data=a->GetMatrixArray();
   // maximum size of the output matrix
   int nMax=0;
   for (Int_t irow = 0; irow < a->GetNrows(); irow++) {
      if(a_rows[irow+1]-a_rows[irow]>0) nMax += b->GetNcols();
   }
   if(nMax>0) {
      Int_t *r_rows=new Int_t[nMax];
      Int_t *r_cols=new Int_t[nMax];
      Double_t *r_data=new Double_t[nMax];

      Int_t n=0;
      // fill matrix r
      for (Int_t irow = 0; irow < a->GetNrows(); irow++) {
         if(a_rows[irow+1]-a_rows[irow]<=0) continue;
         for(Int_t icol=0;icol<b->GetNcols();icol++) {
            r_rows[n]=irow;
            r_cols[n]=icol;
            r_data[n]=0.0;
            for(Int_t i=a_rows[irow];i<a_rows[irow+1];i++) {
               Int_t j=a_cols[i];
               r_data[n] += a_data[i]*(*b)(j,icol);
            }
            if(r_data[n]!=0.0) n++;
         }
      }
      if(n>0) {
         r->SetMatrixArray(n,r_rows,r_cols,r_data);
      }
      delete[] r_rows;
      delete[] r_cols;
      delete[] r_data;
   }
   return r;
}

TMatrixDSparse *TUnfold::MultiplyMSparseMSparseTranspVector
(const TMatrixDSparse *m1,const TMatrixDSparse *m2,
 const TMatrixTBase<Double_t> *v) const
{
   // calculate M_ij = sum_k [m1_ik*m2_jk*v[k] ].
   //    m1: pointer to sparse matrix with dimension I*K
   //    m2: pointer to sparse matrix with dimension J*K
   //    v: pointer to vector (matrix) with dimension K*1
   if((m1->GetNcols() != m2->GetNcols())||
      (v && ((m1->GetNcols()!=v->GetNrows())||(v->GetNcols()!=1)))) {
      if(v) {
         Fatal("MultiplyMSparseMSparseTranspVector",
               "matrix cols/vector rows %d!=%d!=%d or vector rows %d!=1\n",
               m1->GetNcols(),m2->GetNcols(),v->GetNrows(),v->GetNcols());
      } else {
         Fatal("MultiplyMSparseMSparseTranspVector",
               "matrix cols %d!=%d\n",m1->GetNcols(),m2->GetNcols());
      }
   }
   const Int_t *rows_m1=m1->GetRowIndexArray();
   const Int_t *cols_m1=m1->GetColIndexArray();
   const Double_t *data_m1=m1->GetMatrixArray();
   Int_t num_m1=0;
   for(Int_t i=0;i<m1->GetNrows();i++) {
      if(rows_m1[i]<rows_m1[i+1]) num_m1++;
   }
   const Int_t *rows_m2=m2->GetRowIndexArray();
   const Int_t *cols_m2=m2->GetColIndexArray();
   const Double_t *data_m2=m2->GetMatrixArray();
   Int_t num_m2=0;
   for(Int_t j=0;j<m2->GetNrows();j++) {
      if(rows_m2[j]<rows_m2[j+1]) num_m2++;
   }
   const TMatrixDSparse *v_sparse=dynamic_cast<const TMatrixDSparse *>(v);
   const Int_t *v_rows=0;
   const Double_t *v_data=0;
   if(v_sparse) {
      v_rows=v_sparse->GetRowIndexArray();
      v_data=v_sparse->GetMatrixArray();
   }
   Int_t num_r=num_m1*num_m2+1;
   Int_t *row_r=new Int_t[num_r];
   Int_t *col_r=new Int_t[num_r];
   Double_t *data_r=new Double_t[num_r];
   num_r=0;
   for(Int_t i=0;i<m1->GetNrows();i++) {
      for(Int_t j=0;j<m2->GetNrows();j++) {
         data_r[num_r]=0.0;
         Int_t index_m1=rows_m1[i];
         Int_t index_m2=rows_m2[j];
         while((index_m1<rows_m1[i+1])&&(index_m2<rows_m2[j+1])) {
            Int_t k1=cols_m1[index_m1];
            Int_t k2=cols_m2[index_m2];
            if(k1<k2) {
               index_m1++;
            } else if(k1>k2) {
               index_m2++;
            } else {
               if(v_sparse) {
                  Int_t v_index=v_rows[k1];
                  if(v_index<v_rows[k1+1]) {
                     data_r[num_r] += data_m1[index_m1] * data_m2[index_m2]
                     * v_data[v_index];
                  } else {
                     data_r[num_r] =0.0;
                  }
               } else if(v) {
                  data_r[num_r] += data_m1[index_m1] * data_m2[index_m2]
                  * (*v)(k1,0);
               } else {
                  data_r[num_r] += data_m1[index_m1] * data_m2[index_m2];
               }
               index_m1++;
               index_m2++;
            }
         }
         if(data_r[num_r] !=0.0) {
            row_r[num_r]=i;
            col_r[num_r]=j;
            num_r++;
         }
      }
   }
   TMatrixDSparse *r=CreateSparseMatrix(m1->GetNrows(),m2->GetNrows(),
                                        num_r,row_r,col_r,data_r);
   delete[] row_r;
   delete[] col_r;
   delete[] data_r;
   return r;
}

void TUnfold::AddMSparse(TMatrixDSparse *dest,Double_t f,
                         const TMatrixDSparse *src) const
{
   // a replacement for
   //     (*dest) += f*(*src)
   const Int_t *dest_rows=dest->GetRowIndexArray();
   const Int_t *dest_cols=dest->GetColIndexArray();
   const Double_t *dest_data=dest->GetMatrixArray();
   const Int_t *src_rows=src->GetRowIndexArray();
   const Int_t *src_cols=src->GetColIndexArray();
   const Double_t *src_data=src->GetMatrixArray();

   if((dest->GetNrows()!=src->GetNrows())||
      (dest->GetNcols()!=src->GetNcols())) {
      Fatal("AddMSparse","inconsistent matrix rows %d!=%d OR cols %d!=%d",
            src->GetNrows(),dest->GetNrows(),src->GetNcols(),dest->GetNcols());
   }
   Int_t nmax=dest->GetNrows()*dest->GetNcols();
   Double_t *result_data=new Double_t[nmax];
   Int_t *result_rows=new Int_t[nmax];
   Int_t *result_cols=new Int_t[nmax];
   Int_t n=0;
   for(Int_t row=0;row<dest->GetNrows();row++) {
      Int_t i_dest=dest_rows[row];
      Int_t i_src=src_rows[row];
      while((i_dest<dest_rows[row+1])||(i_src<src_rows[row+1])) {
         Int_t col_dest=(i_dest<dest_rows[row+1]) ?
         dest_cols[i_dest] : dest->GetNcols();
         Int_t col_src =(i_src <src_rows[row+1] ) ?
         src_cols [i_src] :  src->GetNcols();
         result_rows[n]=row;
         if(col_dest<col_src) {
            result_cols[n]=col_dest;
            result_data[n]=dest_data[i_dest++];
         } else if(col_dest>col_src) {
            result_cols[n]=col_src;
            result_data[n]=f*src_data[i_src++];
         } else {
            result_cols[n]=col_dest;
            result_data[n]=dest_data[i_dest++]+f*src_data[i_src++];
         }
         if(result_data[n] !=0.0) {
            if(!TMath::Finite(result_data[n])) {
               Fatal("AddMSparse","Nan detected %d %d %d",
                     row,i_dest,i_src);
            }
            n++;
         }
      }
   }
   if(n<=0) {
      n=1;
      result_rows[0]=0;
      result_cols[0]=0;
      result_data[0]=0.0;
   }
   dest->SetMatrixArray(n,result_rows,result_cols,result_data);
   delete[] result_data;
   delete[] result_rows;
   delete[] result_cols;
}

TMatrixDSparse *TUnfold::InvertMSparseSymmPos
(const TMatrixDSparse *A,Int_t *rankPtr) const
{
   // get the inverse or pseudo-inverse of a sparse matrix
   //    A: the original matrix
   //    rank:
   //      if(rankPtr==0)
   //          rerturn the inverse if it exists, or return NULL
   //      else
   //          return the pseudo-invers
   //          and return the rank of the matrix in *rankPtr
   // the matrix inversion is optimized for the case
   // where a large submatrix of A is diagonal

   if(A->GetNcols()!=A->GetNrows()) {
      Fatal("InvertMSparseSymmPos","inconsistent matrix row/col %d!=%d",
            A->GetNcols(),A->GetNrows());
   }

   Bool_t *isZero=new Bool_t[A->GetNrows()];
   const Int_t *a_rows=A->GetRowIndexArray();
   const Int_t *a_cols=A->GetColIndexArray();
   const Double_t *a_data=A->GetMatrixArray();

   // determine diagonal elements
   //  Aii: diagonals of A
   Int_t iDiagonal=0;
   Int_t iBlock=A->GetNrows();
   Bool_t isDiagonal=kTRUE;
   TVectorD aII(A->GetNrows());
   Int_t nError=0;
   for(Int_t iA=0;iA<A->GetNrows();iA++) {
      for(Int_t indexA=a_rows[iA];indexA<a_rows[iA+1];indexA++) {
         Int_t jA=a_cols[indexA];
         if(iA==jA) {
            if(!(a_data[indexA]>=0.0)) nError++;
            aII(iA)=a_data[indexA];
         }
      }
   }
   if(nError>0) {
      delete [] isZero;
      Fatal("InvertMSparseSymmPos",
            "Matrix has %d negative elements on the diagonal", nError);
      return 0;
   }

   // reorder matrix such that the largest block of zeros is swapped
   // to the lowest indices
   // the result of this ordering:
   //  swap[i] : for index i point to the row in A
   //  swapBack[iA] : for index iA in A point to the swapped index i
   // the indices are grouped into three groups
   //   0..iDiagonal-1 : these rows only have diagonal elements
   //   iDiagonal..iBlock : these rows contain a diagonal block matrix
   //
   Int_t *swap=new Int_t[A->GetNrows()];
   for(Int_t j=0;j<A->GetNrows();j++) swap[j]=j;
   for(Int_t iStart=0;iStart<iBlock;iStart++) {
      Int_t nZero=0;
      for(Int_t i=iStart;i<iBlock;i++) {
         Int_t iA=swap[i];
         Int_t n=A->GetNrows()-(a_rows[iA+1]-a_rows[iA]);
         if(n>nZero) {
            Int_t tmp=swap[iStart];
            swap[iStart]=swap[i];
            swap[i]=tmp;
            nZero=n;
         }
      }
      for(Int_t i=0;i<A->GetNrows();i++) isZero[i]=kTRUE;
      Int_t iA=swap[iStart];
      for(Int_t indexA=a_rows[iA];indexA<a_rows[iA+1];indexA++) {
         Int_t jA=a_cols[indexA];
         isZero[jA]=kFALSE;
         if(iA!=jA) {
            isDiagonal=kFALSE;
         }
      }
      if(isDiagonal) {
         iDiagonal=iStart+1;
      } else {
         for(Int_t i=iStart+1;i<iBlock;) {
            if(isZero[swap[i]]) {
               i++;
            } else {
               iBlock--;
               Int_t tmp=swap[iBlock];
               swap[iBlock]=swap[i];
               swap[i]=tmp;
            }
         }
      }
   }

   // for tests uncomment this:
   //  iBlock=iDiagonal;


   // conditioning of the iBlock part
#ifdef CONDITION_BLOCK_PART
   Int_t nn=A->GetNrows()-iBlock;
   for(int inc=(nn+1)/2;inc;inc /= 2) {
      for(int i=inc;i<nn;i++) {
         int itmp=swap[i+iBlock];
         int j;
         for(j=i;(j>=inc)&&(aII(swap[j-inc+iBlock])<aII(itmp));j -=inc) {
            swap[j+iBlock]=swap[j-inc+iBlock];
         }
         swap[j+iBlock]=itmp;
      }
   }
#endif
   // construct array for swapping back
   Int_t *swapBack=new Int_t[A->GetNrows()];
   for(Int_t i=0;i<A->GetNrows();i++) {
      swapBack[swap[i]]=i;
   }
#ifdef DEBUG_DETAIL
   for(Int_t i=0;i<A->GetNrows();i++) {
      std::cout<<"    "<<i<<" "<<swap[i]<<" "<<swapBack[i]<<"\n";
   }
   std::cout<<"after sorting\n";
   for(Int_t i=0;i<A->GetNrows();i++) {
      if(i==iDiagonal) std::cout<<"iDiagonal="<<i<<"\n";
      if(i==iBlock) std::cout<<"iBlock="<<i<<"\n";
      std::cout<<" "<<swap[i]<<" "<<aII(swap[i])<<"\n";
   }
   {
      // sanity check:
      // (1) sub-matrix swapped[0]..swapped[iDiagonal]
      //       must not contain off-diagonals
      // (2) sub-matrix swapped[0]..swapped[iBlock-1] must be diagonal
      Int_t nDiag=0;
      Int_t nError1=0;
      Int_t nError2=0;
      Int_t nBlock=0;
      Int_t nNonzero=0;
      for(Int_t i=0;i<A->GetNrows();i++) {
         Int_t row=swap[i];
         for(Int_t indexA=a_rows[row];indexA<a_rows[row+1];indexA++) {
            Int_t j=swapBack[a_cols[indexA]];
            if(i==j) nDiag++;
            else if((i<iDiagonal)||(j<iDiagonal)) nError1++;
            else if((i<iBlock)&&(j<iBlock)) nError2++;
            else if((i<iBlock)||(j<iBlock)) nBlock++;
            else nNonzero++;
         }
      }
      if(nError1+nError2>0) {
         Fatal("InvertMSparseSymmPos","sparse matrix analysis failed %d %d %d %d %d",
               iDiagonal,iBlock,A->GetNrows(),nError1,nError2);
      }
   }
#endif
#ifdef DEBUG
   Info("InvertMSparseSymmPos","iDiagonal=%d iBlock=%d nRow=%d",
        iDiagonal,iBlock,A->GetNrows());
#endif

   //=============================================
   // matrix inversion starts here
   //
   //  the matrix is split into several parts
   //         D1  0   0
   //  A = (  0   D2  B# )
   //         0   B   C
   //
   //  D1,D2 are diagonal matrices
   //
   //  first, the D1 part is inverted by calculating 1/D1
   //   dim(D1)= iDiagonal
   //  next, the other parts are inverted using Schur complement
   //
   //           1/D1   0    0
   //  Ainv = (  0     E    G#   )
   //            0     G    F^-1
   //
   //  where F = C + (-B/D2) B#
   //        G = (F^-1) (-B/D2)
   //        E = 1/D2 + (-B#/D2) G)
   //
   //  the inverse of F is calculated using a Cholesky decomposition
   //
   // Error handling:
   // (a) if rankPtr==0: user requests inverse
   //
   //    if D1 is not strictly positive, return NULL
   //    if D2 is not strictly positive, return NULL
   //    if F is not strictly positive (Cholesky decomposition failed)
   //           return NULL
   //    else
   //      return Ainv as defined above
   //
   // (b) if rankPtr !=0: user requests pseudo-inverse
   //    if D2 is not strictly positive or F is not strictly positive
   //      calculate singular-value decomposition of
   //          D2   B#
   //         (       ) = O D O^-1
   //           B   C
   //      if some eigenvalues are negative, return NULL
   //      else calculate pseudo-inverse
   //        *rankPtr = rank(D1)+rank(D)
   //    else
   //      calculate pseudo-inverse of D1  (D1_ii==0) ? 0 : 1/D1_ii
   //      *rankPtr=rank(D1)+nrow(D2)+nrow(C)
   //      return Ainv as defined above

   Double_t *rEl_data=new Double_t[A->GetNrows()*A->GetNrows()];
   Int_t *rEl_col=new Int_t[A->GetNrows()*A->GetNrows()];
   Int_t *rEl_row=new Int_t[A->GetNrows()*A->GetNrows()];
   Int_t rNumEl=0;

   //====================================================
   // invert D1
   Int_t rankD1=0;
   for(Int_t i=0;i<iDiagonal;++i) {
      Int_t iA=swap[i];
      if(aII(iA)>0.0) {
         rEl_col[rNumEl]=iA;
         rEl_row[rNumEl]=iA;
         rEl_data[rNumEl]=1./aII(iA);
         ++rankD1;
         ++rNumEl;
      }
   }
   if((!rankPtr)&&(rankD1!=iDiagonal)) {
      Fatal("InvertMSparseSymmPos",
            "diagonal part 1 has rank %d != %d, matrix can not be inverted",
            rankD1,iDiagonal);
      rNumEl=-1;
   }


   //====================================================
   // invert D2
   Int_t nD2=iBlock-iDiagonal;
   TMatrixDSparse *D2inv=0;
   if((rNumEl>=0)&&(nD2>0)) {
      Double_t *D2inv_data=new Double_t[nD2];
      Int_t *D2inv_col=new Int_t[nD2];
      Int_t *D2inv_row=new Int_t[nD2];
      Int_t D2invNumEl=0;
      for(Int_t i=0;i<nD2;++i) {
         Int_t iA=swap[i+iDiagonal];
         if(aII(iA)>0.0) {
            D2inv_col[D2invNumEl]=i;
            D2inv_row[D2invNumEl]=i;
            D2inv_data[D2invNumEl]=1./aII(iA);
            ++D2invNumEl;
         }
      }
      if(D2invNumEl==nD2) {
         D2inv=CreateSparseMatrix(nD2,nD2,D2invNumEl,D2inv_row,D2inv_col,
                                  D2inv_data);
      } else if(!rankPtr) {
         Fatal("InvertMSparseSymmPos",
               "diagonal part 2 has rank %d != %d, matrix can not be inverted",
               D2invNumEl,nD2);
         rNumEl=-2;
      }
      delete [] D2inv_data;
      delete [] D2inv_col;
      delete [] D2inv_row;
   }

   //====================================================
   // invert F

   Int_t nF=A->GetNrows()-iBlock;
   TMatrixDSparse *Finv=0;
   TMatrixDSparse *B=0;
   TMatrixDSparse *minusBD2inv=0;
   if((rNumEl>=0)&&(nF>0)&&((nD2==0)||D2inv)) {
      // construct matrices F and B
      Int_t nFmax=nF*nF;
      Double_t epsilonF2=fEpsMatrix;
      Double_t *F_data=new Double_t[nFmax];
      Int_t *F_col=new Int_t[nFmax];
      Int_t *F_row=new Int_t[nFmax];
      Int_t FnumEl=0;

      Int_t nBmax=nF*(nD2+1);
      Double_t *B_data=new Double_t[nBmax];
      Int_t *B_col=new Int_t[nBmax];
      Int_t *B_row=new Int_t[nBmax];
      Int_t BnumEl=0;

      for(Int_t i=0;i<nF;i++) {
         Int_t iA=swap[i+iBlock];
         for(Int_t indexA=a_rows[iA];indexA<a_rows[iA+1];indexA++) {
            Int_t jA=a_cols[indexA];
            Int_t j0=swapBack[jA];
            if(j0>=iBlock) {
               Int_t j=j0-iBlock;
               F_row[FnumEl]=i;
               F_col[FnumEl]=j;
               F_data[FnumEl]=a_data[indexA];
               FnumEl++;
            } else if(j0>=iDiagonal) {
               Int_t j=j0-iDiagonal;
               B_row[BnumEl]=i;
               B_col[BnumEl]=j;
               B_data[BnumEl]=a_data[indexA];
               BnumEl++;
            }
         }
      }
      TMatrixDSparse *F=0;
      if(FnumEl) {
#ifndef FORCE_EIGENVALUE_DECOMPOSITION
         F=CreateSparseMatrix(nF,nF,FnumEl,F_row,F_col,F_data);
#endif
      }
      delete [] F_data;
      delete [] F_col;
      delete [] F_row;
      if(BnumEl) {
         B=CreateSparseMatrix(nF,nD2,BnumEl,B_row,B_col,B_data);
      }
      delete [] B_data;
      delete [] B_col;
      delete [] B_row;

      if(B && D2inv) {
         minusBD2inv=MultiplyMSparseMSparse(B,D2inv);
         if(minusBD2inv) {
            Int_t mbd2_nMax=minusBD2inv->GetRowIndexArray()
            [minusBD2inv->GetNrows()];
            Double_t *mbd2_data=minusBD2inv->GetMatrixArray();
            for(Int_t i=0;i<mbd2_nMax;i++) {
               mbd2_data[i] = -  mbd2_data[i];
            }
         }
      }
      if(minusBD2inv && F) {
         TMatrixDSparse *minusBD2invBt=
         MultiplyMSparseMSparseTranspVector(minusBD2inv,B,0);
         AddMSparse(F,1.,minusBD2invBt);
         DeleteMatrix(&minusBD2invBt);
      }

      if(F) {
         // cholesky decomposition with preconditioning
         const Int_t *f_rows=F->GetRowIndexArray();
         const Int_t *f_cols=F->GetColIndexArray();
         const Double_t *f_data=F->GetMatrixArray();
         // cholesky-type decomposition of F
         TMatrixD c(nF,nF);
         Int_t nErrorF=0;
         for(Int_t i=0;i<nF;i++) {
            for(Int_t indexF=f_rows[i];indexF<f_rows[i+1];indexF++) {
               if(f_cols[indexF]>=i) c(f_cols[indexF],i)=f_data[indexF];
            }
            // calculate diagonal element
            Double_t c_ii=c(i,i);
            for(Int_t j=0;j<i;j++) {
               Double_t c_ij=c(i,j);
               c_ii -= c_ij*c_ij;
            }
            if(c_ii<=0.0) {
               nErrorF++;
               break;
            }
            c_ii=TMath::Sqrt(c_ii);
            c(i,i)=c_ii;
            // off-diagonal elements
            for(Int_t j=i+1;j<nF;j++) {
               Double_t c_ji=c(j,i);
               for(Int_t k=0;k<i;k++) {
                  c_ji -= c(i,k)*c(j,k);
               }
               c(j,i) = c_ji/c_ii;
            }
         }
         // check condition of dInv
         if(!nErrorF) {
            Double_t dmin=c(0,0);
            Double_t dmax=dmin;
            for(Int_t i=1;i<nF;i++) {
               dmin=TMath::Min(dmin,c(i,i));
               dmax=TMath::Max(dmax,c(i,i));
            }
#ifdef DEBUG
            std::cout<<"dmin,dmax: "<<dmin<<" "<<dmax<<"\n";
#endif
            if(dmin/dmax<epsilonF2*nF) nErrorF=2;
         }
         if(!nErrorF) {
            // here: F = c c#
            // construct inverse of c
            TMatrixD cinv(nF,nF);
            for(Int_t i=0;i<nF;i++) {
               cinv(i,i)=1./c(i,i);
            }
            for(Int_t i=0;i<nF;i++) {
               for(Int_t j=i+1;j<nF;j++) {
                  Double_t tmp=-c(j,i)*cinv(i,i);
                  for(Int_t k=i+1;k<j;k++) {
                     tmp -= cinv(k,i)*c(j,k);
                  }
                  cinv(j,i)=tmp*cinv(j,j);
               }
            }
            TMatrixDSparse cInvSparse(cinv);
            Finv=MultiplyMSparseTranspMSparse
            (&cInvSparse,&cInvSparse);
         }
         DeleteMatrix(&F);
      }
   }

   // here:
   //   rNumEl>=0: diagonal part has been inverted
   //   (nD2==0)||D2inv : D2 part has been inverted or is empty
   //   (nF==0)||Finv : F part has been inverted or is empty

   Int_t rankD2Block=0;
   if(rNumEl>=0) {
      if( ((nD2==0)||D2inv) && ((nF==0)||Finv) ) {
         // all matrix parts have been inverted, compose full matrix
         //           1/D1   0    0
         //  Ainv = (  0     E    G#   )
         //            0     G    F^-1
         //
         //        G = (F^-1) (-B/D2)
         //        E = 1/D2 + (-B#/D2) G)

         TMatrixDSparse *G=0;
         if(Finv && minusBD2inv) {
            G=MultiplyMSparseMSparse(Finv,minusBD2inv);
         }
         TMatrixDSparse *E=0;
         if(D2inv) E=new TMatrixDSparse(*D2inv);
         if(G && minusBD2inv) {
            TMatrixDSparse *minusBD2invTransG=
            MultiplyMSparseTranspMSparse(minusBD2inv,G);
            if(E) {
               AddMSparse(E,1.,minusBD2invTransG);
               DeleteMatrix(&minusBD2invTransG);
            } else {
               E=minusBD2invTransG;
            }
         }
         // pack matrix E to r
         if(E) {
            const Int_t *e_rows=E->GetRowIndexArray();
            const Int_t *e_cols=E->GetColIndexArray();
            const Double_t *e_data=E->GetMatrixArray();
            for(Int_t iE=0;iE<E->GetNrows();iE++) {
               Int_t iA=swap[iE+iDiagonal];
               for(Int_t indexE=e_rows[iE];indexE<e_rows[iE+1];++indexE) {
                  Int_t jE=e_cols[indexE];
                  Int_t jA=swap[jE+iDiagonal];
                  rEl_col[rNumEl]=iA;
                  rEl_row[rNumEl]=jA;
                  rEl_data[rNumEl]=e_data[indexE];
                  ++rNumEl;
               }
            }
            DeleteMatrix(&E);
         }
         // pack matrix G to r
         if(G) {
            const Int_t *g_rows=G->GetRowIndexArray();
            const Int_t *g_cols=G->GetColIndexArray();
            const Double_t *g_data=G->GetMatrixArray();
            for(Int_t iG=0;iG<G->GetNrows();iG++) {
               Int_t iA=swap[iG+iBlock];
               for(Int_t indexG=g_rows[iG];indexG<g_rows[iG+1];++indexG) {
                  Int_t jG=g_cols[indexG];
                  Int_t jA=swap[jG+iDiagonal];
                  // G
                  rEl_col[rNumEl]=iA;
                  rEl_row[rNumEl]=jA;
                  rEl_data[rNumEl]=g_data[indexG];
                  ++rNumEl;
                  // G#
                  rEl_col[rNumEl]=jA;
                  rEl_row[rNumEl]=iA;
                  rEl_data[rNumEl]=g_data[indexG];
                  ++rNumEl;
               }
            }
            DeleteMatrix(&G);
         }
         if(Finv) {
            // pack matrix Finv to r
            const Int_t *finv_rows=Finv->GetRowIndexArray();
            const Int_t *finv_cols=Finv->GetColIndexArray();
            const Double_t *finv_data=Finv->GetMatrixArray();
            for(Int_t iF=0;iF<Finv->GetNrows();iF++) {
               Int_t iA=swap[iF+iBlock];
               for(Int_t indexF=finv_rows[iF];indexF<finv_rows[iF+1];++indexF) {
                  Int_t jF=finv_cols[indexF];
                  Int_t jA=swap[jF+iBlock];
                  rEl_col[rNumEl]=iA;
                  rEl_row[rNumEl]=jA;
                  rEl_data[rNumEl]=finv_data[indexF];
                  ++rNumEl;
               }
            }
         }
         rankD2Block=nD2+nF;
      } else if(!rankPtr) {
         rNumEl=-3;
         Fatal("InvertMSparseSymmPos",
               "non-trivial part has rank < %d, matrix can not be inverted",
               nF);
      } else {
         // part of the matrix could not be inverted, get eingenvalue
         // decomposition
         Int_t nEV=nD2+nF;
         Double_t epsilonEV2=fEpsMatrix /* *nEV*nEV */;
         Info("InvertMSparseSymmPos",
              "cholesky-decomposition failed, try eigenvalue analysis");
#ifdef DEBUG
         std::cout<<"nEV="<<nEV<<" iDiagonal="<<iDiagonal<<"\n";
#endif
         TMatrixDSym EV(nEV);
         for(Int_t i=0;i<nEV;i++) {
            Int_t iA=swap[i+iDiagonal];
            for(Int_t indexA=a_rows[iA];indexA<a_rows[iA+1];indexA++) {
               Int_t jA=a_cols[indexA];
               Int_t j0=swapBack[jA];
               if(j0>=iDiagonal) {
                  Int_t j=j0-iDiagonal;
#ifdef DEBUG
                  if((i<0)||(j<0)||(i>=nEV)||(j>=nEV)) {
                     std::cout<<" error "<<nEV<<" "<<i<<" "<<j<<"\n";
                  }
#endif
                  if(!TMath::Finite(a_data[indexA])) {
                     Fatal("InvertMSparseSymmPos",
                           "non-finite number detected element %d %d\n",
                           iA,jA);
                  }
                  EV(i,j)=a_data[indexA];
               }
            }
         }
         // EV.Print();
         TMatrixDSymEigen Eigen(EV);
#ifdef DEBUG
         std::cout<<"Eigenvalues\n";
         // Eigen.GetEigenValues().Print();
#endif
         Int_t errorEV=0;
         Double_t condition=1.0;
         if(Eigen.GetEigenValues()(0)<0.0) {
            errorEV=1;
         } else if(Eigen.GetEigenValues()(0)>0.0) {
            condition=Eigen.GetEigenValues()(nEV-1)/Eigen.GetEigenValues()(0);
         }
         if(condition<-epsilonEV2) {
            errorEV=2;
         }
         if(errorEV) {
            if(errorEV==1) {
               Error("InvertMSparseSymmPos",
                     "Largest Eigenvalue is negative %f",
                     Eigen.GetEigenValues()(0));
            } else {
               Error("InvertMSparseSymmPos",
                     "Some Eigenvalues are negative (EV%d/EV0=%g epsilon=%g)",
                     nEV-1,
                     Eigen.GetEigenValues()(nEV-1)/Eigen.GetEigenValues()(0),
                     epsilonEV2);
            }
         }
         // compose inverse matrix
         rankD2Block=0;
         Double_t setToZero=epsilonEV2*Eigen.GetEigenValues()(0);
         TMatrixD inverseEV(nEV,1);
         for(Int_t i=0;i<nEV;i++) {
            Double_t x=Eigen.GetEigenValues()(i);
            if(x>setToZero) {
               inverseEV(i,0)=1./x;
               ++rankD2Block;
            }
         }
         TMatrixDSparse V(Eigen.GetEigenVectors());
         TMatrixDSparse *VDVt=MultiplyMSparseMSparseTranspVector
         (&V,&V,&inverseEV);

         // pack matrix VDVt to r
         const Int_t *vdvt_rows=VDVt->GetRowIndexArray();
         const Int_t *vdvt_cols=VDVt->GetColIndexArray();
         const Double_t *vdvt_data=VDVt->GetMatrixArray();
         for(Int_t iVDVt=0;iVDVt<VDVt->GetNrows();iVDVt++) {
            Int_t iA=swap[iVDVt+iDiagonal];
            for(Int_t indexVDVt=vdvt_rows[iVDVt];
                indexVDVt<vdvt_rows[iVDVt+1];++indexVDVt) {
               Int_t jVDVt=vdvt_cols[indexVDVt];
               Int_t jA=swap[jVDVt+iDiagonal];
               rEl_col[rNumEl]=iA;
               rEl_row[rNumEl]=jA;
               rEl_data[rNumEl]=vdvt_data[indexVDVt];
               ++rNumEl;
            }
         }
         DeleteMatrix(&VDVt);
      }
   }
   if(rankPtr) {
      *rankPtr=rankD1+rankD2Block;
   }


   DeleteMatrix(&D2inv);
   DeleteMatrix(&Finv);
   DeleteMatrix(&B);
   DeleteMatrix(&minusBD2inv);

   delete [] swap;
   delete [] swapBack;
   delete [] isZero;

   TMatrixDSparse *r=(rNumEl>=0) ?
   CreateSparseMatrix(A->GetNrows(),A->GetNrows(),rNumEl,
                      rEl_row,rEl_col,rEl_data) : 0;
   delete [] rEl_data;
   delete [] rEl_col;
   delete [] rEl_row;

#ifdef DEBUG_DETAIL
   // sanity test
   if(r) {
      TMatrixDSparse *Ar=MultiplyMSparseMSparse(A,r);
      TMatrixDSparse *ArA=MultiplyMSparseMSparse(Ar,A);
      TMatrixDSparse *rAr=MultiplyMSparseMSparse(r,Ar);

      TMatrixD ar(*Ar);
      TMatrixD a(*A);
      TMatrixD ara(*ArA);
      TMatrixD R(*r);
      TMatrixD rar(*rAr);

      DeleteMatrix(&Ar);
      DeleteMatrix(&ArA);
      DeleteMatrix(&rAr);

      Double_t epsilonA2=fEpsMatrix /* *a.GetNrows()*a.GetNcols() */;
      for(Int_t i=0;i<a.GetNrows();i++) {
         for(Int_t j=0;j<a.GetNcols();j++) {
            // ar should be symmetric
            if(TMath::Abs(ar(i,j)-ar(j,i))>
               epsilonA2*(TMath::Abs(ar(i,j))+TMath::Abs(ar(j,i)))) {
               std::cout<<"Ar is not symmetric Ar("<<i<<","<<j<<")="<<ar(i,j)
               <<" Ar("<<j<<","<<i<<")="<<ar(j,i)<<"\n";
            }
            // ara should be equal a
            if(TMath::Abs(ara(i,j)-a(i,j))>
               epsilonA2*(TMath::Abs(ara(i,j))+TMath::Abs(a(i,j)))) {
               std::cout<<"ArA is not equal A ArA("<<i<<","<<j<<")="<<ara(i,j)
               <<" A("<<i<<","<<j<<")="<<a(i,j)<<"\n";
            }
            // ara should be equal a
            if(TMath::Abs(rar(i,j)-R(i,j))>
               epsilonA2*(TMath::Abs(rar(i,j))+TMath::Abs(R(i,j)))) {
               std::cout<<"rAr is not equal r rAr("<<i<<","<<j<<")="<<rar(i,j)
               <<" r("<<i<<","<<j<<")="<<R(i,j)<<"\n";
            }
         }
      }
      if(rankPtr) std::cout<<"rank="<<*rankPtr<<"\n";
   } else {
      std::cout<<"Matrix is not positive\n";
   }
#endif
   return r;

}

TString TUnfold::GetOutputBinName(Int_t iBinX) const
{
   // given a bin number, return the name of the output bin
   // this method makes more sense for the class TUnfoldDnesity
   // where it gets overwritten
   return TString::Format("#%d",iBinX);
}

TUnfold::TUnfold(const TH2 *hist_A, EHistMap histmap, ERegMode regmode,
                 EConstraint constraint)
{
   // set up unfolding matrix and initial regularisation scheme
   //    hist_A:  matrix that describes the migrations
   //    histmap: mapping of the histogram axes to the unfolding output
   //    regmode: global regularisation mode
   //    constraint: type of constraint to use
   // data members initialized to something different from zero:
   //    fA: filled from hist_A
   //    fDA: filled from hist_A
   //    fX0: filled from hist_A
   //    fL: filled depending on the regularisation scheme
   // Treatment of overflow bins
   //    Bins where the unfolding input (Detector level) is in overflow
   //    are used for the efficiency correction. They have to be filled
   //    properly!
   //    Bins where the unfolding output (Generator level) is in overflow
   //    are treated as a part of the generator level distribution.
   //    I.e. the unfolding output could have non-zero overflow bins if the
   //    input matrix does have such bins.

   InitTUnfold();
   SetConstraint(constraint);
   Int_t nx0, nx, ny;
   if (histmap == kHistMapOutputHoriz) {
      // include overflow bins on the X axis
      nx0 = hist_A->GetNbinsX()+2;
      ny = hist_A->GetNbinsY();
   } else {
      // include overflow bins on the X axis
      nx0 = hist_A->GetNbinsY()+2;
      ny = hist_A->GetNbinsX();
   }
   nx = 0;
   // fNx is expected to be nx0, but the input matrix may be ill-formed
   // -> all columns with zero events have to be removed
   //    (because y does not contain any information on that bin in x)
   fSumOverY.Set(nx0);
   fXToHist.Set(nx0);
   fHistToX.Set(nx0);
   Int_t nonzeroA=0;
   // loop
   //  - calculate bias distribution
   //      sum_over_y
   //  - count those generator bins which can be unfolded
   //      fNx
   //  - histogram bins are added to the lookup-tables
   //      fHistToX[] and fXToHist[]
   //    these convert histogram bins to matrix indices and vice versa
   //  - the number of non-zero elements is counted
   //      nonzeroA
   Int_t nskipped=0;
   for (Int_t ix = 0; ix < nx0; ix++) {
      // calculate sum over all detector bins
      // excluding the overflow bins
      Double_t sum = 0.0;
      Int_t nonZeroY = 0;
      for (Int_t iy = 0; iy < ny; iy++) {
         Double_t z;
         if (histmap == kHistMapOutputHoriz) {
            z = hist_A->GetBinContent(ix, iy + 1);
         } else {
            z = hist_A->GetBinContent(iy + 1, ix);
         }
         if (z != 0.0) {
            nonzeroA++;
            nonZeroY++;
            sum += z;
         }
      }
      // check whether there is any sensitivity to this generator bin

      if (nonZeroY) {
         // update mapping tables to convert bin number to matrix index
         fXToHist[nx] = ix;
         fHistToX[ix] = nx;
         // add overflow bins -> important to keep track of the
         // non-reconstructed events
         fSumOverY[nx] = sum;
         if (histmap == kHistMapOutputHoriz) {
            fSumOverY[nx] +=
            hist_A->GetBinContent(ix, 0) +
            hist_A->GetBinContent(ix, ny + 1);
         } else {
            fSumOverY[nx] +=
            hist_A->GetBinContent(0, ix) +
            hist_A->GetBinContent(ny + 1, ix);
         }
         nx++;
      } else {
         nskipped++;
         // histogram bin pointing to -1 (non-existing matrix entry)
         fHistToX[ix] = -1;
      }
   }
   Int_t underflowBin=0,overflowBin=0;
   for (Int_t ix = 0; ix < nx; ix++) {
      Int_t ibinx = fXToHist[ix];
      if(ibinx<1) underflowBin=1;
      if (histmap == kHistMapOutputHoriz) {
         if(ibinx>hist_A->GetNbinsX()) overflowBin=1;
      } else {
         if(ibinx>hist_A->GetNbinsY()) overflowBin=1;
      }
   }
   if(nskipped) {
      Int_t nprint=0;
      Int_t ixfirst=-1,ixlast=-1;
      TString binlist;
      int nDisconnected=0;
      for (Int_t ix = 0; ix < nx0; ix++) {
         if(fHistToX[ix]<0) {
            nprint++;
            if(ixlast<0) {
               binlist +=" ";
               binlist +=ix;
               ixfirst=ix;
            }
            ixlast=ix;
            nDisconnected++;
         }
         if(((fHistToX[ix]>=0)&&(ixlast>=0))||
            (nprint==nskipped)) {
            if(ixlast>ixfirst) {
               binlist += "-";
               binlist += ixlast;
            }
            ixfirst=-1;
            ixlast=-1;
         }
         if(nprint==nskipped) {
            break;
         }
      }
      if(nskipped==(2-underflowBin-overflowBin)) {
         Info("TUnfold","underflow and overflow bin "
              "do not depend on the input data");
      } else {
         Warning("TUnfold","%d output bins "
                 "do not depend on the input data %s",nDisconnected,
                 static_cast<const char *>(binlist));
      }
   }
   // store bias as matrix
   fX0 = new TMatrixD(nx, 1, fSumOverY.GetArray());
   // store non-zero elements in sparse matrix fA
   // construct sparse matrix fA
   Int_t *rowA = new Int_t[nonzeroA];
   Int_t *colA = new Int_t[nonzeroA];
   Double_t *dataA = new Double_t[nonzeroA];
   Int_t index=0;
   for (Int_t iy = 0; iy < ny; iy++) {
      for (Int_t ix = 0; ix < nx; ix++) {
         Int_t ibinx = fXToHist[ix];
         Double_t z;
         if (histmap == kHistMapOutputHoriz) {
            z = hist_A->GetBinContent(ibinx, iy + 1);
         } else {
            z = hist_A->GetBinContent(iy + 1, ibinx);
         }
         if (z != 0.0) {
            rowA[index]=iy;
            colA[index] = ix;
            dataA[index] = z / fSumOverY[ix];
            index++;
         }
      }
   }
   if(underflowBin && overflowBin) {
      Info("TUnfold","%d input bins and %d output bins (includes 2 underflow/overflow bins)",ny,nx);
   } else if(underflowBin) {
      Info("TUnfold","%d input bins and %d output bins (includes 1 underflow bin)",ny,nx);
   } else if(overflowBin) {
      Info("TUnfold","%d input bins and %d output bins (includes 1 overflow bin)",ny,nx);
   } else {
      Info("TUnfold","%d input bins and %d output bins",ny,nx);
   }
   fA = CreateSparseMatrix(ny,nx,index,rowA,colA,dataA);
   if(ny<nx) {
      Error("TUnfold","too few (ny=%d) input bins for nx=%d output bins",ny,nx);
   } else if(ny==nx) {
      Warning("TUnfold","too few (ny=%d) input bins for nx=%d output bins",ny,nx);
   }
   delete[] rowA;
   delete[] colA;
   delete[] dataA;
   // regularisation conditions squared
   fL = new TMatrixDSparse(1, GetNx());
   if (regmode != kRegModeNone) {
      Int_t nError=RegularizeBins(0, 1, nx0, regmode);
      if(nError>0) {
         if(nError>1) {
            Info("TUnfold",
                 "%d regularisation conditions have been skipped",nError);
         } else {
            Info("TUnfold",
                 "One regularisation condition has been skipped");
         }
      }
   }
}

TUnfold::~TUnfold(void)
{
   // delete all data members

   DeleteMatrix(&fA);
   DeleteMatrix(&fL);
   DeleteMatrix(&fVyy);
   DeleteMatrix(&fY);
   DeleteMatrix(&fX0);

   ClearResults();
}

void TUnfold::SetBias(const TH1 *bias)
{
   // initialize alternative bias from histogram
   // modifies data member fX0
   DeleteMatrix(&fX0);
   fX0 = new TMatrixD(GetNx(), 1);
   for (Int_t i = 0; i < GetNx(); i++) {
      (*fX0) (i, 0) = bias->GetBinContent(fXToHist[i]);
   }
}

Bool_t TUnfold::AddRegularisationCondition
(Int_t i0,Double_t f0,Int_t i1,Double_t f1,Int_t i2,Double_t f2)
{
   // add regularisation condition for a triplet of bins and scale factors
   // the arguments are used to form one row (k) of the matrix L
   //   L(k,i0)=f0
   //   L(k,i1)=f1
   //   L(k,i2)=f2
   // the indices i0,i1,i2 are transformed of bin numbers
   // if i2<0, do not fill  L(k,i2)
   // if i1<0, do not fill  L(k,i1)

   Int_t indices[3];
   Double_t data[3];
   Int_t nEle=0;

   if(i2>=0) {
      data[nEle]=f2;
      indices[nEle]=i2;
      nEle++;
   }
   if(i1>=0) {
      data[nEle]=f1;
      indices[nEle]=i1;
      nEle++;
   }
   if(i0>=0) {
      data[nEle]=f0;
      indices[nEle]=i0;
      nEle++;
   }
   return AddRegularisationCondition(nEle,indices,data);
}

Bool_t TUnfold::AddRegularisationCondition
(Int_t nEle,const Int_t *indices,const Double_t *rowData)
{
   // add a regularisation condition
   // the arguments are used to form one row (k) of the matrix L
   //   L(k,indices[0])=rowData[0]
   //    ...
   //   L(k,indices[nEle-1])=rowData[nEle-1]
   //
   // the indices are taken as bin numbers,
   // transformed to internal bin numbers using the array fHistToX


   Bool_t r=kTRUE;
   const Int_t *l0_rows=fL->GetRowIndexArray();
   const Int_t *l0_cols=fL->GetColIndexArray();
   const Double_t *l0_data=fL->GetMatrixArray();

   Int_t nF=l0_rows[fL->GetNrows()]+nEle;
   Int_t *l_row=new Int_t[nF];
   Int_t *l_col=new Int_t[nF];
   Double_t *l_data=new Double_t[nF];
   // decode original matrix
   nF=0;
   for(Int_t row=0;row<fL->GetNrows();row++) {
      for(Int_t k=l0_rows[row];k<l0_rows[row+1];k++) {
         l_row[nF]=row;
         l_col[nF]=l0_cols[k];
         l_data[nF]=l0_data[k];
         nF++;
      }
   }

   // if the original matrix does not have any data, reset its row count
   Int_t rowMax=0;
   if(nF>0) {
      rowMax=fL->GetNrows();
   }

   // add the new regularisation conditions
   for(Int_t i=0;i<nEle;i++) {
      Int_t col=fHistToX[indices[i]];
      if(col<0) {
         r=kFALSE;
         break;
      }
      l_row[nF]=rowMax;
      l_col[nF]=col;
      l_data[nF]=rowData[i];
      nF++;
   }

   // replace the old matrix fL
   if(r) {
      DeleteMatrix(&fL);
      fL=CreateSparseMatrix(rowMax+1,GetNx(),nF,l_row,l_col,l_data);
   }
   delete [] l_row;
   delete [] l_col;
   delete [] l_data;
   return r;
}

Int_t TUnfold::RegularizeSize(int bin, Double_t scale)
{
   // add regularisation on the size of bin i
   //    bin: bin number
   //    scale: size of the regularisation
   // return value: number of conditions which have been skipped
   // modifies data member fL

   if(fRegMode==kRegModeNone) fRegMode=kRegModeSize;
   if(fRegMode!=kRegModeSize) fRegMode=kRegModeMixed;

   return AddRegularisationCondition(bin,scale) ? 0 : 1;
}

Int_t TUnfold::RegularizeDerivative(int left_bin, int right_bin,
                                    Double_t scale)
{
   // add regularisation on the difference of two bins
   //   left_bin: 1st bin
   //   right_bin: 2nd bin
   //   scale: size of the regularisation
   // return value: number of conditions which have been skipped
   // modifies data member fL

   if(fRegMode==kRegModeNone) fRegMode=kRegModeDerivative;
   if(fRegMode!=kRegModeDerivative) fRegMode=kRegModeMixed;

   return AddRegularisationCondition(left_bin,-scale,right_bin,scale) ? 0 : 1;
}

Int_t TUnfold::RegularizeCurvature(int left_bin, int center_bin,
                                   int right_bin,
                                   Double_t scale_left,
                                   Double_t scale_right)
{
   // add regularisation on the curvature through 3 bins (2nd derivative)
   //   left_bin: 1st bin
   //   center_bin: 2nd bin
   //   right_bin: 3rd bin
   //   scale_left: scale factor on center-left difference
   //   scale_right: scale factor on right-center difference
   // return value: number of conditions which have been skipped
   // modifies data member fL

   if(fRegMode==kRegModeNone) fRegMode=kRegModeCurvature;
   if(fRegMode!=kRegModeCurvature) fRegMode=kRegModeMixed;

   return AddRegularisationCondition
   (left_bin,-scale_left,
    center_bin,scale_left+scale_right,
    right_bin,-scale_right)
   ? 0 : 1;
}

Int_t TUnfold::RegularizeBins(int start, int step, int nbin,
                              ERegMode regmode)
{
   // set regulatisation on a 1-dimensional curve
   //   start: first bin
   //   step:  distance between neighbouring bins
   //   nbin:  total number of bins
   //   regmode:  regularisation mode
   // return value:
   //   number of errors (i.e. conditions which have been skipped)
   // modifies data member fL

   Int_t i0, i1, i2;
   i0 = start;
   i1 = i0 + step;
   i2 = i1 + step;
   Int_t nSkip = 0;
   Int_t nError= 0;
   if (regmode == kRegModeDerivative) {
      nSkip = 1;
   } else if (regmode == kRegModeCurvature) {
      nSkip = 2;
   } else if(regmode != kRegModeSize) {
      Error("RegularizeBins","regmode = %d is not valid",regmode);
   }
   for (Int_t i = nSkip; i < nbin; i++) {
      if (regmode == kRegModeSize) {
         nError += RegularizeSize(i0);
      } else if (regmode == kRegModeDerivative) {
         nError += RegularizeDerivative(i0, i1);
      } else if (regmode == kRegModeCurvature) {
         nError += RegularizeCurvature(i0, i1, i2);
      }
      i0 = i1;
      i1 = i2;
      i2 += step;
   }
   return nError;
}

Int_t TUnfold::RegularizeBins2D(int start_bin, int step1, int nbin1,
                                int step2, int nbin2, ERegMode regmode)
{
   // set regularisation on a 2-dimensional grid of bins
   //     start: first bin
   //     step1: distance between bins in 1st direction
   //     nbin1: number of bins in 1st direction
   //     step2: distance between bins in 2nd direction
   //     nbin2: number of bins in 2nd direction
   // return value:
   //   number of errors (i.e. conditions which have been skipped)
   // modifies data member fL

   Int_t nError = 0;
   for (Int_t i1 = 0; i1 < nbin1; i1++) {
      nError += RegularizeBins(start_bin + step1 * i1, step2, nbin2, regmode);
   }
   for (Int_t i2 = 0; i2 < nbin2; i2++) {
      nError += RegularizeBins(start_bin + step2 * i2, step1, nbin1, regmode);
   }
   return nError;
}

Double_t TUnfold::DoUnfold(Double_t tau_reg,const TH1 *input,
                           Double_t scaleBias)
{
   // Do unfolding of an input histogram
   //   tau_reg: regularisation parameter
   //   input:   input distribution with errors
   //   scaleBias:  scale factor applied to the bias
   // Data members required:
   //   fA, fX0, fL
   // Data members modified:
   //   those documented in SetInput()
   //   and those documented in DoUnfold(Double_t)
   // Return value:
   //   maximum global correlation coefficient
   //   NOTE!!! return value >=1.0 means error, and the result is junk
   //
   // Overflow bins of the input distribution are ignored!

   SetInput(input,scaleBias);
   return DoUnfold(tau_reg);
}

Int_t TUnfold::SetInput(const TH1 *input, Double_t scaleBias,
                        Double_t oneOverZeroError,const TH2 *hist_vyy,
                        const TH2 *hist_vyy_inv)
{
   // Define the input data for subsequent calls to DoUnfold(Double_t)
   //   input:   input distribution with errors
   //   scaleBias:  scale factor applied to the bias
   //   oneOverZeroError: for bins with zero error, this number defines 1/error.
   //   hist_vyy: if non-zero, defines the data covariance matrix
   //             otherwise it is calculated from the data errors
   //   hist_vyy_inv: if non-zero and if hist_vyy  is set, defines the inverse of the data covariance matrix
   // Return value: number of bins with bad error
   //                 +10000*number of unconstrained output bins
   //         Note: return values>=10000 are fatal errors,
   //               for the given input, the unfolding can not be done!
   // Data members modified:
   //   fY, fVyy, , fBiasScale
   // Data members cleared
   //   fVyyInv, fNdf
   //   + see ClearResults

   DeleteMatrix(&fVyyInv);
   fNdf=0;

   fBiasScale = scaleBias;

   // delete old results (if any)
   ClearResults();

   // construct error matrix and inverted error matrix of measured quantities
   // from errors of input histogram or use error matrix

   Int_t *rowVyyN=new Int_t[GetNy()*GetNy()+1];
   Int_t *colVyyN=new Int_t[GetNy()*GetNy()+1];
   Double_t *dataVyyN=new Double_t[GetNy()*GetNy()+1];

   Int_t *rowVyy1=new Int_t[GetNy()];
   Int_t *colVyy1=new Int_t[GetNy()];
   Double_t *dataVyy1=new Double_t[GetNy()];
   Double_t *dataVyyDiag=new Double_t[GetNy()];

   Int_t nError=0;
   Int_t nVyyN=0;
   Int_t nVyy1=0;
   for (Int_t iy = 0; iy < GetNy(); iy++) {
      // diagonals
      Double_t dy2;
      if(!hist_vyy) {
         Double_t dy = input->GetBinError(iy + 1);
         dy2=dy*dy;
         if (dy2 <= 0.0) {
            nError++;
            if(oneOverZeroError>0.0) {
               dy2 = 1./ ( oneOverZeroError*oneOverZeroError);
            }
         }
      } else {
         dy2 = hist_vyy->GetBinContent(iy+1,iy+1);
      }
      rowVyyN[nVyyN] = iy;
      colVyyN[nVyyN] = iy;
      rowVyy1[nVyy1] = iy;
      colVyy1[nVyy1] = 0;
      dataVyyDiag[iy] = dy2;
      if(dy2>0.0) {
         dataVyyN[nVyyN++] = dy2;
         dataVyy1[nVyy1++] = dy2;
      }
   }
   if(hist_vyy) {
      // non-diagonal elements
      for (Int_t iy = 0; iy < GetNy(); iy++) {
         // ignore rows where the diagonal is zero
         if(dataVyyDiag[iy]<=0.0) continue;
         for (Int_t jy = 0; jy < GetNy(); jy++) {
            // skip diagonal elements
            if(iy==jy) continue;
            // ignore columns where the diagonal is zero
            if(dataVyyDiag[jy]<=0.0) continue;

            rowVyyN[nVyyN] = iy;
            colVyyN[nVyyN] = jy;
            dataVyyN[nVyyN]= hist_vyy->GetBinContent(iy+1,jy+1);
            if(dataVyyN[nVyyN] == 0.0) continue;
            nVyyN ++;
         }
      }
      if(hist_vyy_inv) {
         Warning("SetInput",
                 "inverse of input covariance is taken from user input");
         Int_t *rowVyyInv=new Int_t[GetNy()*GetNy()+1];
         Int_t *colVyyInv=new Int_t[GetNy()*GetNy()+1];
         Double_t *dataVyyInv=new Double_t[GetNy()*GetNy()+1];
         Int_t nVyyInv=0;
         for (Int_t iy = 0; iy < GetNy(); iy++) {
            for (Int_t jy = 0; jy < GetNy(); jy++) {
               rowVyyInv[nVyyInv] = iy;
               colVyyInv[nVyyInv] = jy;
               dataVyyInv[nVyyInv]= hist_vyy_inv->GetBinContent(iy+1,jy+1);
               if(dataVyyInv[nVyyInv] == 0.0) continue;
               nVyyInv ++;
            }
         }
         fVyyInv=CreateSparseMatrix
         (GetNy(),GetNy(),nVyyInv,rowVyyInv,colVyyInv,dataVyyInv);
         delete [] rowVyyInv;
         delete [] colVyyInv;
         delete [] dataVyyInv;
      }
   }
   DeleteMatrix(&fVyy);
   fVyy = CreateSparseMatrix
   (GetNy(),GetNy(),nVyyN,rowVyyN,colVyyN,dataVyyN);

   delete[] rowVyyN;
   delete[] colVyyN;
   delete[] dataVyyN;

   TMatrixDSparse *vecV=CreateSparseMatrix
   (GetNy(),1,nVyy1,rowVyy1,colVyy1, dataVyy1);

   delete[] rowVyy1;
   delete[] colVyy1;
   delete[] dataVyy1;

   //
   // get input vector
   DeleteMatrix(&fY);
   fY = new TMatrixD(GetNy(), 1);
   for (Int_t i = 0; i < GetNy(); i++) {
      (*fY) (i, 0) = input->GetBinContent(i + 1);
   }
   // simple check whether unfolding is possible, given the matrices fA and  fV
   TMatrixDSparse *mAtV=MultiplyMSparseTranspMSparse(fA,vecV);
   DeleteMatrix(&vecV);
   Int_t nError2=0;
   for (Int_t i = 0; i <mAtV->GetNrows();i++) {
      if(mAtV->GetRowIndexArray()[i]==
         mAtV->GetRowIndexArray()[i+1]) {
         nError2 ++;
      }
   }
   if(nError>0) {
      if(oneOverZeroError !=0.0) {
         if(nError>1) {
            Warning("SetInput","%d/%d input bins have zero error,"
                    " 1/error set to %lf.",nError,GetNy(),oneOverZeroError);
         } else {
            Warning("SetInput","One input bin has zero error,"
                    " 1/error set to %lf.",oneOverZeroError);
         }
      } else {
         if(nError>1) {
            Warning("SetInput","%d/%d input bins have zero error,"
                    " and are ignored.",nError,GetNy());
         } else {
            Warning("SetInput","One input bin has zero error,"
                    " and is ignored.");
         }
      }
      fIgnoredBins=nError;
   }
   if(nError2>0) {
      // check whether data points with zero error are responsible
      if(oneOverZeroError<=0.0) {
         //const Int_t *a_rows=fA->GetRowIndexArray();
         //const Int_t *a_cols=fA->GetColIndexArray();
         for (Int_t col = 0; col <mAtV->GetNrows();col++) {
            if(mAtV->GetRowIndexArray()[col]==
               mAtV->GetRowIndexArray()[col+1]) {
               TString binlist("no data to constrain output bin ");
               binlist += GetOutputBinName(fXToHist[col]);
               /* binlist +=" depends on ignored input bins ";
                for(Int_t row=0;row<fA->GetNrows();row++) {
                if(dataVyyDiag[row]>0.0) continue;
                for(Int_t i=a_rows[row];i<a_rows[row+1];i++) {
                if(a_cols[i]!=col) continue;
                binlist +=" ";
                binlist +=row;
                }
                } */
               Warning("SetInput","%s",binlist.Data());
            }
         }
      }
      if(nError2>1) {
         Error("SetInput","%d/%d output bins are not constrained by any data.",
               nError2,mAtV->GetNrows());
      } else {
         Error("SetInput","One output bins is not constrained by any data.");
      }
   }
   DeleteMatrix(&mAtV);

   delete[] dataVyyDiag;

   return nError+10000*nError2;
}

Double_t TUnfold::DoUnfold(Double_t tau)
{
   // Unfold with given value of regularisation parameter tau
   //     tau: new tau parameter
   // required data members:
   //     fA:  matrix to relate x and y
   //     fY:  measured data points
   //     fX0: bias on x
   //     fBiasScale: scale factor for fX0
   //     fV:  inverse of covariance matrix for y
   //     fL: regularisation conditions
   // modified data members:
   //     fTauSquared and those documented in DoUnfold(void)
   fTauSquared=tau*tau;
   return DoUnfold();
}

Int_t TUnfold::ScanLcurve(Int_t nPoint,
                          Double_t tauMin,Double_t tauMax,
                          TGraph **lCurve,TSpline **logTauX,
                          TSpline **logTauY)
{
   // scan the L curve
   //   nPoint: number of points on the resulting curve
   //   tauMin: smallest tau value to study
   //   tauMax: largest tau value to study
   //   lCurve: the L curve as graph
   //   logTauX: output spline of x-coordinates vs tau for the L curve
   //   logTauY: output spline of y-coordinates vs tau for the L curve
   // return value: the coordinate number (0..nPoint-1) with the "best" choice
   //     of tau
   typedef std::map<Double_t,std::pair<Double_t,Double_t> > XYtau_t;
   XYtau_t curve;

   //==========================================================
   // algorithm:
   //  (1) do the unfolding for nPoint-1 points
   //      and store the results in the map
   //        curve
   //    (1a) store minimum and maximum tau to curve
   //    (1b) insert additional points, until nPoint-1 values
   //          have been calculated
   //
   //  (2) determine the best choice of tau
   //      do the unfolding for this point
   //      and store the result in
   //        curve
   //  (3) return the result in
   //       lCurve logTauX logTauY

   //==========================================================
   //  (1) do the unfolding for nPoint-1 points
   //      and store the results in
   //        curve
   //    (1a) store minimum and maximum tau to curve

   if((tauMin<=0)||(tauMax<=0.0)||(tauMin>=tauMax)) {
      // here no range is given, has to be determined automatically
      // the maximum tau is determined from the chi**2 values
      // observed from unfolding without regulatisation

      // first unfolding, without regularisation
      DoUnfold(0.0);

      // if the number of degrees of freedom is too small, create an error
      if(GetNdf()<=0) {
         Error("ScanLcurve","too few input bins, NDF<=0 %d",GetNdf());
      }

      Double_t x0=GetLcurveX();
      Double_t y0=GetLcurveY();
      Info("ScanLcurve","logtau=-Infinity X=%lf Y=%lf",x0,y0);
      if(!TMath::Finite(x0)) {
         Fatal("ScanLcurve","problem (too few input bins?) X=%f",x0);
      }
      if(!TMath::Finite(y0)) {
         Fatal("ScanLcurve","problem (missing regularisation?) Y=%f",y0);
      }
      {
         // unfolding guess maximum tau and store it
         Double_t logTau=
         0.5*(TMath::Log10(fChi2A+3.*TMath::Sqrt(GetNdf()+1.0))
              -GetLcurveY());
         DoUnfold(TMath::Power(10.,logTau));
         if((!TMath::Finite(GetLcurveX())) ||(!TMath::Finite(GetLcurveY()))) {
            Fatal("ScanLcurve","problem (missing regularisation?) X=%f Y=%f",
                  GetLcurveX(),GetLcurveY());
         }
         curve[logTau]=std::make_pair(GetLcurveX(),GetLcurveY());
         Info("ScanLcurve","logtau=%lf X=%lf Y=%lf",
              logTau,GetLcurveX(),GetLcurveY());
      }
      if((*curve.begin()).second.first<x0) {
         // if the point at tau==0 seems numerically unstable,
         // try to find the minimum chi**2 as start value
         //
         // "unstable" means that there is a finite tau where the
         // unfolding chi**2 is smaller than for the case of no
         // regularisation. Ideally this should never happen
         do {
            x0=GetLcurveX();
            Double_t logTau=(*curve.begin()).first-0.5;
            DoUnfold(TMath::Power(10.,logTau));
            if((!TMath::Finite(GetLcurveX())) ||(!TMath::Finite(GetLcurveY()))) {
               Fatal("ScanLcurve","problem (missing regularisation?) X=%f Y=%f",
                     GetLcurveX(),GetLcurveY());
            }
            curve[logTau]=std::make_pair(GetLcurveX(),GetLcurveY());
            Info("ScanLcurve","logtau=%lf X=%lf Y=%lf",
                 logTau,GetLcurveX(),GetLcurveY());
         }
         while(((int)curve.size()<(nPoint-1)/2)&&
               ((*curve.begin()).second.first<x0));
      } else {
         // minimum tau is chosen such that is less than
         // 1% different from the case of no regularusation
         // log10(1.01) = 0.00432

         // here, more than one point are inserted if necessary
         while(((int)curve.size()<nPoint-1)&&
               (((*curve.begin()).second.first-x0>0.00432)||
                ((*curve.begin()).second.second-y0>0.00432)||
                (curve.size()<2))) {
                  Double_t logTau=(*curve.begin()).first-0.5;
                  DoUnfold(TMath::Power(10.,logTau));
                  if((!TMath::Finite(GetLcurveX())) ||(!TMath::Finite(GetLcurveY()))) {
                     Fatal("ScanLcurve","problem (missing regularisation?) X=%f Y=%f",
                           GetLcurveX(),GetLcurveY());
                  }
                  curve[logTau]=std::make_pair(GetLcurveX(),GetLcurveY());
                  Info("ScanLcurve","logtau=%lf X=%lf Y=%lf",
                       logTau,GetLcurveX(),GetLcurveY());
               }
      }
   } else {
      Double_t logTauMin=TMath::Log10(tauMin);
      Double_t logTauMax=TMath::Log10(tauMax);
      if(nPoint>1) {
         // insert maximum tau
         DoUnfold(TMath::Power(10.,logTauMax));
         if((!TMath::Finite(GetLcurveX())) ||(!TMath::Finite(GetLcurveY()))) {
            Fatal("ScanLcurve","problem (missing regularisation?) X=%f Y=%f",
                  GetLcurveX(),GetLcurveY());
         }
         Info("ScanLcurve","logtau=%lf X=%lf Y=%lf",
              logTauMax,GetLcurveX(),GetLcurveY());
         curve[logTauMax]=std::make_pair(GetLcurveX(),GetLcurveY());
      }
      // insert minimum tau
      DoUnfold(TMath::Power(10.,logTauMin));
      if((!TMath::Finite(GetLcurveX())) ||(!TMath::Finite(GetLcurveY()))) {
         Fatal("ScanLcurve","problem (missing regularisation?) X=%f Y=%f",
               GetLcurveX(),GetLcurveY());
      }
      Info("ScanLcurve","logtau=%lf X=%lf Y=%lf",
           logTauMin,GetLcurveX(),GetLcurveY());
      curve[logTauMin]=std::make_pair(GetLcurveX(),GetLcurveY());
   }


   //==========================================================
   //    (1b) insert additional points, until nPoint-1 values
   //          have been calculated

   while(int(curve.size())<nPoint-1) {
      // insert additional points, such that the sizes of the delta(XY) vectors
      // are getting smaller and smaller
      XYtau_t::const_iterator i0,i1;
      i0=curve.begin();
      i1=i0;
      Double_t logTau=(*i0).first;
      Double_t distMax=0.0;
      for(i1++;i1!=curve.end();i1++) {
         const std::pair<Double_t,Double_t> &xy0=(*i0).second;
         const std::pair<Double_t,Double_t> &xy1=(*i1).second;
         Double_t dx=xy1.first-xy0.first;
         Double_t dy=xy1.second-xy0.second;
         Double_t d=TMath::Sqrt(dx*dx+dy*dy);
         if(d>=distMax) {
            distMax=d;
            logTau=0.5*((*i0).first+(*i1).first);
         }
         i0=i1;
      }
      DoUnfold(TMath::Power(10.,logTau));
      if((!TMath::Finite(GetLcurveX())) ||(!TMath::Finite(GetLcurveY()))) {
         Fatal("ScanLcurve","problem (missing regularisation?) X=%f Y=%f",
               GetLcurveX(),GetLcurveY());
      }
      Info("ScanLcurve","logtau=%lf X=%lf Y=%lf",logTau,GetLcurveX(),GetLcurveY());
      curve[logTau]=std::make_pair(GetLcurveX(),GetLcurveY());
   }

   //==========================================================
   //  (2) determine the best choice of tau
   //      do the unfolding for this point
   //      and store the result in
   //        curve
   XYtau_t::const_iterator i0,i1;
   i0=curve.begin();
   i1=i0;
   i1++;
   Double_t logTauFin=(*i0).first;
   if( ((int)curve.size())<nPoint) {
      // set up splines and determine (x,y) curvature in each point
      Double_t *cTi=new Double_t[curve.size()-1];
      Double_t *cCi=new Double_t[curve.size()-1];
      Int_t n=0;
      {
         Double_t *lXi=new Double_t[curve.size()];
         Double_t *lYi=new Double_t[curve.size()];
         Double_t *lTi=new Double_t[curve.size()];
         for( XYtau_t::const_iterator i=curve.begin();i!=curve.end();i++) {
            lXi[n]=(*i).second.first;
            lYi[n]=(*i).second.second;
            lTi[n]=(*i).first;
            n++;
         }
         TSpline3 *splineX=new TSpline3("x vs tau",lTi,lXi,n);
         TSpline3 *splineY=new TSpline3("y vs tau",lTi,lYi,n);
         // calculate (x,y) curvature for all points
         // the curvature is stored in the array cCi[] as a function of cTi[]
         for(Int_t i=0;i<n-1;i++) {
            Double_t ltau,xy,bi,ci,di;
            splineX->GetCoeff(i,ltau,xy,bi,ci,di);
            Double_t tauBar=0.5*(lTi[i]+lTi[i+1]);
            Double_t dTau=0.5*(lTi[i+1]-lTi[i]);
            Double_t dx1=bi+dTau*(2.*ci+3.*di*dTau);
            Double_t dx2=2.*ci+6.*di*dTau;
            splineY->GetCoeff(i,ltau,xy,bi,ci,di);
            Double_t dy1=bi+dTau*(2.*ci+3.*di*dTau);
            Double_t dy2=2.*ci+6.*di*dTau;
            cTi[i]=tauBar;
            cCi[i]=(dy2*dx1-dy1*dx2)/TMath::Power(dx1*dx1+dy1*dy1,1.5);
         }
         delete splineX;
         delete splineY;
         delete[] lXi;
         delete[] lYi;
         delete[] lTi;
      }
      // create curvature Spline
      TSpline3 *splineC=new TSpline3("L curve curvature",cTi,cCi,n-1);
      // find the maximum of the curvature
      // if the parameter iskip is non-zero, then iskip points are
      // ignored when looking for the largest curvature
      // (there are problems with the curvature determined from the first
      //  few points of splineX,splineY in the algorithm above)
      Int_t iskip=0;
      if(n>4) iskip=1;
      if(n>7) iskip=2;
      Double_t cCmax=cCi[iskip];
      Double_t cTmax=cTi[iskip];
      for(Int_t i=iskip;i<n-2-iskip;i++) {
         // find maximum on this spline section
         // check boundary conditions for x[i+1]
         Double_t xMax=cTi[i+1];
         Double_t yMax=cCi[i+1];
         if(cCi[i]>yMax) {
            yMax=cCi[i];
            xMax=cTi[i];
         }
         // find maximum for x[i]<x<x[i+1]
         // get spline coefficiencts and solve equation
         //   derivative(x)==0
         Double_t x,y,b,c,d;
         splineC->GetCoeff(i,x,y,b,c,d);
         // coefficiencts of quadratic equation
         Double_t m_p_half=-c/(3.*d);
         Double_t q=b/(3.*d);
         Double_t discr=m_p_half*m_p_half-q;
         if(discr>=0.0) {
            // solution found
            discr=TMath::Sqrt(discr);
            Double_t xx;
            if(m_p_half>0.0) {
               xx = m_p_half + discr;
            } else {
               xx = m_p_half - discr;
            }
            Double_t dx=cTi[i+1]-x;
            // check first solution
            if((xx>0.0)&&(xx<dx)) {
               y=splineC->Eval(x+xx);
               if(y>yMax) {
                  yMax=y;
                  xMax=x+xx;
               }
            }
            // second solution
            if(xx !=0.0) {
               xx= q/xx;
            } else {
               xx=0.0;
            }
            // check second solution
            if((xx>0.0)&&(xx<dx)) {
               y=splineC->Eval(x+xx);
               if(y>yMax) {
                  yMax=y;
                  xMax=x+xx;
               }
            }
         }
         // check whether this local minimum is a global minimum
         if(yMax>cCmax) {
            cCmax=yMax;
            cTmax=xMax;
         }
      }
#ifdef DEBUG_LCURVE
      {
         TCanvas lcc;
         lcc.Divide(1,1);
         lcc.cd(1);
         splineC->Draw();
         lcc.SaveAs("splinec.ps");
      }
#endif
      delete splineC;
      delete[] cTi;
      delete[] cCi;
      logTauFin=cTmax;
      DoUnfold(TMath::Power(10.,logTauFin));
      if((!TMath::Finite(GetLcurveX())) ||(!TMath::Finite(GetLcurveY()))) {
         Fatal("ScanLcurve","problem (missing regularisation?) X=%f Y=%f",
               GetLcurveX(),GetLcurveY());
      }
      Info("ScanLcurve","Result logtau=%lf X=%lf Y=%lf",
           logTauFin,GetLcurveX(),GetLcurveY());
      curve[logTauFin]=std::make_pair(GetLcurveX(),GetLcurveY());
   }


   //==========================================================
   //  (3) return the result in
   //       lCurve logTauX logTauY

   Int_t bestChoice=-1;
   if(curve.size()>0) {
      Double_t *x=new Double_t[curve.size()];
      Double_t *y=new Double_t[curve.size()];
      Double_t *logT=new Double_t[curve.size()];
      int n=0;
      for( XYtau_t::const_iterator i=curve.begin();i!=curve.end();i++) {
         if(logTauFin==(*i).first) {
            bestChoice=n;
         }
         x[n]=(*i).second.first;
         y[n]=(*i).second.second;
         logT[n]=(*i).first;
         n++;
      }
      if(lCurve) {
         (*lCurve)=new TGraph(n,x,y);
         (*lCurve)->SetTitle("L curve");
      }
      if(logTauX) (*logTauX)=new TSpline3("log(chi**2)%log(tau)",logT,x,n);
      if(logTauY) (*logTauY)=new TSpline3("log(reg.cond)%log(tau)",logT,y,n);
      delete[] x;
      delete[] y;
      delete[] logT;
   }

   return bestChoice;
}

void TUnfold::GetNormalisationVector(TH1 *out,const Int_t *binMap) const
{
   // get vector of normalisation factors
   //   out: output histogram
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...

   ClearHistogram(out);
   for (Int_t i = 0; i < GetNx(); i++) {
      int dest=binMap ? binMap[fXToHist[i]] : fXToHist[i];
      if(dest>=0) {
         out->SetBinContent(dest, fSumOverY[i] + out->GetBinContent(dest));
      }
   }
}

void TUnfold::GetBias(TH1 *out,const Int_t *binMap) const
{
   // get bias distribution, possibly with bin remapping
   //   out: output histogram
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...

   ClearHistogram(out);
   for (Int_t i = 0; i < GetNx(); i++) {
      int dest=binMap ? binMap[fXToHist[i]] : fXToHist[i];
      if(dest>=0) {
         out->SetBinContent(dest, fBiasScale*(*fX0) (i, 0) +
                            out->GetBinContent(dest));
      }
   }
}

void TUnfold::GetFoldedOutput(TH1 *out,const Int_t *binMap) const
{
   // get unfolding result, folded back trough the matrix
   //   out: output histogram
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...

   ClearHistogram(out);

   TMatrixDSparse *AVxx=MultiplyMSparseMSparse(fA,fVxx);

   const Int_t *rows_A=fA->GetRowIndexArray();
   const Int_t *cols_A=fA->GetColIndexArray();
   const Double_t *data_A=fA->GetMatrixArray();
   const Int_t *rows_AVxx=AVxx->GetRowIndexArray();
   const Int_t *cols_AVxx=AVxx->GetColIndexArray();
   const Double_t *data_AVxx=AVxx->GetMatrixArray();

   for (Int_t i = 0; i < GetNy(); i++) {
      Int_t destI = binMap ? binMap[i+1] : i+1;
      if(destI<0) continue;

      out->SetBinContent(destI, (*fAx) (i, 0)+ out->GetBinContent(destI));
      Double_t e2=0.0;
      Int_t index_a=rows_A[i];
      Int_t index_av=rows_AVxx[i];
      while((index_a<rows_A[i+1])&&(index_av<rows_AVxx[i])) {
         Int_t j_a=cols_A[index_a];
         Int_t j_av=cols_AVxx[index_av];
         if(j_a<j_av) {
            index_a++;
         } else if(j_a>j_av) {
            index_av++;
         } else {
            e2 += data_AVxx[index_av] * data_A[index_a];
            index_a++;
            index_av++;
         }
      }
      out->SetBinError(destI,TMath::Sqrt(e2));
   }
   DeleteMatrix(&AVxx);
}

void TUnfold::GetProbabilityMatrix(TH2 *A,EHistMap histmap) const
{
   // retreive matrix of probabilities
   //    histmap: on which axis to arrange the input/output vector
   //    A: histogram to store the probability matrix
   const Int_t *rows_A=fA->GetRowIndexArray();
   const Int_t *cols_A=fA->GetColIndexArray();
   const Double_t *data_A=fA->GetMatrixArray();
   for (Int_t iy = 0; iy <fA->GetNrows(); iy++) {
      for(Int_t indexA=rows_A[iy];indexA<rows_A[iy+1];indexA++) {
         Int_t ix = cols_A[indexA];
         Int_t ih=fXToHist[ix];
         if (histmap == kHistMapOutputHoriz) {
            A->SetBinContent(ih, iy,data_A[indexA]);
         } else {
            A->SetBinContent(iy, ih,data_A[indexA]);
         }
      }
   }
}

void TUnfold::GetInput(TH1 *out,const Int_t *binMap) const
{
   // retreive input distribution
   //   out: output histogram
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...

   ClearHistogram(out);

   const Int_t *rows_Vyy=fVyy->GetRowIndexArray();
   const Int_t *cols_Vyy=fVyy->GetColIndexArray();
   const Double_t *data_Vyy=fVyy->GetMatrixArray();

   for (Int_t i = 0; i < GetNy(); i++) {
      Int_t destI=binMap ? binMap[i] : i;
      if(destI<0) continue;

      out->SetBinContent(destI, (*fY) (i, 0)+out->GetBinContent(destI));

      Double_t e=0.0;
      for(int index=rows_Vyy[i];index<rows_Vyy[i+1];index++) {
         if(cols_Vyy[index]==i) {
            e=TMath::Sqrt(data_Vyy[index]);
         }
      }
      out->SetBinError(destI, e);
   }
}

void TUnfold::GetInputInverseEmatrix(TH2 *out)
{
   // calculate the inverse of the contribution to the error matrix
   // corresponding to the input data
   if(!fVyyInv) {
      Int_t rank=0;
      fVyyInv=InvertMSparseSymmPos(fVyy,&rank);
      // and count number of degrees of freedom
      fNdf = rank-GetNpar();

      if(rank<GetNy()-fIgnoredBins) {
         Warning("GetInputInverseEmatrix","input covariance matrix has rank %d expect %d",
                 rank,GetNy());
      }
      if(fNdf<0) {
         Error("GetInputInverseEmatrix","number of parameters %d > %d (rank of input covariance). Problem can not be solved",GetNpar(),rank);
      } else if(fNdf==0) {
         Warning("GetInputInverseEmatrix","number of parameters %d = input rank %d. Problem is ill posed",GetNpar(),rank);
      }
   }
   if(out) {
      // return matrix as histogram
      const Int_t *rows_Vyy=fVyy->GetRowIndexArray();
      const Int_t *cols_Vyy=fVyy->GetColIndexArray();
      const Double_t *data_Vyy=fVyy->GetMatrixArray();

      for(int i=0;i<=out->GetNbinsX()+1;i++) {
         for(int j=0;j<=out->GetNbinsY()+1;j++) {
            out->SetBinContent(i,j,0.);
         }
      }

      for (Int_t i = 0; i < fVyy->GetNrows(); i++) {
         for(int index=rows_Vyy[i];index<rows_Vyy[i+1];index++) {
            Int_t j=cols_Vyy[index];
            out->SetBinContent(i+1,j+1,data_Vyy[index]);
         }
      }
   }
}

void TUnfold::GetLsquared(TH2 *out) const
{
   // retreive matrix of regularisation conditions squared
   //   out: prebooked matrix

   TMatrixDSparse *lSquared=MultiplyMSparseTranspMSparse(fL,fL);
   // loop over sparse matrix
   const Int_t *rows=lSquared->GetRowIndexArray();
   const Int_t *cols=lSquared->GetColIndexArray();
   const Double_t *data=lSquared->GetMatrixArray();
   for (Int_t i = 0; i < GetNx(); i++) {
      for (Int_t cindex = rows[i]; cindex < rows[i+1]; cindex++) {
         Int_t j=cols[cindex];
         out->SetBinContent(fXToHist[i], fXToHist[j],data[cindex]);
      }
   }
   DeleteMatrix(&lSquared);
}

void TUnfold::GetL(TH2 *out) const
{
   // retreive matrix of regularisation conditions
   //   out: prebooked matrix

   // loop over sparse matrix
   const Int_t *rows=fL->GetRowIndexArray();
   const Int_t *cols=fL->GetColIndexArray();
   const Double_t *data=fL->GetMatrixArray();
   for (Int_t row = 0; row < GetNr(); row++) {
      for (Int_t cindex = rows[row]; cindex < rows[row+1]; cindex++) {
         Int_t col=cols[cindex];
         Int_t indexH=fXToHist[col];
         out->SetBinContent(indexH,row+1,data[cindex]);
      }
   }
}

void TUnfold::SetConstraint(EConstraint constraint)
{
   // set type of constraint for the next unfolding
   if(fConstraint !=constraint) ClearResults();
   fConstraint=constraint;
   Info("SetConstraint","fConstraint=%d",fConstraint);
}

Double_t TUnfold::GetTau(void) const
{
   // return regularisation parameter
   return TMath::Sqrt(fTauSquared);
}

Double_t TUnfold::GetChi2L(void) const
{
   // return chi**2 contribution from regularisation conditions
   return fLXsquared*fTauSquared;
}

Int_t TUnfold::GetNpar(void) const
{
   // return number of parameters
   return GetNx();
}

Double_t TUnfold::GetLcurveX(void) const
{
   // return value on x axis of L curve
   return TMath::Log10(fChi2A);
}

Double_t TUnfold::GetLcurveY(void) const
{
   // return value on y axis of L curve
   return TMath::Log10(fLXsquared);
}

void TUnfold::GetOutput(TH1 *output,const Int_t *binMap) const
{
   // get output distribution, cumulated over several bins
   //   output: output histogram
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...

   ClearHistogram(output);
   /* Int_t nbin=output->GetNbinsX();
    Double_t *c=new Double_t[nbin+2];
    Double_t *e2=new Double_t[nbin+2];
    for(Int_t i=0;i<nbin+2;i++) {
    c[i]=0.0;
    e2[i]=0.0;
    } */

   std::map<Int_t,Double_t> e2;

   const Int_t *rows_Vxx=fVxx->GetRowIndexArray();
   const Int_t *cols_Vxx=fVxx->GetColIndexArray();
   const Double_t *data_Vxx=fVxx->GetMatrixArray();

   Int_t binMapSize = fHistToX.GetSize();
   for(Int_t i=0;i<binMapSize;i++) {
      Int_t destBinI=binMap ? binMap[i] : i; // histogram bin
      Int_t srcBinI=fHistToX[i]; // matrix row index
      if((destBinI>=0)&&(srcBinI>=0)) {
         output->SetBinContent
         (destBinI, (*fX)(srcBinI,0)+ output->GetBinContent(destBinI));
         // here we loop over the columns of the error matrix
         //   j: counts histogram bins
         //   index: counts sparse matrix index
         // the algorithm makes use of the fact that fHistToX is ordered
         Int_t j=0; // histogram bin
         Int_t index_vxx=rows_Vxx[srcBinI];
         //Double_t e2=TMath::Power(output->GetBinError(destBinI),2.);
         while((j<binMapSize)&&(index_vxx<rows_Vxx[srcBinI+1])) {
            Int_t destBinJ=binMap ? binMap[j] : j; // histogram bin
            if(destBinI!=destBinJ) {
               // only diagonal elements are calculated
               j++;
            } else {
               Int_t srcBinJ=fHistToX[j]; // matrix column index
               if(srcBinJ<0) {
                  // bin was not unfolded, check next bin
                  j++;
               } else {
                  if(cols_Vxx[index_vxx]<srcBinJ) {
                     // index is too small
                     index_vxx++;
                  } else if(cols_Vxx[index_vxx]>srcBinJ) {
                     // index is too large, skip bin
                     j++;
                  } else {
                     // add this bin
                     e2[destBinI] += data_Vxx[index_vxx];
                     j++;
                     index_vxx++;
                  }
               }
            }
         }
         //output->SetBinError(destBinI,TMath::Sqrt(e2));
      }
   }
   for(std::map<Int_t,Double_t>::const_iterator i=e2.begin();
       i!=e2.end();i++) {
      //cout<<(*i).first<<" "<<(*i).second<<"\n";
      output->SetBinError((*i).first,TMath::Sqrt((*i).second));
   }
}

void TUnfold::ErrorMatrixToHist(TH2 *ematrix,const TMatrixDSparse *emat,
                                const Int_t *binMap,Bool_t doClear) const
{
   // get an error matrix, cumulated over several bins
   //   ematrix: output error matrix histogram
   //   emat: error matrix
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...
   Int_t nbin=ematrix->GetNbinsX();
   if(doClear) {
      for(Int_t i=0;i<nbin+2;i++) {
         for(Int_t j=0;j<nbin+2;j++) {
            ematrix->SetBinContent(i,j,0.0);
            ematrix->SetBinError(i,j,0.0);
         }
      }
   }

   if(emat) {
      const Int_t *rows_emat=emat->GetRowIndexArray();
      const Int_t *cols_emat=emat->GetColIndexArray();
      const Double_t *data_emat=emat->GetMatrixArray();

      Int_t binMapSize = fHistToX.GetSize();
      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)) {
            // here we loop over the columns of the source matrix
            //   j: counts histogram bins
            //   index: counts sparse matrix index
            // the algorithm makes use of the fact that fHistToX is ordered
            Int_t j=0;
            Int_t index_vxx=rows_emat[srcBinI];
            while((j<binMapSize)&&(index_vxx<rows_emat[srcBinI+1])) {
               Int_t destBinJ=binMap ? binMap[j] : j;
               Int_t srcBinJ=fHistToX[j];
               if((destBinJ<0)||(destBinJ>=nbin+2)||(srcBinJ<0)) {
                  // check next bin
                  j++;
               } else {
                  if(cols_emat[index_vxx]<srcBinJ) {
                     // index is too small
                     index_vxx++;
                  } else if(cols_emat[index_vxx]>srcBinJ) {
                     // index is too large, skip bin
                     j++;
                  } else {
                     // add this bin
                     Double_t e2= ematrix->GetBinContent(destBinI,destBinJ)
                     + data_emat[index_vxx];
                     ematrix->SetBinContent(destBinI,destBinJ,e2);
                     j++;
                     index_vxx++;
                  }
               }
            }
         }
      }
   }
}

void TUnfold::GetEmatrix(TH2 *ematrix,const Int_t *binMap) const
{
   // get output error matrix, cumulated over several bins
   //   ematrix: output error matrix histogram
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...
   ErrorMatrixToHist(ematrix,fVxx,binMap,kTRUE);
}

void TUnfold::GetRhoIJ(TH2 *rhoij,const Int_t *binMap) const
{
   // get correlation coefficient matrix, cumulated over several bins
   //   rhoij:  correlation coefficient matrix histogram
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...
   GetEmatrix(rhoij,binMap);
   Int_t nbin=rhoij->GetNbinsX();
   Double_t *e=new Double_t[nbin+2];
   for(Int_t i=0;i<nbin+2;i++) {
      e[i]=TMath::Sqrt(rhoij->GetBinContent(i,i));
   }
   for(Int_t i=0;i<nbin+2;i++) {
      for(Int_t j=0;j<nbin+2;j++) {
         if((e[i]>0.0)&&(e[j]>0.0)) {
            rhoij->SetBinContent(i,j,rhoij->GetBinContent(i,j)/e[i]/e[j]);
         } else {
            rhoij->SetBinContent(i,j,0.0);
         }
      }
   }
   delete[] e;
}

Double_t TUnfold::GetRhoI(TH1 *rhoi,const Int_t *binMap,TH2 *invEmat) const
{
   // get global correlation coefficients with arbitrary min map
   //   rhoi: global correlation histogram
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...
   // return value: maximum global correlation

   ClearHistogram(rhoi,-1.);

   if(binMap) {
      // if there is a bin map, the matrix needs to be inverted
      // otherwise, use the existing inverse, such that
      // no matrix inversion is needed
      return GetRhoIFromMatrix(rhoi,fVxx,binMap,invEmat);
   } else {
      Double_t rhoMax=0.0;

      const Int_t *rows_Vxx=fVxx->GetRowIndexArray();
      const Int_t *cols_Vxx=fVxx->GetColIndexArray();
      const Double_t *data_Vxx=fVxx->GetMatrixArray();

      const Int_t *rows_VxxInv=fVxxInv->GetRowIndexArray();
      const Int_t *cols_VxxInv=fVxxInv->GetColIndexArray();
      const Double_t *data_VxxInv=fVxxInv->GetMatrixArray();

      for(Int_t i=0;i<GetNx();i++) {
         Int_t destI=fXToHist[i];
         Double_t e_ii=0.0,einv_ii=0.0;
         for(int index_vxx=rows_Vxx[i];index_vxx<rows_Vxx[i+1];index_vxx++) {
            if(cols_Vxx[index_vxx]==i) {
               e_ii=data_Vxx[index_vxx];
               break;
            }
         }
         for(int index_vxxinv=rows_VxxInv[i];index_vxxinv<rows_VxxInv[i+1];
             index_vxxinv++) {
            if(cols_VxxInv[index_vxxinv]==i) {
               einv_ii=data_VxxInv[index_vxxinv];
               break;
            }
         }
         Double_t rho=1.0;
         if((einv_ii>0.0)&&(e_ii>0.0)) rho=1.-1./(einv_ii*e_ii);
         if(rho>=0.0) rho=TMath::Sqrt(rho);
         else rho=-TMath::Sqrt(-rho);
         if(rho>rhoMax) {
            rhoMax = rho;
         }
         rhoi->SetBinContent(destI,rho);
      }
      return rhoMax;
   }
}

Double_t TUnfold::GetRhoIFromMatrix(TH1 *rhoi,const TMatrixDSparse *eOrig,
                                    const Int_t *binMap,TH2 *invEmat) const
{
   // get global correlation coefficients with arbitrary min map
   //   rhoi: global correlation histogram
   //   emat: error matrix
   //   binMap: for each bin of the original output distribution
   //           specify the destination bin. A value of -1 means that the bin
   //           is discarded. 0 means underflow bin, 1 first bin, ...
   //        binMap[0] : destination of underflow bin
   //        binMap[1] : destination of first bin
   //          ...
   // return value: maximum global correlation

   Double_t rhoMax=0.;
   // original number of bins:
   //    fHistToX.GetSize()
   // loop over binMap and find number of used bins

   Int_t binMapSize = fHistToX.GetSize();

   // histToLocalBin[iBin] points to a local index
   //    only bins iBin of the histogram rhoi whih are referenced
   //    in the bin map have a local index
   std::map<int,int> histToLocalBin;
   Int_t nBin=0;
   for(Int_t i=0;i<binMapSize;i++) {
      Int_t mapped_i=binMap ? binMap[i] : i;
      if(mapped_i>=0) {
         if(histToLocalBin.find(mapped_i)==histToLocalBin.end()) {
            histToLocalBin[mapped_i]=nBin;
            nBin++;
         }
      }
   }
   // number of local indices: nBin
   if(nBin>0) {
      // construct inverse mapping function
      //    local index -> histogram bin
      Int_t *localBinToHist=new Int_t[nBin];
      for(std::map<int,int>::const_iterator i=histToLocalBin.begin();
          i!=histToLocalBin.end();i++) {
         localBinToHist[(*i).second]=(*i).first;
      }

      const Int_t *rows_eOrig=eOrig->GetRowIndexArray();
      const Int_t *cols_eOrig=eOrig->GetColIndexArray();
      const Double_t *data_eOrig=eOrig->GetMatrixArray();

      // remap error matrix
      //   matrix row  i  -> origI  (fXToHist[i])
      //   origI  -> destI  (binMap)
      //   destI -> ematBinI  (histToLocalBin)
      TMatrixD eRemap(nBin,nBin);
      // i:  row of the matrix eOrig
      for(Int_t i=0;i<GetNx();i++) {
         // origI: pointer in output histogram with all bins
         Int_t origI=fXToHist[i];
         // destI: pointer in the histogram rhoi
         Int_t destI=binMap ? binMap[origI] : origI;
         if(destI<0) continue;
         Int_t ematBinI=histToLocalBin[destI];
         for(int index_eOrig=rows_eOrig[i];index_eOrig<rows_eOrig[i+1];
             index_eOrig++) {
            // j: column of the matrix fVxx
            Int_t j=cols_eOrig[index_eOrig];
            // origJ: pointer in output histogram with all bins
            Int_t origJ=fXToHist[j];
            // destJ: pointer in the histogram rhoi
            Int_t destJ=binMap ? binMap[origJ] : origJ;
            if(destJ<0) continue;
            Int_t ematBinJ=histToLocalBin[destJ];
            eRemap(ematBinI,ematBinJ) += data_eOrig[index_eOrig];
         }
      }
      // invert remapped error matrix
      TMatrixDSparse eSparse(eRemap);
      Int_t rank=0;
      TMatrixDSparse *einvSparse=InvertMSparseSymmPos(&eSparse,&rank);
      if(rank!=einvSparse->GetNrows()) {
         Warning("GetRhoIFormMatrix","Covariance matrix has rank %d expect %d",
                 rank,einvSparse->GetNrows());
      }
      // fill to histogram
      const Int_t *rows_eInv=einvSparse->GetRowIndexArray();
      const Int_t *cols_eInv=einvSparse->GetColIndexArray();
      const Double_t *data_eInv=einvSparse->GetMatrixArray();

      for(Int_t i=0;i<einvSparse->GetNrows();i++) {
         Double_t e_ii=eRemap(i,i);
         Double_t einv_ii=0.0;
         for(Int_t index_einv=rows_eInv[i];index_einv<rows_eInv[i+1];
             index_einv++) {
            Int_t j=cols_eInv[index_einv];
            if(j==i) {
               einv_ii=data_eInv[index_einv];
            }
            if(invEmat) {
               invEmat->SetBinContent(localBinToHist[i],localBinToHist[j],
                                      data_eInv[index_einv]);
            }
         }
         Double_t rho=1.0;
         if((einv_ii>0.0)&&(e_ii>0.0)) rho=1.-1./(einv_ii*e_ii);
         if(rho>=0.0) rho=TMath::Sqrt(rho);
         else rho=-TMath::Sqrt(-rho);
         if(rho>rhoMax) {
            rhoMax = rho;
         }
         //std::cout<<i<<" "<<localBinToHist[i]<<" "<<rho<<"\n";
         rhoi->SetBinContent(localBinToHist[i],rho);
      }

      DeleteMatrix(&einvSparse);
      delete [] localBinToHist;
   }
   return rhoMax;
}

void TUnfold::ClearHistogram(TH1 *h,Double_t x) const
{
   // clear histogram contents and error
   Int_t nxyz[3];
   nxyz[0]=h->GetNbinsX()+1;
   nxyz[1]=h->GetNbinsY()+1;
   nxyz[2]=h->GetNbinsZ()+1;
   for(int i=h->GetDimension();i<3;i++) nxyz[i]=0;
   Int_t ixyz[3];
   for(int i=0;i<3;i++) ixyz[i]=0;
   while((ixyz[0]<=nxyz[0])&&
         (ixyz[1]<=nxyz[1])&&
         (ixyz[2]<=nxyz[2])){
      Int_t ibin=h->GetBin(ixyz[0],ixyz[1],ixyz[2]);
      h->SetBinContent(ibin,x);
      h->SetBinError(ibin,0.0);
      for(Int_t i=0;i<3;i++) {
         ixyz[i] += 1;
         if(ixyz[i]<=nxyz[i]) break;
         if(i<2) ixyz[i]=0;
      }
   }
}

void TUnfold::SetEpsMatrix(Double_t eps) {
   // set accuracy for matrix inversion
   if((eps>0.0)&&(eps<1.0)) fEpsMatrix=eps;
}
 TUnfold.cxx:1
 TUnfold.cxx:2
 TUnfold.cxx:3
 TUnfold.cxx:4
 TUnfold.cxx:5
 TUnfold.cxx:6
 TUnfold.cxx:7
 TUnfold.cxx:8
 TUnfold.cxx:9
 TUnfold.cxx:10
 TUnfold.cxx:11
 TUnfold.cxx:12
 TUnfold.cxx:13
 TUnfold.cxx:14
 TUnfold.cxx:15
 TUnfold.cxx:16
 TUnfold.cxx:17
 TUnfold.cxx:18
 TUnfold.cxx:19
 TUnfold.cxx:20
 TUnfold.cxx:21
 TUnfold.cxx:22
 TUnfold.cxx:23
 TUnfold.cxx:24
 TUnfold.cxx:25
 TUnfold.cxx:26
 TUnfold.cxx:27
 TUnfold.cxx:28
 TUnfold.cxx:29
 TUnfold.cxx:30
 TUnfold.cxx:31
 TUnfold.cxx:32
 TUnfold.cxx:33
 TUnfold.cxx:34
 TUnfold.cxx:35
 TUnfold.cxx:36
 TUnfold.cxx:37
 TUnfold.cxx:38
 TUnfold.cxx:39
 TUnfold.cxx:40
 TUnfold.cxx:41
 TUnfold.cxx:42
 TUnfold.cxx:43
 TUnfold.cxx:44
 TUnfold.cxx:45
 TUnfold.cxx:46
 TUnfold.cxx:47
 TUnfold.cxx:48
 TUnfold.cxx:49
 TUnfold.cxx:50
 TUnfold.cxx:51
 TUnfold.cxx:52
 TUnfold.cxx:53
 TUnfold.cxx:54
 TUnfold.cxx:55
 TUnfold.cxx:56
 TUnfold.cxx:57
 TUnfold.cxx:58
 TUnfold.cxx:59
 TUnfold.cxx:60
 TUnfold.cxx:61
 TUnfold.cxx:62
 TUnfold.cxx:63
 TUnfold.cxx:64
 TUnfold.cxx:65
 TUnfold.cxx:66
 TUnfold.cxx:67
 TUnfold.cxx:68
 TUnfold.cxx:69
 TUnfold.cxx:70
 TUnfold.cxx:71
 TUnfold.cxx:72
 TUnfold.cxx:73
 TUnfold.cxx:74
 TUnfold.cxx:75
 TUnfold.cxx:76
 TUnfold.cxx:77
 TUnfold.cxx:78
 TUnfold.cxx:79
 TUnfold.cxx:80
 TUnfold.cxx:81
 TUnfold.cxx:82
 TUnfold.cxx:83
 TUnfold.cxx:84
 TUnfold.cxx:85
 TUnfold.cxx:86
 TUnfold.cxx:87
 TUnfold.cxx:88
 TUnfold.cxx:89
 TUnfold.cxx:90
 TUnfold.cxx:91
 TUnfold.cxx:92
 TUnfold.cxx:93
 TUnfold.cxx:94
 TUnfold.cxx:95
 TUnfold.cxx:96
 TUnfold.cxx:97
 TUnfold.cxx:98
 TUnfold.cxx:99
 TUnfold.cxx:100
 TUnfold.cxx:101
 TUnfold.cxx:102
 TUnfold.cxx:103
 TUnfold.cxx:104
 TUnfold.cxx:105
 TUnfold.cxx:106
 TUnfold.cxx:107
 TUnfold.cxx:108
 TUnfold.cxx:109
 TUnfold.cxx:110
 TUnfold.cxx:111
 TUnfold.cxx:112
 TUnfold.cxx:113
 TUnfold.cxx:114
 TUnfold.cxx:115
 TUnfold.cxx:116
 TUnfold.cxx:117
 TUnfold.cxx:118
 TUnfold.cxx:119
 TUnfold.cxx:120
 TUnfold.cxx:121
 TUnfold.cxx:122
 TUnfold.cxx:123
 TUnfold.cxx:124
 TUnfold.cxx:125
 TUnfold.cxx:126
 TUnfold.cxx:127
 TUnfold.cxx:128
 TUnfold.cxx:129
 TUnfold.cxx:130
 TUnfold.cxx:131
 TUnfold.cxx:132
 TUnfold.cxx:133
 TUnfold.cxx:134
 TUnfold.cxx:135
 TUnfold.cxx:136
 TUnfold.cxx:137
 TUnfold.cxx:138
 TUnfold.cxx:139
 TUnfold.cxx:140
 TUnfold.cxx:141
 TUnfold.cxx:142
 TUnfold.cxx:143
 TUnfold.cxx:144
 TUnfold.cxx:145
 TUnfold.cxx:146
 TUnfold.cxx:147
 TUnfold.cxx:148
 TUnfold.cxx:149
 TUnfold.cxx:150
 TUnfold.cxx:151
 TUnfold.cxx:152
 TUnfold.cxx:153
 TUnfold.cxx:154
 TUnfold.cxx:155
 TUnfold.cxx:156
 TUnfold.cxx:157
 TUnfold.cxx:158
 TUnfold.cxx:159
 TUnfold.cxx:160
 TUnfold.cxx:161
 TUnfold.cxx:162
 TUnfold.cxx:163
 TUnfold.cxx:164
 TUnfold.cxx:165
 TUnfold.cxx:166
 TUnfold.cxx:167
 TUnfold.cxx:168
 TUnfold.cxx:169
 TUnfold.cxx:170
 TUnfold.cxx:171
 TUnfold.cxx:172
 TUnfold.cxx:173
 TUnfold.cxx:174
 TUnfold.cxx:175
 TUnfold.cxx:176
 TUnfold.cxx:177
 TUnfold.cxx:178
 TUnfold.cxx:179
 TUnfold.cxx:180
 TUnfold.cxx:181
 TUnfold.cxx:182
 TUnfold.cxx:183
 TUnfold.cxx:184
 TUnfold.cxx:185
 TUnfold.cxx:186
 TUnfold.cxx:187
 TUnfold.cxx:188
 TUnfold.cxx:189
 TUnfold.cxx:190
 TUnfold.cxx:191
 TUnfold.cxx:192
 TUnfold.cxx:193
 TUnfold.cxx:194
 TUnfold.cxx:195
 TUnfold.cxx:196
 TUnfold.cxx:197
 TUnfold.cxx:198
 TUnfold.cxx:199
 TUnfold.cxx:200
 TUnfold.cxx:201
 TUnfold.cxx:202
 TUnfold.cxx:203
 TUnfold.cxx:204
 TUnfold.cxx:205
 TUnfold.cxx:206
 TUnfold.cxx:207
 TUnfold.cxx:208
 TUnfold.cxx:209
 TUnfold.cxx:210
 TUnfold.cxx:211
 TUnfold.cxx:212
 TUnfold.cxx:213
 TUnfold.cxx:214
 TUnfold.cxx:215
 TUnfold.cxx:216
 TUnfold.cxx:217
 TUnfold.cxx:218
 TUnfold.cxx:219
 TUnfold.cxx:220
 TUnfold.cxx:221
 TUnfold.cxx:222
 TUnfold.cxx:223
 TUnfold.cxx:224
 TUnfold.cxx:225
 TUnfold.cxx:226
 TUnfold.cxx:227
 TUnfold.cxx:228
 TUnfold.cxx:229
 TUnfold.cxx:230
 TUnfold.cxx:231
 TUnfold.cxx:232
 TUnfold.cxx:233
 TUnfold.cxx:234
 TUnfold.cxx:235
 TUnfold.cxx:236
 TUnfold.cxx:237
 TUnfold.cxx:238
 TUnfold.cxx:239
 TUnfold.cxx:240
 TUnfold.cxx:241
 TUnfold.cxx:242
 TUnfold.cxx:243
 TUnfold.cxx:244
 TUnfold.cxx:245
 TUnfold.cxx:246
 TUnfold.cxx:247
 TUnfold.cxx:248
 TUnfold.cxx:249
 TUnfold.cxx:250
 TUnfold.cxx:251
 TUnfold.cxx:252
 TUnfold.cxx:253
 TUnfold.cxx:254
 TUnfold.cxx:255
 TUnfold.cxx:256
 TUnfold.cxx:257
 TUnfold.cxx:258
 TUnfold.cxx:259
 TUnfold.cxx:260
 TUnfold.cxx:261
 TUnfold.cxx:262
 TUnfold.cxx:263
 TUnfold.cxx:264
 TUnfold.cxx:265
 TUnfold.cxx:266
 TUnfold.cxx:267
 TUnfold.cxx:268
 TUnfold.cxx:269
 TUnfold.cxx:270
 TUnfold.cxx:271
 TUnfold.cxx:272
 TUnfold.cxx:273
 TUnfold.cxx:274
 TUnfold.cxx:275
 TUnfold.cxx:276
 TUnfold.cxx:277
 TUnfold.cxx:278
 TUnfold.cxx:279
 TUnfold.cxx:280
 TUnfold.cxx:281
 TUnfold.cxx:282
 TUnfold.cxx:283
 TUnfold.cxx:284
 TUnfold.cxx:285
 TUnfold.cxx:286
 TUnfold.cxx:287
 TUnfold.cxx:288
 TUnfold.cxx:289
 TUnfold.cxx:290
 TUnfold.cxx:291
 TUnfold.cxx:292
 TUnfold.cxx:293
 TUnfold.cxx:294
 TUnfold.cxx:295
 TUnfold.cxx:296
 TUnfold.cxx:297
 TUnfold.cxx:298
 TUnfold.cxx:299
 TUnfold.cxx:300
 TUnfold.cxx:301
 TUnfold.cxx:302
 TUnfold.cxx:303
 TUnfold.cxx:304
 TUnfold.cxx:305
 TUnfold.cxx:306
 TUnfold.cxx:307
 TUnfold.cxx:308
 TUnfold.cxx:309
 TUnfold.cxx:310
 TUnfold.cxx:311
 TUnfold.cxx:312
 TUnfold.cxx:313
 TUnfold.cxx:314
 TUnfold.cxx:315
 TUnfold.cxx:316
 TUnfold.cxx:317
 TUnfold.cxx:318
 TUnfold.cxx:319
 TUnfold.cxx:320
 TUnfold.cxx:321
 TUnfold.cxx:322
 TUnfold.cxx:323
 TUnfold.cxx:324
 TUnfold.cxx:325
 TUnfold.cxx:326
 TUnfold.cxx:327
 TUnfold.cxx:328
 TUnfold.cxx:329
 TUnfold.cxx:330
 TUnfold.cxx:331
 TUnfold.cxx:332
 TUnfold.cxx:333
 TUnfold.cxx:334
 TUnfold.cxx:335
 TUnfold.cxx:336
 TUnfold.cxx:337
 TUnfold.cxx:338
 TUnfold.cxx:339
 TUnfold.cxx:340
 TUnfold.cxx:341
 TUnfold.cxx:342
 TUnfold.cxx:343
 TUnfold.cxx:344
 TUnfold.cxx:345
 TUnfold.cxx:346
 TUnfold.cxx:347
 TUnfold.cxx:348
 TUnfold.cxx:349
 TUnfold.cxx:350
 TUnfold.cxx:351
 TUnfold.cxx:352
 TUnfold.cxx:353
 TUnfold.cxx:354
 TUnfold.cxx:355
 TUnfold.cxx:356
 TUnfold.cxx:357
 TUnfold.cxx:358
 TUnfold.cxx:359
 TUnfold.cxx:360
 TUnfold.cxx:361
 TUnfold.cxx:362
 TUnfold.cxx:363
 TUnfold.cxx:364
 TUnfold.cxx:365
 TUnfold.cxx:366
 TUnfold.cxx:367
 TUnfold.cxx:368
 TUnfold.cxx:369
 TUnfold.cxx:370
 TUnfold.cxx:371
 TUnfold.cxx:372
 TUnfold.cxx:373
 TUnfold.cxx:374
 TUnfold.cxx:375
 TUnfold.cxx:376
 TUnfold.cxx:377
 TUnfold.cxx:378
 TUnfold.cxx:379
 TUnfold.cxx:380
 TUnfold.cxx:381
 TUnfold.cxx:382
 TUnfold.cxx:383
 TUnfold.cxx:384
 TUnfold.cxx:385
 TUnfold.cxx:386
 TUnfold.cxx:387
 TUnfold.cxx:388
 TUnfold.cxx:389
 TUnfold.cxx:390
 TUnfold.cxx:391
 TUnfold.cxx:392
 TUnfold.cxx:393
 TUnfold.cxx:394
 TUnfold.cxx:395
 TUnfold.cxx:396
 TUnfold.cxx:397
 TUnfold.cxx:398
 TUnfold.cxx:399
 TUnfold.cxx:400
 TUnfold.cxx:401
 TUnfold.cxx:402
 TUnfold.cxx:403
 TUnfold.cxx:404
 TUnfold.cxx:405
 TUnfold.cxx:406
 TUnfold.cxx:407
 TUnfold.cxx:408
 TUnfold.cxx:409
 TUnfold.cxx:410
 TUnfold.cxx:411
 TUnfold.cxx:412
 TUnfold.cxx:413
 TUnfold.cxx:414
 TUnfold.cxx:415
 TUnfold.cxx:416
 TUnfold.cxx:417
 TUnfold.cxx:418
 TUnfold.cxx:419
 TUnfold.cxx:420
 TUnfold.cxx:421
 TUnfold.cxx:422
 TUnfold.cxx:423
 TUnfold.cxx:424
 TUnfold.cxx:425
 TUnfold.cxx:426
 TUnfold.cxx:427
 TUnfold.cxx:428
 TUnfold.cxx:429
 TUnfold.cxx:430
 TUnfold.cxx:431
 TUnfold.cxx:432
 TUnfold.cxx:433
 TUnfold.cxx:434
 TUnfold.cxx:435
 TUnfold.cxx:436
 TUnfold.cxx:437
 TUnfold.cxx:438
 TUnfold.cxx:439
 TUnfold.cxx:440
 TUnfold.cxx:441
 TUnfold.cxx:442
 TUnfold.cxx:443
 TUnfold.cxx:444
 TUnfold.cxx:445
 TUnfold.cxx:446
 TUnfold.cxx:447
 TUnfold.cxx:448
 TUnfold.cxx:449
 TUnfold.cxx:450
 TUnfold.cxx:451
 TUnfold.cxx:452
 TUnfold.cxx:453
 TUnfold.cxx:454
 TUnfold.cxx:455
 TUnfold.cxx:456
 TUnfold.cxx:457
 TUnfold.cxx:458
 TUnfold.cxx:459
 TUnfold.cxx:460
 TUnfold.cxx:461
 TUnfold.cxx:462
 TUnfold.cxx:463
 TUnfold.cxx:464
 TUnfold.cxx:465
 TUnfold.cxx:466
 TUnfold.cxx:467
 TUnfold.cxx:468
 TUnfold.cxx:469
 TUnfold.cxx:470
 TUnfold.cxx:471
 TUnfold.cxx:472
 TUnfold.cxx:473
 TUnfold.cxx:474
 TUnfold.cxx:475
 TUnfold.cxx:476
 TUnfold.cxx:477
 TUnfold.cxx:478
 TUnfold.cxx:479
 TUnfold.cxx:480
 TUnfold.cxx:481
 TUnfold.cxx:482
 TUnfold.cxx:483
 TUnfold.cxx:484
 TUnfold.cxx:485
 TUnfold.cxx:486
 TUnfold.cxx:487
 TUnfold.cxx:488
 TUnfold.cxx:489
 TUnfold.cxx:490
 TUnfold.cxx:491
 TUnfold.cxx:492
 TUnfold.cxx:493
 TUnfold.cxx:494
 TUnfold.cxx:495
 TUnfold.cxx:496
 TUnfold.cxx:497
 TUnfold.cxx:498
 TUnfold.cxx:499
 TUnfold.cxx:500
 TUnfold.cxx:501
 TUnfold.cxx:502
 TUnfold.cxx:503
 TUnfold.cxx:504
 TUnfold.cxx:505
 TUnfold.cxx:506
 TUnfold.cxx:507
 TUnfold.cxx:508
 TUnfold.cxx:509
 TUnfold.cxx:510
 TUnfold.cxx:511
 TUnfold.cxx:512
 TUnfold.cxx:513
 TUnfold.cxx:514
 TUnfold.cxx:515
 TUnfold.cxx:516
 TUnfold.cxx:517
 TUnfold.cxx:518
 TUnfold.cxx:519
 TUnfold.cxx:520
 TUnfold.cxx:521
 TUnfold.cxx:522
 TUnfold.cxx:523
 TUnfold.cxx:524
 TUnfold.cxx:525
 TUnfold.cxx:526
 TUnfold.cxx:527
 TUnfold.cxx:528
 TUnfold.cxx:529
 TUnfold.cxx:530
 TUnfold.cxx:531
 TUnfold.cxx:532
 TUnfold.cxx:533
 TUnfold.cxx:534
 TUnfold.cxx:535
 TUnfold.cxx:536
 TUnfold.cxx:537
 TUnfold.cxx:538
 TUnfold.cxx:539
 TUnfold.cxx:540
 TUnfold.cxx:541
 TUnfold.cxx:542
 TUnfold.cxx:543
 TUnfold.cxx:544
 TUnfold.cxx:545
 TUnfold.cxx:546
 TUnfold.cxx:547
 TUnfold.cxx:548
 TUnfold.cxx:549
 TUnfold.cxx:550
 TUnfold.cxx:551
 TUnfold.cxx:552
 TUnfold.cxx:553
 TUnfold.cxx:554
 TUnfold.cxx:555
 TUnfold.cxx:556
 TUnfold.cxx:557
 TUnfold.cxx:558
 TUnfold.cxx:559
 TUnfold.cxx:560
 TUnfold.cxx:561
 TUnfold.cxx:562
 TUnfold.cxx:563
 TUnfold.cxx:564
 TUnfold.cxx:565
 TUnfold.cxx:566
 TUnfold.cxx:567
 TUnfold.cxx:568
 TUnfold.cxx:569
 TUnfold.cxx:570
 TUnfold.cxx:571
 TUnfold.cxx:572
 TUnfold.cxx:573
 TUnfold.cxx:574
 TUnfold.cxx:575
 TUnfold.cxx:576
 TUnfold.cxx:577
 TUnfold.cxx:578
 TUnfold.cxx:579
 TUnfold.cxx:580
 TUnfold.cxx:581
 TUnfold.cxx:582
 TUnfold.cxx:583
 TUnfold.cxx:584
 TUnfold.cxx:585
 TUnfold.cxx:586
 TUnfold.cxx:587
 TUnfold.cxx:588
 TUnfold.cxx:589
 TUnfold.cxx:590
 TUnfold.cxx:591
 TUnfold.cxx:592
 TUnfold.cxx:593
 TUnfold.cxx:594
 TUnfold.cxx:595
 TUnfold.cxx:596
 TUnfold.cxx:597
 TUnfold.cxx:598
 TUnfold.cxx:599
 TUnfold.cxx:600
 TUnfold.cxx:601
 TUnfold.cxx:602
 TUnfold.cxx:603
 TUnfold.cxx:604
 TUnfold.cxx:605
 TUnfold.cxx:606
 TUnfold.cxx:607
 TUnfold.cxx:608
 TUnfold.cxx:609
 TUnfold.cxx:610
 TUnfold.cxx:611
 TUnfold.cxx:612
 TUnfold.cxx:613
 TUnfold.cxx:614
 TUnfold.cxx:615
 TUnfold.cxx:616
 TUnfold.cxx:617
 TUnfold.cxx:618
 TUnfold.cxx:619
 TUnfold.cxx:620
 TUnfold.cxx:621
 TUnfold.cxx:622
 TUnfold.cxx:623
 TUnfold.cxx:624
 TUnfold.cxx:625
 TUnfold.cxx:626
 TUnfold.cxx:627
 TUnfold.cxx:628
 TUnfold.cxx:629
 TUnfold.cxx:630
 TUnfold.cxx:631
 TUnfold.cxx:632
 TUnfold.cxx:633
 TUnfold.cxx:634
 TUnfold.cxx:635
 TUnfold.cxx:636
 TUnfold.cxx:637
 TUnfold.cxx:638
 TUnfold.cxx:639
 TUnfold.cxx:640
 TUnfold.cxx:641
 TUnfold.cxx:642
 TUnfold.cxx:643
 TUnfold.cxx:644
 TUnfold.cxx:645
 TUnfold.cxx:646
 TUnfold.cxx:647
 TUnfold.cxx:648
 TUnfold.cxx:649
 TUnfold.cxx:650
 TUnfold.cxx:651
 TUnfold.cxx:652
 TUnfold.cxx:653
 TUnfold.cxx:654
 TUnfold.cxx:655
 TUnfold.cxx:656
 TUnfold.cxx:657
 TUnfold.cxx:658
 TUnfold.cxx:659
 TUnfold.cxx:660
 TUnfold.cxx:661
 TUnfold.cxx:662
 TUnfold.cxx:663
 TUnfold.cxx:664
 TUnfold.cxx:665
 TUnfold.cxx:666
 TUnfold.cxx:667
 TUnfold.cxx:668
 TUnfold.cxx:669
 TUnfold.cxx:670
 TUnfold.cxx:671
 TUnfold.cxx:672
 TUnfold.cxx:673
 TUnfold.cxx:674
 TUnfold.cxx:675
 TUnfold.cxx:676
 TUnfold.cxx:677
 TUnfold.cxx:678
 TUnfold.cxx:679
 TUnfold.cxx:680
 TUnfold.cxx:681
 TUnfold.cxx:682
 TUnfold.cxx:683
 TUnfold.cxx:684
 TUnfold.cxx:685
 TUnfold.cxx:686
 TUnfold.cxx:687
 TUnfold.cxx:688
 TUnfold.cxx:689
 TUnfold.cxx:690
 TUnfold.cxx:691
 TUnfold.cxx:692
 TUnfold.cxx:693
 TUnfold.cxx:694
 TUnfold.cxx:695
 TUnfold.cxx:696
 TUnfold.cxx:697
 TUnfold.cxx:698
 TUnfold.cxx:699
 TUnfold.cxx:700
 TUnfold.cxx:701
 TUnfold.cxx:702
 TUnfold.cxx:703
 TUnfold.cxx:704
 TUnfold.cxx:705
 TUnfold.cxx:706
 TUnfold.cxx:707
 TUnfold.cxx:708
 TUnfold.cxx:709
 TUnfold.cxx:710
 TUnfold.cxx:711
 TUnfold.cxx:712
 TUnfold.cxx:713
 TUnfold.cxx:714
 TUnfold.cxx:715
 TUnfold.cxx:716
 TUnfold.cxx:717
 TUnfold.cxx:718
 TUnfold.cxx:719
 TUnfold.cxx:720
 TUnfold.cxx:721
 TUnfold.cxx:722
 TUnfold.cxx:723
 TUnfold.cxx:724
 TUnfold.cxx:725
 TUnfold.cxx:726
 TUnfold.cxx:727
 TUnfold.cxx:728
 TUnfold.cxx:729
 TUnfold.cxx:730
 TUnfold.cxx:731
 TUnfold.cxx:732
 TUnfold.cxx:733
 TUnfold.cxx:734
 TUnfold.cxx:735
 TUnfold.cxx:736
 TUnfold.cxx:737
 TUnfold.cxx:738
 TUnfold.cxx:739
 TUnfold.cxx:740
 TUnfold.cxx:741
 TUnfold.cxx:742
 TUnfold.cxx:743
 TUnfold.cxx:744
 TUnfold.cxx:745
 TUnfold.cxx:746
 TUnfold.cxx:747
 TUnfold.cxx:748
 TUnfold.cxx:749
 TUnfold.cxx:750
 TUnfold.cxx:751
 TUnfold.cxx:752
 TUnfold.cxx:753
 TUnfold.cxx:754
 TUnfold.cxx:755
 TUnfold.cxx:756
 TUnfold.cxx:757
 TUnfold.cxx:758
 TUnfold.cxx:759
 TUnfold.cxx:760
 TUnfold.cxx:761
 TUnfold.cxx:762
 TUnfold.cxx:763
 TUnfold.cxx:764
 TUnfold.cxx:765
 TUnfold.cxx:766
 TUnfold.cxx:767
 TUnfold.cxx:768
 TUnfold.cxx:769
 TUnfold.cxx:770
 TUnfold.cxx:771
 TUnfold.cxx:772
 TUnfold.cxx:773
 TUnfold.cxx:774
 TUnfold.cxx:775
 TUnfold.cxx:776
 TUnfold.cxx:777
 TUnfold.cxx:778
 TUnfold.cxx:779
 TUnfold.cxx:780
 TUnfold.cxx:781
 TUnfold.cxx:782
 TUnfold.cxx:783
 TUnfold.cxx:784
 TUnfold.cxx:785
 TUnfold.cxx:786
 TUnfold.cxx:787
 TUnfold.cxx:788
 TUnfold.cxx:789
 TUnfold.cxx:790
 TUnfold.cxx:791
 TUnfold.cxx:792
 TUnfold.cxx:793
 TUnfold.cxx:794
 TUnfold.cxx:795
 TUnfold.cxx:796
 TUnfold.cxx:797
 TUnfold.cxx:798
 TUnfold.cxx:799
 TUnfold.cxx:800
 TUnfold.cxx:801
 TUnfold.cxx:802
 TUnfold.cxx:803
 TUnfold.cxx:804
 TUnfold.cxx:805
 TUnfold.cxx:806
 TUnfold.cxx:807
 TUnfold.cxx:808
 TUnfold.cxx:809
 TUnfold.cxx:810
 TUnfold.cxx:811
 TUnfold.cxx:812
 TUnfold.cxx:813
 TUnfold.cxx:814
 TUnfold.cxx:815
 TUnfold.cxx:816
 TUnfold.cxx:817
 TUnfold.cxx:818
 TUnfold.cxx:819
 TUnfold.cxx:820
 TUnfold.cxx:821
 TUnfold.cxx:822
 TUnfold.cxx:823
 TUnfold.cxx:824
 TUnfold.cxx:825
 TUnfold.cxx:826
 TUnfold.cxx:827
 TUnfold.cxx:828
 TUnfold.cxx:829
 TUnfold.cxx:830
 TUnfold.cxx:831
 TUnfold.cxx:832
 TUnfold.cxx:833
 TUnfold.cxx:834
 TUnfold.cxx:835
 TUnfold.cxx:836
 TUnfold.cxx:837
 TUnfold.cxx:838
 TUnfold.cxx:839
 TUnfold.cxx:840
 TUnfold.cxx:841
 TUnfold.cxx:842
 TUnfold.cxx:843
 TUnfold.cxx:844
 TUnfold.cxx:845
 TUnfold.cxx:846
 TUnfold.cxx:847
 TUnfold.cxx:848
 TUnfold.cxx:849
 TUnfold.cxx:850
 TUnfold.cxx:851
 TUnfold.cxx:852
 TUnfold.cxx:853
 TUnfold.cxx:854
 TUnfold.cxx:855
 TUnfold.cxx:856
 TUnfold.cxx:857
 TUnfold.cxx:858
 TUnfold.cxx:859
 TUnfold.cxx:860
 TUnfold.cxx:861
 TUnfold.cxx:862
 TUnfold.cxx:863
 TUnfold.cxx:864
 TUnfold.cxx:865
 TUnfold.cxx:866
 TUnfold.cxx:867
 TUnfold.cxx:868
 TUnfold.cxx:869
 TUnfold.cxx:870
 TUnfold.cxx:871
 TUnfold.cxx:872
 TUnfold.cxx:873
 TUnfold.cxx:874
 TUnfold.cxx:875
 TUnfold.cxx:876
 TUnfold.cxx:877
 TUnfold.cxx:878
 TUnfold.cxx:879
 TUnfold.cxx:880
 TUnfold.cxx:881
 TUnfold.cxx:882
 TUnfold.cxx:883
 TUnfold.cxx:884
 TUnfold.cxx:885
 TUnfold.cxx:886
 TUnfold.cxx:887
 TUnfold.cxx:888
 TUnfold.cxx:889
 TUnfold.cxx:890
 TUnfold.cxx:891
 TUnfold.cxx:892
 TUnfold.cxx:893
 TUnfold.cxx:894
 TUnfold.cxx:895
 TUnfold.cxx:896
 TUnfold.cxx:897
 TUnfold.cxx:898
 TUnfold.cxx:899
 TUnfold.cxx:900
 TUnfold.cxx:901
 TUnfold.cxx:902
 TUnfold.cxx:903
 TUnfold.cxx:904
 TUnfold.cxx:905
 TUnfold.cxx:906
 TUnfold.cxx:907
 TUnfold.cxx:908
 TUnfold.cxx:909
 TUnfold.cxx:910
 TUnfold.cxx:911
 TUnfold.cxx:912
 TUnfold.cxx:913
 TUnfold.cxx:914
 TUnfold.cxx:915
 TUnfold.cxx:916
 TUnfold.cxx:917
 TUnfold.cxx:918
 TUnfold.cxx:919
 TUnfold.cxx:920
 TUnfold.cxx:921
 TUnfold.cxx:922
 TUnfold.cxx:923
 TUnfold.cxx:924
 TUnfold.cxx:925
 TUnfold.cxx:926
 TUnfold.cxx:927
 TUnfold.cxx:928
 TUnfold.cxx:929
 TUnfold.cxx:930
 TUnfold.cxx:931
 TUnfold.cxx:932
 TUnfold.cxx:933
 TUnfold.cxx:934
 TUnfold.cxx:935
 TUnfold.cxx:936
 TUnfold.cxx:937
 TUnfold.cxx:938
 TUnfold.cxx:939
 TUnfold.cxx:940
 TUnfold.cxx:941
 TUnfold.cxx:942
 TUnfold.cxx:943
 TUnfold.cxx:944
 TUnfold.cxx:945
 TUnfold.cxx:946
 TUnfold.cxx:947
 TUnfold.cxx:948
 TUnfold.cxx:949
 TUnfold.cxx:950
 TUnfold.cxx:951
 TUnfold.cxx:952
 TUnfold.cxx:953
 TUnfold.cxx:954
 TUnfold.cxx:955
 TUnfold.cxx:956
 TUnfold.cxx:957
 TUnfold.cxx:958
 TUnfold.cxx:959
 TUnfold.cxx:960
 TUnfold.cxx:961
 TUnfold.cxx:962
 TUnfold.cxx:963
 TUnfold.cxx:964
 TUnfold.cxx:965
 TUnfold.cxx:966
 TUnfold.cxx:967
 TUnfold.cxx:968
 TUnfold.cxx:969
 TUnfold.cxx:970
 TUnfold.cxx:971
 TUnfold.cxx:972
 TUnfold.cxx:973
 TUnfold.cxx:974
 TUnfold.cxx:975
 TUnfold.cxx:976
 TUnfold.cxx:977
 TUnfold.cxx:978
 TUnfold.cxx:979
 TUnfold.cxx:980
 TUnfold.cxx:981
 TUnfold.cxx:982
 TUnfold.cxx:983
 TUnfold.cxx:984
 TUnfold.cxx:985
 TUnfold.cxx:986
 TUnfold.cxx:987
 TUnfold.cxx:988
 TUnfold.cxx:989
 TUnfold.cxx:990
 TUnfold.cxx:991
 TUnfold.cxx:992
 TUnfold.cxx:993
 TUnfold.cxx:994
 TUnfold.cxx:995
 TUnfold.cxx:996
 TUnfold.cxx:997
 TUnfold.cxx:998
 TUnfold.cxx:999
 TUnfold.cxx:1000
 TUnfold.cxx:1001
 TUnfold.cxx:1002
 TUnfold.cxx:1003
 TUnfold.cxx:1004
 TUnfold.cxx:1005
 TUnfold.cxx:1006
 TUnfold.cxx:1007
 TUnfold.cxx:1008
 TUnfold.cxx:1009
 TUnfold.cxx:1010
 TUnfold.cxx:1011
 TUnfold.cxx:1012
 TUnfold.cxx:1013
 TUnfold.cxx:1014
 TUnfold.cxx:1015
 TUnfold.cxx:1016
 TUnfold.cxx:1017
 TUnfold.cxx:1018
 TUnfold.cxx:1019
 TUnfold.cxx:1020
 TUnfold.cxx:1021
 TUnfold.cxx:1022
 TUnfold.cxx:1023
 TUnfold.cxx:1024
 TUnfold.cxx:1025
 TUnfold.cxx:1026
 TUnfold.cxx:1027
 TUnfold.cxx:1028
 TUnfold.cxx:1029
 TUnfold.cxx:1030
 TUnfold.cxx:1031
 TUnfold.cxx:1032
 TUnfold.cxx:1033
 TUnfold.cxx:1034
 TUnfold.cxx:1035
 TUnfold.cxx:1036
 TUnfold.cxx:1037
 TUnfold.cxx:1038
 TUnfold.cxx:1039
 TUnfold.cxx:1040
 TUnfold.cxx:1041
 TUnfold.cxx:1042
 TUnfold.cxx:1043
 TUnfold.cxx:1044
 TUnfold.cxx:1045
 TUnfold.cxx:1046
 TUnfold.cxx:1047
 TUnfold.cxx:1048
 TUnfold.cxx:1049
 TUnfold.cxx:1050
 TUnfold.cxx:1051
 TUnfold.cxx:1052
 TUnfold.cxx:1053
 TUnfold.cxx:1054
 TUnfold.cxx:1055
 TUnfold.cxx:1056
 TUnfold.cxx:1057
 TUnfold.cxx:1058
 TUnfold.cxx:1059
 TUnfold.cxx:1060
 TUnfold.cxx:1061
 TUnfold.cxx:1062
 TUnfold.cxx:1063
 TUnfold.cxx:1064
 TUnfold.cxx:1065
 TUnfold.cxx:1066
 TUnfold.cxx:1067
 TUnfold.cxx:1068
 TUnfold.cxx:1069
 TUnfold.cxx:1070
 TUnfold.cxx:1071
 TUnfold.cxx:1072
 TUnfold.cxx:1073
 TUnfold.cxx:1074
 TUnfold.cxx:1075
 TUnfold.cxx:1076
 TUnfold.cxx:1077
 TUnfold.cxx:1078
 TUnfold.cxx:1079
 TUnfold.cxx:1080
 TUnfold.cxx:1081
 TUnfold.cxx:1082
 TUnfold.cxx:1083
 TUnfold.cxx:1084
 TUnfold.cxx:1085
 TUnfold.cxx:1086
 TUnfold.cxx:1087
 TUnfold.cxx:1088
 TUnfold.cxx:1089
 TUnfold.cxx:1090
 TUnfold.cxx:1091
 TUnfold.cxx:1092
 TUnfold.cxx:1093
 TUnfold.cxx:1094
 TUnfold.cxx:1095
 TUnfold.cxx:1096
 TUnfold.cxx:1097
 TUnfold.cxx:1098
 TUnfold.cxx:1099
 TUnfold.cxx:1100
 TUnfold.cxx:1101
 TUnfold.cxx:1102
 TUnfold.cxx:1103
 TUnfold.cxx:1104
 TUnfold.cxx:1105
 TUnfold.cxx:1106
 TUnfold.cxx:1107
 TUnfold.cxx:1108
 TUnfold.cxx:1109
 TUnfold.cxx:1110
 TUnfold.cxx:1111
 TUnfold.cxx:1112
 TUnfold.cxx:1113
 TUnfold.cxx:1114
 TUnfold.cxx:1115
 TUnfold.cxx:1116
 TUnfold.cxx:1117
 TUnfold.cxx:1118
 TUnfold.cxx:1119
 TUnfold.cxx:1120
 TUnfold.cxx:1121
 TUnfold.cxx:1122
 TUnfold.cxx:1123
 TUnfold.cxx:1124
 TUnfold.cxx:1125
 TUnfold.cxx:1126
 TUnfold.cxx:1127
 TUnfold.cxx:1128
 TUnfold.cxx:1129
 TUnfold.cxx:1130
 TUnfold.cxx:1131
 TUnfold.cxx:1132
 TUnfold.cxx:1133
 TUnfold.cxx:1134
 TUnfold.cxx:1135
 TUnfold.cxx:1136
 TUnfold.cxx:1137
 TUnfold.cxx:1138
 TUnfold.cxx:1139
 TUnfold.cxx:1140
 TUnfold.cxx:1141
 TUnfold.cxx:1142
 TUnfold.cxx:1143
 TUnfold.cxx:1144
 TUnfold.cxx:1145
 TUnfold.cxx:1146
 TUnfold.cxx:1147
 TUnfold.cxx:1148
 TUnfold.cxx:1149
 TUnfold.cxx:1150
 TUnfold.cxx:1151
 TUnfold.cxx:1152
 TUnfold.cxx:1153
 TUnfold.cxx:1154
 TUnfold.cxx:1155
 TUnfold.cxx:1156
 TUnfold.cxx:1157
 TUnfold.cxx:1158
 TUnfold.cxx:1159
 TUnfold.cxx:1160
 TUnfold.cxx:1161
 TUnfold.cxx:1162
 TUnfold.cxx:1163
 TUnfold.cxx:1164
 TUnfold.cxx:1165
 TUnfold.cxx:1166
 TUnfold.cxx:1167
 TUnfold.cxx:1168
 TUnfold.cxx:1169
 TUnfold.cxx:1170
 TUnfold.cxx:1171
 TUnfold.cxx:1172
 TUnfold.cxx:1173
 TUnfold.cxx:1174
 TUnfold.cxx:1175
 TUnfold.cxx:1176
 TUnfold.cxx:1177
 TUnfold.cxx:1178
 TUnfold.cxx:1179
 TUnfold.cxx:1180
 TUnfold.cxx:1181
 TUnfold.cxx:1182
 TUnfold.cxx:1183
 TUnfold.cxx:1184
 TUnfold.cxx:1185
 TUnfold.cxx:1186
 TUnfold.cxx:1187
 TUnfold.cxx:1188
 TUnfold.cxx:1189
 TUnfold.cxx:1190
 TUnfold.cxx:1191
 TUnfold.cxx:1192
 TUnfold.cxx:1193
 TUnfold.cxx:1194
 TUnfold.cxx:1195
 TUnfold.cxx:1196
 TUnfold.cxx:1197
 TUnfold.cxx:1198
 TUnfold.cxx:1199
 TUnfold.cxx:1200
 TUnfold.cxx:1201
 TUnfold.cxx:1202
 TUnfold.cxx:1203
 TUnfold.cxx:1204
 TUnfold.cxx:1205
 TUnfold.cxx:1206
 TUnfold.cxx:1207
 TUnfold.cxx:1208
 TUnfold.cxx:1209
 TUnfold.cxx:1210
 TUnfold.cxx:1211
 TUnfold.cxx:1212
 TUnfold.cxx:1213
 TUnfold.cxx:1214
 TUnfold.cxx:1215
 TUnfold.cxx:1216
 TUnfold.cxx:1217
 TUnfold.cxx:1218
 TUnfold.cxx:1219
 TUnfold.cxx:1220
 TUnfold.cxx:1221
 TUnfold.cxx:1222
 TUnfold.cxx:1223
 TUnfold.cxx:1224
 TUnfold.cxx:1225
 TUnfold.cxx:1226
 TUnfold.cxx:1227
 TUnfold.cxx:1228
 TUnfold.cxx:1229
 TUnfold.cxx:1230
 TUnfold.cxx:1231
 TUnfold.cxx:1232
 TUnfold.cxx:1233
 TUnfold.cxx:1234
 TUnfold.cxx:1235
 TUnfold.cxx:1236
 TUnfold.cxx:1237
 TUnfold.cxx:1238
 TUnfold.cxx:1239
 TUnfold.cxx:1240
 TUnfold.cxx:1241
 TUnfold.cxx:1242
 TUnfold.cxx:1243
 TUnfold.cxx:1244
 TUnfold.cxx:1245
 TUnfold.cxx:1246
 TUnfold.cxx:1247
 TUnfold.cxx:1248
 TUnfold.cxx:1249
 TUnfold.cxx:1250
 TUnfold.cxx:1251
 TUnfold.cxx:1252
 TUnfold.cxx:1253
 TUnfold.cxx:1254
 TUnfold.cxx:1255
 TUnfold.cxx:1256
 TUnfold.cxx:1257
 TUnfold.cxx:1258
 TUnfold.cxx:1259
 TUnfold.cxx:1260
 TUnfold.cxx:1261
 TUnfold.cxx:1262
 TUnfold.cxx:1263
 TUnfold.cxx:1264
 TUnfold.cxx:1265
 TUnfold.cxx:1266
 TUnfold.cxx:1267
 TUnfold.cxx:1268
 TUnfold.cxx:1269
 TUnfold.cxx:1270
 TUnfold.cxx:1271
 TUnfold.cxx:1272
 TUnfold.cxx:1273
 TUnfold.cxx:1274
 TUnfold.cxx:1275
 TUnfold.cxx:1276
 TUnfold.cxx:1277
 TUnfold.cxx:1278
 TUnfold.cxx:1279
 TUnfold.cxx:1280
 TUnfold.cxx:1281
 TUnfold.cxx:1282
 TUnfold.cxx:1283
 TUnfold.cxx:1284
 TUnfold.cxx:1285
 TUnfold.cxx:1286
 TUnfold.cxx:1287
 TUnfold.cxx:1288
 TUnfold.cxx:1289
 TUnfold.cxx:1290
 TUnfold.cxx:1291
 TUnfold.cxx:1292
 TUnfold.cxx:1293
 TUnfold.cxx:1294
 TUnfold.cxx:1295
 TUnfold.cxx:1296
 TUnfold.cxx:1297
 TUnfold.cxx:1298
 TUnfold.cxx:1299
 TUnfold.cxx:1300
 TUnfold.cxx:1301
 TUnfold.cxx:1302
 TUnfold.cxx:1303
 TUnfold.cxx:1304
 TUnfold.cxx:1305
 TUnfold.cxx:1306
 TUnfold.cxx:1307
 TUnfold.cxx:1308
 TUnfold.cxx:1309
 TUnfold.cxx:1310
 TUnfold.cxx:1311
 TUnfold.cxx:1312
 TUnfold.cxx:1313
 TUnfold.cxx:1314
 TUnfold.cxx:1315
 TUnfold.cxx:1316
 TUnfold.cxx:1317
 TUnfold.cxx:1318
 TUnfold.cxx:1319
 TUnfold.cxx:1320
 TUnfold.cxx:1321
 TUnfold.cxx:1322
 TUnfold.cxx:1323
 TUnfold.cxx:1324
 TUnfold.cxx:1325
 TUnfold.cxx:1326
 TUnfold.cxx:1327
 TUnfold.cxx:1328
 TUnfold.cxx:1329
 TUnfold.cxx:1330
 TUnfold.cxx:1331
 TUnfold.cxx:1332
 TUnfold.cxx:1333
 TUnfold.cxx:1334
 TUnfold.cxx:1335
 TUnfold.cxx:1336
 TUnfold.cxx:1337
 TUnfold.cxx:1338
 TUnfold.cxx:1339
 TUnfold.cxx:1340
 TUnfold.cxx:1341
 TUnfold.cxx:1342
 TUnfold.cxx:1343
 TUnfold.cxx:1344
 TUnfold.cxx:1345
 TUnfold.cxx:1346
 TUnfold.cxx:1347
 TUnfold.cxx:1348
 TUnfold.cxx:1349
 TUnfold.cxx:1350
 TUnfold.cxx:1351
 TUnfold.cxx:1352
 TUnfold.cxx:1353
 TUnfold.cxx:1354
 TUnfold.cxx:1355
 TUnfold.cxx:1356
 TUnfold.cxx:1357
 TUnfold.cxx:1358
 TUnfold.cxx:1359
 TUnfold.cxx:1360
 TUnfold.cxx:1361
 TUnfold.cxx:1362
 TUnfold.cxx:1363
 TUnfold.cxx:1364
 TUnfold.cxx:1365
 TUnfold.cxx:1366
 TUnfold.cxx:1367
 TUnfold.cxx:1368
 TUnfold.cxx:1369
 TUnfold.cxx:1370
 TUnfold.cxx:1371
 TUnfold.cxx:1372
 TUnfold.cxx:1373
 TUnfold.cxx:1374
 TUnfold.cxx:1375
 TUnfold.cxx:1376
 TUnfold.cxx:1377
 TUnfold.cxx:1378
 TUnfold.cxx:1379
 TUnfold.cxx:1380
 TUnfold.cxx:1381
 TUnfold.cxx:1382
 TUnfold.cxx:1383
 TUnfold.cxx:1384
 TUnfold.cxx:1385
 TUnfold.cxx:1386
 TUnfold.cxx:1387
 TUnfold.cxx:1388
 TUnfold.cxx:1389
 TUnfold.cxx:1390
 TUnfold.cxx:1391
 TUnfold.cxx:1392
 TUnfold.cxx:1393
 TUnfold.cxx:1394
 TUnfold.cxx:1395
 TUnfold.cxx:1396
 TUnfold.cxx:1397
 TUnfold.cxx:1398
 TUnfold.cxx:1399
 TUnfold.cxx:1400
 TUnfold.cxx:1401
 TUnfold.cxx:1402
 TUnfold.cxx:1403
 TUnfold.cxx:1404
 TUnfold.cxx:1405
 TUnfold.cxx:1406
 TUnfold.cxx:1407
 TUnfold.cxx:1408
 TUnfold.cxx:1409
 TUnfold.cxx:1410
 TUnfold.cxx:1411
 TUnfold.cxx:1412
 TUnfold.cxx:1413
 TUnfold.cxx:1414
 TUnfold.cxx:1415
 TUnfold.cxx:1416
 TUnfold.cxx:1417
 TUnfold.cxx:1418
 TUnfold.cxx:1419
 TUnfold.cxx:1420
 TUnfold.cxx:1421
 TUnfold.cxx:1422
 TUnfold.cxx:1423
 TUnfold.cxx:1424
 TUnfold.cxx:1425
 TUnfold.cxx:1426
 TUnfold.cxx:1427
 TUnfold.cxx:1428
 TUnfold.cxx:1429
 TUnfold.cxx:1430
 TUnfold.cxx:1431
 TUnfold.cxx:1432
 TUnfold.cxx:1433
 TUnfold.cxx:1434
 TUnfold.cxx:1435
 TUnfold.cxx:1436
 TUnfold.cxx:1437
 TUnfold.cxx:1438
 TUnfold.cxx:1439
 TUnfold.cxx:1440
 TUnfold.cxx:1441
 TUnfold.cxx:1442
 TUnfold.cxx:1443
 TUnfold.cxx:1444
 TUnfold.cxx:1445
 TUnfold.cxx:1446
 TUnfold.cxx:1447
 TUnfold.cxx:1448
 TUnfold.cxx:1449
 TUnfold.cxx:1450
 TUnfold.cxx:1451
 TUnfold.cxx:1452
 TUnfold.cxx:1453
 TUnfold.cxx:1454
 TUnfold.cxx:1455
 TUnfold.cxx:1456
 TUnfold.cxx:1457
 TUnfold.cxx:1458
 TUnfold.cxx:1459
 TUnfold.cxx:1460
 TUnfold.cxx:1461
 TUnfold.cxx:1462
 TUnfold.cxx:1463
 TUnfold.cxx:1464
 TUnfold.cxx:1465
 TUnfold.cxx:1466
 TUnfold.cxx:1467
 TUnfold.cxx:1468
 TUnfold.cxx:1469
 TUnfold.cxx:1470
 TUnfold.cxx:1471
 TUnfold.cxx:1472
 TUnfold.cxx:1473
 TUnfold.cxx:1474
 TUnfold.cxx:1475
 TUnfold.cxx:1476
 TUnfold.cxx:1477
 TUnfold.cxx:1478
 TUnfold.cxx:1479
 TUnfold.cxx:1480
 TUnfold.cxx:1481
 TUnfold.cxx:1482
 TUnfold.cxx:1483
 TUnfold.cxx:1484
 TUnfold.cxx:1485
 TUnfold.cxx:1486
 TUnfold.cxx:1487
 TUnfold.cxx:1488
 TUnfold.cxx:1489
 TUnfold.cxx:1490
 TUnfold.cxx:1491
 TUnfold.cxx:1492
 TUnfold.cxx:1493
 TUnfold.cxx:1494
 TUnfold.cxx:1495
 TUnfold.cxx:1496
 TUnfold.cxx:1497
 TUnfold.cxx:1498
 TUnfold.cxx:1499
 TUnfold.cxx:1500
 TUnfold.cxx:1501
 TUnfold.cxx:1502
 TUnfold.cxx:1503
 TUnfold.cxx:1504
 TUnfold.cxx:1505
 TUnfold.cxx:1506
 TUnfold.cxx:1507
 TUnfold.cxx:1508
 TUnfold.cxx:1509
 TUnfold.cxx:1510
 TUnfold.cxx:1511
 TUnfold.cxx:1512
 TUnfold.cxx:1513
 TUnfold.cxx:1514
 TUnfold.cxx:1515
 TUnfold.cxx:1516
 TUnfold.cxx:1517
 TUnfold.cxx:1518
 TUnfold.cxx:1519
 TUnfold.cxx:1520
 TUnfold.cxx:1521
 TUnfold.cxx:1522
 TUnfold.cxx:1523
 TUnfold.cxx:1524
 TUnfold.cxx:1525
 TUnfold.cxx:1526
 TUnfold.cxx:1527
 TUnfold.cxx:1528
 TUnfold.cxx:1529
 TUnfold.cxx:1530
 TUnfold.cxx:1531
 TUnfold.cxx:1532
 TUnfold.cxx:1533
 TUnfold.cxx:1534
 TUnfold.cxx:1535
 TUnfold.cxx:1536
 TUnfold.cxx:1537
 TUnfold.cxx:1538
 TUnfold.cxx:1539
 TUnfold.cxx:1540
 TUnfold.cxx:1541
 TUnfold.cxx:1542
 TUnfold.cxx:1543
 TUnfold.cxx:1544
 TUnfold.cxx:1545
 TUnfold.cxx:1546
 TUnfold.cxx:1547
 TUnfold.cxx:1548
 TUnfold.cxx:1549
 TUnfold.cxx:1550
 TUnfold.cxx:1551
 TUnfold.cxx:1552
 TUnfold.cxx:1553
 TUnfold.cxx:1554
 TUnfold.cxx:1555
 TUnfold.cxx:1556
 TUnfold.cxx:1557
 TUnfold.cxx:1558
 TUnfold.cxx:1559
 TUnfold.cxx:1560
 TUnfold.cxx:1561
 TUnfold.cxx:1562
 TUnfold.cxx:1563
 TUnfold.cxx:1564
 TUnfold.cxx:1565
 TUnfold.cxx:1566
 TUnfold.cxx:1567
 TUnfold.cxx:1568
 TUnfold.cxx:1569
 TUnfold.cxx:1570
 TUnfold.cxx:1571
 TUnfold.cxx:1572
 TUnfold.cxx:1573
 TUnfold.cxx:1574
 TUnfold.cxx:1575
 TUnfold.cxx:1576
 TUnfold.cxx:1577
 TUnfold.cxx:1578
 TUnfold.cxx:1579
 TUnfold.cxx:1580
 TUnfold.cxx:1581
 TUnfold.cxx:1582
 TUnfold.cxx:1583
 TUnfold.cxx:1584
 TUnfold.cxx:1585
 TUnfold.cxx:1586
 TUnfold.cxx:1587
 TUnfold.cxx:1588
 TUnfold.cxx:1589
 TUnfold.cxx:1590
 TUnfold.cxx:1591
 TUnfold.cxx:1592
 TUnfold.cxx:1593
 TUnfold.cxx:1594
 TUnfold.cxx:1595
 TUnfold.cxx:1596
 TUnfold.cxx:1597
 TUnfold.cxx:1598
 TUnfold.cxx:1599
 TUnfold.cxx:1600
 TUnfold.cxx:1601
 TUnfold.cxx:1602
 TUnfold.cxx:1603
 TUnfold.cxx:1604
 TUnfold.cxx:1605
 TUnfold.cxx:1606
 TUnfold.cxx:1607
 TUnfold.cxx:1608
 TUnfold.cxx:1609
 TUnfold.cxx:1610
 TUnfold.cxx:1611
 TUnfold.cxx:1612
 TUnfold.cxx:1613
 TUnfold.cxx:1614
 TUnfold.cxx:1615
 TUnfold.cxx:1616
 TUnfold.cxx:1617
 TUnfold.cxx:1618
 TUnfold.cxx:1619
 TUnfold.cxx:1620
 TUnfold.cxx:1621
 TUnfold.cxx:1622
 TUnfold.cxx:1623
 TUnfold.cxx:1624
 TUnfold.cxx:1625
 TUnfold.cxx:1626
 TUnfold.cxx:1627
 TUnfold.cxx:1628
 TUnfold.cxx:1629
 TUnfold.cxx:1630
 TUnfold.cxx:1631
 TUnfold.cxx:1632
 TUnfold.cxx:1633
 TUnfold.cxx:1634
 TUnfold.cxx:1635
 TUnfold.cxx:1636
 TUnfold.cxx:1637
 TUnfold.cxx:1638
 TUnfold.cxx:1639
 TUnfold.cxx:1640
 TUnfold.cxx:1641
 TUnfold.cxx:1642
 TUnfold.cxx:1643
 TUnfold.cxx:1644
 TUnfold.cxx:1645
 TUnfold.cxx:1646
 TUnfold.cxx:1647
 TUnfold.cxx:1648
 TUnfold.cxx:1649
 TUnfold.cxx:1650
 TUnfold.cxx:1651
 TUnfold.cxx:1652
 TUnfold.cxx:1653
 TUnfold.cxx:1654
 TUnfold.cxx:1655
 TUnfold.cxx:1656
 TUnfold.cxx:1657
 TUnfold.cxx:1658
 TUnfold.cxx:1659
 TUnfold.cxx:1660
 TUnfold.cxx:1661
 TUnfold.cxx:1662
 TUnfold.cxx:1663
 TUnfold.cxx:1664
 TUnfold.cxx:1665
 TUnfold.cxx:1666
 TUnfold.cxx:1667
 TUnfold.cxx:1668
 TUnfold.cxx:1669
 TUnfold.cxx:1670
 TUnfold.cxx:1671
 TUnfold.cxx:1672
 TUnfold.cxx:1673
 TUnfold.cxx:1674
 TUnfold.cxx:1675
 TUnfold.cxx:1676
 TUnfold.cxx:1677
 TUnfold.cxx:1678
 TUnfold.cxx:1679
 TUnfold.cxx:1680
 TUnfold.cxx:1681
 TUnfold.cxx:1682
 TUnfold.cxx:1683
 TUnfold.cxx:1684
 TUnfold.cxx:1685
 TUnfold.cxx:1686
 TUnfold.cxx:1687
 TUnfold.cxx:1688
 TUnfold.cxx:1689
 TUnfold.cxx:1690
 TUnfold.cxx:1691
 TUnfold.cxx:1692
 TUnfold.cxx:1693
 TUnfold.cxx:1694
 TUnfold.cxx:1695
 TUnfold.cxx:1696
 TUnfold.cxx:1697
 TUnfold.cxx:1698
 TUnfold.cxx:1699
 TUnfold.cxx:1700
 TUnfold.cxx:1701
 TUnfold.cxx:1702
 TUnfold.cxx:1703
 TUnfold.cxx:1704
 TUnfold.cxx:1705
 TUnfold.cxx:1706
 TUnfold.cxx:1707
 TUnfold.cxx:1708
 TUnfold.cxx:1709
 TUnfold.cxx:1710
 TUnfold.cxx:1711
 TUnfold.cxx:1712
 TUnfold.cxx:1713
 TUnfold.cxx:1714
 TUnfold.cxx:1715
 TUnfold.cxx:1716
 TUnfold.cxx:1717
 TUnfold.cxx:1718
 TUnfold.cxx:1719
 TUnfold.cxx:1720
 TUnfold.cxx:1721
 TUnfold.cxx:1722
 TUnfold.cxx:1723
 TUnfold.cxx:1724
 TUnfold.cxx:1725
 TUnfold.cxx:1726
 TUnfold.cxx:1727
 TUnfold.cxx:1728
 TUnfold.cxx:1729
 TUnfold.cxx:1730
 TUnfold.cxx:1731
 TUnfold.cxx:1732
 TUnfold.cxx:1733
 TUnfold.cxx:1734
 TUnfold.cxx:1735
 TUnfold.cxx:1736
 TUnfold.cxx:1737
 TUnfold.cxx:1738
 TUnfold.cxx:1739
 TUnfold.cxx:1740
 TUnfold.cxx:1741
 TUnfold.cxx:1742
 TUnfold.cxx:1743
 TUnfold.cxx:1744
 TUnfold.cxx:1745
 TUnfold.cxx:1746
 TUnfold.cxx:1747
 TUnfold.cxx:1748
 TUnfold.cxx:1749
 TUnfold.cxx:1750
 TUnfold.cxx:1751
 TUnfold.cxx:1752
 TUnfold.cxx:1753
 TUnfold.cxx:1754
 TUnfold.cxx:1755
 TUnfold.cxx:1756
 TUnfold.cxx:1757
 TUnfold.cxx:1758
 TUnfold.cxx:1759
 TUnfold.cxx:1760
 TUnfold.cxx:1761
 TUnfold.cxx:1762
 TUnfold.cxx:1763
 TUnfold.cxx:1764
 TUnfold.cxx:1765
 TUnfold.cxx:1766
 TUnfold.cxx:1767
 TUnfold.cxx:1768
 TUnfold.cxx:1769
 TUnfold.cxx:1770
 TUnfold.cxx:1771
 TUnfold.cxx:1772
 TUnfold.cxx:1773
 TUnfold.cxx:1774
 TUnfold.cxx:1775
 TUnfold.cxx:1776
 TUnfold.cxx:1777
 TUnfold.cxx:1778
 TUnfold.cxx:1779
 TUnfold.cxx:1780
 TUnfold.cxx:1781
 TUnfold.cxx:1782
 TUnfold.cxx:1783
 TUnfold.cxx:1784
 TUnfold.cxx:1785
 TUnfold.cxx:1786
 TUnfold.cxx:1787
 TUnfold.cxx:1788
 TUnfold.cxx:1789
 TUnfold.cxx:1790
 TUnfold.cxx:1791
 TUnfold.cxx:1792
 TUnfold.cxx:1793
 TUnfold.cxx:1794
 TUnfold.cxx:1795
 TUnfold.cxx:1796
 TUnfold.cxx:1797
 TUnfold.cxx:1798
 TUnfold.cxx:1799
 TUnfold.cxx:1800
 TUnfold.cxx:1801
 TUnfold.cxx:1802
 TUnfold.cxx:1803
 TUnfold.cxx:1804
 TUnfold.cxx:1805
 TUnfold.cxx:1806
 TUnfold.cxx:1807
 TUnfold.cxx:1808
 TUnfold.cxx:1809
 TUnfold.cxx:1810
 TUnfold.cxx:1811
 TUnfold.cxx:1812
 TUnfold.cxx:1813
 TUnfold.cxx:1814
 TUnfold.cxx:1815
 TUnfold.cxx:1816
 TUnfold.cxx:1817
 TUnfold.cxx:1818
 TUnfold.cxx:1819
 TUnfold.cxx:1820
 TUnfold.cxx:1821
 TUnfold.cxx:1822
 TUnfold.cxx:1823
 TUnfold.cxx:1824
 TUnfold.cxx:1825
 TUnfold.cxx:1826
 TUnfold.cxx:1827
 TUnfold.cxx:1828
 TUnfold.cxx:1829
 TUnfold.cxx:1830
 TUnfold.cxx:1831
 TUnfold.cxx:1832
 TUnfold.cxx:1833
 TUnfold.cxx:1834
 TUnfold.cxx:1835
 TUnfold.cxx:1836
 TUnfold.cxx:1837
 TUnfold.cxx:1838
 TUnfold.cxx:1839
 TUnfold.cxx:1840
 TUnfold.cxx:1841
 TUnfold.cxx:1842
 TUnfold.cxx:1843
 TUnfold.cxx:1844
 TUnfold.cxx:1845
 TUnfold.cxx:1846
 TUnfold.cxx:1847
 TUnfold.cxx:1848
 TUnfold.cxx:1849
 TUnfold.cxx:1850
 TUnfold.cxx:1851
 TUnfold.cxx:1852
 TUnfold.cxx:1853
 TUnfold.cxx:1854
 TUnfold.cxx:1855
 TUnfold.cxx:1856
 TUnfold.cxx:1857
 TUnfold.cxx:1858
 TUnfold.cxx:1859
 TUnfold.cxx:1860
 TUnfold.cxx:1861
 TUnfold.cxx:1862
 TUnfold.cxx:1863
 TUnfold.cxx:1864
 TUnfold.cxx:1865
 TUnfold.cxx:1866
 TUnfold.cxx:1867
 TUnfold.cxx:1868
 TUnfold.cxx:1869
 TUnfold.cxx:1870
 TUnfold.cxx:1871
 TUnfold.cxx:1872
 TUnfold.cxx:1873
 TUnfold.cxx:1874
 TUnfold.cxx:1875
 TUnfold.cxx:1876
 TUnfold.cxx:1877
 TUnfold.cxx:1878
 TUnfold.cxx:1879
 TUnfold.cxx:1880
 TUnfold.cxx:1881
 TUnfold.cxx:1882
 TUnfold.cxx:1883
 TUnfold.cxx:1884
 TUnfold.cxx:1885
 TUnfold.cxx:1886
 TUnfold.cxx:1887
 TUnfold.cxx:1888
 TUnfold.cxx:1889
 TUnfold.cxx:1890
 TUnfold.cxx:1891
 TUnfold.cxx:1892
 TUnfold.cxx:1893
 TUnfold.cxx:1894
 TUnfold.cxx:1895
 TUnfold.cxx:1896
 TUnfold.cxx:1897
 TUnfold.cxx:1898
 TUnfold.cxx:1899
 TUnfold.cxx:1900
 TUnfold.cxx:1901
 TUnfold.cxx:1902
 TUnfold.cxx:1903
 TUnfold.cxx:1904
 TUnfold.cxx:1905
 TUnfold.cxx:1906
 TUnfold.cxx:1907
 TUnfold.cxx:1908
 TUnfold.cxx:1909
 TUnfold.cxx:1910
 TUnfold.cxx:1911
 TUnfold.cxx:1912
 TUnfold.cxx:1913
 TUnfold.cxx:1914
 TUnfold.cxx:1915
 TUnfold.cxx:1916
 TUnfold.cxx:1917
 TUnfold.cxx:1918
 TUnfold.cxx:1919
 TUnfold.cxx:1920
 TUnfold.cxx:1921
 TUnfold.cxx:1922
 TUnfold.cxx:1923
 TUnfold.cxx:1924
 TUnfold.cxx:1925
 TUnfold.cxx:1926
 TUnfold.cxx:1927
 TUnfold.cxx:1928
 TUnfold.cxx:1929
 TUnfold.cxx:1930
 TUnfold.cxx:1931
 TUnfold.cxx:1932
 TUnfold.cxx:1933
 TUnfold.cxx:1934
 TUnfold.cxx:1935
 TUnfold.cxx:1936
 TUnfold.cxx:1937
 TUnfold.cxx:1938
 TUnfold.cxx:1939
 TUnfold.cxx:1940
 TUnfold.cxx:1941
 TUnfold.cxx:1942
 TUnfold.cxx:1943
 TUnfold.cxx:1944
 TUnfold.cxx:1945
 TUnfold.cxx:1946
 TUnfold.cxx:1947
 TUnfold.cxx:1948
 TUnfold.cxx:1949
 TUnfold.cxx:1950
 TUnfold.cxx:1951
 TUnfold.cxx:1952
 TUnfold.cxx:1953
 TUnfold.cxx:1954
 TUnfold.cxx:1955
 TUnfold.cxx:1956
 TUnfold.cxx:1957
 TUnfold.cxx:1958
 TUnfold.cxx:1959
 TUnfold.cxx:1960
 TUnfold.cxx:1961
 TUnfold.cxx:1962
 TUnfold.cxx:1963
 TUnfold.cxx:1964
 TUnfold.cxx:1965
 TUnfold.cxx:1966
 TUnfold.cxx:1967
 TUnfold.cxx:1968
 TUnfold.cxx:1969
 TUnfold.cxx:1970
 TUnfold.cxx:1971
 TUnfold.cxx:1972
 TUnfold.cxx:1973
 TUnfold.cxx:1974
 TUnfold.cxx:1975
 TUnfold.cxx:1976
 TUnfold.cxx:1977
 TUnfold.cxx:1978
 TUnfold.cxx:1979
 TUnfold.cxx:1980
 TUnfold.cxx:1981
 TUnfold.cxx:1982
 TUnfold.cxx:1983
 TUnfold.cxx:1984
 TUnfold.cxx:1985
 TUnfold.cxx:1986
 TUnfold.cxx:1987
 TUnfold.cxx:1988
 TUnfold.cxx:1989
 TUnfold.cxx:1990
 TUnfold.cxx:1991
 TUnfold.cxx:1992
 TUnfold.cxx:1993
 TUnfold.cxx:1994
 TUnfold.cxx:1995
 TUnfold.cxx:1996
 TUnfold.cxx:1997
 TUnfold.cxx:1998
 TUnfold.cxx:1999
 TUnfold.cxx:2000
 TUnfold.cxx:2001
 TUnfold.cxx:2002
 TUnfold.cxx:2003
 TUnfold.cxx:2004
 TUnfold.cxx:2005
 TUnfold.cxx:2006
 TUnfold.cxx:2007
 TUnfold.cxx:2008
 TUnfold.cxx:2009
 TUnfold.cxx:2010
 TUnfold.cxx:2011
 TUnfold.cxx:2012
 TUnfold.cxx:2013
 TUnfold.cxx:2014
 TUnfold.cxx:2015
 TUnfold.cxx:2016
 TUnfold.cxx:2017
 TUnfold.cxx:2018
 TUnfold.cxx:2019
 TUnfold.cxx:2020
 TUnfold.cxx:2021
 TUnfold.cxx:2022
 TUnfold.cxx:2023
 TUnfold.cxx:2024
 TUnfold.cxx:2025
 TUnfold.cxx:2026
 TUnfold.cxx:2027
 TUnfold.cxx:2028
 TUnfold.cxx:2029
 TUnfold.cxx:2030
 TUnfold.cxx:2031
 TUnfold.cxx:2032
 TUnfold.cxx:2033
 TUnfold.cxx:2034
 TUnfold.cxx:2035
 TUnfold.cxx:2036
 TUnfold.cxx:2037
 TUnfold.cxx:2038
 TUnfold.cxx:2039
 TUnfold.cxx:2040
 TUnfold.cxx:2041
 TUnfold.cxx:2042
 TUnfold.cxx:2043
 TUnfold.cxx:2044
 TUnfold.cxx:2045
 TUnfold.cxx:2046
 TUnfold.cxx:2047
 TUnfold.cxx:2048
 TUnfold.cxx:2049
 TUnfold.cxx:2050
 TUnfold.cxx:2051
 TUnfold.cxx:2052
 TUnfold.cxx:2053
 TUnfold.cxx:2054
 TUnfold.cxx:2055
 TUnfold.cxx:2056
 TUnfold.cxx:2057
 TUnfold.cxx:2058
 TUnfold.cxx:2059
 TUnfold.cxx:2060
 TUnfold.cxx:2061
 TUnfold.cxx:2062
 TUnfold.cxx:2063
 TUnfold.cxx:2064
 TUnfold.cxx:2065
 TUnfold.cxx:2066
 TUnfold.cxx:2067
 TUnfold.cxx:2068
 TUnfold.cxx:2069
 TUnfold.cxx:2070
 TUnfold.cxx:2071
 TUnfold.cxx:2072
 TUnfold.cxx:2073
 TUnfold.cxx:2074
 TUnfold.cxx:2075
 TUnfold.cxx:2076
 TUnfold.cxx:2077
 TUnfold.cxx:2078
 TUnfold.cxx:2079
 TUnfold.cxx:2080
 TUnfold.cxx:2081
 TUnfold.cxx:2082
 TUnfold.cxx:2083
 TUnfold.cxx:2084
 TUnfold.cxx:2085
 TUnfold.cxx:2086
 TUnfold.cxx:2087
 TUnfold.cxx:2088
 TUnfold.cxx:2089
 TUnfold.cxx:2090
 TUnfold.cxx:2091
 TUnfold.cxx:2092
 TUnfold.cxx:2093
 TUnfold.cxx:2094
 TUnfold.cxx:2095
 TUnfold.cxx:2096
 TUnfold.cxx:2097
 TUnfold.cxx:2098
 TUnfold.cxx:2099
 TUnfold.cxx:2100
 TUnfold.cxx:2101
 TUnfold.cxx:2102
 TUnfold.cxx:2103
 TUnfold.cxx:2104
 TUnfold.cxx:2105
 TUnfold.cxx:2106
 TUnfold.cxx:2107
 TUnfold.cxx:2108
 TUnfold.cxx:2109
 TUnfold.cxx:2110
 TUnfold.cxx:2111
 TUnfold.cxx:2112
 TUnfold.cxx:2113
 TUnfold.cxx:2114
 TUnfold.cxx:2115
 TUnfold.cxx:2116
 TUnfold.cxx:2117
 TUnfold.cxx:2118
 TUnfold.cxx:2119
 TUnfold.cxx:2120
 TUnfold.cxx:2121
 TUnfold.cxx:2122
 TUnfold.cxx:2123
 TUnfold.cxx:2124
 TUnfold.cxx:2125
 TUnfold.cxx:2126
 TUnfold.cxx:2127
 TUnfold.cxx:2128
 TUnfold.cxx:2129
 TUnfold.cxx:2130
 TUnfold.cxx:2131
 TUnfold.cxx:2132
 TUnfold.cxx:2133
 TUnfold.cxx:2134
 TUnfold.cxx:2135
 TUnfold.cxx:2136
 TUnfold.cxx:2137
 TUnfold.cxx:2138
 TUnfold.cxx:2139
 TUnfold.cxx:2140
 TUnfold.cxx:2141
 TUnfold.cxx:2142
 TUnfold.cxx:2143
 TUnfold.cxx:2144
 TUnfold.cxx:2145
 TUnfold.cxx:2146
 TUnfold.cxx:2147
 TUnfold.cxx:2148
 TUnfold.cxx:2149
 TUnfold.cxx:2150
 TUnfold.cxx:2151
 TUnfold.cxx:2152
 TUnfold.cxx:2153
 TUnfold.cxx:2154
 TUnfold.cxx:2155
 TUnfold.cxx:2156
 TUnfold.cxx:2157
 TUnfold.cxx:2158
 TUnfold.cxx:2159
 TUnfold.cxx:2160
 TUnfold.cxx:2161
 TUnfold.cxx:2162
 TUnfold.cxx:2163
 TUnfold.cxx:2164
 TUnfold.cxx:2165
 TUnfold.cxx:2166
 TUnfold.cxx:2167
 TUnfold.cxx:2168
 TUnfold.cxx:2169
 TUnfold.cxx:2170
 TUnfold.cxx:2171
 TUnfold.cxx:2172
 TUnfold.cxx:2173
 TUnfold.cxx:2174
 TUnfold.cxx:2175
 TUnfold.cxx:2176
 TUnfold.cxx:2177
 TUnfold.cxx:2178
 TUnfold.cxx:2179
 TUnfold.cxx:2180
 TUnfold.cxx:2181
 TUnfold.cxx:2182
 TUnfold.cxx:2183
 TUnfold.cxx:2184
 TUnfold.cxx:2185
 TUnfold.cxx:2186
 TUnfold.cxx:2187
 TUnfold.cxx:2188
 TUnfold.cxx:2189
 TUnfold.cxx:2190
 TUnfold.cxx:2191
 TUnfold.cxx:2192
 TUnfold.cxx:2193
 TUnfold.cxx:2194
 TUnfold.cxx:2195
 TUnfold.cxx:2196
 TUnfold.cxx:2197
 TUnfold.cxx:2198
 TUnfold.cxx:2199
 TUnfold.cxx:2200
 TUnfold.cxx:2201
 TUnfold.cxx:2202
 TUnfold.cxx:2203
 TUnfold.cxx:2204
 TUnfold.cxx:2205
 TUnfold.cxx:2206
 TUnfold.cxx:2207
 TUnfold.cxx:2208
 TUnfold.cxx:2209
 TUnfold.cxx:2210
 TUnfold.cxx:2211
 TUnfold.cxx:2212
 TUnfold.cxx:2213
 TUnfold.cxx:2214
 TUnfold.cxx:2215
 TUnfold.cxx:2216
 TUnfold.cxx:2217
 TUnfold.cxx:2218
 TUnfold.cxx:2219
 TUnfold.cxx:2220
 TUnfold.cxx:2221
 TUnfold.cxx:2222
 TUnfold.cxx:2223
 TUnfold.cxx:2224
 TUnfold.cxx:2225
 TUnfold.cxx:2226
 TUnfold.cxx:2227
 TUnfold.cxx:2228
 TUnfold.cxx:2229
 TUnfold.cxx:2230
 TUnfold.cxx:2231
 TUnfold.cxx:2232
 TUnfold.cxx:2233
 TUnfold.cxx:2234
 TUnfold.cxx:2235
 TUnfold.cxx:2236
 TUnfold.cxx:2237
 TUnfold.cxx:2238
 TUnfold.cxx:2239
 TUnfold.cxx:2240
 TUnfold.cxx:2241
 TUnfold.cxx:2242
 TUnfold.cxx:2243
 TUnfold.cxx:2244
 TUnfold.cxx:2245
 TUnfold.cxx:2246
 TUnfold.cxx:2247
 TUnfold.cxx:2248
 TUnfold.cxx:2249
 TUnfold.cxx:2250
 TUnfold.cxx:2251
 TUnfold.cxx:2252
 TUnfold.cxx:2253
 TUnfold.cxx:2254
 TUnfold.cxx:2255
 TUnfold.cxx:2256
 TUnfold.cxx:2257
 TUnfold.cxx:2258
 TUnfold.cxx:2259
 TUnfold.cxx:2260
 TUnfold.cxx:2261
 TUnfold.cxx:2262
 TUnfold.cxx:2263
 TUnfold.cxx:2264
 TUnfold.cxx:2265
 TUnfold.cxx:2266
 TUnfold.cxx:2267
 TUnfold.cxx:2268
 TUnfold.cxx:2269
 TUnfold.cxx:2270
 TUnfold.cxx:2271
 TUnfold.cxx:2272
 TUnfold.cxx:2273
 TUnfold.cxx:2274
 TUnfold.cxx:2275
 TUnfold.cxx:2276
 TUnfold.cxx:2277
 TUnfold.cxx:2278
 TUnfold.cxx:2279
 TUnfold.cxx:2280
 TUnfold.cxx:2281
 TUnfold.cxx:2282
 TUnfold.cxx:2283
 TUnfold.cxx:2284
 TUnfold.cxx:2285
 TUnfold.cxx:2286
 TUnfold.cxx:2287
 TUnfold.cxx:2288
 TUnfold.cxx:2289
 TUnfold.cxx:2290
 TUnfold.cxx:2291
 TUnfold.cxx:2292
 TUnfold.cxx:2293
 TUnfold.cxx:2294
 TUnfold.cxx:2295
 TUnfold.cxx:2296
 TUnfold.cxx:2297
 TUnfold.cxx:2298
 TUnfold.cxx:2299
 TUnfold.cxx:2300
 TUnfold.cxx:2301
 TUnfold.cxx:2302
 TUnfold.cxx:2303
 TUnfold.cxx:2304
 TUnfold.cxx:2305
 TUnfold.cxx:2306
 TUnfold.cxx:2307
 TUnfold.cxx:2308
 TUnfold.cxx:2309
 TUnfold.cxx:2310
 TUnfold.cxx:2311
 TUnfold.cxx:2312
 TUnfold.cxx:2313
 TUnfold.cxx:2314
 TUnfold.cxx:2315
 TUnfold.cxx:2316
 TUnfold.cxx:2317
 TUnfold.cxx:2318
 TUnfold.cxx:2319
 TUnfold.cxx:2320
 TUnfold.cxx:2321
 TUnfold.cxx:2322
 TUnfold.cxx:2323
 TUnfold.cxx:2324
 TUnfold.cxx:2325
 TUnfold.cxx:2326
 TUnfold.cxx:2327
 TUnfold.cxx:2328
 TUnfold.cxx:2329
 TUnfold.cxx:2330
 TUnfold.cxx:2331
 TUnfold.cxx:2332
 TUnfold.cxx:2333
 TUnfold.cxx:2334
 TUnfold.cxx:2335
 TUnfold.cxx:2336
 TUnfold.cxx:2337
 TUnfold.cxx:2338
 TUnfold.cxx:2339
 TUnfold.cxx:2340
 TUnfold.cxx:2341
 TUnfold.cxx:2342
 TUnfold.cxx:2343
 TUnfold.cxx:2344
 TUnfold.cxx:2345
 TUnfold.cxx:2346
 TUnfold.cxx:2347
 TUnfold.cxx:2348
 TUnfold.cxx:2349
 TUnfold.cxx:2350
 TUnfold.cxx:2351
 TUnfold.cxx:2352
 TUnfold.cxx:2353
 TUnfold.cxx:2354
 TUnfold.cxx:2355
 TUnfold.cxx:2356
 TUnfold.cxx:2357
 TUnfold.cxx:2358
 TUnfold.cxx:2359
 TUnfold.cxx:2360
 TUnfold.cxx:2361
 TUnfold.cxx:2362
 TUnfold.cxx:2363
 TUnfold.cxx:2364
 TUnfold.cxx:2365
 TUnfold.cxx:2366
 TUnfold.cxx:2367
 TUnfold.cxx:2368
 TUnfold.cxx:2369
 TUnfold.cxx:2370
 TUnfold.cxx:2371
 TUnfold.cxx:2372
 TUnfold.cxx:2373
 TUnfold.cxx:2374
 TUnfold.cxx:2375
 TUnfold.cxx:2376
 TUnfold.cxx:2377
 TUnfold.cxx:2378
 TUnfold.cxx:2379
 TUnfold.cxx:2380
 TUnfold.cxx:2381
 TUnfold.cxx:2382
 TUnfold.cxx:2383
 TUnfold.cxx:2384
 TUnfold.cxx:2385
 TUnfold.cxx:2386
 TUnfold.cxx:2387
 TUnfold.cxx:2388
 TUnfold.cxx:2389
 TUnfold.cxx:2390
 TUnfold.cxx:2391
 TUnfold.cxx:2392
 TUnfold.cxx:2393
 TUnfold.cxx:2394
 TUnfold.cxx:2395
 TUnfold.cxx:2396
 TUnfold.cxx:2397
 TUnfold.cxx:2398
 TUnfold.cxx:2399
 TUnfold.cxx:2400
 TUnfold.cxx:2401
 TUnfold.cxx:2402
 TUnfold.cxx:2403
 TUnfold.cxx:2404
 TUnfold.cxx:2405
 TUnfold.cxx:2406
 TUnfold.cxx:2407
 TUnfold.cxx:2408
 TUnfold.cxx:2409
 TUnfold.cxx:2410
 TUnfold.cxx:2411
 TUnfold.cxx:2412
 TUnfold.cxx:2413
 TUnfold.cxx:2414
 TUnfold.cxx:2415
 TUnfold.cxx:2416
 TUnfold.cxx:2417
 TUnfold.cxx:2418
 TUnfold.cxx:2419
 TUnfold.cxx:2420
 TUnfold.cxx:2421
 TUnfold.cxx:2422
 TUnfold.cxx:2423
 TUnfold.cxx:2424
 TUnfold.cxx:2425
 TUnfold.cxx:2426
 TUnfold.cxx:2427
 TUnfold.cxx:2428
 TUnfold.cxx:2429
 TUnfold.cxx:2430
 TUnfold.cxx:2431
 TUnfold.cxx:2432
 TUnfold.cxx:2433
 TUnfold.cxx:2434
 TUnfold.cxx:2435
 TUnfold.cxx:2436
 TUnfold.cxx:2437
 TUnfold.cxx:2438
 TUnfold.cxx:2439
 TUnfold.cxx:2440
 TUnfold.cxx:2441
 TUnfold.cxx:2442
 TUnfold.cxx:2443
 TUnfold.cxx:2444
 TUnfold.cxx:2445
 TUnfold.cxx:2446
 TUnfold.cxx:2447
 TUnfold.cxx:2448
 TUnfold.cxx:2449
 TUnfold.cxx:2450
 TUnfold.cxx:2451
 TUnfold.cxx:2452
 TUnfold.cxx:2453
 TUnfold.cxx:2454
 TUnfold.cxx:2455
 TUnfold.cxx:2456
 TUnfold.cxx:2457
 TUnfold.cxx:2458
 TUnfold.cxx:2459
 TUnfold.cxx:2460
 TUnfold.cxx:2461
 TUnfold.cxx:2462
 TUnfold.cxx:2463
 TUnfold.cxx:2464
 TUnfold.cxx:2465
 TUnfold.cxx:2466
 TUnfold.cxx:2467
 TUnfold.cxx:2468
 TUnfold.cxx:2469
 TUnfold.cxx:2470
 TUnfold.cxx:2471
 TUnfold.cxx:2472
 TUnfold.cxx:2473
 TUnfold.cxx:2474
 TUnfold.cxx:2475
 TUnfold.cxx:2476
 TUnfold.cxx:2477
 TUnfold.cxx:2478
 TUnfold.cxx:2479
 TUnfold.cxx:2480
 TUnfold.cxx:2481
 TUnfold.cxx:2482
 TUnfold.cxx:2483
 TUnfold.cxx:2484
 TUnfold.cxx:2485
 TUnfold.cxx:2486
 TUnfold.cxx:2487
 TUnfold.cxx:2488
 TUnfold.cxx:2489
 TUnfold.cxx:2490
 TUnfold.cxx:2491
 TUnfold.cxx:2492
 TUnfold.cxx:2493
 TUnfold.cxx:2494
 TUnfold.cxx:2495
 TUnfold.cxx:2496
 TUnfold.cxx:2497
 TUnfold.cxx:2498
 TUnfold.cxx:2499
 TUnfold.cxx:2500
 TUnfold.cxx:2501
 TUnfold.cxx:2502
 TUnfold.cxx:2503
 TUnfold.cxx:2504
 TUnfold.cxx:2505
 TUnfold.cxx:2506
 TUnfold.cxx:2507
 TUnfold.cxx:2508
 TUnfold.cxx:2509
 TUnfold.cxx:2510
 TUnfold.cxx:2511
 TUnfold.cxx:2512
 TUnfold.cxx:2513
 TUnfold.cxx:2514
 TUnfold.cxx:2515
 TUnfold.cxx:2516
 TUnfold.cxx:2517
 TUnfold.cxx:2518
 TUnfold.cxx:2519
 TUnfold.cxx:2520
 TUnfold.cxx:2521
 TUnfold.cxx:2522
 TUnfold.cxx:2523
 TUnfold.cxx:2524
 TUnfold.cxx:2525
 TUnfold.cxx:2526
 TUnfold.cxx:2527
 TUnfold.cxx:2528
 TUnfold.cxx:2529
 TUnfold.cxx:2530
 TUnfold.cxx:2531
 TUnfold.cxx:2532
 TUnfold.cxx:2533
 TUnfold.cxx:2534
 TUnfold.cxx:2535
 TUnfold.cxx:2536
 TUnfold.cxx:2537
 TUnfold.cxx:2538
 TUnfold.cxx:2539
 TUnfold.cxx:2540
 TUnfold.cxx:2541
 TUnfold.cxx:2542
 TUnfold.cxx:2543
 TUnfold.cxx:2544
 TUnfold.cxx:2545
 TUnfold.cxx:2546
 TUnfold.cxx:2547
 TUnfold.cxx:2548
 TUnfold.cxx:2549
 TUnfold.cxx:2550
 TUnfold.cxx:2551
 TUnfold.cxx:2552
 TUnfold.cxx:2553
 TUnfold.cxx:2554
 TUnfold.cxx:2555
 TUnfold.cxx:2556
 TUnfold.cxx:2557
 TUnfold.cxx:2558
 TUnfold.cxx:2559
 TUnfold.cxx:2560
 TUnfold.cxx:2561
 TUnfold.cxx:2562
 TUnfold.cxx:2563
 TUnfold.cxx:2564
 TUnfold.cxx:2565
 TUnfold.cxx:2566
 TUnfold.cxx:2567
 TUnfold.cxx:2568
 TUnfold.cxx:2569
 TUnfold.cxx:2570
 TUnfold.cxx:2571
 TUnfold.cxx:2572
 TUnfold.cxx:2573
 TUnfold.cxx:2574
 TUnfold.cxx:2575
 TUnfold.cxx:2576
 TUnfold.cxx:2577
 TUnfold.cxx:2578
 TUnfold.cxx:2579
 TUnfold.cxx:2580
 TUnfold.cxx:2581
 TUnfold.cxx:2582
 TUnfold.cxx:2583
 TUnfold.cxx:2584
 TUnfold.cxx:2585
 TUnfold.cxx:2586
 TUnfold.cxx:2587
 TUnfold.cxx:2588
 TUnfold.cxx:2589
 TUnfold.cxx:2590
 TUnfold.cxx:2591
 TUnfold.cxx:2592
 TUnfold.cxx:2593
 TUnfold.cxx:2594
 TUnfold.cxx:2595
 TUnfold.cxx:2596
 TUnfold.cxx:2597
 TUnfold.cxx:2598
 TUnfold.cxx:2599
 TUnfold.cxx:2600
 TUnfold.cxx:2601
 TUnfold.cxx:2602
 TUnfold.cxx:2603
 TUnfold.cxx:2604
 TUnfold.cxx:2605
 TUnfold.cxx:2606
 TUnfold.cxx:2607
 TUnfold.cxx:2608
 TUnfold.cxx:2609
 TUnfold.cxx:2610
 TUnfold.cxx:2611
 TUnfold.cxx:2612
 TUnfold.cxx:2613
 TUnfold.cxx:2614
 TUnfold.cxx:2615
 TUnfold.cxx:2616
 TUnfold.cxx:2617
 TUnfold.cxx:2618
 TUnfold.cxx:2619
 TUnfold.cxx:2620
 TUnfold.cxx:2621
 TUnfold.cxx:2622
 TUnfold.cxx:2623
 TUnfold.cxx:2624
 TUnfold.cxx:2625
 TUnfold.cxx:2626
 TUnfold.cxx:2627
 TUnfold.cxx:2628
 TUnfold.cxx:2629
 TUnfold.cxx:2630
 TUnfold.cxx:2631
 TUnfold.cxx:2632
 TUnfold.cxx:2633
 TUnfold.cxx:2634
 TUnfold.cxx:2635
 TUnfold.cxx:2636
 TUnfold.cxx:2637
 TUnfold.cxx:2638
 TUnfold.cxx:2639
 TUnfold.cxx:2640
 TUnfold.cxx:2641
 TUnfold.cxx:2642
 TUnfold.cxx:2643
 TUnfold.cxx:2644
 TUnfold.cxx:2645
 TUnfold.cxx:2646
 TUnfold.cxx:2647
 TUnfold.cxx:2648
 TUnfold.cxx:2649
 TUnfold.cxx:2650
 TUnfold.cxx:2651
 TUnfold.cxx:2652
 TUnfold.cxx:2653
 TUnfold.cxx:2654
 TUnfold.cxx:2655
 TUnfold.cxx:2656
 TUnfold.cxx:2657
 TUnfold.cxx:2658
 TUnfold.cxx:2659
 TUnfold.cxx:2660
 TUnfold.cxx:2661
 TUnfold.cxx:2662
 TUnfold.cxx:2663
 TUnfold.cxx:2664
 TUnfold.cxx:2665
 TUnfold.cxx:2666
 TUnfold.cxx:2667
 TUnfold.cxx:2668
 TUnfold.cxx:2669
 TUnfold.cxx:2670
 TUnfold.cxx:2671
 TUnfold.cxx:2672
 TUnfold.cxx:2673
 TUnfold.cxx:2674
 TUnfold.cxx:2675
 TUnfold.cxx:2676
 TUnfold.cxx:2677
 TUnfold.cxx:2678
 TUnfold.cxx:2679
 TUnfold.cxx:2680
 TUnfold.cxx:2681
 TUnfold.cxx:2682
 TUnfold.cxx:2683
 TUnfold.cxx:2684
 TUnfold.cxx:2685
 TUnfold.cxx:2686
 TUnfold.cxx:2687
 TUnfold.cxx:2688
 TUnfold.cxx:2689
 TUnfold.cxx:2690
 TUnfold.cxx:2691
 TUnfold.cxx:2692
 TUnfold.cxx:2693
 TUnfold.cxx:2694
 TUnfold.cxx:2695
 TUnfold.cxx:2696
 TUnfold.cxx:2697
 TUnfold.cxx:2698
 TUnfold.cxx:2699
 TUnfold.cxx:2700
 TUnfold.cxx:2701
 TUnfold.cxx:2702
 TUnfold.cxx:2703
 TUnfold.cxx:2704
 TUnfold.cxx:2705
 TUnfold.cxx:2706
 TUnfold.cxx:2707
 TUnfold.cxx:2708
 TUnfold.cxx:2709
 TUnfold.cxx:2710
 TUnfold.cxx:2711
 TUnfold.cxx:2712
 TUnfold.cxx:2713
 TUnfold.cxx:2714
 TUnfold.cxx:2715
 TUnfold.cxx:2716
 TUnfold.cxx:2717
 TUnfold.cxx:2718
 TUnfold.cxx:2719
 TUnfold.cxx:2720
 TUnfold.cxx:2721
 TUnfold.cxx:2722
 TUnfold.cxx:2723
 TUnfold.cxx:2724
 TUnfold.cxx:2725
 TUnfold.cxx:2726
 TUnfold.cxx:2727
 TUnfold.cxx:2728
 TUnfold.cxx:2729
 TUnfold.cxx:2730
 TUnfold.cxx:2731
 TUnfold.cxx:2732
 TUnfold.cxx:2733
 TUnfold.cxx:2734
 TUnfold.cxx:2735
 TUnfold.cxx:2736
 TUnfold.cxx:2737
 TUnfold.cxx:2738
 TUnfold.cxx:2739
 TUnfold.cxx:2740
 TUnfold.cxx:2741
 TUnfold.cxx:2742
 TUnfold.cxx:2743
 TUnfold.cxx:2744
 TUnfold.cxx:2745
 TUnfold.cxx:2746
 TUnfold.cxx:2747
 TUnfold.cxx:2748
 TUnfold.cxx:2749
 TUnfold.cxx:2750
 TUnfold.cxx:2751
 TUnfold.cxx:2752
 TUnfold.cxx:2753
 TUnfold.cxx:2754
 TUnfold.cxx:2755
 TUnfold.cxx:2756
 TUnfold.cxx:2757
 TUnfold.cxx:2758
 TUnfold.cxx:2759
 TUnfold.cxx:2760
 TUnfold.cxx:2761
 TUnfold.cxx:2762
 TUnfold.cxx:2763
 TUnfold.cxx:2764
 TUnfold.cxx:2765
 TUnfold.cxx:2766
 TUnfold.cxx:2767
 TUnfold.cxx:2768
 TUnfold.cxx:2769
 TUnfold.cxx:2770
 TUnfold.cxx:2771
 TUnfold.cxx:2772
 TUnfold.cxx:2773
 TUnfold.cxx:2774
 TUnfold.cxx:2775
 TUnfold.cxx:2776
 TUnfold.cxx:2777
 TUnfold.cxx:2778
 TUnfold.cxx:2779
 TUnfold.cxx:2780
 TUnfold.cxx:2781
 TUnfold.cxx:2782
 TUnfold.cxx:2783
 TUnfold.cxx:2784
 TUnfold.cxx:2785
 TUnfold.cxx:2786
 TUnfold.cxx:2787
 TUnfold.cxx:2788
 TUnfold.cxx:2789
 TUnfold.cxx:2790
 TUnfold.cxx:2791
 TUnfold.cxx:2792
 TUnfold.cxx:2793
 TUnfold.cxx:2794
 TUnfold.cxx:2795
 TUnfold.cxx:2796
 TUnfold.cxx:2797
 TUnfold.cxx:2798
 TUnfold.cxx:2799
 TUnfold.cxx:2800
 TUnfold.cxx:2801
 TUnfold.cxx:2802
 TUnfold.cxx:2803
 TUnfold.cxx:2804
 TUnfold.cxx:2805
 TUnfold.cxx:2806
 TUnfold.cxx:2807
 TUnfold.cxx:2808
 TUnfold.cxx:2809
 TUnfold.cxx:2810
 TUnfold.cxx:2811
 TUnfold.cxx:2812
 TUnfold.cxx:2813
 TUnfold.cxx:2814
 TUnfold.cxx:2815
 TUnfold.cxx:2816
 TUnfold.cxx:2817
 TUnfold.cxx:2818
 TUnfold.cxx:2819
 TUnfold.cxx:2820
 TUnfold.cxx:2821
 TUnfold.cxx:2822
 TUnfold.cxx:2823
 TUnfold.cxx:2824
 TUnfold.cxx:2825
 TUnfold.cxx:2826
 TUnfold.cxx:2827
 TUnfold.cxx:2828
 TUnfold.cxx:2829
 TUnfold.cxx:2830
 TUnfold.cxx:2831
 TUnfold.cxx:2832
 TUnfold.cxx:2833
 TUnfold.cxx:2834
 TUnfold.cxx:2835
 TUnfold.cxx:2836
 TUnfold.cxx:2837
 TUnfold.cxx:2838
 TUnfold.cxx:2839
 TUnfold.cxx:2840
 TUnfold.cxx:2841
 TUnfold.cxx:2842
 TUnfold.cxx:2843
 TUnfold.cxx:2844
 TUnfold.cxx:2845
 TUnfold.cxx:2846
 TUnfold.cxx:2847
 TUnfold.cxx:2848
 TUnfold.cxx:2849
 TUnfold.cxx:2850
 TUnfold.cxx:2851
 TUnfold.cxx:2852
 TUnfold.cxx:2853
 TUnfold.cxx:2854
 TUnfold.cxx:2855
 TUnfold.cxx:2856
 TUnfold.cxx:2857
 TUnfold.cxx:2858
 TUnfold.cxx:2859
 TUnfold.cxx:2860
 TUnfold.cxx:2861
 TUnfold.cxx:2862
 TUnfold.cxx:2863
 TUnfold.cxx:2864
 TUnfold.cxx:2865
 TUnfold.cxx:2866
 TUnfold.cxx:2867
 TUnfold.cxx:2868
 TUnfold.cxx:2869
 TUnfold.cxx:2870
 TUnfold.cxx:2871
 TUnfold.cxx:2872
 TUnfold.cxx:2873
 TUnfold.cxx:2874
 TUnfold.cxx:2875
 TUnfold.cxx:2876
 TUnfold.cxx:2877
 TUnfold.cxx:2878
 TUnfold.cxx:2879
 TUnfold.cxx:2880
 TUnfold.cxx:2881
 TUnfold.cxx:2882
 TUnfold.cxx:2883
 TUnfold.cxx:2884
 TUnfold.cxx:2885
 TUnfold.cxx:2886
 TUnfold.cxx:2887
 TUnfold.cxx:2888
 TUnfold.cxx:2889
 TUnfold.cxx:2890
 TUnfold.cxx:2891
 TUnfold.cxx:2892
 TUnfold.cxx:2893
 TUnfold.cxx:2894
 TUnfold.cxx:2895
 TUnfold.cxx:2896
 TUnfold.cxx:2897
 TUnfold.cxx:2898
 TUnfold.cxx:2899
 TUnfold.cxx:2900
 TUnfold.cxx:2901
 TUnfold.cxx:2902
 TUnfold.cxx:2903
 TUnfold.cxx:2904
 TUnfold.cxx:2905
 TUnfold.cxx:2906
 TUnfold.cxx:2907
 TUnfold.cxx:2908
 TUnfold.cxx:2909
 TUnfold.cxx:2910
 TUnfold.cxx:2911
 TUnfold.cxx:2912
 TUnfold.cxx:2913
 TUnfold.cxx:2914
 TUnfold.cxx:2915
 TUnfold.cxx:2916
 TUnfold.cxx:2917
 TUnfold.cxx:2918
 TUnfold.cxx:2919
 TUnfold.cxx:2920
 TUnfold.cxx:2921
 TUnfold.cxx:2922
 TUnfold.cxx:2923
 TUnfold.cxx:2924
 TUnfold.cxx:2925
 TUnfold.cxx:2926
 TUnfold.cxx:2927
 TUnfold.cxx:2928
 TUnfold.cxx:2929
 TUnfold.cxx:2930
 TUnfold.cxx:2931
 TUnfold.cxx:2932
 TUnfold.cxx:2933
 TUnfold.cxx:2934
 TUnfold.cxx:2935
 TUnfold.cxx:2936
 TUnfold.cxx:2937
 TUnfold.cxx:2938
 TUnfold.cxx:2939
 TUnfold.cxx:2940
 TUnfold.cxx:2941
 TUnfold.cxx:2942
 TUnfold.cxx:2943
 TUnfold.cxx:2944
 TUnfold.cxx:2945
 TUnfold.cxx:2946
 TUnfold.cxx:2947
 TUnfold.cxx:2948
 TUnfold.cxx:2949
 TUnfold.cxx:2950
 TUnfold.cxx:2951
 TUnfold.cxx:2952
 TUnfold.cxx:2953
 TUnfold.cxx:2954
 TUnfold.cxx:2955
 TUnfold.cxx:2956
 TUnfold.cxx:2957
 TUnfold.cxx:2958
 TUnfold.cxx:2959
 TUnfold.cxx:2960
 TUnfold.cxx:2961
 TUnfold.cxx:2962
 TUnfold.cxx:2963
 TUnfold.cxx:2964
 TUnfold.cxx:2965
 TUnfold.cxx:2966
 TUnfold.cxx:2967
 TUnfold.cxx:2968
 TUnfold.cxx:2969
 TUnfold.cxx:2970
 TUnfold.cxx:2971
 TUnfold.cxx:2972
 TUnfold.cxx:2973
 TUnfold.cxx:2974
 TUnfold.cxx:2975
 TUnfold.cxx:2976
 TUnfold.cxx:2977
 TUnfold.cxx:2978
 TUnfold.cxx:2979
 TUnfold.cxx:2980
 TUnfold.cxx:2981
 TUnfold.cxx:2982
 TUnfold.cxx:2983
 TUnfold.cxx:2984
 TUnfold.cxx:2985
 TUnfold.cxx:2986
 TUnfold.cxx:2987
 TUnfold.cxx:2988
 TUnfold.cxx:2989
 TUnfold.cxx:2990
 TUnfold.cxx:2991
 TUnfold.cxx:2992
 TUnfold.cxx:2993
 TUnfold.cxx:2994
 TUnfold.cxx:2995
 TUnfold.cxx:2996
 TUnfold.cxx:2997
 TUnfold.cxx:2998
 TUnfold.cxx:2999
 TUnfold.cxx:3000
 TUnfold.cxx:3001
 TUnfold.cxx:3002
 TUnfold.cxx:3003
 TUnfold.cxx:3004
 TUnfold.cxx:3005
 TUnfold.cxx:3006
 TUnfold.cxx:3007
 TUnfold.cxx:3008
 TUnfold.cxx:3009
 TUnfold.cxx:3010
 TUnfold.cxx:3011
 TUnfold.cxx:3012
 TUnfold.cxx:3013
 TUnfold.cxx:3014
 TUnfold.cxx:3015
 TUnfold.cxx:3016
 TUnfold.cxx:3017
 TUnfold.cxx:3018
 TUnfold.cxx:3019
 TUnfold.cxx:3020
 TUnfold.cxx:3021
 TUnfold.cxx:3022
 TUnfold.cxx:3023
 TUnfold.cxx:3024
 TUnfold.cxx:3025
 TUnfold.cxx:3026
 TUnfold.cxx:3027
 TUnfold.cxx:3028
 TUnfold.cxx:3029
 TUnfold.cxx:3030
 TUnfold.cxx:3031
 TUnfold.cxx:3032
 TUnfold.cxx:3033
 TUnfold.cxx:3034
 TUnfold.cxx:3035
 TUnfold.cxx:3036
 TUnfold.cxx:3037
 TUnfold.cxx:3038
 TUnfold.cxx:3039
 TUnfold.cxx:3040
 TUnfold.cxx:3041
 TUnfold.cxx:3042
 TUnfold.cxx:3043
 TUnfold.cxx:3044
 TUnfold.cxx:3045
 TUnfold.cxx:3046
 TUnfold.cxx:3047
 TUnfold.cxx:3048
 TUnfold.cxx:3049
 TUnfold.cxx:3050
 TUnfold.cxx:3051
 TUnfold.cxx:3052
 TUnfold.cxx:3053
 TUnfold.cxx:3054
 TUnfold.cxx:3055
 TUnfold.cxx:3056
 TUnfold.cxx:3057
 TUnfold.cxx:3058
 TUnfold.cxx:3059
 TUnfold.cxx:3060
 TUnfold.cxx:3061
 TUnfold.cxx:3062
 TUnfold.cxx:3063
 TUnfold.cxx:3064
 TUnfold.cxx:3065
 TUnfold.cxx:3066
 TUnfold.cxx:3067
 TUnfold.cxx:3068
 TUnfold.cxx:3069
 TUnfold.cxx:3070
 TUnfold.cxx:3071
 TUnfold.cxx:3072
 TUnfold.cxx:3073
 TUnfold.cxx:3074
 TUnfold.cxx:3075
 TUnfold.cxx:3076
 TUnfold.cxx:3077
 TUnfold.cxx:3078
 TUnfold.cxx:3079
 TUnfold.cxx:3080
 TUnfold.cxx:3081
 TUnfold.cxx:3082
 TUnfold.cxx:3083
 TUnfold.cxx:3084
 TUnfold.cxx:3085
 TUnfold.cxx:3086
 TUnfold.cxx:3087
 TUnfold.cxx:3088
 TUnfold.cxx:3089
 TUnfold.cxx:3090
 TUnfold.cxx:3091
 TUnfold.cxx:3092
 TUnfold.cxx:3093
 TUnfold.cxx:3094
 TUnfold.cxx:3095
 TUnfold.cxx:3096
 TUnfold.cxx:3097
 TUnfold.cxx:3098
 TUnfold.cxx:3099
 TUnfold.cxx:3100
 TUnfold.cxx:3101
 TUnfold.cxx:3102
 TUnfold.cxx:3103
 TUnfold.cxx:3104
 TUnfold.cxx:3105
 TUnfold.cxx:3106
 TUnfold.cxx:3107
 TUnfold.cxx:3108
 TUnfold.cxx:3109
 TUnfold.cxx:3110
 TUnfold.cxx:3111
 TUnfold.cxx:3112
 TUnfold.cxx:3113
 TUnfold.cxx:3114
 TUnfold.cxx:3115
 TUnfold.cxx:3116
 TUnfold.cxx:3117
 TUnfold.cxx:3118
 TUnfold.cxx:3119
 TUnfold.cxx:3120
 TUnfold.cxx:3121
 TUnfold.cxx:3122
 TUnfold.cxx:3123
 TUnfold.cxx:3124
 TUnfold.cxx:3125
 TUnfold.cxx:3126
 TUnfold.cxx:3127
 TUnfold.cxx:3128
 TUnfold.cxx:3129
 TUnfold.cxx:3130
 TUnfold.cxx:3131
 TUnfold.cxx:3132
 TUnfold.cxx:3133
 TUnfold.cxx:3134
 TUnfold.cxx:3135
 TUnfold.cxx:3136
 TUnfold.cxx:3137
 TUnfold.cxx:3138
 TUnfold.cxx:3139
 TUnfold.cxx:3140
 TUnfold.cxx:3141
 TUnfold.cxx:3142
 TUnfold.cxx:3143
 TUnfold.cxx:3144
 TUnfold.cxx:3145
 TUnfold.cxx:3146
 TUnfold.cxx:3147
 TUnfold.cxx:3148
 TUnfold.cxx:3149
 TUnfold.cxx:3150
 TUnfold.cxx:3151
 TUnfold.cxx:3152
 TUnfold.cxx:3153
 TUnfold.cxx:3154
 TUnfold.cxx:3155
 TUnfold.cxx:3156
 TUnfold.cxx:3157
 TUnfold.cxx:3158
 TUnfold.cxx:3159
 TUnfold.cxx:3160
 TUnfold.cxx:3161
 TUnfold.cxx:3162
 TUnfold.cxx:3163
 TUnfold.cxx:3164
 TUnfold.cxx:3165
 TUnfold.cxx:3166
 TUnfold.cxx:3167
 TUnfold.cxx:3168
 TUnfold.cxx:3169
 TUnfold.cxx:3170
 TUnfold.cxx:3171
 TUnfold.cxx:3172
 TUnfold.cxx:3173
 TUnfold.cxx:3174
 TUnfold.cxx:3175
 TUnfold.cxx:3176
 TUnfold.cxx:3177
 TUnfold.cxx:3178
 TUnfold.cxx:3179
 TUnfold.cxx:3180
 TUnfold.cxx:3181
 TUnfold.cxx:3182
 TUnfold.cxx:3183
 TUnfold.cxx:3184
 TUnfold.cxx:3185
 TUnfold.cxx:3186
 TUnfold.cxx:3187
 TUnfold.cxx:3188
 TUnfold.cxx:3189
 TUnfold.cxx:3190
 TUnfold.cxx:3191
 TUnfold.cxx:3192
 TUnfold.cxx:3193
 TUnfold.cxx:3194
 TUnfold.cxx:3195
 TUnfold.cxx:3196
 TUnfold.cxx:3197
 TUnfold.cxx:3198
 TUnfold.cxx:3199
 TUnfold.cxx:3200
 TUnfold.cxx:3201
 TUnfold.cxx:3202
 TUnfold.cxx:3203
 TUnfold.cxx:3204
 TUnfold.cxx:3205
 TUnfold.cxx:3206
 TUnfold.cxx:3207
 TUnfold.cxx:3208
 TUnfold.cxx:3209
 TUnfold.cxx:3210
 TUnfold.cxx:3211
 TUnfold.cxx:3212
 TUnfold.cxx:3213
 TUnfold.cxx:3214
 TUnfold.cxx:3215
 TUnfold.cxx:3216
 TUnfold.cxx:3217
 TUnfold.cxx:3218
 TUnfold.cxx:3219
 TUnfold.cxx:3220
 TUnfold.cxx:3221
 TUnfold.cxx:3222
 TUnfold.cxx:3223
 TUnfold.cxx:3224
 TUnfold.cxx:3225
 TUnfold.cxx:3226
 TUnfold.cxx:3227
 TUnfold.cxx:3228
 TUnfold.cxx:3229
 TUnfold.cxx:3230
 TUnfold.cxx:3231
 TUnfold.cxx:3232
 TUnfold.cxx:3233
 TUnfold.cxx:3234
 TUnfold.cxx:3235
 TUnfold.cxx:3236
 TUnfold.cxx:3237
 TUnfold.cxx:3238
 TUnfold.cxx:3239
 TUnfold.cxx:3240
 TUnfold.cxx:3241
 TUnfold.cxx:3242
 TUnfold.cxx:3243
 TUnfold.cxx:3244
 TUnfold.cxx:3245
 TUnfold.cxx:3246
 TUnfold.cxx:3247
 TUnfold.cxx:3248
 TUnfold.cxx:3249
 TUnfold.cxx:3250
 TUnfold.cxx:3251
 TUnfold.cxx:3252
 TUnfold.cxx:3253
 TUnfold.cxx:3254
 TUnfold.cxx:3255
 TUnfold.cxx:3256
 TUnfold.cxx:3257
 TUnfold.cxx:3258
 TUnfold.cxx:3259
 TUnfold.cxx:3260
 TUnfold.cxx:3261
 TUnfold.cxx:3262
 TUnfold.cxx:3263
 TUnfold.cxx:3264
 TUnfold.cxx:3265
 TUnfold.cxx:3266
 TUnfold.cxx:3267
 TUnfold.cxx:3268
 TUnfold.cxx:3269
 TUnfold.cxx:3270
 TUnfold.cxx:3271
 TUnfold.cxx:3272
 TUnfold.cxx:3273
 TUnfold.cxx:3274
 TUnfold.cxx:3275
 TUnfold.cxx:3276
 TUnfold.cxx:3277
 TUnfold.cxx:3278
 TUnfold.cxx:3279
 TUnfold.cxx:3280
 TUnfold.cxx:3281
 TUnfold.cxx:3282
 TUnfold.cxx:3283
 TUnfold.cxx:3284
 TUnfold.cxx:3285
 TUnfold.cxx:3286
 TUnfold.cxx:3287
 TUnfold.cxx:3288
 TUnfold.cxx:3289
 TUnfold.cxx:3290
 TUnfold.cxx:3291
 TUnfold.cxx:3292
 TUnfold.cxx:3293
 TUnfold.cxx:3294
 TUnfold.cxx:3295
 TUnfold.cxx:3296
 TUnfold.cxx:3297
 TUnfold.cxx:3298
 TUnfold.cxx:3299
 TUnfold.cxx:3300
 TUnfold.cxx:3301
 TUnfold.cxx:3302
 TUnfold.cxx:3303
 TUnfold.cxx:3304
 TUnfold.cxx:3305
 TUnfold.cxx:3306
 TUnfold.cxx:3307
 TUnfold.cxx:3308
 TUnfold.cxx:3309
 TUnfold.cxx:3310
 TUnfold.cxx:3311
 TUnfold.cxx:3312
 TUnfold.cxx:3313
 TUnfold.cxx:3314
 TUnfold.cxx:3315
 TUnfold.cxx:3316
 TUnfold.cxx:3317
 TUnfold.cxx:3318
 TUnfold.cxx:3319
 TUnfold.cxx:3320
 TUnfold.cxx:3321
 TUnfold.cxx:3322
 TUnfold.cxx:3323
 TUnfold.cxx:3324
 TUnfold.cxx:3325
 TUnfold.cxx:3326
 TUnfold.cxx:3327
 TUnfold.cxx:3328
 TUnfold.cxx:3329
 TUnfold.cxx:3330
 TUnfold.cxx:3331
 TUnfold.cxx:3332
 TUnfold.cxx:3333
 TUnfold.cxx:3334
 TUnfold.cxx:3335
 TUnfold.cxx:3336
 TUnfold.cxx:3337
 TUnfold.cxx:3338
 TUnfold.cxx:3339
 TUnfold.cxx:3340
 TUnfold.cxx:3341
 TUnfold.cxx:3342
 TUnfold.cxx:3343
 TUnfold.cxx:3344
 TUnfold.cxx:3345
 TUnfold.cxx:3346
 TUnfold.cxx:3347
 TUnfold.cxx:3348
 TUnfold.cxx:3349
 TUnfold.cxx:3350
 TUnfold.cxx:3351
 TUnfold.cxx:3352
 TUnfold.cxx:3353
 TUnfold.cxx:3354
 TUnfold.cxx:3355
 TUnfold.cxx:3356
 TUnfold.cxx:3357
 TUnfold.cxx:3358
 TUnfold.cxx:3359
 TUnfold.cxx:3360
 TUnfold.cxx:3361
 TUnfold.cxx:3362
 TUnfold.cxx:3363
 TUnfold.cxx:3364
 TUnfold.cxx:3365
 TUnfold.cxx:3366
 TUnfold.cxx:3367
 TUnfold.cxx:3368
 TUnfold.cxx:3369
 TUnfold.cxx:3370
 TUnfold.cxx:3371
 TUnfold.cxx:3372
 TUnfold.cxx:3373
 TUnfold.cxx:3374
 TUnfold.cxx:3375
 TUnfold.cxx:3376
 TUnfold.cxx:3377
 TUnfold.cxx:3378
 TUnfold.cxx:3379
 TUnfold.cxx:3380
 TUnfold.cxx:3381
 TUnfold.cxx:3382
 TUnfold.cxx:3383
 TUnfold.cxx:3384
 TUnfold.cxx:3385
 TUnfold.cxx:3386
 TUnfold.cxx:3387
 TUnfold.cxx:3388
 TUnfold.cxx:3389
 TUnfold.cxx:3390
 TUnfold.cxx:3391
 TUnfold.cxx:3392
 TUnfold.cxx:3393
 TUnfold.cxx:3394
 TUnfold.cxx:3395
 TUnfold.cxx:3396
 TUnfold.cxx:3397
 TUnfold.cxx:3398
 TUnfold.cxx:3399
 TUnfold.cxx:3400
 TUnfold.cxx:3401
 TUnfold.cxx:3402
 TUnfold.cxx:3403
 TUnfold.cxx:3404
 TUnfold.cxx:3405
 TUnfold.cxx:3406
 TUnfold.cxx:3407
 TUnfold.cxx:3408
 TUnfold.cxx:3409
 TUnfold.cxx:3410
 TUnfold.cxx:3411
 TUnfold.cxx:3412
 TUnfold.cxx:3413
 TUnfold.cxx:3414
 TUnfold.cxx:3415
 TUnfold.cxx:3416
 TUnfold.cxx:3417
 TUnfold.cxx:3418
 TUnfold.cxx:3419
 TUnfold.cxx:3420
 TUnfold.cxx:3421
 TUnfold.cxx:3422
 TUnfold.cxx:3423
 TUnfold.cxx:3424
 TUnfold.cxx:3425
 TUnfold.cxx:3426
 TUnfold.cxx:3427
 TUnfold.cxx:3428
 TUnfold.cxx:3429
 TUnfold.cxx:3430
 TUnfold.cxx:3431
 TUnfold.cxx:3432
 TUnfold.cxx:3433
 TUnfold.cxx:3434
 TUnfold.cxx:3435
 TUnfold.cxx:3436
 TUnfold.cxx:3437
 TUnfold.cxx:3438
 TUnfold.cxx:3439
 TUnfold.cxx:3440