TSpectrum2Transform.cxx

Go to the documentation of this file.
00001 // @(#)root/spectrum:$Id: TSpectrum2Transform.cxx 35999 2010-10-01 12:50:11Z brun $
00002 // Author: Miroslav Morhac   25/09/06
00003 
00004 //__________________________________________________________________________
00005 //   THIS CLASS CONTAINS 2-DIMENSIONAL ORTHOGONAL TRANSFORM  FUNCTIONS.    //
00006 //                                                                         //
00007 //   These functions were written by:                                      //
00008 //   Miroslav Morhac                                                       //
00009 //   Institute of Physics                                                  //
00010 //   Slovak Academy of Sciences                                            //
00011 //   Dubravska cesta 9, 842 28 BRATISLAVA                                  //
00012 //   SLOVAKIA                                                              //
00013 //                                                                         //
00014 //   email:fyzimiro@savba.sk,    fax:+421 7 54772479                       //
00015 //                                                                         //
00016 //  The original code in C has been repackaged as a C++ class by R.Brun    //
00017 //                                                                         //
00018 //  The algorithms in this class have been published in the following      //
00019 //  references:                                                            //
00020 //                                                                         //
00021 //  [1] C.V. Hampton, B. Lian, Wm. C. McHarris: Fast-Fourier-transform     //
00022 //      spectral enhancement techniques for gamma-ray spectroscopy.NIM A353//
00023 //      (1994) 280-284.                                                    //
00024 //  [2] Morhac M., Matousek V., New adaptive Cosine-Walsh  transform and   //
00025 //      its application to nuclear data compression, IEEE Transactions on  //
00026 //      Signal Processing 48 (2000) 2693.                                  //  
00027 //  [3] Morhac M., Matousek V., Data compression using new fast adaptive   //
00028 //      Cosine-Haar transforms, Digital Signal Processing 8 (1998) 63.     //
00029 //  [4] Morhac M., Matousek V.: Multidimensional nuclear data compression  //
00030 //      using fast adaptive Walsh-Haar transform. Acta Physica Slovaca 51  //
00031 //     (2001) 307.                                                         //
00032 //____________________________________________________________________________
00033 
00034 #include "TSpectrum2Transform.h"
00035 #include "TMath.h"
00036 
00037 ClassImp(TSpectrum2Transform)  
00038     
00039 //____________________________________________________________________________    
00040 TSpectrum2Transform::TSpectrum2Transform() 
00041 {
00042    //default constructor
00043    fSizeX = 0, fSizeY = 0;
00044    fTransformType = kTransformCos;
00045    fDegree = 0;
00046    fDirection = kTransformForward;
00047    fXmin = 0;
00048    fXmax = 0;
00049    fYmin = 0;
00050    fYmax = 0;
00051    fFilterCoeff=0;
00052    fEnhanceCoeff=0.5;
00053 }
00054 
00055 //____________________________________________________________________________    
00056 TSpectrum2Transform::TSpectrum2Transform(Int_t sizeX, Int_t sizeY) :TObject()
00057 {
00058 //the constructor creates TSpectrum2Transform object. Its sizes must be > than zero and must be power of 2.
00059 //It sets default transform type to be Cosine transform. Transform parameters can be changed using setter functions.   
00060    Int_t j1, j2, n;
00061    if (sizeX <= 0 || sizeY <= 0){
00062       Error ("TSpectrumTransform","Invalid length, must be > than 0");
00063       return;
00064    }    
00065    j1 = 0;
00066    n = 1;
00067    for (; n < sizeX;) {
00068       j1 += 1;
00069       n = n * 2;
00070    }
00071    if (n != sizeX){
00072       Error ("TSpectrumTransform","Invalid length, must be power of 2");
00073       return;   
00074    }
00075    j2 = 0;
00076    n = 1;
00077    for (; n < sizeY;) {
00078       j2 += 1;
00079       n = n * 2;
00080    }
00081    if (n != sizeY){
00082       Error ("TSpectrumTransform","Invalid length, must be power of 2");
00083       return;   
00084    }   
00085    fSizeX = sizeX, fSizeY = sizeY;
00086    fTransformType = kTransformCos;
00087    fDegree = 0;
00088    fDirection = kTransformForward;
00089    fXmin = sizeX/4;
00090    fXmax = sizeX-1;
00091    fYmin = sizeY/4;
00092    fYmax = sizeY-1;   
00093    fFilterCoeff=0;
00094    fEnhanceCoeff=0.5;
00095 }
00096 
00097 
00098 //______________________________________________________________________________
00099 TSpectrum2Transform::~TSpectrum2Transform() 
00100 {
00101    //destructor
00102 }
00103 
00104 
00105 //////////AUXILIARY FUNCTIONS FOR TRANSFORM BASED FUNCTIONS////////////////////////
00106 //_____________________________________________________________________________
00107 void TSpectrum2Transform::Haar(Float_t *working_space, Int_t num, Int_t direction) 
00108 {
00109 //////////////////////////////////////////////////////////////////////////////////
00110 //   AUXILIARY FUNCION                                                          //
00111 //                                                                              //
00112 //   This function calculates Haar transform of a part of data                   //
00113 //      Function parameters:                                                    //
00114 //              -working_space-pointer to vector of transformed data            //
00115 //              -num-length of processed data                                   //
00116 //              -direction-forward or inverse transform                         //
00117 //                                                                              //
00118 //////////////////////////////////////////////////////////////////////////////////
00119    Int_t i, ii, li, l2, l3, j, jj, jj1, lj, iter, m, jmin, jmax;
00120    Double_t a, b, c, wlk;
00121    Float_t val;
00122    for (i = 0; i < num; i++)
00123       working_space[i + num] = 0;
00124    i = num;
00125    iter = 0;
00126    for (; i > 1;) {
00127       iter += 1;
00128       i = i / 2;
00129    }
00130    if (direction == kTransformForward) {
00131       for (m = 1; m <= iter; m++) {
00132          li = iter + 1 - m;
00133          l2 = (Int_t) TMath::Power(2, li - 1);
00134          for (i = 0; i < (2 * l2); i++) {
00135             working_space[num + i] = working_space[i];
00136          }
00137          for (j = 0; j < l2; j++) {
00138             l3 = l2 + j;
00139             jj = 2 * j;
00140             val = working_space[jj + num] + working_space[jj + 1 + num];
00141             working_space[j] = val;
00142             val = working_space[jj + num] - working_space[jj + 1 + num];
00143             working_space[l3] = val;
00144          }
00145       }
00146    }
00147    val = working_space[0];
00148    val = val / TMath::Sqrt(TMath::Power(2, iter));
00149    working_space[0] = val;
00150    val = working_space[1];
00151    val = val / TMath::Sqrt(TMath::Power(2, iter));
00152    working_space[1] = val;
00153    for (ii = 2; ii <= iter; ii++) {
00154       i = ii - 1;
00155       wlk = 1 / TMath::Sqrt(TMath::Power(2, iter - i));
00156       jmin = (Int_t) TMath::Power(2, i);
00157       jmax = (Int_t) TMath::Power(2, ii) - 1;
00158       for (j = jmin; j <= jmax; j++) {
00159          val = working_space[j];
00160          a = val;
00161          a = a * wlk;
00162          val = a;
00163          working_space[j] = val;
00164       }
00165    }
00166    if (direction == kTransformInverse) {
00167       for (m = 1; m <= iter; m++) {
00168          a = 2;
00169          b = m - 1;
00170          c = TMath::Power(a, b);
00171          li = (Int_t) c;
00172          for (i = 0; i < (2 * li); i++) {
00173             working_space[i + num] = working_space[i];
00174          }
00175          for (j = 0; j < li; j++) {
00176             lj = li + j;
00177             jj = 2 * (j + 1) - 1;
00178             jj1 = jj - 1;
00179             val = working_space[j + num] - working_space[lj + num];
00180             working_space[jj] = val;
00181             val = working_space[j + num] + working_space[lj + num];
00182             working_space[jj1] = val;
00183          }
00184       }
00185    }
00186    return;
00187 }
00188 
00189 //_____________________________________________________________________________
00190 void TSpectrum2Transform::Walsh(Float_t *working_space, Int_t num) 
00191 {
00192 //////////////////////////////////////////////////////////////////////////////////
00193 //   AUXILIARY FUNCION                                                          //
00194 //                                                                              //
00195 //   This function calculates Walsh transform of a part of data                  //
00196 //      Function parameters:                                                    //
00197 //              -working_space-pointer to vector of transformed data            //
00198 //              -num-length of processed data                                   //
00199 //                                                                              //
00200 //////////////////////////////////////////////////////////////////////////////////
00201    Int_t i, m, nump = 1, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter;
00202    Double_t a;
00203    Float_t val1, val2;
00204    for (i = 0; i < num; i++)
00205       working_space[i + num] = 0;
00206    i = num;
00207    iter = 0;
00208    for (; i > 1;) {
00209       iter += 1;
00210       i = i / 2;
00211    }
00212    for (m = 1; m <= iter; m++) {
00213       if (m == 1)
00214          nump = 1;
00215       
00216       else
00217          nump = nump * 2;
00218       mnum = num / nump;
00219       mnum2 = mnum / 2;
00220       for (mp = 0; mp < nump; mp++) {
00221          ib = mp * mnum;
00222          for (mp2 = 0; mp2 < mnum2; mp2++) {
00223             mnum21 = mnum2 + mp2 + ib;
00224             iba = ib + mp2;
00225             val1 = working_space[iba];
00226             val2 = working_space[mnum21];
00227             working_space[iba + num] = val1 + val2;
00228             working_space[mnum21 + num] = val1 - val2;
00229          }
00230       }
00231       for (i = 0; i < num; i++) {
00232          working_space[i] = working_space[i + num];
00233       }
00234    }
00235    a = num;
00236    a = TMath::Sqrt(a);
00237    val2 = a;
00238    for (i = 0; i < num; i++) {
00239       val1 = working_space[i];
00240       val1 = val1 / val2;
00241       working_space[i] = val1;
00242    }
00243    return;
00244 }
00245 
00246 //_____________________________________________________________________________
00247 void TSpectrum2Transform::BitReverse(Float_t *working_space, Int_t num) 
00248 {
00249 //////////////////////////////////////////////////////////////////////////////////
00250 //   AUXILIARY FUNCION                                                          //
00251 //                                                                              //
00252 //   This function carries out bir-reverse reordering of data                    //
00253 //      Function parameters:                                                    //
00254 //              -working_space-pointer to vector of processed data              //
00255 //              -num-length of processed data                                   //
00256 //                                                                              //
00257 //////////////////////////////////////////////////////////////////////////////////
00258    Int_t ipower[26];
00259    Int_t i, ib, il, ibd, ip, ifac, i1;
00260    for (i = 0; i < num; i++) {
00261       working_space[i + num] = working_space[i];
00262    }
00263    for (i = 1; i <= num; i++) {
00264       ib = i - 1;
00265       il = 1;
00266       lab9: ibd = ib / 2;
00267       ipower[il - 1] = 1;
00268       if (ib == (ibd * 2))
00269          ipower[il - 1] = 0;
00270       if (ibd == 0)
00271          goto lab10;
00272       ib = ibd;
00273       il = il + 1;
00274       goto lab9;
00275       lab10: ip = 1;
00276       ifac = num;
00277       for (i1 = 1; i1 <= il; i1++) {
00278          ifac = ifac / 2;
00279          ip = ip + ifac * ipower[i1 - 1];
00280       }
00281       working_space[ip - 1] = working_space[i - 1 + num];
00282    }
00283    return;
00284 }
00285 
00286 //_____________________________________________________________________________
00287 void TSpectrum2Transform::Fourier(Float_t *working_space, Int_t num, Int_t hartley,
00288                            Int_t direction, Int_t zt_clear) 
00289 {
00290 //////////////////////////////////////////////////////////////////////////////////
00291 //   AUXILIARY FUNCION                                                          //
00292 //                                                                              //
00293 //   This function calculates Fourier based transform of a part of data          //
00294 //      Function parameters:                                                    //
00295 //              -working_space-pointer to vector of transformed data            //
00296 //              -num-length of processed data                                   //
00297 //              -hartley-1 if it is Hartley transform, 0 othewise               //
00298 //              -direction-forward or inverse transform                         //
00299 //                                                                              //
00300 //////////////////////////////////////////////////////////////////////////////////
00301    Int_t nxp2, nxp, i, j, k, m, iter, mxp, j1, j2, n1, n2, it;
00302    Double_t a, b, c, d, sign, wpwr, arg, wr, wi, tr, ti, pi =
00303        3.14159265358979323846;
00304    Float_t val1, val2, val3, val4;
00305    if (direction == kTransformForward && zt_clear == 0) {
00306       for (i = 0; i < num; i++)
00307          working_space[i + num] = 0;
00308    }
00309    i = num;
00310    iter = 0;
00311    for (; i > 1;) {
00312       iter += 1;
00313       i = i / 2;
00314    }
00315    sign = -1;
00316    if (direction == kTransformInverse)
00317       sign = 1;
00318    nxp2 = num;
00319    for (it = 1; it <= iter; it++) {
00320       nxp = nxp2;
00321       nxp2 = nxp / 2;
00322       a = nxp2;
00323       wpwr = pi / a;
00324       for (m = 1; m <= nxp2; m++) {
00325          a = m - 1;
00326          arg = a * wpwr;
00327          wr = TMath::Cos(arg);
00328          wi = sign * TMath::Sin(arg);
00329          for (mxp = nxp; mxp <= num; mxp += nxp) {
00330             j1 = mxp - nxp + m;
00331             j2 = j1 + nxp2;
00332             val1 = working_space[j1 - 1];
00333             val2 = working_space[j2 - 1];
00334             val3 = working_space[j1 - 1 + num];
00335             val4 = working_space[j2 - 1 + num];
00336             a = val1;
00337             b = val2;
00338             c = val3;
00339             d = val4;
00340             tr = a - b;
00341             ti = c - d;
00342             a = a + b;
00343             val1 = a;
00344             working_space[j1 - 1] = val1;
00345             c = c + d;
00346             val1 = c;
00347             working_space[j1 - 1 + num] = val1;
00348             a = tr * wr - ti * wi;
00349             val1 = a;
00350             working_space[j2 - 1] = val1;
00351             a = ti * wr + tr * wi;
00352             val1 = a;
00353             working_space[j2 - 1 + num] = val1;
00354          }
00355       }
00356    }
00357    n2 = num / 2;
00358    n1 = num - 1;
00359    j = 1;
00360    for (i = 1; i <= n1; i++) {
00361       if (i >= j)
00362          goto lab55;
00363       val1 = working_space[j - 1];
00364       val2 = working_space[j - 1 + num];
00365       val3 = working_space[i - 1];
00366       working_space[j - 1] = val3;
00367       working_space[j - 1 + num] = working_space[i - 1 + num];
00368       working_space[i - 1] = val1;
00369       working_space[i - 1 + num] = val2;
00370       lab55: k = n2;
00371       lab60: if (k >= j) goto lab65;
00372       j = j - k;
00373       k = k / 2;
00374       goto lab60;
00375       lab65: j = j + k;
00376    }
00377    a = num;
00378    a = TMath::Sqrt(a);
00379    for (i = 0; i < num; i++) {
00380       if (hartley == 0) {
00381          val1 = working_space[i];
00382          b = val1;
00383          b = b / a;
00384          val1 = b;
00385          working_space[i] = val1;
00386          b = working_space[i + num];
00387          b = b / a;
00388          working_space[i + num] = b;
00389       }
00390       
00391       else {
00392          b = working_space[i];
00393          c = working_space[i + num];
00394          b = (b + c) / a;
00395          working_space[i] = b;
00396          working_space[i + num] = 0;
00397       }
00398    }
00399    if (hartley == 1 && direction == kTransformInverse) {
00400       for (i = 1; i < num; i++)
00401          working_space[num - i + num] = working_space[i];
00402       working_space[0 + num] = working_space[0];
00403       for (i = 0; i < num; i++) {
00404          working_space[i] = working_space[i + num];
00405          working_space[i + num] = 0;
00406       }
00407    }
00408    return;
00409 }
00410 
00411 //_____________________________________________________________________________
00412 void TSpectrum2Transform::BitReverseHaar(Float_t *working_space, Int_t shift, Int_t num,
00413                                   Int_t start) 
00414 {
00415 //////////////////////////////////////////////////////////////////////////////////
00416 //   AUXILIARY FUNCION                                                          //
00417 //                                                                              //
00418 //   This function carries out bir-reverse reordering for Haar transform         //
00419 //      Function parameters:                                                    //
00420 //              -working_space-pointer to vector of processed data              //
00421 //              -shift-shift of position of processing                          //
00422 //              -start-initial position of processed data                       //
00423 //              -num-length of processed data                                   //
00424 //                                                                              //
00425 //////////////////////////////////////////////////////////////////////////////////
00426    Int_t ipower[26];
00427    Int_t i, ib, il, ibd, ip, ifac, i1;
00428    for (i = 0; i < num; i++) {
00429       working_space[i + shift + start] = working_space[i + start];
00430       working_space[i + shift + start + 2 * shift] =
00431           working_space[i + start + 2 * shift];
00432    }
00433    for (i = 1; i <= num; i++) {
00434       ib = i - 1;
00435       il = 1;
00436       lab9:  ibd = ib / 2;
00437       ipower[il - 1] = 1;
00438       if (ib == (ibd * 2))
00439          ipower[il - 1] = 0;
00440       if (ibd == 0)
00441          goto lab10;
00442       ib = ibd;
00443       il = il + 1;
00444       goto lab9;
00445       lab10:  ip = 1;
00446       ifac = num;
00447       for (i1 = 1; i1 <= il; i1++) {
00448          ifac = ifac / 2;
00449          ip = ip + ifac * ipower[i1 - 1];
00450       }
00451       working_space[ip - 1 + start] =
00452           working_space[i - 1 + shift + start];
00453       working_space[ip - 1 + start + 2 * shift] =
00454           working_space[i - 1 + shift + start + 2 * shift];
00455    }
00456    return;
00457 }
00458 
00459 //_____________________________________________________________________________
00460 Int_t TSpectrum2Transform::GeneralExe(Float_t *working_space, Int_t zt_clear, Int_t num,
00461                              Int_t degree, Int_t type) 
00462 {
00463 //////////////////////////////////////////////////////////////////////////////////
00464 //   AUXILIARY FUNCION                                                          //
00465 //                                                                              //
00466 //   This function calculates generalized (mixed) transforms of different degrees//
00467 //      Function parameters:                                                    //
00468 //              -working_space-pointer to vector of transformed data            //
00469 //              -zt_clear-flag to clear imaginary data before staring           //
00470 //              -num-length of processed data                                   //
00471 //              -degree-degree of transform (see manual)                        //
00472 //              -type-type of mixed transform (see manual)                      //
00473 //                                                                              //
00474 //////////////////////////////////////////////////////////////////////////////////
00475    Int_t i, j, k, m, nump, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter,
00476        mp2step, mppom, ring;
00477    Double_t a, b, c, d, wpwr, arg, wr, wi, tr, ti, pi =
00478        3.14159265358979323846;
00479    Float_t val1, val2, val3, val4, a0oldr = 0, b0oldr = 0, a0r, b0r;
00480    if (zt_clear == 0) {
00481       for (i = 0; i < num; i++)
00482          working_space[i + 2 * num] = 0;
00483    }
00484    i = num;
00485    iter = 0;
00486    for (; i > 1;) {
00487       iter += 1;
00488       i = i / 2;
00489    }
00490    a = num;
00491    wpwr = 2.0 * pi / a;
00492    nump = num;
00493    mp2step = 1;
00494    ring = num;
00495    for (i = 0; i < iter - degree; i++)
00496       ring = ring / 2;
00497    for (m = 1; m <= iter; m++) {
00498       nump = nump / 2;
00499       mnum = num / nump;
00500       mnum2 = mnum / 2;
00501       if (m > degree
00502            && (type == kTransformFourierHaar
00503                || type == kTransformWalshHaar
00504                || type == kTransformCosHaar
00505                || type == kTransformSinHaar))
00506          mp2step *= 2;
00507       if (ring > 1)
00508          ring = ring / 2;
00509       for (mp = 0; mp < nump; mp++) {
00510          if (type != kTransformWalshHaar) {
00511             mppom = mp;
00512             mppom = mppom % ring;
00513             a = 0;
00514             j = 1;
00515             k = num / 4;
00516             for (i = 0; i < (iter - 1); i++) {
00517                if ((mppom & j) != 0)
00518                   a = a + k;
00519                j = j * 2;
00520                k = k / 2;
00521             }
00522             arg = a * wpwr;
00523             wr = TMath::Cos(arg);
00524             wi = TMath::Sin(arg);
00525          }
00526          
00527          else {
00528             wr = 1;
00529             wi = 0;
00530          }
00531          ib = mp * mnum;
00532          for (mp2 = 0; mp2 < mnum2; mp2++) {
00533             mnum21 = mnum2 + mp2 + ib;
00534             iba = ib + mp2;
00535             if (mp2 % mp2step == 0) {
00536                a0r = a0oldr;
00537                b0r = b0oldr;
00538                a0r = 1 / TMath::Sqrt(2.0);
00539                b0r = 1 / TMath::Sqrt(2.0);
00540             }
00541             
00542             else {
00543                a0r = 1;
00544                b0r = 0;
00545             }
00546             val1 = working_space[iba];
00547             val2 = working_space[mnum21];
00548             val3 = working_space[iba + 2 * num];
00549             val4 = working_space[mnum21 + 2 * num];
00550             a = val1;
00551             b = val2;
00552             c = val3;
00553             d = val4;
00554             tr = a * a0r + b * b0r;
00555             val1 = tr;
00556             working_space[num + iba] = val1;
00557             ti = c * a0r + d * b0r;
00558             val1 = ti;
00559             working_space[num + iba + 2 * num] = val1;
00560             tr =
00561                 a * b0r * wr - c * b0r * wi - b * a0r * wr + d * a0r * wi;
00562             val1 = tr;
00563             working_space[num + mnum21] = val1;
00564             ti =
00565                 c * b0r * wr + a * b0r * wi - d * a0r * wr - b * a0r * wi;
00566             val1 = ti;
00567             working_space[num + mnum21 + 2 * num] = val1;
00568          }
00569       }
00570       for (i = 0; i < num; i++) {
00571          val1 = working_space[num + i];
00572          working_space[i] = val1;
00573          val1 = working_space[num + i + 2 * num];
00574          working_space[i + 2 * num] = val1;
00575       }
00576    }
00577    return (0);
00578 }
00579 
00580 //_____________________________________________________________________________
00581 Int_t TSpectrum2Transform::GeneralInv(Float_t *working_space, Int_t num, Int_t degree,
00582                              Int_t type) 
00583 {
00584 //////////////////////////////////////////////////////////////////////////////////
00585 //   AUXILIARY FUNCION                                                          //
00586 //                                                                              //
00587 //   This function calculates inverse generalized (mixed) transforms             //
00588 //      Function parameters:                                                    //
00589 //              -working_space-pointer to vector of transformed data            //
00590 //              -num-length of processed data                                   //
00591 //              -degree-degree of transform (see manual)                        //
00592 //              -type-type of mixed transform (see manual)                      //
00593 //                                                                              //
00594 //////////////////////////////////////////////////////////////////////////////////
00595    Int_t i, j, k, m, nump =
00596        1, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter, mp2step, mppom,
00597        ring;
00598    Double_t a, b, c, d, wpwr, arg, wr, wi, tr, ti, pi =
00599        3.14159265358979323846;
00600    Float_t val1, val2, val3, val4, a0oldr = 0, b0oldr = 0, a0r, b0r;
00601    i = num;
00602    iter = 0;
00603    for (; i > 1;) {
00604       iter += 1;
00605       i = i / 2;
00606    }
00607    a = num;
00608    wpwr = 2.0 * pi / a;
00609    mp2step = 1;
00610    if (type == kTransformFourierHaar || type == kTransformWalshHaar
00611         || type == kTransformCosHaar || type == kTransformSinHaar) {
00612       for (i = 0; i < iter - degree; i++)
00613          mp2step *= 2;
00614    }
00615    ring = 1;
00616    for (m = 1; m <= iter; m++) {
00617       if (m == 1)
00618          nump = 1;
00619       
00620       else
00621          nump = nump * 2;
00622       mnum = num / nump;
00623       mnum2 = mnum / 2;
00624       if (m > iter - degree + 1)
00625          ring *= 2;
00626       for (mp = nump - 1; mp >= 0; mp--) {
00627          if (type != kTransformWalshHaar) {
00628             mppom = mp;
00629             mppom = mppom % ring;
00630             a = 0;
00631             j = 1;
00632             k = num / 4;
00633             for (i = 0; i < (iter - 1); i++) {
00634                if ((mppom & j) != 0)
00635                   a = a + k;
00636                j = j * 2;
00637                k = k / 2;
00638             }
00639             arg = a * wpwr;
00640             wr = TMath::Cos(arg);
00641             wi = TMath::Sin(arg);
00642          }
00643          
00644          else {
00645             wr = 1;
00646             wi = 0;
00647          }
00648          ib = mp * mnum;
00649          for (mp2 = 0; mp2 < mnum2; mp2++) {
00650             mnum21 = mnum2 + mp2 + ib;
00651             iba = ib + mp2;
00652             if (mp2 % mp2step == 0) {
00653                a0r = a0oldr;
00654                b0r = b0oldr;
00655                a0r = 1 / TMath::Sqrt(2.0);
00656                b0r = 1 / TMath::Sqrt(2.0);
00657             }
00658             
00659             else {
00660                a0r = 1;
00661                b0r = 0;
00662             }
00663             val1 = working_space[iba];
00664             val2 = working_space[mnum21];
00665             val3 = working_space[iba + 2 * num];
00666             val4 = working_space[mnum21 + 2 * num];
00667             a = val1;
00668             b = val2;
00669             c = val3;
00670             d = val4;
00671             tr = a * a0r + b * wr * b0r + d * wi * b0r;
00672             val1 = tr;
00673             working_space[num + iba] = val1;
00674             ti = c * a0r + d * wr * b0r - b * wi * b0r;
00675             val1 = ti;
00676             working_space[num + iba + 2 * num] = val1;
00677             tr = a * b0r - b * wr * a0r - d * wi * a0r;
00678             val1 = tr;
00679             working_space[num + mnum21] = val1;
00680             ti = c * b0r - d * wr * a0r + b * wi * a0r;
00681             val1 = ti;
00682             working_space[num + mnum21 + 2 * num] = val1;
00683          }
00684       }
00685       if (m <= iter - degree
00686            && (type == kTransformFourierHaar
00687                || type == kTransformWalshHaar
00688                || type == kTransformCosHaar
00689                || type == kTransformSinHaar))
00690          mp2step /= 2;
00691       for (i = 0; i < num; i++) {
00692          val1 = working_space[num + i];
00693          working_space[i] = val1;
00694          val1 = working_space[num + i + 2 * num];
00695          working_space[i + 2 * num] = val1;
00696       }
00697    }
00698    return (0);
00699 }
00700 
00701 //_____________________________________________________________________________
00702 void TSpectrum2Transform::HaarWalsh2(Float_t **working_matrix,
00703                               Float_t *working_vector, Int_t numx, Int_t numy,
00704                               Int_t direction, Int_t type) 
00705 {
00706 //////////////////////////////////////////////////////////////////////////////////
00707 //   AUXILIARY FUNCION                                                          //
00708 //                                                                              //
00709 //   This function calculates 2D Haar and Walsh transforms                       //
00710 //      Function parameters:                                                    //
00711 //              -working_matrix-pointer to matrix of transformed data           //
00712 //              -working_vector-pointer to vector where the data are processed  //
00713 //              -numx,numy-lengths of processed data                            //
00714 //              -direction-forward or inverse                                   //
00715 //              -type-type of transform (see manual)                            //
00716 //                                                                              //
00717 //////////////////////////////////////////////////////////////////////////////////
00718    Int_t i, j;
00719    if (direction == kTransformForward) {
00720       for (j = 0; j < numy; j++) {
00721          for (i = 0; i < numx; i++) {
00722             working_vector[i] = working_matrix[i][j];
00723          }
00724          switch (type) {
00725          case kTransformHaar:
00726             Haar(working_vector, numx, kTransformForward);
00727             break;
00728          case kTransformWalsh:
00729             Walsh(working_vector, numx);
00730             BitReverse(working_vector, numx);
00731             break;
00732          }
00733          for (i = 0; i < numx; i++) {
00734             working_matrix[i][j] = working_vector[i];
00735          }
00736       }
00737       for (i = 0; i < numx; i++) {
00738          for (j = 0; j < numy; j++) {
00739             working_vector[j] = working_matrix[i][j];
00740          }
00741          switch (type) {
00742          case kTransformHaar:
00743             Haar(working_vector, numy, kTransformForward);
00744             break;
00745          case kTransformWalsh:
00746             Walsh(working_vector, numy);
00747             BitReverse(working_vector, numy);
00748             break;
00749          }
00750          for (j = 0; j < numy; j++) {
00751             working_matrix[i][j] = working_vector[j];
00752          }
00753       }
00754    }
00755    
00756    else if (direction == kTransformInverse) {
00757       for (i = 0; i < numx; i++) {
00758          for (j = 0; j < numy; j++) {
00759             working_vector[j] = working_matrix[i][j];
00760          }
00761          switch (type) {
00762          case kTransformHaar:
00763             Haar(working_vector, numy, kTransformInverse);
00764             break;
00765          case kTransformWalsh:
00766             BitReverse(working_vector, numy);
00767             Walsh(working_vector, numy);
00768             break;
00769          }
00770          for (j = 0; j < numy; j++) {
00771             working_matrix[i][j] = working_vector[j];
00772          }
00773       }
00774       for (j = 0; j < numy; j++) {
00775          for (i = 0; i < numx; i++) {
00776             working_vector[i] = working_matrix[i][j];
00777          }
00778          switch (type) {
00779          case kTransformHaar:
00780             Haar(working_vector, numx, kTransformInverse);
00781             break;
00782          case kTransformWalsh:
00783             BitReverse(working_vector, numx);
00784             Walsh(working_vector, numx);
00785             break;
00786          }
00787          for (i = 0; i < numx; i++) {
00788             working_matrix[i][j] = working_vector[i];
00789          }
00790       }
00791    }
00792    return;
00793 }
00794 
00795 //_____________________________________________________________________________
00796 void TSpectrum2Transform::FourCos2(Float_t **working_matrix, Float_t *working_vector,
00797                             Int_t numx, Int_t numy, Int_t direction, Int_t type) 
00798 {
00799 //////////////////////////////////////////////////////////////////////////////////
00800 //   AUXILIARY FUNCION                                                          //
00801 //                                                                              //
00802 //   This function calculates 2D Fourier based transforms                        //
00803 //      Function parameters:                                                    //
00804 //              -working_matrix-pointer to matrix of transformed data           //
00805 //              -working_vector-pointer to vector where the data are processed  //
00806 //              -numx,numy-lengths of processed data                            //
00807 //              -direction-forward or inverse                                   //
00808 //              -type-type of transform (see manual)                            //
00809 //                                                                              //
00810 //////////////////////////////////////////////////////////////////////////////////
00811    Int_t i, j, iterx, itery, n, size;
00812    Double_t pi = 3.14159265358979323846;
00813    j = 0;
00814    n = 1;
00815    for (; n < numx;) {
00816       j += 1;
00817       n = n * 2;
00818    }
00819    j = 0;
00820    n = 1;
00821    for (; n < numy;) {
00822       j += 1;
00823       n = n * 2;
00824    }
00825    i = numx;
00826    iterx = 0;
00827    for (; i > 1;) {
00828       iterx += 1;
00829       i = i / 2;
00830    }
00831    i = numy;
00832    itery = 0;
00833    for (; i > 1;) {
00834       itery += 1;
00835       i = i / 2;
00836    }
00837    size = numx;
00838    if (size < numy)
00839       size = numy;
00840    if (direction == kTransformForward) {
00841       for (j = 0; j < numy; j++) {
00842          for (i = 0; i < numx; i++) {
00843             working_vector[i] = working_matrix[i][j];
00844          }
00845          switch (type) {
00846          case kTransformCos:
00847             for (i = 1; i <= numx; i++) {
00848                working_vector[2 * numx - i] = working_vector[i - 1];
00849             }
00850             Fourier(working_vector, 2 * numx, 0, kTransformForward, 0);
00851             for (i = 0; i < numx; i++) {
00852                working_vector[i] =
00853                    working_vector[i] / TMath::Cos(pi * i / (2 * numx));
00854             }
00855             working_vector[0] = working_vector[0] / TMath::Sqrt(2.);
00856             break;
00857          case kTransformSin:
00858             for (i = 1; i <= numx; i++) {
00859                working_vector[2 * numx - i] = -working_vector[i - 1];
00860             }
00861             Fourier(working_vector, 2 * numx, 0, kTransformForward, 0);
00862             for (i = 1; i < numx; i++) {
00863                working_vector[i - 1] =
00864                    working_vector[i] / TMath::Sin(pi * i / (2 * numx));
00865             }
00866             working_vector[numx - 1] =
00867                 working_vector[numx] / TMath::Sqrt(2.);
00868             break;
00869          case kTransformFourier:
00870             Fourier(working_vector, numx, 0, kTransformForward, 0);
00871             break;
00872          case kTransformHartley:
00873             Fourier(working_vector, numx, 1, kTransformForward, 0);
00874             break;
00875          }
00876          for (i = 0; i < numx; i++) {
00877             working_matrix[i][j] = working_vector[i];
00878             if (type == kTransformFourier)
00879                working_matrix[i][j + numy] = working_vector[i + numx];
00880             
00881             else
00882                working_matrix[i][j + numy] = working_vector[i + 2 * numx];
00883          }
00884       }
00885       for (i = 0; i < numx; i++) {
00886          for (j = 0; j < numy; j++) {
00887             working_vector[j] = working_matrix[i][j];
00888             if (type == kTransformFourier)
00889                working_vector[j + numy] = working_matrix[i][j + numy];
00890             
00891             else
00892                working_vector[j + 2 * numy] = working_matrix[i][j + numy];
00893          }
00894          switch (type) {
00895          case kTransformCos:
00896             for (j = 1; j <= numy; j++) {
00897                working_vector[2 * numy - j] = working_vector[j - 1];
00898             }
00899             Fourier(working_vector, 2 * numy, 0, kTransformForward, 0);
00900             for (j = 0; j < numy; j++) {
00901                working_vector[j] =
00902                    working_vector[j] / TMath::Cos(pi * j / (2 * numy));
00903                working_vector[j + 2 * numy] = 0;
00904             }
00905             working_vector[0] = working_vector[0] / TMath::Sqrt(2.);
00906             break;
00907          case kTransformSin:
00908             for (j = 1; j <= numy; j++) {
00909                working_vector[2 * numy - j] = -working_vector[j - 1];
00910             }
00911             Fourier(working_vector, 2 * numy, 0, kTransformForward, 0);
00912             for (j = 1; j < numy; j++) {
00913                working_vector[j - 1] =
00914                    working_vector[j] / TMath::Sin(pi * j / (2 * numy));
00915                working_vector[j + numy] = 0;
00916             }
00917             working_vector[numy - 1] =
00918                 working_vector[numy] / TMath::Sqrt(2.);
00919             working_vector[numy] = 0;
00920             break;
00921          case kTransformFourier:
00922             Fourier(working_vector, numy, 0, kTransformForward, 1);
00923             break;
00924          case kTransformHartley:
00925             Fourier(working_vector, numy, 1, kTransformForward, 0);
00926             break;
00927          }
00928          for (j = 0; j < numy; j++) {
00929             working_matrix[i][j] = working_vector[j];
00930             if (type == kTransformFourier)
00931                working_matrix[i][j + numy] = working_vector[j + numy];
00932             
00933             else
00934                working_matrix[i][j + numy] = working_vector[j + 2 * numy];
00935          }
00936       }
00937    }
00938    
00939    else if (direction == kTransformInverse) {
00940       for (i = 0; i < numx; i++) {
00941          for (j = 0; j < numy; j++) {
00942             working_vector[j] = working_matrix[i][j];
00943             if (type == kTransformFourier)
00944                working_vector[j + numy] = working_matrix[i][j + numy];
00945             
00946             else
00947                working_vector[j + 2 * numy] = working_matrix[i][j + numy];
00948          }
00949          switch (type) {
00950          case kTransformCos:
00951             working_vector[0] = working_vector[0] * TMath::Sqrt(2.);
00952             for (j = 0; j < numy; j++) {
00953                working_vector[j + 2 * numy] =
00954                    working_vector[j] * TMath::Sin(pi * j / (2 * numy));
00955                working_vector[j] =
00956                    working_vector[j] * TMath::Cos(pi * j / (2 * numy));
00957             }
00958             for (j = 1; j < numy; j++) {
00959                working_vector[2 * numy - j] = working_vector[j];
00960                working_vector[2 * numy - j + 2 * numy] =
00961                    -working_vector[j + 2 * numy];
00962             }
00963             working_vector[numy] = 0;
00964             working_vector[numy + 2 * numy] = 0;
00965             Fourier(working_vector, 2 * numy, 0, kTransformInverse, 1);
00966             break;
00967          case kTransformSin:
00968             working_vector[numy] =
00969                 working_vector[numy - 1] * TMath::Sqrt(2.);
00970             for (j = numy - 1; j > 0; j--) {
00971                working_vector[j + 2 * numy] =
00972                    -working_vector[j -
00973                                    1] * TMath::Cos(pi * j / (2 * numy));
00974                working_vector[j] =
00975                    working_vector[j - 1] * TMath::Sin(pi * j / (2 * numy));
00976             }
00977             for (j = 1; j < numy; j++) {
00978                working_vector[2 * numy - j] = working_vector[j];
00979                working_vector[2 * numy - j + 2 * numy] =
00980                    -working_vector[j + 2 * numy];
00981             }
00982             working_vector[0] = 0;
00983             working_vector[0 + 2 * numy] = 0;
00984             working_vector[numy + 2 * numy] = 0;
00985             Fourier(working_vector, 2 * numy, 0, kTransformInverse, 1);
00986             break;
00987          case kTransformFourier:
00988             Fourier(working_vector, numy, 0, kTransformInverse, 1);
00989             break;
00990          case kTransformHartley:
00991             Fourier(working_vector, numy, 1, kTransformInverse, 1);
00992             break;
00993          }
00994          for (j = 0; j < numy; j++) {
00995             working_matrix[i][j] = working_vector[j];
00996             if (type == kTransformFourier)
00997                working_matrix[i][j + numy] = working_vector[j + numy];
00998             
00999             else
01000                working_matrix[i][j + numy] = working_vector[j + 2 * numy];
01001          }
01002       }
01003       for (j = 0; j < numy; j++) {
01004          for (i = 0; i < numx; i++) {
01005             working_vector[i] = working_matrix[i][j];
01006             if (type == kTransformFourier)
01007                working_vector[i + numx] = working_matrix[i][j + numy];
01008             
01009             else
01010                working_vector[i + 2 * numx] = working_matrix[i][j + numy];
01011          }
01012          switch (type) {
01013          case kTransformCos:
01014             working_vector[0] = working_vector[0] * TMath::Sqrt(2.);
01015             for (i = 0; i < numx; i++) {
01016                working_vector[i + 2 * numx] =
01017                    working_vector[i] * TMath::Sin(pi * i / (2 * numx));
01018                working_vector[i] =
01019                    working_vector[i] * TMath::Cos(pi * i / (2 * numx));
01020             }
01021             for (i = 1; i < numx; i++) {
01022                working_vector[2 * numx - i] = working_vector[i];
01023                working_vector[2 * numx - i + 2 * numx] =
01024                    -working_vector[i + 2 * numx];
01025             }
01026             working_vector[numx] = 0;
01027             working_vector[numx + 2 * numx] = 0;
01028             Fourier(working_vector, 2 * numx, 0, kTransformInverse, 1);
01029             break;
01030          case kTransformSin:
01031             working_vector[numx] =
01032                 working_vector[numx - 1] * TMath::Sqrt(2.);
01033             for (i = numx - 1; i > 0; i--) {
01034                working_vector[i + 2 * numx] =
01035                    -working_vector[i -
01036                                    1] * TMath::Cos(pi * i / (2 * numx));
01037                working_vector[i] =
01038                    working_vector[i - 1] * TMath::Sin(pi * i / (2 * numx));
01039             }
01040             for (i = 1; i < numx; i++) {
01041                working_vector[2 * numx - i] = working_vector[i];
01042                working_vector[2 * numx - i + 2 * numx] =
01043                    -working_vector[i + 2 * numx];
01044             }
01045             working_vector[0] = 0;
01046             working_vector[0 + 2 * numx] = 0;
01047             working_vector[numx + 2 * numx] = 0;
01048             Fourier(working_vector, 2 * numx, 0, kTransformInverse, 1);
01049             break;
01050          case kTransformFourier:
01051             Fourier(working_vector, numx, 0, kTransformInverse, 1);
01052             break;
01053          case kTransformHartley:
01054             Fourier(working_vector, numx, 1, kTransformInverse, 1);
01055             break;
01056          }
01057          for (i = 0; i < numx; i++) {
01058             working_matrix[i][j] = working_vector[i];
01059          }
01060       }
01061    }
01062    return;
01063 }
01064 
01065 //_____________________________________________________________________________
01066 void TSpectrum2Transform::General2(Float_t **working_matrix, Float_t *working_vector,
01067                             Int_t numx, Int_t numy, Int_t direction, Int_t type,
01068                             Int_t degree) 
01069 {
01070 //////////////////////////////////////////////////////////////////////////////////
01071 //   AUXILIARY FUNCION                                                          //
01072 //                                                                              //
01073 //   This function calculates generalized (mixed) 2D transforms                  //
01074 //      Function parameters:                                                    //
01075 //              -working_matrix-pointer to matrix of transformed data           //
01076 //              -working_vector-pointer to vector where the data are processed  //
01077 //              -numx,numy-lengths of processed data                            //
01078 //              -direction-forward or inverse                                   //
01079 //              -type-type of transform (see manual)                            //
01080 //              -degree-degree of transform (see manual)                        //
01081 //                                                                              //
01082 //////////////////////////////////////////////////////////////////////////////////
01083    Int_t i, j, jstup, kstup, l, m;
01084    Float_t val, valx, valz;
01085    Double_t a, b, pi = 3.14159265358979323846;
01086    if (direction == kTransformForward) {
01087       for (j = 0; j < numy; j++) {
01088          kstup = (Int_t) TMath::Power(2, degree);
01089          jstup = numx / kstup;
01090          for (i = 0; i < numx; i++) {
01091             val = working_matrix[i][j];
01092             if (type == kTransformCosWalsh
01093                  || type == kTransformCosHaar) {
01094                jstup = (Int_t) TMath::Power(2, degree) / 2;
01095                kstup = i / jstup;
01096                kstup = 2 * kstup * jstup;
01097                working_vector[kstup + i % jstup] = val;
01098                working_vector[kstup + 2 * jstup - 1 - i % jstup] = val;
01099             }
01100             
01101             else if (type == kTransformSinWalsh
01102                      || type == kTransformSinHaar) {
01103                jstup = (Int_t) TMath::Power(2, degree) / 2;
01104                kstup = i / jstup;
01105                kstup = 2 * kstup * jstup;
01106                working_vector[kstup + i % jstup] = val;
01107                working_vector[kstup + 2 * jstup - 1 - i % jstup] = -val;
01108             }
01109             
01110             else
01111                working_vector[i] = val;
01112          }
01113          switch (type) {
01114          case kTransformFourierWalsh:
01115          case kTransformFourierHaar:
01116          case kTransformWalshHaar:
01117             GeneralExe(working_vector, 0, numx, degree, type);
01118             for (i = 0; i < jstup; i++)
01119                BitReverseHaar(working_vector, numx, kstup, i * kstup);
01120             break;
01121          case kTransformCosWalsh:
01122          case kTransformCosHaar:
01123             m = (Int_t) TMath::Power(2, degree);
01124             l = 2 * numx / m;
01125             for (i = 0; i < l; i++)
01126                BitReverseHaar(working_vector, 2 * numx, m, i * m);
01127             GeneralExe(working_vector, 0, 2 * numx, degree, type);
01128             for (i = 0; i < numx; i++) {
01129                kstup = i / jstup;
01130                kstup = 2 * kstup * jstup;
01131                a = pi * (Double_t) (i % jstup) / (Double_t) (2 * jstup);
01132                a = TMath::Cos(a);
01133                b = working_vector[kstup + i % jstup];
01134                if (i % jstup == 0)
01135                   a = b / TMath::Sqrt(2.0);
01136                
01137                else
01138                   a = b / a;
01139                working_vector[i] = a;
01140                working_vector[i + 4 * numx] = 0;
01141             }
01142             break;
01143          case kTransformSinWalsh:
01144          case kTransformSinHaar:
01145             m = (Int_t) TMath::Power(2, degree);
01146             l = 2 * numx / m;
01147             for (i = 0; i < l; i++)
01148                BitReverseHaar(working_vector, 2 * numx, m, i * m);
01149             GeneralExe(working_vector, 0, 2 * numx, degree, type);
01150             for (i = 0; i < numx; i++) {
01151                kstup = i / jstup;
01152                kstup = 2 * kstup * jstup;
01153                a = pi * (Double_t) (i % jstup) / (Double_t) (2 * jstup);
01154                a = TMath::Cos(a);
01155                b = working_vector[jstup + kstup + i % jstup];
01156                if (i % jstup == 0)
01157                   a = b / TMath::Sqrt(2.0);
01158                
01159                else
01160                   a = b / a;
01161                working_vector[jstup + kstup / 2 - i % jstup - 1] = a;
01162                working_vector[i + 4 * numx] = 0;
01163             }
01164             break;
01165          }
01166          if (type > kTransformWalshHaar)
01167             kstup = (Int_t) TMath::Power(2, degree - 1);
01168          
01169          else
01170             kstup = (Int_t) TMath::Power(2, degree);
01171          jstup = numx / kstup;
01172          for (i = 0, l = 0; i < numx; i++, l = (l + kstup) % numx) {
01173             working_vector[numx + i] = working_vector[l + i / jstup];
01174             if (type == kTransformFourierWalsh
01175                  || type == kTransformFourierHaar
01176                  || type == kTransformWalshHaar)
01177                working_vector[numx + i + 2 * numx] =
01178                    working_vector[l + i / jstup + 2 * numx];
01179             
01180             else
01181                working_vector[numx + i + 4 * numx] =
01182                    working_vector[l + i / jstup + 4 * numx];
01183          }
01184          for (i = 0; i < numx; i++) {
01185             working_vector[i] = working_vector[numx + i];
01186             if (type == kTransformFourierWalsh
01187                  || type == kTransformFourierHaar
01188                  || type == kTransformWalshHaar)
01189                working_vector[i + 2 * numx] =
01190                    working_vector[numx + i + 2 * numx];
01191             
01192             else
01193                working_vector[i + 4 * numx] =
01194                    working_vector[numx + i + 4 * numx];
01195          }
01196          for (i = 0; i < numx; i++) {
01197             working_matrix[i][j] = working_vector[i];
01198             if (type == kTransformFourierWalsh
01199                  || type == kTransformFourierHaar
01200                  || type == kTransformWalshHaar)
01201                working_matrix[i][j + numy] = working_vector[i + 2 * numx];
01202             
01203             else
01204                working_matrix[i][j + numy] = working_vector[i + 4 * numx];
01205          }
01206       }
01207       for (i = 0; i < numx; i++) {
01208          kstup = (Int_t) TMath::Power(2, degree);
01209          jstup = numy / kstup;
01210          for (j = 0; j < numy; j++) {
01211             valx = working_matrix[i][j];
01212             valz = working_matrix[i][j + numy];
01213             if (type == kTransformCosWalsh
01214                  || type == kTransformCosHaar) {
01215                jstup = (Int_t) TMath::Power(2, degree) / 2;
01216                kstup = j / jstup;
01217                kstup = 2 * kstup * jstup;
01218                working_vector[kstup + j % jstup] = valx;
01219                working_vector[kstup + 2 * jstup - 1 - j % jstup] = valx;
01220                working_vector[kstup + j % jstup + 4 * numy] = valz;
01221                working_vector[kstup + 2 * jstup - 1 - j % jstup +
01222                                4 * numy] = valz;
01223             }
01224             
01225             else if (type == kTransformSinWalsh
01226                      || type == kTransformSinHaar) {
01227                jstup = (Int_t) TMath::Power(2, degree) / 2;
01228                kstup = j / jstup;
01229                kstup = 2 * kstup * jstup;
01230                working_vector[kstup + j % jstup] = valx;
01231                working_vector[kstup + 2 * jstup - 1 - j % jstup] = -valx;
01232                working_vector[kstup + j % jstup + 4 * numy] = valz;
01233                working_vector[kstup + 2 * jstup - 1 - j % jstup +
01234                                4 * numy] = -valz;
01235             }
01236             
01237             else {
01238                working_vector[j] = valx;
01239                working_vector[j + 2 * numy] = valz;
01240             }
01241          }
01242          switch (type) {
01243          case kTransformFourierWalsh:
01244          case kTransformFourierHaar:
01245          case kTransformWalshHaar:
01246             GeneralExe(working_vector, 1, numy, degree, type);
01247             for (j = 0; j < jstup; j++)
01248                BitReverseHaar(working_vector, numy, kstup, j * kstup);
01249             break;
01250          case kTransformCosWalsh:
01251          case kTransformCosHaar:
01252             m = (Int_t) TMath::Power(2, degree);
01253             l = 2 * numy / m;
01254             for (j = 0; j < l; j++)
01255                BitReverseHaar(working_vector, 2 * numy, m, j * m);
01256             GeneralExe(working_vector, 1, 2 * numy, degree, type);
01257             for (j = 0; j < numy; j++) {
01258                kstup = j / jstup;
01259                kstup = 2 * kstup * jstup;
01260                a = pi * (Double_t) (j % jstup) / (Double_t) (2 * jstup);
01261                a = TMath::Cos(a);
01262                b = working_vector[kstup + j % jstup];
01263                if (j % jstup == 0)
01264                   a = b / TMath::Sqrt(2.0);
01265                
01266                else
01267                   a = b / a;
01268                working_vector[j] = a;
01269                working_vector[j + 4 * numy] = 0;
01270             }
01271             break;
01272          case kTransformSinWalsh:
01273          case kTransformSinHaar:
01274             m = (Int_t) TMath::Power(2, degree);
01275             l = 2 * numy / m;
01276             for (j = 0; j < l; j++)
01277                BitReverseHaar(working_vector, 2 * numy, m, j * m);
01278             GeneralExe(working_vector, 1, 2 * numy, degree, type);
01279             for (j = 0; j < numy; j++) {
01280                kstup = j / jstup;
01281                kstup = 2 * kstup * jstup;
01282                a = pi * (Double_t) (j % jstup) / (Double_t) (2 * jstup);
01283                a = TMath::Cos(a);
01284                b = working_vector[jstup + kstup + j % jstup];
01285                if (j % jstup == 0)
01286                   a = b / TMath::Sqrt(2.0);
01287                
01288                else
01289                   a = b / a;
01290                working_vector[jstup + kstup / 2 - j % jstup - 1] = a;
01291                working_vector[j + 4 * numy] = 0;
01292             }
01293             break;
01294          }
01295          if (type > kTransformWalshHaar)
01296             kstup = (Int_t) TMath::Power(2, degree - 1);
01297          
01298          else
01299             kstup = (Int_t) TMath::Power(2, degree);
01300          jstup = numy / kstup;
01301          for (j = 0, l = 0; j < numy; j++, l = (l + kstup) % numy) {
01302             working_vector[numy + j] = working_vector[l + j / jstup];
01303             if (type == kTransformFourierWalsh
01304                  || type == kTransformFourierHaar
01305                  || type == kTransformWalshHaar)
01306                working_vector[numy + j + 2 * numy] =
01307                    working_vector[l + j / jstup + 2 * numy];
01308             
01309             else
01310                working_vector[numy + j + 4 * numy] =
01311                    working_vector[l + j / jstup + 4 * numy];
01312          }
01313          for (j = 0; j < numy; j++) {
01314             working_vector[j] = working_vector[numy + j];
01315             if (type == kTransformFourierWalsh
01316                  || type == kTransformFourierHaar
01317                  || type == kTransformWalshHaar)
01318                working_vector[j + 2 * numy] =
01319                    working_vector[numy + j + 2 * numy];
01320             
01321             else
01322                working_vector[j + 4 * numy] =
01323                    working_vector[numy + j + 4 * numy];
01324          }
01325          for (j = 0; j < numy; j++) {
01326             working_matrix[i][j] = working_vector[j];
01327             if (type == kTransformFourierWalsh
01328                  || type == kTransformFourierHaar
01329                  || type == kTransformWalshHaar)
01330                working_matrix[i][j + numy] = working_vector[j + 2 * numy];
01331             
01332             else
01333                working_matrix[i][j + numy] = working_vector[j + 4 * numy];
01334          }
01335       }
01336    }
01337    
01338    else if (direction == kTransformInverse) {
01339       for (i = 0; i < numx; i++) {
01340          kstup = (Int_t) TMath::Power(2, degree);
01341          jstup = numy / kstup;
01342          for (j = 0; j < numy; j++) {
01343             working_vector[j] = working_matrix[i][j];
01344             if (type == kTransformFourierWalsh
01345                  || type == kTransformFourierHaar
01346                  || type == kTransformWalshHaar)
01347                working_vector[j + 2 * numy] = working_matrix[i][j + numy];
01348             
01349             else
01350                working_vector[j + 4 * numy] = working_matrix[i][j + numy];
01351          }
01352          if (type > kTransformWalshHaar)
01353             kstup = (Int_t) TMath::Power(2, degree - 1);
01354          
01355          else
01356             kstup = (Int_t) TMath::Power(2, degree);
01357          jstup = numy / kstup;
01358          for (j = 0, l = 0; j < numy; j++, l = (l + kstup) % numy) {
01359             working_vector[numy + l + j / jstup] = working_vector[j];
01360             if (type == kTransformFourierWalsh
01361                  || type == kTransformFourierHaar
01362                  || type == kTransformWalshHaar)
01363                working_vector[numy + l + j / jstup + 2 * numy] =
01364                    working_vector[j + 2 * numy];
01365             
01366             else
01367                working_vector[numy + l + j / jstup + 4 * numy] =
01368                    working_vector[j + 4 * numy];
01369          }
01370          for (j = 0; j < numy; j++) {
01371             working_vector[j] = working_vector[numy + j];
01372             if (type == kTransformFourierWalsh
01373                  || type == kTransformFourierHaar
01374                  || type == kTransformWalshHaar)
01375                working_vector[j + 2 * numy] =
01376                    working_vector[numy + j + 2 * numy];
01377             
01378             else
01379                working_vector[j + 4 * numy] =
01380                    working_vector[numy + j + 4 * numy];
01381          }
01382          switch (type) {
01383          case kTransformFourierWalsh:
01384          case kTransformFourierHaar:
01385          case kTransformWalshHaar:
01386             for (j = 0; j < jstup; j++)
01387                BitReverseHaar(working_vector, numy, kstup, j * kstup);
01388             GeneralInv(working_vector, numy, degree, type);
01389             break;
01390          case kTransformCosWalsh:
01391          case kTransformCosHaar:
01392             jstup = (Int_t) TMath::Power(2, degree) / 2;
01393             m = (Int_t) TMath::Power(2, degree);
01394             l = 2 * numy / m;
01395             for (j = 0; j < numy; j++) {
01396                kstup = j / jstup;
01397                kstup = 2 * kstup * jstup;
01398                a = pi * (Double_t) (j % jstup) / (Double_t) (2 * jstup);
01399                if (j % jstup == 0) {
01400                   working_vector[2 * numy + kstup + j % jstup] =
01401                       working_vector[j] * TMath::Sqrt(2.0);
01402                   working_vector[2 * numy + kstup + j % jstup +
01403                                   4 * numy] = 0;
01404                }
01405                
01406                else {
01407                   b = TMath::Sin(a);
01408                   a = TMath::Cos(a);
01409                   working_vector[2 * numy + kstup + j % jstup +
01410                                   4 * numy] =
01411                       -(Double_t) working_vector[j] * b;
01412                   working_vector[2 * numy + kstup + j % jstup] =
01413                       (Double_t) working_vector[j] * a;
01414             } } for (j = 0; j < numy; j++) {
01415                kstup = j / jstup;
01416                kstup = 2 * kstup * jstup;
01417                if (j % jstup == 0) {
01418                   working_vector[2 * numy + kstup + jstup] = 0;
01419                   working_vector[2 * numy + kstup + jstup + 4 * numy] = 0;
01420                }
01421                
01422                else {
01423                   working_vector[2 * numy + kstup + 2 * jstup -
01424                                   j % jstup] =
01425                       working_vector[2 * numy + kstup + j % jstup];
01426                   working_vector[2 * numy + kstup + 2 * jstup -
01427                                   j % jstup + 4 * numy] =
01428                       -working_vector[2 * numy + kstup + j % jstup +
01429                                       4 * numy];
01430                }
01431             }
01432             for (j = 0; j < 2 * numy; j++) {
01433                working_vector[j] = working_vector[2 * numy + j];
01434                working_vector[j + 4 * numy] =
01435                    working_vector[2 * numy + j + 4 * numy];
01436             }
01437             GeneralInv(working_vector, 2 * numy, degree, type);
01438             m = (Int_t) TMath::Power(2, degree);
01439             l = 2 * numy / m;
01440             for (j = 0; j < l; j++)
01441                BitReverseHaar(working_vector, 2 * numy, m, j * m);
01442             break;
01443          case kTransformSinWalsh:
01444          case kTransformSinHaar:
01445             jstup = (Int_t) TMath::Power(2, degree) / 2;
01446             m = (Int_t) TMath::Power(2, degree);
01447             l = 2 * numy / m;
01448             for (j = 0; j < numy; j++) {
01449                kstup = j / jstup;
01450                kstup = 2 * kstup * jstup;
01451                a = pi * (Double_t) (j % jstup) / (Double_t) (2 * jstup);
01452                if (j % jstup == 0) {
01453                   working_vector[2 * numy + kstup + jstup + j % jstup] =
01454                       working_vector[jstup + kstup / 2 - j % jstup -
01455                                      1] * TMath::Sqrt(2.0);
01456                   working_vector[2 * numy + kstup + jstup + j % jstup +
01457                                   4 * numy] = 0;
01458                }
01459                
01460                else {
01461                   b = TMath::Sin(a);
01462                   a = TMath::Cos(a);
01463                   working_vector[2 * numy + kstup + jstup + j % jstup +
01464                                   4 * numy] =
01465                       -(Double_t) working_vector[jstup + kstup / 2 -
01466                                                j % jstup - 1] * b;
01467                   working_vector[2 * numy + kstup + jstup + j % jstup] =
01468                       (Double_t) working_vector[jstup + kstup / 2 -
01469                                               j % jstup - 1] * a;
01470             } } for (j = 0; j < numy; j++) {
01471                kstup = j / jstup;
01472                kstup = 2 * kstup * jstup;
01473                if (j % jstup == 0) {
01474                   working_vector[2 * numy + kstup] = 0;
01475                   working_vector[2 * numy + kstup + 4 * numy] = 0;
01476                }
01477                
01478                else {
01479                   working_vector[2 * numy + kstup + j % jstup] =
01480                       working_vector[2 * numy + kstup + 2 * jstup -
01481                                      j % jstup];
01482                   working_vector[2 * numy + kstup + j % jstup +
01483                                   4 * numy] =
01484                       -working_vector[2 * numy + kstup + 2 * jstup -
01485                                       j % jstup + 4 * numy];
01486                }
01487             }
01488             for (j = 0; j < 2 * numy; j++) {
01489                working_vector[j] = working_vector[2 * numy + j];
01490                working_vector[j + 4 * numy] =
01491                    working_vector[2 * numy + j + 4 * numy];
01492             }
01493             GeneralInv(working_vector, 2 * numy, degree, type);
01494             for (j = 0; j < l; j++)
01495                BitReverseHaar(working_vector, 2 * numy, m, j * m);
01496             break;
01497          }
01498          for (j = 0; j < numy; j++) {
01499             if (type > kTransformWalshHaar) {
01500                kstup = j / jstup;
01501                kstup = 2 * kstup * jstup;
01502                valx = working_vector[kstup + j % jstup];
01503                valz = working_vector[kstup + j % jstup + 4 * numy];
01504             }
01505             
01506             else {
01507                valx = working_vector[j];
01508                valz = working_vector[j + 2 * numy];
01509             }
01510             working_matrix[i][j] = valx;
01511             working_matrix[i][j + numy] = valz;
01512          }
01513       }
01514       for (j = 0; j < numy; j++) {
01515          kstup = (Int_t) TMath::Power(2, degree);
01516          jstup = numy / kstup;
01517          for (i = 0; i < numx; i++) {
01518             working_vector[i] = working_matrix[i][j];
01519             if (type == kTransformFourierWalsh
01520                  || type == kTransformFourierHaar
01521                  || type == kTransformWalshHaar)
01522                working_vector[i + 2 * numx] = working_matrix[i][j + numy];
01523             
01524             else
01525                working_vector[i + 4 * numx] = working_matrix[i][j + numy];
01526          }
01527          if (type > kTransformWalshHaar)
01528             kstup = (Int_t) TMath::Power(2, degree - 1);
01529          
01530          else
01531             kstup = (Int_t) TMath::Power(2, degree);
01532          jstup = numx / kstup;
01533          for (i = 0, l = 0; i < numx; i++, l = (l + kstup) % numx) {
01534             working_vector[numx + l + i / jstup] = working_vector[i];
01535             if (type == kTransformFourierWalsh
01536                  || type == kTransformFourierHaar
01537                  || type == kTransformWalshHaar)
01538                working_vector[numx + l + i / jstup + 2 * numx] =
01539                    working_vector[i + 2 * numx];
01540             
01541             else
01542                working_vector[numx + l + i / jstup + 4 * numx] =
01543                    working_vector[i + 4 * numx];
01544          }
01545          for (i = 0; i < numx; i++) {
01546             working_vector[i] = working_vector[numx + i];
01547             if (type == kTransformFourierWalsh
01548                  || type == kTransformFourierHaar
01549                  || type == kTransformWalshHaar)
01550                working_vector[i + 2 * numx] =
01551                    working_vector[numx + i + 2 * numx];
01552             
01553             else
01554                working_vector[i + 4 * numx] =
01555                    working_vector[numx + i + 4 * numx];
01556          }
01557          switch (type) {
01558          case kTransformFourierWalsh:
01559          case kTransformFourierHaar:
01560          case kTransformWalshHaar:
01561             for (i = 0; i < jstup; i++)
01562                BitReverseHaar(working_vector, numx, kstup, i * kstup);
01563             GeneralInv(working_vector, numx, degree, type);
01564             break;
01565          case kTransformCosWalsh:
01566          case kTransformCosHaar:
01567             jstup = (Int_t) TMath::Power(2, degree) / 2;
01568             m = (Int_t) TMath::Power(2, degree);
01569             l = 2 * numx / m;
01570             for (i = 0; i < numx; i++) {
01571                kstup = i / jstup;
01572                kstup = 2 * kstup * jstup;
01573                a = pi * (Double_t) (i % jstup) / (Double_t) (2 * jstup);
01574                if (i % jstup == 0) {
01575                   working_vector[2 * numx + kstup + i % jstup] =
01576                       working_vector[i] * TMath::Sqrt(2.0);
01577                   working_vector[2 * numx + kstup + i % jstup +
01578                                   4 * numx] = 0;
01579                }
01580                
01581                else {
01582                   b = TMath::Sin(a);
01583                   a = TMath::Cos(a);
01584                   working_vector[2 * numx + kstup + i % jstup +
01585                                   4 * numx] =
01586                       -(Double_t) working_vector[i] * b;
01587                   working_vector[2 * numx + kstup + i % jstup] =
01588                       (Double_t) working_vector[i] * a;
01589             } } for (i = 0; i < numx; i++) {
01590                kstup = i / jstup;
01591                kstup = 2 * kstup * jstup;
01592                if (i % jstup == 0) {
01593                   working_vector[2 * numx + kstup + jstup] = 0;
01594                   working_vector[2 * numx + kstup + jstup + 4 * numx] = 0;
01595                }
01596                
01597                else {
01598                   working_vector[2 * numx + kstup + 2 * jstup -
01599                                   i % jstup] =
01600                       working_vector[2 * numx + kstup + i % jstup];
01601                   working_vector[2 * numx + kstup + 2 * jstup -
01602                                   i % jstup + 4 * numx] =
01603                       -working_vector[2 * numx + kstup + i % jstup +
01604                                       4 * numx];
01605                }
01606             }
01607             for (i = 0; i < 2 * numx; i++) {
01608                working_vector[i] = working_vector[2 * numx + i];
01609                working_vector[i + 4 * numx] =
01610                    working_vector[2 * numx + i + 4 * numx];
01611             }
01612             GeneralInv(working_vector, 2 * numx, degree, type);
01613             m = (Int_t) TMath::Power(2, degree);
01614             l = 2 * numx / m;
01615             for (i = 0; i < l; i++)
01616                BitReverseHaar(working_vector, 2 * numx, m, i * m);
01617             break;
01618          case kTransformSinWalsh:
01619          case kTransformSinHaar:
01620             jstup = (Int_t) TMath::Power(2, degree) / 2;
01621             m = (Int_t) TMath::Power(2, degree);
01622             l = 2 * numx / m;
01623             for (i = 0; i < numx; i++) {
01624                kstup = i / jstup;
01625                kstup = 2 * kstup * jstup;
01626                a = pi * (Double_t) (i % jstup) / (Double_t) (2 * jstup);
01627                if (i % jstup == 0) {
01628                   working_vector[2 * numx + kstup + jstup + i % jstup] =
01629                       working_vector[jstup + kstup / 2 - i % jstup -
01630                                      1] * TMath::Sqrt(2.0);
01631                   working_vector[2 * numx + kstup + jstup + i % jstup +
01632                                   4 * numx] = 0;
01633                }
01634                
01635                else {
01636                   b = TMath::Sin(a);
01637                   a = TMath::Cos(a);
01638                   working_vector[2 * numx + kstup + jstup + i % jstup +
01639                                   4 * numx] =
01640                       -(Double_t) working_vector[jstup + kstup / 2 -
01641                                                i % jstup - 1] * b;
01642                   working_vector[2 * numx + kstup + jstup + i % jstup] =
01643                       (Double_t) working_vector[jstup + kstup / 2 -
01644                                               i % jstup - 1] * a;
01645             } } for (i = 0; i < numx; i++) {
01646                kstup = i / jstup;
01647                kstup = 2 * kstup * jstup;
01648                if (i % jstup == 0) {
01649                   working_vector[2 * numx + kstup] = 0;
01650                   working_vector[2 * numx + kstup + 4 * numx] = 0;
01651                }
01652                
01653                else {
01654                   working_vector[2 * numx + kstup + i % jstup] =
01655                       working_vector[2 * numx + kstup + 2 * jstup -
01656                                      i % jstup];
01657                   working_vector[2 * numx + kstup + i % jstup +
01658                                   4 * numx] =
01659                       -working_vector[2 * numx + kstup + 2 * jstup -
01660                                       i % jstup + 4 * numx];
01661                }
01662             }
01663             for (i = 0; i < 2 * numx; i++) {
01664                working_vector[i] = working_vector[2 * numx + i];
01665                working_vector[i + 4 * numx] =
01666                    working_vector[2 * numx + i + 4 * numx];
01667             }
01668             GeneralInv(working_vector, 2 * numx, degree, type);
01669             for (i = 0; i < l; i++)
01670                BitReverseHaar(working_vector, 2 * numx, m, i * m);
01671             break;
01672          }
01673          for (i = 0; i < numx; i++) {
01674             if (type > kTransformWalshHaar) {
01675                kstup = i / jstup;
01676                kstup = 2 * kstup * jstup;
01677                val = working_vector[kstup + i % jstup];
01678             }
01679             
01680             else
01681                val = working_vector[i];
01682             working_matrix[i][j] = val;
01683          }
01684       }
01685    }
01686    return;
01687 }
01688 
01689 ///////////////////////END OF AUXILIARY TRANSFORM2 FUNCTIONS//////////////////////////////////////////
01690 
01691     
01692 //////////TRANSFORM2 FUNCTION - CALCULATES DIFFERENT 2-D DIRECT AND INVERSE ORTHOGONAL TRANSFORMS//////
01693 //_____________________________________________________________________________
01694 void TSpectrum2Transform::Transform(const Float_t **fSource, Float_t **fDest)
01695 {
01696 //////////////////////////////////////////////////////////////////////////////////////////
01697 /* TWO-DIMENSIONAL TRANSFORM FUNCTION                    */ 
01698 /* This function transforms the source spectrum. The calling program               */ 
01699 /*      should fill in input parameters.                                          */ 
01700 /* Transformed data are written into dest spectrum.                                */ 
01701 /*                         */ 
01702 /* Function parameters:                      */ 
01703 /* fSource-pointer to the matrix of source spectrum, its size should               */ 
01704 /*             be fSizex*fSizey except for inverse FOURIER, FOUR-WALSH, FOUR-HAAR       */ 
01705 /*             transform. These need fSizex*2*fSizey length to supply real and          */ 
01706 /*             imaginary coefficients.                                                  */ 
01707 /* fDest-pointer to the matrix of destination data, its size should be             */ 
01708 /*           fSizex*fSizey except for direct FOURIER, FOUR-WALSh, FOUR-HAAR. These      */ 
01709 /*           need fSizex*2*fSizey length to store real and imaginary coefficients       */ 
01710 /* fSizex,fSizey-basic dimensions of source and dest spectra                       */ 
01711 /*                         */ 
01712 //////////////////////////////////////////////////////////////////////////////////////////
01713 //Begin_Html <!--
01714 /* -->
01715 <div class=Section1>
01716 
01717 <p class=MsoNormal><b><span style='font-size:14.0pt'>Transform methods</span></b></p>
01718 
01719 <p class=MsoNormal style='text-align:justify'><i>&nbsp;</i></p>
01720 
01721 <p class=MsoNormal style='text-align:justify'><i>Goal: to analyze experimental
01722 data using orthogonal transforms</i></p>
01723 
01724 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01725 -18.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01726 </span>orthogonal transforms can be successfully used for the processing of
01727 nuclear spectra (not only) </p>
01728 
01729 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01730 -18.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01731 </span>they can be used to remove high frequency noise, to increase
01732 signal-to-background ratio as well as to enhance low intensity components [1],
01733 to carry out e.g. Fourier analysis etc. </p>
01734 
01735 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01736 -18.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01737 </span>we have implemented the function for the calculation of the commonly
01738 used orthogonal transforms as well as functions for the filtration and
01739 enhancement of experimental data</p>
01740 
01741 <p class=MsoNormal><i>&nbsp;</i></p>
01742 
01743 <p class=MsoNormal><i>Function:</i></p>
01744 
01745 <p class=MsoNormal>void <a
01746 href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b>TSpectrumTransform2::Transform</b></a><b>(const
01747 <a href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a> **fSource,
01748 <a href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a> **fDest)</b></p>
01749 
01750 <p class=MsoNormal style='text-align:justify'>&nbsp;</p>
01751 
01752 <p class=MsoNormal style='text-align:justify'>This function transforms the
01753 source spectrum according to the given input parameters. Transformed data are
01754 written into dest spectrum. Before the Transform function is called the class
01755 must be created by constructor and the type of the transform as well as some
01756 other parameters must be set using a set of setter functions:</p>
01757 
01758 <p class=MsoNormal><span lang=FR>&nbsp;</span></p>
01759 
01760 <p class=MsoNormal><i><span style='color:red'>Member variables of
01761 TSpectrumTransform2 class:</span></i></p>
01762 
01763 <p class=MsoNormal style='margin-left:25.65pt;text-align:justify'><b>fSource</b>-pointer
01764 to the matrix of source spectrum. Its lengths should be equal to the “fSizex,
01765 fSizey” parameters except for inverse FOURIER, FOUR-WALSH, FOUR-HAAR
01766 transforms. These need “2*fSizex*fSizey” length to supply real and imaginary
01767 coefficients.                   </p>
01768 
01769 <p class=MsoNormal style='margin-left:25.65pt;text-align:justify'><b>fDest</b>-pointer
01770 to the matrix of destination spectrum. Its lengths should be equal to the
01771 “fSizex, fSizey” parameters except for inverse FOURIER, FOUR-WALSH, FOUR-HAAR
01772 transforms. These need “2*fSizex*fSizey” length to store real and imaginary
01773 coefficients. </p>
01774 
01775 <p class=MsoNormal style='text-align:justify'>        <b>fSizeX,fSizeY</b>-basic
01776 lengths of the source and dest spectra. They<span style='color:fuchsia'> should
01777 be power  </span></p>
01778 
01779 <p class=MsoNormal style='text-align:justify'><span style='color:fuchsia'>     
01780 of 2.</span></p>
01781 
01782 <p class=MsoNormal style='margin-left:25.65pt;text-align:justify;text-indent:
01783 -2.85pt'><b>fType</b>-type of transform</p>
01784 
01785 <p class=MsoNormal style='text-align:justify'>            Classic transforms:</p>
01786 
01787 <p class=MsoNormal style='text-align:justify'>                        kTransformHaar
01788 </p>
01789 
01790 <p class=MsoNormal style='text-align:justify'>                        kTransformWalsh
01791 </p>
01792 
01793 <p class=MsoNormal style='text-align:justify'>                        kTransformCos
01794 </p>
01795 
01796 <p class=MsoNormal style='text-align:justify'>                        kTransformSin
01797 </p>
01798 
01799 <p class=MsoNormal style='text-align:justify'>                        kTransformFourier
01800 </p>
01801 
01802 <p class=MsoNormal style='text-align:justify'>                        kTransformHartley
01803 </p>
01804 
01805 <p class=MsoNormal style='text-align:justify'>            Mixed transforms:</p>
01806 
01807 <p class=MsoNormal style='text-align:justify'>                        kTransformFourierWalsh
01808 </p>
01809 
01810 <p class=MsoNormal style='text-align:justify'>                        kTransformFourierHaar
01811 </p>
01812 
01813 <p class=MsoNormal style='text-align:justify'>                        kTransformWalshHaar
01814 </p>
01815 
01816 <p class=MsoNormal style='text-align:justify'>                        kTransformCosWalsh
01817 </p>
01818 
01819 <p class=MsoNormal style='text-align:justify'>                        kTransformCosHaar
01820 </p>
01821 
01822 <p class=MsoNormal style='text-align:justify'>                        kTransformSinWalsh
01823 </p>
01824 
01825 <p class=MsoNormal style='text-align:justify'>                        kTransformSinHaar
01826 </p>
01827 
01828 <p class=MsoNormal style='text-align:justify;text-indent:22.8pt'><b>fDirection</b>-direction-transform
01829 direction (forward, inverse)</p>
01830 
01831 <p class=MsoNormal style='text-align:justify'>                        kTransformForward
01832 </p>
01833 
01834 <p class=MsoNormal style='text-align:justify'>                        kTransformInverse
01835 </p>
01836 
01837 <p class=MsoNormal style='text-align:justify;text-indent:22.8pt'><b>fDegree</b>-applies
01838 only for mixed transforms [2], [3], [4]. </p>
01839 
01840 <p class=MsoNormal style='text-align:justify;text-indent:22.8pt'>                
01841 <span style='color:fuchsia'> Allowed range  <sub><img border=0 width=100
01842 height=27 src="gif/spectrum2transform_transform_image001.gif"></sub>. </span></p>
01843 
01844 <p class=MsoNormal style='text-align:justify'><b><i>References:</i></b></p>
01845 
01846 <p class=MsoNormal style='text-align:justify'>[1] C.V. Hampton, B. Lian, Wm. C.
01847 McHarris: Fast-Fourier-transform spectral enhancement techniques for gamma-ray
01848 spectroscopy. NIM A353 (1994) 280-284. </p>
01849 
01850 <p class=MsoNormal style='text-align:justify'>[2] Morhá&#269; M., Matoušek V.,
01851 New adaptive Cosine-Walsh  transform and its application to nuclear data
01852 compression, IEEE Transactions on Signal Processing 48 (2000) 2693.  </p>
01853 
01854 <p class=MsoNormal style='text-align:justify'>[3] Morhá&#269; M., Matoušek V.,
01855 Data compression using new fast adaptive Cosine-Haar transforms, Digital Signal
01856 Processing 8 (1998) 63. </p>
01857 
01858 <p class=MsoNormal style='text-align:justify'>[4] Morhá&#269; M., Matoušek V.:
01859 Multidimensional nuclear data compression using fast adaptive Walsh-Haar
01860 transform. Acta Physica Slovaca 51 (2001) 307. </p>
01861 
01862 <p class=MsoNormal style='text-align:justify'>&nbsp;</p>
01863 
01864 <p class=MsoNormal style='text-align:justify'><i>Example 1 – script Transform2.c:</i></p>
01865 
01866 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'><img
01867 border=0 width=602 height=455 src="gif/spectrum2transform_transform_image002.jpg"></span></p>
01868 
01869 <p class=MsoNormal><b>Fig. 1 Original two-dimensional noisy spectrum</b></p>
01870 
01871 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'><img
01872 border=0 width=602 height=455 src="gif/spectrum2transform_transform_image003.jpg"></span></p>
01873 
01874 <p class=MsoNormal style='text-align:justify'><b>Fig. 2 Transformed spectrum
01875 from Fig. 1 using Cosine transform. Energy of the trasnsformed data is
01876 concentrated around the beginning of the coordinate system</b></p>
01877 
01878 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>&nbsp;</span></b></p>
01879 
01880 <p class=MsoNormal><b><span style='color:#339966'>Script:</span></b></p>
01881 
01882 <p class=MsoNormal><span style='font-size:10.0pt'>// Example to illustrate
01883 Transform function (class TSpectrumTransform2).</span></p>
01884 
01885 <p class=MsoNormal><span style='font-size:10.0pt'>// To execute this example,
01886 do</span></p>
01887 
01888 <p class=MsoNormal><span style='font-size:10.0pt'>// root &gt; .x Transform2.C</span></p>
01889 
01890 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>void Transform2() {</span></p>
01891 
01892 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t i, j;</span></p>
01893 
01894 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t nbinsx =
01895 256;</span></p>
01896 
01897 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t nbinsy =
01898 256;   </span></p>
01899 
01900 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t xmin  = 0;</span></p>
01901 
01902 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t xmax  =
01903 nbinsx;</span></p>
01904 
01905 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t ymin  = 0;</span></p>
01906 
01907 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t ymax  = nbinsy;</span></p>
01908 
01909 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   </span><span
01910 style='font-size:10.0pt'>Float_t ** source = new float *[nbinsx];   </span></p>
01911 
01912 <p class=MsoNormal><span style='font-size:10.0pt'>   Float_t ** dest = new
01913 float *[nbinsx];      </span></p>
01914 
01915 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i=0;i&lt;nbinsx;i++)</span></p>
01916 
01917 <p class=MsoNormal><span style='font-size:10.0pt'>                                                source[i]=new
01918 float[nbinsy];</span></p>
01919 
01920 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i=0;i&lt;nbinsx;i++)</span></p>
01921 
01922 <p class=MsoNormal><span style='font-size:10.0pt'>                                                dest[i]=new
01923 float[nbinsy];   </span></p>
01924 
01925 <p class=MsoNormal><span style='font-size:10.0pt'>   TH2F *trans = new
01926 TH2F(&quot;trans&quot;,&quot;Background
01927 estimation&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</span></p>
01928 
01929 <p class=MsoNormal><span style='font-size:10.0pt'>   TFile *f = new
01930 TFile(&quot;TSpectrum2.root&quot;);</span></p>
01931 
01932 <p class=MsoNormal><span style='font-size:10.0pt'>   trans=(TH2F*)
01933 f-&gt;Get(&quot;back3;1&quot;);</span></p>
01934 
01935 <p class=MsoNormal><span style='font-size:10.0pt'>   TCanvas *Tr = new
01936 TCanvas(&quot;Transform&quot;,&quot;Illustation of transform
01937 function&quot;,10,10,1000,700);</span></p>
01938 
01939 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i = 0; i &lt; nbinsx;
01940 i++){</span></p>
01941 
01942 <p class=MsoNormal><span style='font-size:10.0pt'>     for (j = 0; j &lt;
01943 nbinsy; j++){</span></p>
01944 
01945 <p class=MsoNormal><span style='font-size:10.0pt'>                    source[i][j]
01946 = trans-&gt;GetBinContent(i + 1,j + 1); </span></p>
01947 
01948 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>                 }</span></p>
01949 
01950 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   }           </span></p>
01951 
01952 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
01953 TSpectrumTransform2 *t = new TSpectrumTransform2(256,256);   </span></p>
01954 
01955 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
01956 t-&gt;SetTransformType(t-&gt;kTransformCos,0);</span></p>
01957 
01958 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   t-&gt;SetDirection(t-&gt;kTransformForward);</span></p>
01959 
01960 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
01961 t-&gt;Transform(source,dest);</span></p>
01962 
01963 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   </span><span
01964 style='font-size:10.0pt'>for (i = 0; i &lt; nbinsx; i++){</span></p>
01965 
01966 <p class=MsoNormal><span style='font-size:10.0pt'>     for (j = 0; j &lt;
01967 nbinsy; j++){</span></p>
01968 
01969 <p class=MsoNormal><span style='font-size:10.0pt'>                  trans-&gt;SetBinContent(i
01970 + 1, j + 1,dest[i][j]);</span></p>
01971 
01972 <p class=MsoNormal><span style='font-size:10.0pt'>                 }</span></p>
01973 
01974 <p class=MsoNormal><span style='font-size:10.0pt'>   }   </span></p>
01975 
01976 <p class=MsoNormal><span style='font-size:10.0pt'>  
01977 trans-&gt;Draw(&quot;SURF&quot;);      </span></p>
01978 
01979 <p class=MsoNormal><span style='font-size:10.0pt'>}</span></p>
01980 
01981 </div>
01982 
01983 <!-- */
01984 // --> End_Html
01985    Int_t i, j;
01986    Int_t size;
01987    Float_t *working_vector = 0, **working_matrix = 0;
01988    size = (Int_t) TMath::Max(fSizeX, fSizeY);
01989    switch (fTransformType) {
01990    case kTransformHaar:
01991    case kTransformWalsh:
01992       working_vector = new Float_t[2 * size];
01993       working_matrix = new Float_t *[fSizeX];
01994       for (i = 0; i < fSizeX; i++)
01995          working_matrix[i] = new Float_t[fSizeY];
01996       break;
01997    case kTransformCos:
01998    case kTransformSin:
01999    case kTransformFourier:
02000    case kTransformHartley:
02001    case kTransformFourierWalsh:
02002    case kTransformFourierHaar:
02003    case kTransformWalshHaar:
02004       working_vector = new Float_t[4 * size];
02005       working_matrix = new Float_t *[fSizeX];
02006       for (i = 0; i < fSizeX; i++)
02007          working_matrix[i] = new Float_t[2 * fSizeY];
02008       break;
02009    case kTransformCosWalsh:
02010    case kTransformCosHaar:
02011    case kTransformSinWalsh:
02012    case kTransformSinHaar:
02013       working_vector = new Float_t[8 * size];
02014       working_matrix = new Float_t *[fSizeX];
02015       for (i = 0; i < fSizeX; i++)
02016          working_matrix[i] = new Float_t[2 * fSizeY];
02017       break;
02018    }
02019    if (fDirection == kTransformForward) {
02020       switch (fTransformType) {
02021       case kTransformHaar:
02022          for (i = 0; i < fSizeX; i++) {
02023             for (j = 0; j < fSizeY; j++) {
02024                working_matrix[i][j] = fSource[i][j];
02025             }
02026          }
02027          HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02028                      fDirection, kTransformHaar);
02029          for (i = 0; i < fSizeX; i++) {
02030             for (j = 0; j < fSizeY; j++) {
02031                fDest[i][j] = working_matrix[i][j];
02032             }
02033          }
02034          break;
02035       case kTransformWalsh:
02036          for (i = 0; i < fSizeX; i++) {
02037             for (j = 0; j < fSizeY; j++) {
02038                working_matrix[i][j] = fSource[i][j];
02039             }
02040          }
02041          HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02042                      fDirection, kTransformWalsh);
02043          for (i = 0; i < fSizeX; i++) {
02044             for (j = 0; j < fSizeY; j++) {
02045                fDest[i][j] = working_matrix[i][j];
02046             }
02047          }
02048          break;
02049       case kTransformCos:
02050          for (i = 0; i < fSizeX; i++) {
02051             for (j = 0; j < fSizeY; j++) {
02052                working_matrix[i][j] = fSource[i][j];
02053             }
02054          }
02055          FourCos2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02056                    kTransformCos);
02057          for (i = 0; i < fSizeX; i++) {
02058             for (j = 0; j < fSizeY; j++) {
02059                fDest[i][j] = working_matrix[i][j];
02060             }
02061          }
02062          break;
02063       case kTransformSin:
02064          for (i = 0; i < fSizeX; i++) {
02065             for (j = 0; j < fSizeY; j++) {
02066                working_matrix[i][j] = fSource[i][j];
02067             }
02068          }
02069          FourCos2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02070                    kTransformSin);
02071          for (i = 0; i < fSizeX; i++) {
02072             for (j = 0; j < fSizeY; j++) {
02073                fDest[i][j] = working_matrix[i][j];
02074             }
02075          }
02076          break;
02077       case kTransformFourier:
02078          for (i = 0; i < fSizeX; i++) {
02079             for (j = 0; j < fSizeY; j++) {
02080                working_matrix[i][j] = fSource[i][j];
02081             }
02082          }
02083          FourCos2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02084                    kTransformFourier);
02085          for (i = 0; i < fSizeX; i++) {
02086             for (j = 0; j < fSizeY; j++) {
02087                fDest[i][j] = working_matrix[i][j];
02088             }
02089          }
02090          for (i = 0; i < fSizeX; i++) {
02091             for (j = 0; j < fSizeY; j++) {
02092                fDest[i][j + fSizeY] = working_matrix[i][j + fSizeY];
02093             }
02094          }
02095          break;
02096       case kTransformHartley:
02097          for (i = 0; i < fSizeX; i++) {
02098             for (j = 0; j < fSizeY; j++) {
02099                working_matrix[i][j] = fSource[i][j];
02100             }
02101          }
02102          FourCos2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02103                    kTransformHartley);
02104          for (i = 0; i < fSizeX; i++) {
02105             for (j = 0; j < fSizeY; j++) {
02106                fDest[i][j] = working_matrix[i][j];
02107             }
02108          }
02109          break;
02110       case kTransformFourierWalsh:
02111       case kTransformFourierHaar:
02112       case kTransformWalshHaar:
02113       case kTransformCosWalsh:
02114       case kTransformCosHaar:
02115       case kTransformSinWalsh:
02116       case kTransformSinHaar:
02117          for (i = 0; i < fSizeX; i++) {
02118             for (j = 0; j < fSizeY; j++) {
02119                working_matrix[i][j] = fSource[i][j];
02120             }
02121          }
02122          General2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02123                    fTransformType, fDegree);
02124          for (i = 0; i < fSizeX; i++) {
02125             for (j = 0; j < fSizeY; j++) {
02126                fDest[i][j] = working_matrix[i][j];
02127             }
02128          }
02129          if (fTransformType == kTransformFourierWalsh
02130               || fTransformType == kTransformFourierHaar) {
02131             for (i = 0; i < fSizeX; i++) {
02132                for (j = 0; j < fSizeY; j++) {
02133                   fDest[i][j + fSizeY] = working_matrix[i][j + fSizeY];
02134                }
02135             }
02136          }
02137          break;
02138       }
02139    }
02140    
02141    else if (fDirection == kTransformInverse) {
02142       switch (fTransformType) {
02143       case kTransformHaar:
02144          for (i = 0; i < fSizeX; i++) {
02145             for (j = 0; j < fSizeY; j++) {
02146                working_matrix[i][j] = fSource[i][j];
02147             }
02148          }
02149          HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02150                      fDirection, kTransformHaar);
02151          for (i = 0; i < fSizeX; i++) {
02152             for (j = 0; j < fSizeY; j++) {
02153                fDest[i][j] = working_matrix[i][j];
02154             }
02155          }
02156          break;
02157       case kTransformWalsh:
02158          for (i = 0; i < fSizeX; i++) {
02159             for (j = 0; j < fSizeY; j++) {
02160                working_matrix[i][j] = fSource[i][j];
02161             }
02162          }
02163          HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02164                      fDirection, kTransformWalsh);
02165          for (i = 0; i < fSizeX; i++) {
02166             for (j = 0; j < fSizeY; j++) {
02167                fDest[i][j] = working_matrix[i][j];
02168             }
02169          }
02170          break;
02171       case kTransformCos:
02172          for (i = 0; i < fSizeX; i++) {
02173             for (j = 0; j < fSizeY; j++) {
02174                working_matrix[i][j] = fSource[i][j];
02175             }
02176          }
02177          FourCos2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02178                    kTransformCos);
02179          for (i = 0; i < fSizeX; i++) {
02180             for (j = 0; j < fSizeY; j++) {
02181                fDest[i][j] = working_matrix[i][j];
02182             }
02183          }
02184          break;
02185       case kTransformSin:
02186          for (i = 0; i < fSizeX; i++) {
02187             for (j = 0; j < fSizeY; j++) {
02188                working_matrix[i][j] = fSource[i][j];
02189             }
02190          }
02191          FourCos2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02192                    kTransformSin);
02193          for (i = 0; i < fSizeX; i++) {
02194             for (j = 0; j < fSizeY; j++) {
02195                fDest[i][j] = working_matrix[i][j];
02196             }
02197          }
02198          break;
02199       case kTransformFourier:
02200          for (i = 0; i < fSizeX; i++) {
02201             for (j = 0; j < fSizeY; j++) {
02202                working_matrix[i][j] = fSource[i][j];
02203             }
02204          }
02205          for (i = 0; i < fSizeX; i++) {
02206             for (j = 0; j < fSizeY; j++) {
02207                working_matrix[i][j + fSizeY] = fSource[i][j + fSizeY];
02208             }
02209          }
02210          FourCos2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02211                    kTransformFourier);
02212          for (i = 0; i < fSizeX; i++) {
02213             for (j = 0; j < fSizeY; j++) {
02214                fDest[i][j] = working_matrix[i][j];
02215             }
02216          }
02217          break;
02218       case kTransformHartley:
02219          for (i = 0; i < fSizeX; i++) {
02220             for (j = 0; j < fSizeY; j++) {
02221                working_matrix[i][j] = fSource[i][j];
02222             }
02223          }
02224          FourCos2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02225                    kTransformHartley);
02226          for (i = 0; i < fSizeX; i++) {
02227             for (j = 0; j < fSizeY; j++) {
02228                fDest[i][j] = working_matrix[i][j];
02229             }
02230          }
02231          break;
02232       case kTransformFourierWalsh:
02233       case kTransformFourierHaar:
02234       case kTransformWalshHaar:
02235       case kTransformCosWalsh:
02236       case kTransformCosHaar:
02237       case kTransformSinWalsh:
02238       case kTransformSinHaar:
02239          for (i = 0; i < fSizeX; i++) {
02240             for (j = 0; j < fSizeY; j++) {
02241                working_matrix[i][j] = fSource[i][j];
02242             }
02243          }
02244          if (fTransformType == kTransformFourierWalsh
02245               || fTransformType == kTransformFourierHaar) {
02246             for (i = 0; i < fSizeX; i++) {
02247                for (j = 0; j < fSizeY; j++) {
02248                   working_matrix[i][j + fSizeY] = fSource[i][j + fSizeY];
02249                }
02250             }
02251          }
02252          General2(working_matrix, working_vector, fSizeX, fSizeY, fDirection,
02253                    fTransformType, fDegree);
02254          for (i = 0; i < fSizeX; i++) {
02255             for (j = 0; j < fSizeY; j++) {
02256                fDest[i][j] = working_matrix[i][j];
02257             }
02258          }
02259          break;
02260       }
02261    }
02262    for (i = 0; i < fSizeX; i++) {
02263       if (working_matrix) delete[]working_matrix[i];
02264    }
02265    delete[]working_matrix;
02266    delete[]working_vector;
02267    return;
02268 }
02269 //////////END OF TRANSFORM2 FUNCTION/////////////////////////////////
02270 //_______________________________________________________________________________________
02271 //////////FILTER2_ZONAL FUNCTION - CALCULATES DIFFERENT 2-D ORTHOGONAL TRANSFORMS, SETS GIVEN REGION TO FILTER COEFFICIENT AND TRANSFORMS IT BACK//////
02272 void TSpectrum2Transform::FilterZonal(const Float_t **fSource, Float_t **fDest) 
02273 {
02274 //////////////////////////////////////////////////////////////////////////////////////////
02275 /* TWO-DIMENSIONAL FILTER ZONAL FUNCTION                      */ 
02276 /* This function transforms the source spectrum. The calling program               */ 
02277 /*      should fill in input parameters. Then it sets transformed                       */ 
02278 /*      coefficients in the given region to the given                                   */ 
02279 /*      filter_coeff and transforms it back                                             */ 
02280 /* Filtered data are written into dest spectrum.                                   */ 
02281 /*                         */ 
02282 /* Function parameters:                      */ 
02283 /* fSource-pointer to the matrix of source spectrum, its size should               */ 
02284 /*             be fSizeX*fSizeY                                                         */ 
02285 /* fDest-pointer to the matrix of destination data, its size should be             */ 
02286 /*           fSizeX*fSizeY                                                              */ 
02287 /*                         */ 
02288 //////////////////////////////////////////////////////////////////////////////////////////
02289 //Begin_Html <!--
02290 /* -->
02291 <div class=Section2>
02292 
02293 <p class=MsoNormal><b><span style='font-size:14.0pt'>Example of zonal filtering</span></b></p>
02294 
02295 <p class=MsoNormal><i>&nbsp;</i></p>
02296 
02297 <p class=MsoNormal><i>Function:</i></p>
02298 
02299 <p class=MsoNormal>void <a
02300 href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b>TSpectrumTransform2::FilterZonal</b></a><b>(const
02301 <a href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a> **fSource,
02302 <a href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a> **fDest)</b></p>
02303 
02304 <p class=MsoNormal style='text-align:justify'>&nbsp;</p>
02305 
02306 <p class=MsoNormal style='text-align:justify'>This function transforms the
02307 source spectrum (for details see Transform function).  Before the FilterZonal
02308 function is called the class must be created by constructor and the type of the
02309 transform as well as some other parameters must be set using a set of setter
02310 functions. The FilterZonal function sets transformed coefficients in the given
02311 region (fXmin, fXmax) to the given fFilterCoeff and transforms it back. Filtered
02312 data are written into dest spectrum. </p>
02313 
02314 <p class=MsoNormal style='text-align:justify'>&nbsp;</p>
02315 
02316 <p class=MsoNormal style='text-align:justify'><i>Example  – script Fitler2.c:</i></p>
02317 
02318 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'><img
02319 border=0 width=602 height=455 src="gif/spectrum2transform_filter_image001.jpg"></span></p>
02320 
02321 <p class=MsoNormal><b>Fig. 1 Original two-dimensional noisy spectrum</b></p>
02322 
02323 <p class=MsoNormal><b><span style='font-size:14.0pt'><img border=0 width=602
02324 height=455 src="gif/spectrum2transform_filter_image002.jpg"></span></b></p>
02325 
02326 <p class=MsoNormal style='text-align:justify'><b>Fig. 2 Filtered spectrum using
02327 Cosine transform and zonal filtration (channels in regions (128-255)x(0-255)
02328 and (0-255)x(128-255) were set to 0).  </b></p>
02329 
02330 <p class=MsoNormal><b><span style='color:#339966'>&nbsp;</span></b></p>
02331 
02332 <p class=MsoNormal><b><span style='color:#339966'>Script:</span></b></p>
02333 
02334 <p class=MsoNormal><span style='font-size:10.0pt'>// Example to illustrate
02335 zonal filtration (class TSpectrumTransform2).</span></p>
02336 
02337 <p class=MsoNormal><span style='font-size:10.0pt'>// To execute this example,
02338 do</span></p>
02339 
02340 <p class=MsoNormal><span style='font-size:10.0pt'>// root &gt; .x Filter2.C</span></p>
02341 
02342 <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
02343 
02344 <p class=MsoNormal><span style='font-size:10.0pt'>void Filter2() {</span></p>
02345 
02346 <p class=MsoNormal><span style='font-size:10.0pt'>   Int_t i, j;</span></p>
02347 
02348 <p class=MsoNormal><span style='font-size:10.0pt'>   </span><span lang=FR
02349 style='font-size:10.0pt'>Int_t nbinsx = 256;</span></p>
02350 
02351 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t nbinsy =
02352 256;   </span></p>
02353 
02354 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t xmin  = 0;</span></p>
02355 
02356 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t xmax  =
02357 nbinsx;</span></p>
02358 
02359 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t ymin  = 0;</span></p>
02360 
02361 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t ymax  =
02362 nbinsy;</span></p>
02363 
02364 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   </span><span
02365 style='font-size:10.0pt'>Float_t ** source = new float *[nbinsx];   </span></p>
02366 
02367 <p class=MsoNormal><span style='font-size:10.0pt'>   Float_t ** dest = new
02368 float *[nbinsx];      </span></p>
02369 
02370 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i=0;i&lt;nbinsx;i++)</span></p>
02371 
02372 <p class=MsoNormal><span style='font-size:10.0pt'>                                                source[i]=new
02373 float[nbinsy];</span></p>
02374 
02375 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i=0;i&lt;nbinsx;i++)</span></p>
02376 
02377 <p class=MsoNormal><span style='font-size:10.0pt'>                                                dest[i]=new
02378 float[nbinsy];   </span></p>
02379 
02380 <p class=MsoNormal><span style='font-size:10.0pt'>   TH2F *trans = new
02381 TH2F(&quot;trans&quot;,&quot;Background
02382 estimation&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</span></p>
02383 
02384 <p class=MsoNormal><span style='font-size:10.0pt'>   TFile *f = new
02385 TFile(&quot;TSpectrum2.root&quot;);</span></p>
02386 
02387 <p class=MsoNormal><span style='font-size:10.0pt'>   trans=(TH2F*)
02388 f-&gt;Get(&quot;back3;1&quot;);</span></p>
02389 
02390 <p class=MsoNormal><span style='font-size:10.0pt'>   TCanvas *Tr = new
02391 TCanvas(&quot;Transform&quot;,&quot;Illustation of transform
02392 function&quot;,10,10,1000,700);</span></p>
02393 
02394 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i = 0; i &lt; nbinsx;
02395 i++){</span></p>
02396 
02397 <p class=MsoNormal><span style='font-size:10.0pt'>     for (j = 0; j &lt;
02398 nbinsy; j++){</span></p>
02399 
02400 <p class=MsoNormal><span style='font-size:10.0pt'>                    </span><span
02401 lang=FR style='font-size:10.0pt'>source[i][j] = trans-&gt;GetBinContent(i + 1,j
02402 + 1); </span></p>
02403 
02404 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>                 }</span></p>
02405 
02406 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   }           </span></p>
02407 
02408 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02409 TSpectrumTransform2 *t = new TSpectrumTransform2(256,256);   </span></p>
02410 
02411 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   t-&gt;SetTransformType(t-&gt;kTransformCos,0);  
02412 </span></p>
02413 
02414 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02415 t-&gt;SetRegion(0,255,128,255);</span></p>
02416 
02417 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02418 t-&gt;FilterZonal(source,dest);     </span></p>
02419 
02420 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   </span><span
02421 style='font-size:10.0pt'>for (i = 0; i &lt; nbinsx; i++){</span></p>
02422 
02423 <p class=MsoNormal><span style='font-size:10.0pt'>     for (j = 0; j &lt;
02424 nbinsy; j++){</span></p>
02425 
02426 <p class=MsoNormal><span style='font-size:10.0pt'>                    </span><span
02427 lang=FR style='font-size:10.0pt'>source[i][j] = dest[i][j]; </span></p>
02428 
02429 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>                 }</span></p>
02430 
02431 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   }   </span></p>
02432 
02433 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02434 t-&gt;SetRegion(128,255,0,255);</span></p>
02435 
02436 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   t-&gt;FilterZonal(source,dest);       
02437 </span></p>
02438 
02439 <p class=MsoNormal><span style='font-size:10.0pt'>  
02440 trans-&gt;Draw(&quot;SURF&quot;);     </span></p>
02441 
02442 <p class=MsoNormal><span style='font-size:10.0pt'>}</span></p>
02443 
02444 </div>
02445 
02446 <!-- */
02447 // --> End_Html
02448 
02449    Int_t i, j;
02450    Double_t a, old_area = 0, new_area = 0;
02451    Int_t size;
02452    Float_t *working_vector = 0, **working_matrix = 0;
02453    size = (Int_t) TMath::Max(fSizeX, fSizeY);
02454    switch (fTransformType) {
02455    case kTransformHaar:
02456    case kTransformWalsh:
02457       working_vector = new Float_t[2 * size];
02458       working_matrix = new Float_t *[fSizeX];
02459       for (i = 0; i < fSizeX; i++)
02460          working_matrix[i] = new Float_t[fSizeY];
02461       break;
02462    case kTransformCos:
02463    case kTransformSin:
02464    case kTransformFourier:
02465    case kTransformHartley:
02466    case kTransformFourierWalsh:
02467    case kTransformFourierHaar:
02468    case kTransformWalshHaar:
02469       working_vector = new Float_t[4 * size];
02470       working_matrix = new Float_t *[fSizeX];
02471       for (i = 0; i < fSizeX; i++)
02472          working_matrix[i] = new Float_t[2 * fSizeY];
02473       break;
02474    case kTransformCosWalsh:
02475    case kTransformCosHaar:
02476    case kTransformSinWalsh:
02477    case kTransformSinHaar:
02478       working_vector = new Float_t[8 * size];
02479       working_matrix = new Float_t *[fSizeX];
02480       for (i = 0; i < fSizeX; i++)
02481          working_matrix[i] = new Float_t[2 * fSizeY];
02482       break;
02483    }
02484    switch (fTransformType) {
02485    case kTransformHaar:
02486       for (i = 0; i < fSizeX; i++) {
02487          for (j = 0; j < fSizeY; j++) {
02488             working_matrix[i][j] = fSource[i][j];
02489             old_area = old_area + fSource[i][j];
02490          }
02491       }
02492       HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02493                   kTransformForward, kTransformHaar);
02494       break;
02495    case kTransformWalsh:
02496       for (i = 0; i < fSizeX; i++) {
02497          for (j = 0; j < fSizeY; j++) {
02498             working_matrix[i][j] = fSource[i][j];
02499             old_area = old_area + fSource[i][j];
02500          }
02501       }
02502       HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02503                   kTransformForward, kTransformWalsh);
02504       break;
02505    case kTransformCos:
02506       for (i = 0; i < fSizeX; i++) {
02507          for (j = 0; j < fSizeY; j++) {
02508             working_matrix[i][j] = fSource[i][j];
02509             old_area = old_area + fSource[i][j];
02510          }
02511       }
02512       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02513                 kTransformForward, kTransformCos);
02514       break;
02515    case kTransformSin:
02516       for (i = 0; i < fSizeX; i++) {
02517          for (j = 0; j < fSizeY; j++) {
02518             working_matrix[i][j] = fSource[i][j];
02519             old_area = old_area + fSource[i][j];
02520          }
02521       }
02522       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02523                 kTransformForward, kTransformSin);
02524       break;
02525    case kTransformFourier:
02526       for (i = 0; i < fSizeX; i++) {
02527          for (j = 0; j < fSizeY; j++) {
02528             working_matrix[i][j] = fSource[i][j];
02529             old_area = old_area + fSource[i][j];
02530          }
02531       }
02532       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02533                 kTransformForward, kTransformFourier);
02534       break;
02535    case kTransformHartley:
02536       for (i = 0; i < fSizeX; i++) {
02537          for (j = 0; j < fSizeY; j++) {
02538             working_matrix[i][j] = fSource[i][j];
02539             old_area = old_area + fSource[i][j];
02540          }
02541       }
02542       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02543                 kTransformForward, kTransformHartley);
02544       break;
02545    case kTransformFourierWalsh:
02546    case kTransformFourierHaar:
02547    case kTransformWalshHaar:
02548    case kTransformCosWalsh:
02549    case kTransformCosHaar:
02550    case kTransformSinWalsh:
02551    case kTransformSinHaar:
02552       for (i = 0; i < fSizeX; i++) {
02553          for (j = 0; j < fSizeY; j++) {
02554             working_matrix[i][j] = fSource[i][j];
02555             old_area = old_area + fSource[i][j];
02556          }
02557       }
02558       General2(working_matrix, working_vector, fSizeX, fSizeY,
02559                 kTransformForward, fTransformType, fDegree);
02560       break;
02561    }
02562    for (i = 0; i < fSizeX; i++) {
02563       for (j = 0; j < fSizeY; j++) {
02564          if (i >= fXmin && i <= fXmax && j >= fYmin && j <= fYmax)
02565             if (working_matrix) working_matrix[i][j] = fFilterCoeff;
02566       }
02567    }
02568    if (fTransformType == kTransformFourier || fTransformType == kTransformFourierWalsh
02569         || fTransformType == kTransformFourierHaar) {
02570       for (i = 0; i < fSizeX; i++) {
02571          for (j = 0; j < fSizeY; j++) {
02572             if (i >= fXmin && i <= fXmax && j >= fYmin && j <= fYmax)
02573                if (working_matrix) working_matrix[i][j + fSizeY] = fFilterCoeff;
02574          }
02575       }
02576    }
02577    switch (fTransformType) {
02578    case kTransformHaar:
02579       HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02580                   kTransformInverse, kTransformHaar);
02581       for (i = 0; i < fSizeX; i++) {
02582          for (j = 0; j < fSizeY; j++) {
02583             new_area = new_area + working_matrix[i][j];
02584          }
02585       }
02586       if (new_area != 0) {
02587          a = old_area / new_area;
02588          for (i = 0; i < fSizeX; i++) {
02589             for (j = 0; j < fSizeY; j++) {
02590                fDest[i][j] = working_matrix[i][j] * a;
02591             }
02592          }
02593       }
02594       break;
02595    case kTransformWalsh:
02596       HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02597                   kTransformInverse, kTransformWalsh);
02598       for (i = 0; i < fSizeX; i++) {
02599          for (j = 0; j < fSizeY; j++) {
02600             new_area = new_area + working_matrix[i][j];
02601          }
02602       }
02603       if (new_area != 0) {
02604          a = old_area / new_area;
02605          for (i = 0; i < fSizeX; i++) {
02606             for (j = 0; j < fSizeY; j++) {
02607                fDest[i][j] = working_matrix[i][j] * a;
02608             }
02609          }
02610       }
02611       break;
02612    case kTransformCos:
02613       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02614                 kTransformInverse, kTransformCos);
02615       for (i = 0; i < fSizeX; i++) {
02616          for (j = 0; j < fSizeY; j++) {
02617             new_area = new_area + working_matrix[i][j];
02618          }
02619       }
02620       if (new_area != 0) {
02621          a = old_area / new_area;
02622          for (i = 0; i < fSizeX; i++) {
02623             for (j = 0; j < fSizeY; j++) {
02624                fDest[i][j] = working_matrix[i][j] * a;
02625             }
02626          }
02627       }
02628       break;
02629    case kTransformSin:
02630       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02631                 kTransformInverse, kTransformSin);
02632       for (i = 0; i < fSizeX; i++) {
02633          for (j = 0; j < fSizeY; j++) {
02634             new_area = new_area + working_matrix[i][j];
02635          }
02636       }
02637       if (new_area != 0) {
02638          a = old_area / new_area;
02639          for (i = 0; i < fSizeX; i++) {
02640             for (j = 0; j < fSizeY; j++) {
02641                fDest[i][j] = working_matrix[i][j] * a;
02642             }
02643          }
02644       }
02645       break;
02646    case kTransformFourier:
02647       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02648                 kTransformInverse, kTransformFourier);
02649       for (i = 0; i < fSizeX; i++) {
02650          for (j = 0; j < fSizeY; j++) {
02651             new_area = new_area + working_matrix[i][j];
02652          }
02653       }
02654       if (new_area != 0) {
02655          a = old_area / new_area;
02656          for (i = 0; i < fSizeX; i++) {
02657             for (j = 0; j < fSizeY; j++) {
02658                fDest[i][j] = working_matrix[i][j] * a;
02659             }
02660          }
02661       }
02662       break;
02663    case kTransformHartley:
02664       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02665                 kTransformInverse, kTransformHartley);
02666       for (i = 0; i < fSizeX; i++) {
02667          for (j = 0; j < fSizeY; j++) {
02668             new_area = new_area + working_matrix[i][j];
02669          }
02670       }
02671       if (new_area != 0) {
02672          a = old_area / new_area;
02673          for (i = 0; i < fSizeX; i++) {
02674             for (j = 0; j < fSizeY; j++) {
02675                fDest[i][j] = working_matrix[i][j] * a;
02676             }
02677          }
02678       }
02679       break;
02680    case kTransformFourierWalsh:
02681    case kTransformFourierHaar:
02682    case kTransformWalshHaar:
02683    case kTransformCosWalsh:
02684    case kTransformCosHaar:
02685    case kTransformSinWalsh:
02686    case kTransformSinHaar:
02687       General2(working_matrix, working_vector, fSizeX, fSizeY,
02688                 kTransformInverse, fTransformType, fDegree);
02689       for (i = 0; i < fSizeX; i++) {
02690          for (j = 0; j < fSizeY; j++) {
02691             new_area = new_area + working_matrix[i][j];
02692          }
02693       }
02694       if (new_area != 0) {
02695          a = old_area / new_area;
02696          for (i = 0; i < fSizeX; i++) {
02697             for (j = 0; j < fSizeY; j++) {
02698                fDest[i][j] = working_matrix[i][j] * a;
02699             }
02700          }
02701       }
02702       break;
02703    }
02704    for (i = 0; i < fSizeX; i++) {
02705       if (working_matrix) delete[]working_matrix[i];
02706    }
02707    delete[]working_matrix;
02708    delete[]working_vector;
02709    return;
02710 }
02711 
02712 
02713 //////////  END OF FILTER2_ZONAL FUNCTION/////////////////////////////////
02714 //////////ENHANCE2 FUNCTION - CALCULATES DIFFERENT 2-D ORTHOGONAL TRANSFORMS, MULTIPLIES GIVEN REGION BY ENHANCE COEFFICIENT AND TRANSFORMS IT BACK//////
02715 //______________________________________________________________________
02716 void TSpectrum2Transform::Enhance(const Float_t **fSource, Float_t **fDest)
02717 {
02718 //////////////////////////////////////////////////////////////////////////////////////////
02719 /* TWO-DIMENSIONAL ENHANCE ZONAL FUNCTION                     */ 
02720 /* This function transforms the source spectrum. The calling program               */ 
02721 /*      should fill in input parameters. Then it multiplies transformed                 */ 
02722 /*      coefficients in the given region by the given                                   */ 
02723 /*      enhance_coeff and transforms it back                                            */ 
02724 /*                         */ 
02725 /* Function parameters:                      */ 
02726 /* fSource-pointer to the matrix of source spectrum, its size should               */ 
02727 /*             be fSizeX*fSizeY                                                         */ 
02728 /* fDest-pointer to the matrix of destination data, its size should be             */ 
02729 /*           fSizeX*fSizeY                                                              */ 
02730 /*                         */ 
02731 //////////////////////////////////////////////////////////////////////////////////////////
02732 //Begin_Html <!--
02733 /* -->
02734 <div class=Section3>
02735 
02736 <p class=MsoNormal><b><span style='font-size:14.0pt'>Example of enhancement</span></b></p>
02737 
02738 <p class=MsoNormal><i>&nbsp;</i></p>
02739 
02740 <p class=MsoNormal><i>Function:</i></p>
02741 
02742 <p class=MsoNormal>void <a
02743 href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b>TSpectrumTransform2::Enhance</b></a><b>(const
02744 <a href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a>
02745 **fSource, <a href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a>
02746 **fDest)</b></p>
02747 
02748 <p class=MsoNormal style='text-align:justify'>&nbsp;</p>
02749 
02750 <p class=MsoNormal style='text-align:justify'>This function transforms the
02751 source spectrum (for details see Transform function).  Before the Enhance
02752 function is called the class must be created by constructor and the type of the
02753 transform as well as some other parameters must be set using a set of setter
02754 functions. The Enhance function multiplies transformed coefficients in the given
02755 region (fXmin, fXmax, fYmin, fYmax) by the given fEnhancCoeff and transforms it
02756 back. Enhanced data are written into dest spectrum.</p>
02757 
02758 <p class=MsoNormal style='text-align:justify'><i>Example – script Enhance2.c:</i></p>
02759 
02760 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'><img
02761 border=0 width=602 height=455 src="gif/spectrum2transform_enhance_image001.jpg"></span></p>
02762 
02763 <p class=MsoNormal><b>Fig. 1 Original two-dimensional noisy spectrum</b></p>
02764 
02765 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:16.0pt'><img
02766 border=0 width=602 height=455 src="gif/spectrum2transform_enhance_image002.jpg"></span></i></p>
02767 
02768 <p class=MsoNormal style='text-align:justify'><b>Fig. 2 Enhanced spectrum of
02769 the data from Fig. 1 using Cosine transform (channels in region (0-63)x(0-63)
02770 were multiplied by 5) </b></p>
02771 
02772 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>&nbsp;</span></b></p>
02773 
02774 <p class=MsoNormal><b><span style='color:#339966'>Script:</span></b></p>
02775 
02776 <p class=MsoNormal><span style='font-size:10.0pt'>// Example to illustrate
02777 enhancement (class TSpectrumTransform2).</span></p>
02778 
02779 <p class=MsoNormal><span style='font-size:10.0pt'>// To execute this example,
02780 do</span></p>
02781 
02782 <p class=MsoNormal><span style='font-size:10.0pt'>// root &gt; .x Enhance2.C</span></p>
02783 
02784 <p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
02785 
02786 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>void Enhance2() {</span></p>
02787 
02788 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t i, j;</span></p>
02789 
02790 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t nbinsx =
02791 256;</span></p>
02792 
02793 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t nbinsy =
02794 256;   </span></p>
02795 
02796 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t xmin  = 0;</span></p>
02797 
02798 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t xmax  =
02799 nbinsx;</span></p>
02800 
02801 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t ymin  = 0;</span></p>
02802 
02803 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   Int_t ymax  =
02804 nbinsy;</span></p>
02805 
02806 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   </span><span
02807 style='font-size:10.0pt'>Float_t ** source = new float *[nbinsx];   </span></p>
02808 
02809 <p class=MsoNormal><span style='font-size:10.0pt'>   Float_t ** dest = new
02810 float *[nbinsx];      </span></p>
02811 
02812 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i=0;i&lt;nbinsx;i++)</span></p>
02813 
02814 <p class=MsoNormal><span style='font-size:10.0pt'>                                                source[i]=new
02815 float[nbinsy];</span></p>
02816 
02817 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i=0;i&lt;nbinsx;i++)</span></p>
02818 
02819 <p class=MsoNormal><span style='font-size:10.0pt'>                                                dest[i]=new
02820 float[nbinsy];   </span></p>
02821 
02822 <p class=MsoNormal><span style='font-size:10.0pt'>   TH2F *trans = new
02823 TH2F(&quot;trans&quot;,&quot;Background
02824 estimation&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</span></p>
02825 
02826 <p class=MsoNormal><span style='font-size:10.0pt'>   TFile *f = new
02827 TFile(&quot;TSpectrum2.root&quot;);</span></p>
02828 
02829 <p class=MsoNormal><span style='font-size:10.0pt'>   trans=(TH2F*)
02830 f-&gt;Get(&quot;back3;1&quot;);</span></p>
02831 
02832 <p class=MsoNormal><span style='font-size:10.0pt'>   TCanvas *Tr = new
02833 TCanvas(&quot;Transform&quot;,&quot;Illustation of transform
02834 function&quot;,10,10,1000,700);</span></p>
02835 
02836 <p class=MsoNormal><span style='font-size:10.0pt'>   for (i = 0; i &lt; nbinsx;
02837 i++){</span></p>
02838 
02839 <p class=MsoNormal><span style='font-size:10.0pt'>     for (j = 0; j &lt;
02840 nbinsy; j++){</span></p>
02841 
02842 <p class=MsoNormal><span style='font-size:10.0pt'>                    </span><span
02843 lang=FR style='font-size:10.0pt'>source[i][j] = trans-&gt;GetBinContent(i + 1,j
02844 + 1); </span></p>
02845 
02846 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>                 }</span></p>
02847 
02848 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>   }           </span></p>
02849 
02850 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02851 TSpectrumTransform2 *t = new TSpectrumTransform2(256,256);   </span></p>
02852 
02853 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02854 t-&gt;SetTransformType(t-&gt;kTransformCos,0);   </span></p>
02855 
02856 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02857 t-&gt;SetRegion(0,63,0,63);   </span></p>
02858 
02859 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02860 t-&gt;SetEnhanceCoeff(5);</span></p>
02861 
02862 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'>  
02863 t-&gt;Enhance(source,dest);   </span></p>
02864 
02865 <p class=MsoNormal><span lang=FR style='font-size:10.0pt'> </span><span
02866 style='font-size:10.0pt'>  trans-&gt;Draw(&quot;SURF&quot;);     </span></p>
02867 
02868 <p class=MsoNormal><span style='font-size:10.0pt'>}</span></p>
02869 
02870 </div>
02871 
02872 <!-- */
02873 // --> End_Html
02874 
02875    Int_t i, j;
02876    Double_t a, old_area = 0, new_area = 0;
02877    Int_t size;
02878    Float_t *working_vector = 0, **working_matrix = 0;
02879    size = (Int_t) TMath::Max(fSizeX, fSizeY);
02880    switch (fTransformType) {
02881    case kTransformHaar:
02882    case kTransformWalsh:
02883       working_vector = new Float_t[2 * size];
02884       working_matrix = new Float_t *[fSizeX];
02885       for (i = 0; i < fSizeX; i++)
02886          working_matrix[i] = new Float_t[fSizeY];
02887       break;
02888    case kTransformCos:
02889    case kTransformSin:
02890    case kTransformFourier:
02891    case kTransformHartley:
02892    case kTransformFourierWalsh:
02893    case kTransformFourierHaar:
02894    case kTransformWalshHaar:
02895       working_vector = new Float_t[4 * size];
02896       working_matrix = new Float_t *[fSizeX];
02897       for (i = 0; i < fSizeX; i++)
02898          working_matrix[i] = new Float_t[2 * fSizeY];
02899       break;
02900    case kTransformCosWalsh:
02901    case kTransformCosHaar:
02902    case kTransformSinWalsh:
02903    case kTransformSinHaar:
02904       working_vector = new Float_t[8 * size];
02905       working_matrix = new Float_t *[fSizeX];
02906       for (i = 0; i < fSizeX; i++)
02907          working_matrix[i] = new Float_t[2 * fSizeY];
02908       break;
02909    }
02910    switch (fTransformType) {
02911    case kTransformHaar:
02912       for (i = 0; i < fSizeX; i++) {
02913          for (j = 0; j < fSizeY; j++) {
02914             working_matrix[i][j] = fSource[i][j];
02915             old_area = old_area + fSource[i][j];
02916          }
02917       }
02918       HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02919                   kTransformForward, kTransformHaar);
02920       break;
02921    case kTransformWalsh:
02922       for (i = 0; i < fSizeX; i++) {
02923          for (j = 0; j < fSizeY; j++) {
02924             working_matrix[i][j] = fSource[i][j];
02925             old_area = old_area + fSource[i][j];
02926          }
02927       }
02928       HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
02929                   kTransformForward, kTransformWalsh);
02930       break;
02931    case kTransformCos:
02932       for (i = 0; i < fSizeX; i++) {
02933          for (j = 0; j < fSizeY; j++) {
02934             working_matrix[i][j] = fSource[i][j];
02935             old_area = old_area + fSource[i][j];
02936          }
02937       }
02938       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02939                 kTransformForward, kTransformCos);
02940       break;
02941    case kTransformSin:
02942       for (i = 0; i < fSizeX; i++) {
02943          for (j = 0; j < fSizeY; j++) {
02944             working_matrix[i][j] = fSource[i][j];
02945             old_area = old_area + fSource[i][j];
02946          }
02947       }
02948       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02949                 kTransformForward, kTransformSin);
02950       break;
02951    case kTransformFourier:
02952       for (i = 0; i < fSizeX; i++) {
02953          for (j = 0; j < fSizeY; j++) {
02954             working_matrix[i][j] = fSource[i][j];
02955             old_area = old_area + fSource[i][j];
02956          }
02957       }
02958       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02959                 kTransformForward, kTransformFourier);
02960       break;
02961    case kTransformHartley:
02962       for (i = 0; i < fSizeX; i++) {
02963          for (j = 0; j < fSizeY; j++) {
02964             working_matrix[i][j] = fSource[i][j];
02965             old_area = old_area + fSource[i][j];
02966          }
02967       }
02968       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
02969                 kTransformForward, kTransformHartley);
02970       break;
02971    case kTransformFourierWalsh:
02972    case kTransformFourierHaar:
02973    case kTransformWalshHaar:
02974    case kTransformCosWalsh:
02975    case kTransformCosHaar:
02976    case kTransformSinWalsh:
02977    case kTransformSinHaar:
02978       for (i = 0; i < fSizeX; i++) {
02979          for (j = 0; j < fSizeY; j++) {
02980             working_matrix[i][j] = fSource[i][j];
02981             old_area = old_area + fSource[i][j];
02982          }
02983       }
02984       General2(working_matrix, working_vector, fSizeX, fSizeY,
02985                 kTransformForward, fTransformType, fDegree);
02986       break;
02987    }
02988    for (i = 0; i < fSizeX; i++) {
02989       for (j = 0; j < fSizeY; j++) {
02990          if (i >= fXmin && i <= fXmax && j >= fYmin && j <= fYmax)
02991             if (working_matrix) working_matrix[i][j] *= fEnhanceCoeff;
02992       }
02993    }
02994    if (fTransformType == kTransformFourier || fTransformType == kTransformFourierWalsh
02995         || fTransformType == kTransformFourierHaar) {
02996       for (i = 0; i < fSizeX; i++) {
02997          for (j = 0; j < fSizeY; j++) {
02998             if (i >= fXmin && i <= fXmax && j >= fYmin && j <= fYmax)
02999                working_matrix[i][j + fSizeY] *= fEnhanceCoeff;
03000          }
03001       }
03002    }
03003    switch (fTransformType) {
03004    case kTransformHaar:
03005       HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
03006                   kTransformInverse, kTransformHaar);
03007       for (i = 0; i < fSizeX; i++) {
03008          for (j = 0; j < fSizeY; j++) {
03009             new_area = new_area + working_matrix[i][j];
03010          }
03011       }
03012       if (new_area != 0) {
03013          a = old_area / new_area;
03014          for (i = 0; i < fSizeX; i++) {
03015             for (j = 0; j < fSizeY; j++) {
03016                fDest[i][j] = working_matrix[i][j] * a;
03017             }
03018          }
03019       }
03020       break;
03021    case kTransformWalsh:
03022       HaarWalsh2(working_matrix, working_vector, fSizeX, fSizeY,
03023                   kTransformInverse, kTransformWalsh);
03024       for (i = 0; i < fSizeX; i++) {
03025          for (j = 0; j < fSizeY; j++) {
03026             new_area = new_area + working_matrix[i][j];
03027          }
03028       }
03029       if (new_area != 0) {
03030          a = old_area / new_area;
03031          for (i = 0; i < fSizeX; i++) {
03032             for (j = 0; j < fSizeY; j++) {
03033                fDest[i][j] = working_matrix[i][j] * a;
03034             }
03035          }
03036       }
03037       break;
03038    case kTransformCos:
03039       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
03040                 kTransformInverse, kTransformCos);
03041       for (i = 0; i < fSizeX; i++) {
03042          for (j = 0; j < fSizeY; j++) {
03043             new_area = new_area + working_matrix[i][j];
03044          }
03045       }
03046       if (new_area != 0) {
03047          a = old_area / new_area;
03048          for (i = 0; i < fSizeX; i++) {
03049             for (j = 0; j < fSizeY; j++) {
03050                fDest[i][j] = working_matrix[i][j] * a;
03051             }
03052          }
03053       }
03054       break;
03055    case kTransformSin:
03056       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
03057                 kTransformInverse, kTransformSin);
03058       for (i = 0; i < fSizeX; i++) {
03059          for (j = 0; j < fSizeY; j++) {
03060             new_area = new_area + working_matrix[i][j];
03061          }
03062       }
03063       if (new_area != 0) {
03064          a = old_area / new_area;
03065          for (i = 0; i < fSizeX; i++) {
03066             for (j = 0; j < fSizeY; j++) {
03067                fDest[i][j] = working_matrix[i][j] * a;
03068             }
03069          }
03070       }
03071       break;
03072    case kTransformFourier:
03073       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
03074                 kTransformInverse, kTransformFourier);
03075       for (i = 0; i < fSizeX; i++) {
03076          for (j = 0; j < fSizeY; j++) {
03077             new_area = new_area + working_matrix[i][j];
03078          }
03079       }
03080       if (new_area != 0) {
03081          a = old_area / new_area;
03082          for (i = 0; i < fSizeX; i++) {
03083             for (j = 0; j < fSizeY; j++) {
03084                fDest[i][j] = working_matrix[i][j] * a;
03085             }
03086          }
03087       }
03088       break;
03089    case kTransformHartley:
03090       FourCos2(working_matrix, working_vector, fSizeX, fSizeY,
03091                 kTransformInverse, kTransformHartley);
03092       for (i = 0; i < fSizeX; i++) {
03093          for (j = 0; j < fSizeY; j++) {
03094             new_area = new_area + working_matrix[i][j];
03095          }
03096       }
03097       if (new_area != 0) {
03098          a = old_area / new_area;
03099          for (i = 0; i < fSizeX; i++) {
03100             for (j = 0; j < fSizeY; j++) {
03101                fDest[i][j] = working_matrix[i][j] * a;
03102             }
03103          }
03104       }
03105       break;
03106    case kTransformFourierWalsh:
03107    case kTransformFourierHaar:
03108    case kTransformWalshHaar:
03109    case kTransformCosWalsh:
03110    case kTransformCosHaar:
03111    case kTransformSinWalsh:
03112    case kTransformSinHaar:
03113       General2(working_matrix, working_vector, fSizeX, fSizeY,
03114                 kTransformInverse, fTransformType, fDegree);
03115       for (i = 0; i < fSizeX; i++) {
03116          for (j = 0; j < fSizeY; j++) {
03117             new_area = new_area + working_matrix[i][j];
03118          }
03119       }
03120       if (new_area != 0) {
03121          a = old_area / new_area;
03122          for (i = 0; i < fSizeX; i++) {
03123             for (j = 0; j < fSizeY; j++) {
03124                fDest[i][j] = working_matrix[i][j] * a;
03125             }
03126          }
03127       }
03128       break;
03129    }
03130    for (i = 0; i < fSizeX; i++) {
03131       if (working_matrix) delete[]working_matrix[i];
03132    }
03133    delete[]working_matrix;
03134    delete[]working_vector;
03135    return;
03136 }
03137 
03138 
03139 //////////  END OF ENHANCE2 FUNCTION/////////////////////////////////
03140 
03141 //______________________________________________________________________
03142 void TSpectrum2Transform::SetTransformType(Int_t transType, Int_t degree)
03143 {
03144 //////////////////////////////////////////////////////////////////////////////
03145 //   SETTER FUNCION                                                      
03146 //                                                     
03147 //   This function sets the following parameters for transform:
03148 //         -transType - type of transform (Haar, Walsh, Cosine, Sine, Fourier, Hartley, Fourier-Walsh, Fourier-Haar, Walsh-Haar, Cosine-Walsh, Cosine-Haar, Sine-Walsh, Sine-Haar)
03149 //         -degree - degree of mixed transform, applies only for Fourier-Walsh, Fourier-Haar, Walsh-Haar, Cosine-Walsh, Cosine-Haar, Sine-Walsh, Sine-Haar transforms
03150 //////////////////////////////////////////////////////////////////////////////      
03151    
03152    Int_t j1, j2, n;
03153    j1 = 0;
03154    n = 1;
03155    for (; n < fSizeX;) {
03156       j1 += 1;
03157       n = n * 2;
03158    }
03159    j2 = 0;
03160    n = 1;
03161    for (; n < fSizeY;) {
03162       j2 += 1;
03163       n = n * 2;
03164    }
03165    if (transType < kTransformHaar || transType > kTransformSinHaar){
03166       Error ("TSpectrumTransform","Invalid type of transform");
03167       return;       
03168    }
03169    if (transType >= kTransformFourierWalsh && transType <= kTransformSinHaar) {
03170       if (degree > j1 || degree > j2 || degree < 1){
03171          Error ("TSpectrumTransform","Invalid degree of mixed transform");
03172          return;          
03173       }
03174    }
03175    fTransformType = transType;
03176    fDegree = degree;
03177 }
03178     
03179 //______________________________________________________________________
03180 void TSpectrum2Transform::SetRegion(Int_t xmin, Int_t xmax, Int_t ymin, Int_t ymax)
03181 {
03182 //////////////////////////////////////////////////////////////////////////////
03183 //   SETTER FUNCION                                                      
03184 //                                                     
03185 //   This function sets the filtering or enhancement region:
03186 //         -xmin, xmax, ymin, ymax
03187 //////////////////////////////////////////////////////////////////////////////         
03188    if(xmin<0 || xmax < xmin || xmax >= fSizeX){ 
03189       Error("TSpectrumTransform", "Wrong range");      
03190       return;
03191    }         
03192    if(ymin<0 || ymax < ymin || ymax >= fSizeY){ 
03193       Error("TSpectrumTransform", "Wrong range");      
03194       return;
03195    }            
03196    fXmin = xmin;
03197    fXmax = xmax;
03198    fYmin = ymin;
03199    fYmax = ymax;   
03200 }
03201 
03202 //______________________________________________________________________
03203 void TSpectrum2Transform::SetDirection(Int_t direction)
03204 {
03205 //////////////////////////////////////////////////////////////////////////////
03206 //   SETTER FUNCION                                                      
03207 //                                                     
03208 //   This function sets the direction of the transform:
03209 //         -direction (forward or inverse)
03210 //////////////////////////////////////////////////////////////////////////////      
03211    if(direction != kTransformForward && direction != kTransformInverse){ 
03212       Error("TSpectrumTransform", "Wrong direction");      
03213       return;
03214    }         
03215    fDirection = direction;
03216 }
03217 
03218 //______________________________________________________________________
03219 void TSpectrum2Transform::SetFilterCoeff(Float_t filterCoeff)
03220 {
03221 //////////////////////////////////////////////////////////////////////////////
03222 //   SETTER FUNCION                                                      
03223 //                                                     
03224 //   This function sets the filter coefficient:
03225 //         -filterCoeff - after the transform the filtered region (xmin, xmax, ymin, ymax) is replaced by this coefficient. Applies only for filtereng operation.
03226 //////////////////////////////////////////////////////////////////////////////      
03227    fFilterCoeff = filterCoeff;
03228 }
03229 
03230 //______________________________________________________________________
03231 void TSpectrum2Transform::SetEnhanceCoeff(Float_t enhanceCoeff)
03232 {
03233 //////////////////////////////////////////////////////////////////////////////
03234 //   SETTER FUNCION                                                      
03235 //                                                     
03236 //   This function sets the enhancement coefficient:
03237 //         -enhanceCoeff - after the transform the enhanced region (xmin, xmax, ymin, ymax) is multiplied by this coefficient. Applies only for enhancement operation.
03238 //////////////////////////////////////////////////////////////////////////////      
03239    fEnhanceCoeff = enhanceCoeff;
03240 }
03241     

Generated on Tue Jul 5 14:24:39 2011 for ROOT_528-00b_version by  doxygen 1.5.1