TSpectrum2.cxx

Go to the documentation of this file.
00001 // @(#)root/spectrum:$Id: TSpectrum2.cxx 34991 2010-08-25 10:32:26Z brun $
00002 // Author: Miroslav Morhac   17/01/2006
00003 
00004 /////////////////////////////////////////////////////////////////////////////
00005 //   THIS CLASS CONTAINS ADVANCED SPECTRA PROCESSING FUNCTIONS.            //
00006 //                                                                         //
00007 //   ONE-DIMENSIONAL BACKGROUND ESTIMATION FUNCTIONS                       //
00008 //   TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTIONS                       //
00009 //   ONE-DIMENSIONAL SMOOTHING FUNCTIONS                                   //
00010 //   TWO-DIMENSIONAL SMOOTHING FUNCTIONS                                   //
00011 //   ONE-DIMENSIONAL DECONVOLUTION FUNCTIONS                               //
00012 //   TWO-DIMENSIONAL DECONVOLUTION FUNCTIONS                               //
00013 //   ONE-DIMENSIONAL PEAK SEARCH FUNCTIONS                                 //
00014 //   TWO-DIMENSIONAL PEAK SEARCH FUNCTIONS                                 //
00015 //                                                                         //
00016 //   These functions were written by:                                      //
00017 //   Miroslav Morhac                                                       //
00018 //   Institute of Physics                                                  //
00019 //   Slovak Academy of Sciences                                            //
00020 //   Dubravska cesta 9, 842 28 BRATISLAVA                                  //
00021 //   SLOVAKIA                                                              //
00022 //                                                                         //
00023 //   email:fyzimiro@savba.sk,    fax:+421 7 54772479                       //
00024 //                                                                         //
00025 //  The original code in C has been repackaged as a C++ class by R.Brun    //
00026 //                                                                         //
00027 //  The algorithms in this class have been published in the following      //
00028 //  references:                                                            //
00029 //   [1]  M.Morhac et al.: Background elimination methods for              //
00030 //   multidimensional coincidence gamma-ray spectra. Nuclear               //
00031 //   Instruments and Methods in Physics Research A 401 (1997) 113-         //
00032 //   132.                                                                  //
00033 //                                                                         //
00034 //   [2]  M.Morhac et al.: Efficient one- and two-dimensional Gold         //
00035 //   deconvolution and its application to gamma-ray spectra                //
00036 //   decomposition. Nuclear Instruments and Methods in Physics             //
00037 //   Research A 401 (1997) 385-408.                                        //
00038 //                                                                         //
00039 //   [3]  M.Morhac et al.: Identification of peaks in multidimensional     //
00040 //   coincidence gamma-ray spectra. Nuclear Instruments and Methods in     //
00041 //   Research Physics A  443(2000), 108-125.                               //
00042 //                                                                         //
00043 //   These NIM papers are also available as Postscript files from:         //
00044 //
00045 /*
00046    ftp://root.cern.ch/root/SpectrumDec.ps.gz
00047    ftp://root.cern.ch/root/SpectrumSrc.ps.gz
00048    ftp://root.cern.ch/root/SpectrumBck.ps.gz
00049 */ 
00050 //
00051 /////////////////////////////////////////////////////////////////////////////
00052 //
00053 /////////////////////NEW FUNCTIONS  January 2006
00054 //Begin_Html <!--
00055 /* -->
00056 <div class=Section1>
00057 
00058 <p class=MsoNormal style='text-align:justify'><i><span lang=EN-US
00059 style='font-size:16.0pt'>All figures in this page were prepared using DaqProVis
00060 system, Data Acquisition, Processing and Visualization system, which is being
00061 developed at the Institute of Physics, Slovak Academy of Sciences, Bratislava,
00062 Slovakia:  </span></i></p>
00063 
00064 <p class=MsoNormal style='text-align:justify'><i><span lang=EN-US
00065 style='font-size:16.0pt'><a href="http://www.fu.sav.sk/nph/projects/DaqProVis/">http://www.fu.sav.sk/nph/projects/DaqProVis/</a>
00066 under construction</span></i></p>
00067 
00068 <p class=MsoNormal style='text-align:justify'><i><span lang=EN-US
00069 style='font-size:16.0pt'><a href="http://www.fu.sav.sk/nph/projects/ProcFunc/">http://www.fu.sav.sk/nph/projects/ProcFunc/</a>
00070 .</span></i></p>
00071 
00072 </div>
00073 
00074 <!-- */
00075 // --> End_Html
00076 
00077 //______________________________________________________________________________
00078 
00079 
00080     
00081 #include "TSpectrum2.h"
00082 #include "TPolyMarker.h"
00083 #include "TList.h"
00084 #include "TH1.h"
00085 #include "TMath.h"
00086 #define PEAK_WINDOW 1024
00087 
00088 Int_t TSpectrum2::fgIterations    = 3;
00089 Int_t TSpectrum2::fgAverageWindow = 3;
00090 
00091 ClassImp(TSpectrum2)  
00092 
00093 //______________________________________________________________________________
00094 TSpectrum2::TSpectrum2() :TNamed("Spectrum", "Miroslav Morhac peak finder") 
00095 {
00096    // Constructor.
00097 
00098    Int_t n = 100;
00099    fMaxPeaks   = n;
00100    fPosition   = new Float_t[n];
00101    fPositionX  = new Float_t[n];
00102    fPositionY  = new Float_t[n];
00103    fResolution = 1;
00104    fHistogram  = 0;
00105    fNPeaks     = 0;
00106 }
00107 
00108 
00109 //______________________________________________________________________________
00110 TSpectrum2::TSpectrum2(Int_t maxpositions, Float_t resolution) :TNamed("Spectrum", "Miroslav Morhac peak finder") 
00111 {   
00112 //  maxpositions:  maximum number of peaks
00113 //  resolution:    determines resolution of the neighboring peaks
00114 //                 default value is 1 correspond to 3 sigma distance
00115 //                 between peaks. Higher values allow higher resolution
00116 //                 (smaller distance between peaks.
00117 //                 May be set later through SetResolution.
00118    
00119    Int_t n = maxpositions;
00120    fMaxPeaks  = n;
00121    fPosition  = new Float_t[n];
00122    fPositionX = new Float_t[n];
00123    fPositionY = new Float_t[n];
00124    fHistogram = 0;
00125    fNPeaks    = 0;
00126    SetResolution(resolution);
00127 }
00128 
00129 
00130 //______________________________________________________________________________
00131 TSpectrum2::~TSpectrum2() 
00132 {
00133    // Destructor.
00134 
00135    delete [] fPosition;
00136    delete [] fPositionX;
00137    delete [] fPositionY;
00138    delete    fHistogram;
00139 }
00140 
00141 
00142 //______________________________________________________________________________
00143 void TSpectrum2::SetAverageWindow(Int_t w)
00144 {
00145   // static function: Set average window of searched peaks
00146   // see TSpectrum2::SearchHighRes
00147    
00148    fgAverageWindow = w;
00149 }
00150 
00151 //______________________________________________________________________________
00152 void TSpectrum2::SetDeconIterations(Int_t n)
00153 {
00154   // static function: Set max number of decon iterations in deconvolution operation
00155   // see TSpectrum2::SearchHighRes
00156    
00157    fgIterations = n;
00158 }
00159 
00160 
00161 //______________________________________________________________________________
00162 TH1 *TSpectrum2::Background(const TH1 * h, int number_of_iterations,
00163                                    Option_t * option) 
00164 {
00165 /////////////////////////////////////////////////////////////////////////////
00166 //   TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION                        //
00167 //   This function calculates the background spectrum in the input histogram h.
00168 //   The background is returned as a histogram. 
00169 //                
00170 //   Function parameters:
00171 //   -h: input 2-d histogram
00172 //   -numberIterations, (default value = 20)
00173 //      Increasing numberIterations make the result smoother and lower.
00174 //   -option: may contain one of the following options
00175 //      - to set the direction parameter
00176 //        "BackIncreasingWindow". By default the direction is BackDecreasingWindow
00177 //      - filterOrder-order of clipping filter,  (default "BackOrder2"                         
00178 //                  -possible values= "BackOrder4"                          
00179 //                                    "BackOrder6"                          
00180 //                                    "BackOrder8"                           
00181 //      - "nosmoothing"- if selected, the background is not smoothed
00182 //           By default the background is smoothed.
00183 //      - smoothWindow-width of smoothing window, (default is "BackSmoothing3")         
00184 //                  -possible values= "BackSmoothing5"                        
00185 //                                    "BackSmoothing7"                       
00186 //                                    "BackSmoothing9"                        
00187 //                                    "BackSmoothing11"                       
00188 //                                    "BackSmoothing13"                       
00189 //                                    "BackSmoothing15"                        
00190 //      - "Compton" if selected the estimation of Compton edge
00191 //                  will be included.
00192 //      - "same" : if this option is specified, the resulting background
00193 //                 histogram is superimposed on the picture in the current pad.
00194 //
00195 //  NOTE that the background is only evaluated in the current range of h.
00196 //  ie, if h has a bin range (set via h->GetXaxis()->SetRange(binmin,binmax),
00197 //  the returned histogram will be created with the same number of bins
00198 //  as the input histogram h, but only bins from binmin to binmax will be filled
00199 //  with the estimated background.
00200 //                                                                         //
00201 /////////////////////////////////////////////////////////////////////////////
00202    Error("Background","function not yet implemented: h=%s, iter=%d, option=%sn"
00203         , h->GetName(), number_of_iterations, option);
00204    return 0;
00205 }
00206 
00207 //______________________________________________________________________________
00208 void TSpectrum2::Print(Option_t *) const
00209 {
00210    // Print the array of positions
00211 
00212    printf("\nNumber of positions = %d\n",fNPeaks);
00213    for (Int_t i=0;i<fNPeaks;i++) {
00214       printf(" x[%d] = %g, y[%d] = %g\n",i,fPositionX[i],i,fPositionY[i]);
00215    }
00216 }
00217 
00218 
00219 
00220 //______________________________________________________________________________
00221 Int_t TSpectrum2::Search(const TH1 * hin, Double_t sigma,
00222                              Option_t * option, Double_t threshold) 
00223 {   
00224 /////////////////////////////////////////////////////////////////////////////
00225 //   TWO-DIMENSIONAL PEAK SEARCH FUNCTION                                  //
00226 //   This function searches for peaks in source spectrum in hin            //
00227 //   The number of found peaks and their positions are written into        //
00228 //   the members fNpeaks and fPositionX.                                   //
00229 //   The search is performed in the current histogram range.               //
00230 //                                                                         //
00231 //   Function parameters:                                                  //
00232 //   hin:       pointer to the histogram of source spectrum                //
00233 //   sigma:   sigma of searched peaks, for details we refer to manual      //
00234 //   threshold: (default=0.05)  peaks with amplitude less than             //
00235 //       threshold*highest_peak are discarded.  0<threshold<1              //
00236 //                                                                         //
00237 //   By default, the background is removed before deconvolution.           //
00238 //   Specify the option "nobackground" to not remove the background.       //                //
00239 //                                                                         //
00240 //   By default the "Markov" chain algorithm is used.                      //
00241 //   Specify the option "noMarkov" to disable this algorithm               //
00242 //   Note that by default the source spectrum is replaced by a new spectrum//          //
00243 //                                                                         //
00244 //   By default a polymarker object is created and added to the list of    //
00245 //   functions of the histogram. The histogram is drawn with the specified //
00246 //   option and the polymarker object drawn on top of the histogram.       //
00247 //   The polymarker coordinates correspond to the npeaks peaks found in    //
00248 //   the histogram.                                                        //
00249 //   A pointer to the polymarker object can be retrieved later via:        //
00250 //    TList *functions = hin->GetListOfFunctions();                        //
00251 //    TPolyMarker *pm = (TPolyMarker*)functions->FindObject("TPolyMarker") //
00252 //   Specify the option "goff" to disable the storage and drawing of the   //
00253 //   polymarker.                                                           //
00254 //                                                                         //
00255 /////////////////////////////////////////////////////////////////////////////
00256 
00257    if (hin == 0)
00258       return 0;
00259    Int_t dimension = hin->GetDimension();
00260    if (dimension != 2) {
00261       Error("Search", "Must be a 2-d histogram");
00262       return 0;
00263    }
00264 
00265    TString opt = option;
00266    opt.ToLower();
00267    Bool_t background = kTRUE;
00268    if (opt.Contains("nobackground")) {
00269       background = kFALSE;
00270       opt.ReplaceAll("nobackground","");
00271    }
00272    Bool_t markov = kTRUE;
00273    if (opt.Contains("nomarkov")) {
00274       markov = kFALSE;
00275       opt.ReplaceAll("nomarkov","");
00276    }
00277    
00278    Int_t sizex = hin->GetXaxis()->GetNbins();
00279    Int_t sizey = hin->GetYaxis()->GetNbins();
00280    Int_t i, j, binx,biny, npeaks;
00281    Float_t ** source = new float *[sizex];
00282    Float_t ** dest   = new float *[sizex];
00283    for (i = 0; i < sizex; i++) {
00284       source[i] = new float[sizey];
00285       dest[i]   = new float[sizey];
00286       for (j = 0; j < sizey; j++) {
00287          source[i][j] = (Float_t) hin->GetBinContent(i + 1, j + 1);
00288       }
00289    }
00290    //npeaks = SearchHighRes(source, dest, sizex, sizey, sigma, 100*threshold, kTRUE, 3, kTRUE, 10);
00291    //the smoothing option is used for 1-d but not for 2-d histograms
00292    npeaks = SearchHighRes(source, dest, sizex, sizey, sigma, 100*threshold,  background, fgIterations, markov, fgAverageWindow);
00293 
00294    //The logic in the loop should be improved to use the fact
00295    //that fPositionX,Y give a precise position inside a bin.
00296    //The current algorithm takes the center of the bin only.
00297    for (i = 0; i < npeaks; i++) {
00298       binx = 1 + Int_t(fPositionX[i] + 0.5);
00299       biny = 1 + Int_t(fPositionY[i] + 0.5);
00300       fPositionX[i] = hin->GetXaxis()->GetBinCenter(binx);
00301       fPositionY[i] = hin->GetYaxis()->GetBinCenter(biny);
00302    }
00303    for (i = 0; i < sizex; i++) {
00304       delete [] source[i];
00305       delete [] dest[i];
00306    }
00307    delete [] source;
00308    delete [] dest;
00309       
00310    if (opt.Contains("goff"))
00311       return npeaks;
00312    if (!npeaks) return 0;
00313    TPolyMarker * pm = (TPolyMarker*)hin->GetListOfFunctions()->FindObject("TPolyMarker");
00314    if (pm) {
00315       hin->GetListOfFunctions()->Remove(pm);
00316       delete pm;
00317    }
00318    pm = new TPolyMarker(npeaks, fPositionX, fPositionY);
00319    hin->GetListOfFunctions()->Add(pm);
00320    pm->SetMarkerStyle(23);
00321    pm->SetMarkerColor(kRed);
00322    pm->SetMarkerSize(1.3);
00323    ((TH1*)hin)->Draw(option);
00324    return npeaks;
00325 }
00326 
00327 
00328 //______________________________________________________________________________
00329 void TSpectrum2::SetResolution(Float_t resolution) 
00330 {   
00331 //  resolution: determines resolution of the neighboring peaks
00332 //              default value is 1 correspond to 3 sigma distance
00333 //              between peaks. Higher values allow higher resolution
00334 //              (smaller distance between peaks.
00335 //              May be set later through SetResolution.
00336    if (resolution > 1)
00337       fResolution = resolution;   
00338    else
00339       fResolution = 1;
00340 }
00341 
00342 
00343 //_____________________________________________________________________________
00344 //_____________________________________________________________________________
00345     
00346 /////////////////////NEW FUNCTIONS  JANUARY 2006
00347 //______________________________________________________________________________
00348 const char *TSpectrum2::Background(float **spectrum,
00349                        Int_t ssizex, Int_t ssizey,
00350                        Int_t numberIterationsX,
00351                        Int_t numberIterationsY,
00352                        Int_t direction,
00353                        Int_t filterType) 
00354 {   
00355 /////////////////////////////////////////////////////////////////////////////
00356 //   TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION - RECTANGULAR RIDGES   // 
00357 //   This function calculates background spectrum from source spectrum.    // 
00358 //   The result is placed to the array pointed by spectrum pointer.        // 
00359 //                                                                         // 
00360 //   Function parameters:                                                  // 
00361 //   spectrum-pointer to the array of source spectrum                      // 
00362 //   ssizex-x length of spectrum                                           // 
00363 //   ssizey-y length of spectrum                                           // 
00364 //   numberIterationsX-maximal x width of clipping window                  // 
00365 //   numberIterationsY-maximal y width of clipping window                  // 
00366 //                           for details we refer to manual                // 
00367 //   direction- direction of change of clipping window                     // 
00368 //               - possible values=kBackIncreasingWindow                   // 
00369 //                                 kBackDecreasingWindow                   // 
00370 //   filterType-determines the algorithm of the filtering                  // 
00371 //                  -possible values=kBackSuccessiveFiltering              // 
00372 //                                   kBackOneStepFiltering                 // 
00373 //                                                                         // 
00374 //                                                                         // 
00375 /////////////////////////////////////////////////////////////////////////////
00376 //
00377 //Begin_Html <!--
00378 /* -->
00379 <div class=Section1>
00380 
00381 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:20.0pt'>Background
00382 estimation</span></b></p>
00383 
00384 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:18.0pt'>&nbsp;</span></i></p>
00385 
00386 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:18.0pt'>Goal:
00387 Separation of useful information (peaks) from useless information (background)</span></i><span
00388 style='font-size:18.0pt'> </span></p>
00389 
00390 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
00391 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
00392 </span></span><span style='font-size:16.0pt'>method is based on Sensitive
00393 Nonlinear Iterative Peak (SNIP) clipping algorithm [1]</span></p>
00394 
00395 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
00396 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
00397 </span></span><span style='font-size:16.0pt'>there exist two algorithms for the
00398 estimation of new value in the channel “<sub><img width=28 height=24
00399 src="gif/TSpectrum2_Background1.gif"></sub>”</span></p>
00400 
00401 <p class=MsoNormal style='margin-left:18.0pt;text-align:justify'><span
00402 style='font-size:16.0pt'>&nbsp;</span></p>
00403 
00404 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:16.0pt'>Algorithm
00405 based on Successive Comparisons</span></i></p>
00406 
00407 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>It
00408 is an extension of one-dimensional SNIP algorithm to another dimension. For
00409 details we refer to [2].</span></p>
00410 
00411 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>&nbsp;</span></p>
00412 
00413 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:16.0pt'>Algorithm
00414 based on One Step Filtering</span></i></p>
00415 
00416 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>New
00417 value in the estimated channel is calculated as</span></p>
00418 
00419 <p class=MsoNormal style='text-align:justify'><sub><img width=133 height=39
00420 src="gif/TSpectrum2_Background2.gif"></sub></p>
00421 
00422 <p class=MsoNormal style='text-align:justify'>&nbsp;</p>
00423 
00424 <p class=MsoNormal style='text-align:justify'>&nbsp;</p>
00425 
00426 <p class=MsoNormal style='text-align:justify'><sub><img width=600 height=128
00427 src="gif/TSpectrum2_Background3.gif"></sub></p>
00428 
00429 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>&nbsp;</span></p>
00430 
00431 <p class=MsoNormal><sub><img width=190 height=38
00432 src="gif/TSpectrum2_Background4.gif"></sub>.</p>
00433 
00434 <p class=MsoNormal>&nbsp;</p>
00435 
00436 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>where
00437 p = 1, 2, …, number_of_iterations. </span></p>
00438 
00439 <p class=MsoNormal><i><span style='font-size:18.0pt'>&nbsp;</span></i></p>
00440 
00441 <p class=MsoNormal><i><span style='font-size:18.0pt'>Function:</span></i></p>
00442 
00443 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:18.0pt'>const
00444 <a href="http://root.cern.ch/root/html/ListOfTypes.html#char" target="_parent">char</a>*
00445 </span></b><span style='font-size:18.0pt'><a
00446 href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b>TSpectrum2::Background</b></a><b>
00447 (<a href="http://root.cern.ch/root/html/ListOfTypes.html#float" target="_parent">float</a>
00448 **spectrum, <a href="http://root.cern.ch/root/html/ListOfTypes.html#int"
00449 target="_parent">int</a> ssizex, <a
00450 href="http://root.cern.ch/root/html/ListOfTypes.html#int" target="_parent">int</a>
00451 ssizey, <a href="http://root.cern.ch/root/html/ListOfTypes.html#int"
00452 target="_parent">int</a> numberIterationsX, <a
00453 href="http://root.cern.ch/root/html/ListOfTypes.html#int" target="_parent">int</a>
00454 numberIterationsY, <a href="http://root.cern.ch/root/html/ListOfTypes.html#int"
00455 target="_parent">int</a> direction, <a
00456 href="http://root.cern.ch/root/html/ListOfTypes.html#int" target="_parent">int</a>
00457 filterType)  </b></span></p>
00458 
00459 <p class=MsoNormal>&nbsp;</p>
00460 
00461 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>This
00462 function calculates background spectrum from the source spectrum.  The result
00463 is placed in the matrix pointed by spectrum pointer.  One can also switch the
00464 direction of the change of the clipping window and to select one of the two
00465 above given algorithms.</span><span style='font-size:18.0pt'> </span><span
00466 style='font-size:16.0pt'>On successful completion it returns 0. On error it
00467 returns pointer to the string describing error.</span></p>
00468 
00469 <p class=MsoNormal>&nbsp;</p>
00470 
00471 <p class=MsoNormal><i><span style='font-size:16.0pt;color:red'>Parameters:</span></i></p>
00472 
00473 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>spectrum</span></b>-pointer
00474 to the matrix of source spectrum                  </p>
00475 
00476 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>ssizex, ssizey</span></b>-lengths
00477 of the spectrum matrix                                 </p>
00478 
00479 <p class=MsoNormal style='text-align:justify'>        <b><span
00480 style='font-size:14.0pt'>numberIterationsX, numberIterationsY</span></b>maximal
00481 widths of clipping</p>
00482 
00483 <p class=MsoNormal style='text-align:justify'>        window,                                
00484 </p>
00485 
00486 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>direction</span></b>-
00487 direction of change of clipping window                  </p>
00488 
00489 <p class=MsoNormal>               - possible
00490 values=kBackIncreasingWindow                      </p>
00491 
00492 <p class=MsoNormal>                                           
00493 kBackDecreasingWindow                      </p>
00494 
00495 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>filterType</span></b>-type
00496 of the clipping algorithm,                              </p>
00497 
00498 <p class=MsoNormal>                  -possible values=kBack SuccessiveFiltering</p>
00499 
00500 <p class=MsoNormal>                                             
00501 kBackOneStepFiltering                              </p>
00502 
00503 <p class=MsoNormal>&nbsp;</p>
00504 
00505 <p class=MsoNormal><b><i><span style='font-size:18.0pt'>References:</span></i></b></p>
00506 
00507 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>[1] 
00508 C. G Ryan et al.: SNIP, a statistics-sensitive background treatment for the
00509 quantitative analysis of PIXE spectra in geoscience applications. NIM, B34
00510 (1988), 396-402.</span></p>
00511 
00512 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>[2]
00513 </span><span lang=SK style='font-size:16.0pt'> M. Morhá&#269;, J. Kliman, V.
00514 Matoušek, M. Veselský, I. Turzo</span><span style='font-size:16.0pt'>.:
00515 Background elimination methods for multidimensional gamma-ray spectra. NIM,
00516 A401 (1997) 113-132.</span></p>
00517 
00518 </div>
00519 
00520 <!-- */
00521 // --> End_Html
00522 //Begin_Html <!--
00523 /* -->
00524 <div class=Section1>
00525 
00526 <p class=MsoNormal><i><span style='font-size:18.0pt'>Example 1– script Back_gamma64.c
00527 :</span></i></p>
00528 
00529 <p class=MsoNormal><img width=602 height=418
00530 src="gif/TSpectrum2_Background1.jpg"></p>
00531 
00532 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
00533 1 Original two-dimensional gamma-gamma-ray spectrum</span></b></p>
00534 
00535 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
00536 width=602 height=418 src="gif/TSpectrum2_Background2.jpg"></span></b></p>
00537 
00538 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
00539 2 Background estimated from data from Fig. 1 using decreasing clipping window with
00540 widths 4, 4 and algorithm based on successive comparisons. The estimate
00541 includes not only continuously changing background but also one-dimensional
00542 ridges.</span></b></p>
00543 
00544 <p class=MsoNormal><b><span style='font-size:14.0pt;color:green'><img
00545 width=602 height=418 src="gif/TSpectrum2_Background3.jpg"></span></b></p>
00546 
00547 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
00548 3 Resulting peaks after subtraction of the estimated background (Fig. 2) from original
00549 two-dimensional gamma-gamma-ray spectrum (Fig. 1).</span></b></p>
00550 
00551 <p class=MsoNormal><b><span style='font-size:14.0pt;color:green'>&nbsp;</span></b></p>
00552 
00553 <p class=MsoNormal><b><span style='font-size:14.0pt;color:green'>&nbsp;</span></b></p>
00554 
00555 <p class=MsoNormal><b><span style='font-size:16.0pt;color:green'>Script:</span></b></p>
00556 
00557 <p class=MsoNormal>// Example to illustrate the background estimator (class
00558 TSpectrum).</p>
00559 
00560 <p class=MsoNormal>// To execute this example, do</p>
00561 
00562 <p class=MsoNormal>// root &gt; .x Back_gamma64.C</p>
00563 
00564 <p class=MsoNormal>&nbsp;</p>
00565 
00566 <p class=MsoNormal>#include &lt;TSpectrum&gt; </p>
00567 
00568 <p class=MsoNormal>&nbsp;</p>
00569 
00570 <p class=MsoNormal>void Back_gamma64() {</p>
00571 
00572 <p class=MsoNormal>   Int_t i, j;</p>
00573 
00574 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
00575 
00576 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
00577 
00578 <p class=MsoNormal>   Double_t xmin  = 0;</p>
00579 
00580 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
00581 
00582 <p class=MsoNormal>   Double_t ymin  = 0;</p>
00583 
00584 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
00585 
00586 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
00587 
00588 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
00589 
00590 <p class=MsoNormal>      source[i]=new float[nbinsy];     </p>
00591 
00592 <p class=MsoNormal>   TH2F *back = new TH2F(&quot;back&quot;,&quot;Background estimation&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
00593 
00594 <p class=MsoNormal>   TFile *f = new
00595 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
00596 
00597 <p class=MsoNormal>   back=(TH2F*) f-&gt;Get(&quot;back1;1&quot;);</p>
00598 
00599 <p class=MsoNormal>   TCanvas *Background = new
00600 TCanvas(&quot;Background&quot;,&quot;Estimation of background with increasing
00601 window&quot;,10,10,1000,700);</p>
00602 
00603 <p class=MsoNormal>   TSpectrum *s = new TSpectrum();</p>
00604 
00605 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
00606 
00607 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
00608 
00609 <p class=MsoNormal>                source[i][j] = back-&gt;GetBinContent(i +
00610 1,j + 1); </p>
00611 
00612 <p class=MsoNormal>             }</p>
00613 
00614 <p class=MsoNormal>   }     </p>
00615 
00616 <p class=MsoNormal> s-&gt;Background(source,nbinsx,nbinsy,4,4,kBackDecreasingWindow,kBackSuccessiveFiltering);</p>
00617 
00618 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
00619 
00620 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++)</p>
00621 
00622 <p class=MsoNormal>       back-&gt;SetBinContent(i + 1,j + 1, source[i][j]);   </p>
00623 
00624 <p class=MsoNormal>   }</p>
00625 
00626 <p class=MsoNormal>   back-&gt;Draw(&quot;SURF&quot;);  </p>
00627 
00628 <p class=MsoNormal>   }</p>
00629 
00630 <p class=MsoNormal>&nbsp;</p>
00631 
00632 <p class=MsoNormal><i><span style='font-size:18.0pt'>Example 2– script Back_gamma256.c
00633 :</span></i></p>
00634 
00635 <p class=MsoNormal><img width=602 height=418
00636 src="gif/TSpectrum2_Background4.jpg"></p>
00637 
00638 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
00639 4 Original two-dimensional gamma-gamma-ray spectrum 256x256 channels</span></b></p>
00640 
00641 <p class=MsoNormal><img width=602 height=418
00642 src="gif/TSpectrum2_Background5.jpg"></p>
00643 
00644 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
00645 5 Peaks after subtraction of the estimated background (increasing clipping
00646 window with widths 8, 8 and algorithm based on successive comparisons) from original
00647 two-dimensional gamma-gamma-ray spectrum (Fig. 4).</span></b></p>
00648 
00649 <p class=MsoNormal><b><span style='font-size:16.0pt;color:green'>&nbsp;</span></b></p>
00650 
00651 <p class=MsoNormal><b><span style='font-size:16.0pt;color:green'>Script:</span></b></p>
00652 
00653 <p class=MsoNormal>// Example to illustrate the background estimator (class
00654 TSpectrum).</p>
00655 
00656 <p class=MsoNormal>// To execute this example, do</p>
00657 
00658 <p class=MsoNormal>// root &gt; .x Back_gamma256.C</p>
00659 
00660 <p class=MsoNormal>&nbsp;</p>
00661 
00662 <p class=MsoNormal>#include &lt;TSpectrum&gt; </p>
00663 
00664 <p class=MsoNormal>&nbsp;</p>
00665 
00666 <p class=MsoNormal>void Back_gamma256() {</p>
00667 
00668 <p class=MsoNormal>   Int_t i, j;</p>
00669 
00670 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
00671 
00672 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
00673 
00674 <p class=MsoNormal>   Double_t xmin  = 0;</p>
00675 
00676 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
00677 
00678 <p class=MsoNormal>   Double_t ymin  = 0;</p>
00679 
00680 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
00681 
00682 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
00683 
00684 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
00685 
00686 <p class=MsoNormal>      source[i]=new float[nbinsy];     </p>
00687 
00688 <p class=MsoNormal>   TH2F *back = new TH2F(&quot;back&quot;,&quot;Background estimation&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
00689 
00690 <p class=MsoNormal>   TFile *f = new
00691 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
00692 
00693 <p class=MsoNormal>   back=(TH2F*) f-&gt;Get(&quot;back2;1&quot;);</p>
00694 
00695 <p class=MsoNormal>   TCanvas *Background = new
00696 TCanvas(&quot;Background&quot;,&quot;Estimation of background with increasing
00697 window&quot;,10,10,1000,700);</p>
00698 
00699 <p class=MsoNormal>   TSpectrum *s = new TSpectrum();</p>
00700 
00701 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
00702 
00703 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
00704 
00705 <p class=MsoNormal>                source[i][j] = back-&gt;GetBinContent(i +
00706 1,j + 1); </p>
00707 
00708 <p class=MsoNormal>             }</p>
00709 
00710 <p class=MsoNormal>   }     </p>
00711 
00712 <p class=MsoNormal> s-&gt;Background(source,nbinsx,nbinsy,8,8,kBackIncreasingWindow,kBackSuccessiveFiltering);</p>
00713 
00714 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
00715 
00716 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++)</p>
00717 
00718 <p class=MsoNormal>       back-&gt;SetBinContent(i + 1,j + 1, source[i][j]);   </p>
00719 
00720 <p class=MsoNormal>   }</p>
00721 
00722 <p class=MsoNormal>   back-&gt;Draw(&quot;SURF&quot;);  </p>
00723 
00724 <p class=MsoNormal>   }</p>
00725 
00726 <p class=MsoNormal><i><span style='font-size:18.0pt'>Example 3– script Back_synt256.c
00727 :</span></i></p>
00728 
00729 <p class=MsoNormal><img width=602 height=418
00730 src="gif/TSpectrum2_Background6.jpg"></p>
00731 
00732 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
00733 6 Original two-dimensional synthetic spectrum 256x256 channels</span></b></p>
00734 
00735 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
00736 width=602 height=418 src="gif/TSpectrum2_Background7.jpg"></span></b></p>
00737 
00738 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
00739 7 Peaks after subtraction of the estimated background (increasing clipping
00740 window with widths 8, 8 and algorithm based on successive comparisons) from original
00741 two-dimensional gamma-gamma-ray spectrum (Fig. 6). One can observe artifacts
00742 (ridges) around the peaks due to the employed algorithm.</span></b></p>
00743 
00744 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
00745 width=602 height=418 src="gif/TSpectrum2_Background8.jpg"></span></b></p>
00746 
00747 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
00748 8 Peaks after subtraction of the estimated background (increasing clipping
00749 window with widths 8, 8 and algorithm based on one step filtering) from original
00750 two-dimensional gamma-gamma-ray spectrum (Fig. 6).  The artifacts from the
00751 above given Fig. 7 disappeared.</span></b></p>
00752 
00753 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>&nbsp;</span></b></p>
00754 
00755 <p class=MsoNormal><b><span style='font-size:16.0pt;color:green'>Script:</span></b></p>
00756 
00757 <p class=MsoNormal>// Example to illustrate the background estimator (class
00758 TSpectrum).</p>
00759 
00760 <p class=MsoNormal>// To execute this example, do</p>
00761 
00762 <p class=MsoNormal>// root &gt; .x Back_synt256.C</p>
00763 
00764 <p class=MsoNormal>&nbsp;</p>
00765 
00766 <p class=MsoNormal>#include &lt;TSpectrum&gt; </p>
00767 
00768 <p class=MsoNormal>&nbsp;</p>
00769 
00770 <p class=MsoNormal>void Back_synt256() {</p>
00771 
00772 <p class=MsoNormal>   Int_t i, j;</p>
00773 
00774 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
00775 
00776 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
00777 
00778 <p class=MsoNormal>   Double_t xmin  = 0;</p>
00779 
00780 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
00781 
00782 <p class=MsoNormal>   Double_t ymin  = 0;</p>
00783 
00784 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
00785 
00786 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
00787 
00788 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
00789 
00790 <p class=MsoNormal>      source[i]=new float[nbinsy];     </p>
00791 
00792 <p class=MsoNormal>   TH2F *back = new TH2F(&quot;back&quot;,&quot;Background estimation&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
00793 
00794 <p class=MsoNormal>   TFile *f = new
00795 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
00796 
00797 <p class=MsoNormal>   back=(TH2F*) f-&gt;Get(&quot;back3;1&quot;);</p>
00798 
00799 <p class=MsoNormal>   TCanvas *Background = new
00800 TCanvas(&quot;Background&quot;,&quot;Estimation of background with increasing
00801 window&quot;,10,10,1000,700);</p>
00802 
00803 <p class=MsoNormal>   TSpectrum *s = new TSpectrum();</p>
00804 
00805 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
00806 
00807 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
00808 
00809 <p class=MsoNormal>                source[i][j] = back-&gt;GetBinContent(i +
00810 1,j + 1); </p>
00811 
00812 <p class=MsoNormal>             }</p>
00813 
00814 <p class=MsoNormal>   }     </p>
00815 
00816 <p class=MsoNormal> s-&gt;Background(source,nbinsx,nbinsy,8,8,kBackIncreasingWindow,kBackSuccessiveFiltering);//kBackOneStepFiltering</p>
00817 
00818 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
00819 
00820 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++)</p>
00821 
00822 <p class=MsoNormal>       back-&gt;SetBinContent(i + 1,j + 1, source[i][j]);   </p>
00823 
00824 <p class=MsoNormal>   }</p>
00825 
00826 <p class=MsoNormal>   back-&gt;Draw(&quot;SURF&quot;);  </p>
00827 
00828 <p class=MsoNormal>   }</p>
00829 
00830 </div>
00831 
00832 <!-- */
00833 // --> End_Html
00834 
00835    int i, x, y, sampling, r1, r2;
00836    float a, b, p1, p2, p3, p4, s1, s2, s3, s4;
00837    if (ssizex <= 0 || ssizey <= 0)
00838       return "Wrong parameters";
00839    if (numberIterationsX < 1 || numberIterationsY < 1)
00840       return "Width of Clipping Window Must Be Positive";
00841    if (ssizex < 2 * numberIterationsX + 1
00842         || ssizey < 2 * numberIterationsY + 1)
00843       return ("Too Large Clipping Window");
00844    float **working_space = new float *[ssizex];
00845    for (i = 0; i < ssizex; i++)
00846       working_space[i] = new float[ssizey];
00847    sampling =
00848        (int) TMath::Max(numberIterationsX, numberIterationsY);
00849    if (direction == kBackIncreasingWindow) {
00850       if (filterType == kBackSuccessiveFiltering) {
00851          for (i = 1; i <= sampling; i++) {
00852             r1 = (int) TMath::Min(i, numberIterationsX), r2 =
00853                 (int) TMath::Min(i, numberIterationsY);
00854             for (y = r2; y < ssizey - r2; y++) {
00855                for (x = r1; x < ssizex - r1; x++) {
00856                   a = spectrum[x][y];
00857                   p1 = spectrum[x - r1][y - r2];
00858                   p2 = spectrum[x - r1][y + r2];
00859                   p3 = spectrum[x + r1][y - r2];
00860                   p4 = spectrum[x + r1][y + r2];
00861                   s1 = spectrum[x][y - r2];
00862                   s2 = spectrum[x - r1][y];
00863                   s3 = spectrum[x + r1][y];
00864                   s4 = spectrum[x][y + r2];
00865                   b = (p1 + p2) / 2.0;
00866                   if (b > s2)
00867                      s2 = b;
00868                   b = (p1 + p3) / 2.0;
00869                   if (b > s1)
00870                      s1 = b;
00871                   b = (p2 + p4) / 2.0;
00872                   if (b > s4)
00873                      s4 = b;
00874                   b = (p3 + p4) / 2.0;
00875                   if (b > s3)
00876                      s3 = b;
00877                   s1 = s1 - (p1 + p3) / 2.0;
00878                   s2 = s2 - (p1 + p2) / 2.0;
00879                   s3 = s3 - (p3 + p4) / 2.0;
00880                   s4 = s4 - (p2 + p4) / 2.0;
00881                   b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
00882                                                             p3 +
00883                                                             p4) / 4.0;
00884                   if (b < a && b > 0)
00885                      a = b;
00886                   working_space[x][y] = a;
00887                }
00888             }
00889             for (y = r2; y < ssizey - r2; y++) {
00890                for (x = r1; x < ssizex - r1; x++) {
00891                   spectrum[x][y] = working_space[x][y];
00892                }
00893             }
00894          }                 
00895       }
00896       
00897       else if (filterType == kBackOneStepFiltering) {
00898          for (i = 1; i <= sampling; i++) {
00899             r1 = (int) TMath::Min(i, numberIterationsX), r2 =
00900                 (int) TMath::Min(i, numberIterationsY);
00901             for (y = r2; y < ssizey - r2; y++) {
00902                for (x = r1; x < ssizex - r1; x++) {
00903                   a = spectrum[x][y];
00904                   b = -(spectrum[x - r1][y - r2] +
00905                          spectrum[x - r1][y + r2] + spectrum[x + r1][y -
00906                                                                      r2]
00907                          + spectrum[x + r1][y + r2]) / 4 +
00908                       (spectrum[x][y - r2] + spectrum[x - r1][y] +
00909                        spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
00910                   if (b < a && b > 0)
00911                      a = b;
00912                   working_space[x][y] = a;
00913                }
00914             }
00915             for (y = i; y < ssizey - i; y++) {
00916                for (x = i; x < ssizex - i; x++) {
00917                   spectrum[x][y] = working_space[x][y];
00918                }
00919             }
00920          }
00921       }
00922    }
00923    
00924    else if (direction == kBackDecreasingWindow) {
00925       if (filterType == kBackSuccessiveFiltering) {
00926          for (i = sampling; i >= 1; i--) {
00927             r1 = (int) TMath::Min(i, numberIterationsX), r2 =
00928                 (int) TMath::Min(i, numberIterationsY);
00929             for (y = r2; y < ssizey - r2; y++) {
00930                for (x = r1; x < ssizex - r1; x++) {
00931                   a = spectrum[x][y];
00932                   p1 = spectrum[x - r1][y - r2];
00933                   p2 = spectrum[x - r1][y + r2];
00934                   p3 = spectrum[x + r1][y - r2];
00935                   p4 = spectrum[x + r1][y + r2];
00936                   s1 = spectrum[x][y - r2];
00937                   s2 = spectrum[x - r1][y];
00938                   s3 = spectrum[x + r1][y];
00939                   s4 = spectrum[x][y + r2];
00940                   b = (p1 + p2) / 2.0;
00941                   if (b > s2)
00942                      s2 = b;
00943                   b = (p1 + p3) / 2.0;
00944                   if (b > s1)
00945                      s1 = b;
00946                   b = (p2 + p4) / 2.0;
00947                   if (b > s4)
00948                      s4 = b;
00949                   b = (p3 + p4) / 2.0;
00950                   if (b > s3)
00951                      s3 = b;
00952                   s1 = s1 - (p1 + p3) / 2.0;
00953                   s2 = s2 - (p1 + p2) / 2.0;
00954                   s3 = s3 - (p3 + p4) / 2.0;
00955                   s4 = s4 - (p2 + p4) / 2.0;
00956                   b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
00957                                                             p3 +
00958                                                             p4) / 4.0;
00959                   if (b < a && b > 0)
00960                      a = b;
00961                   working_space[x][y] = a;
00962                }
00963             }
00964             for (y = r2; y < ssizey - r2; y++) {
00965                for (x = r1; x < ssizex - r1; x++) {
00966                   spectrum[x][y] = working_space[x][y];
00967                }
00968             }
00969          }
00970       }        
00971       
00972       else if (filterType == kBackOneStepFiltering) {
00973          for (i = sampling; i >= 1; i--) {
00974             r1 = (int) TMath::Min(i, numberIterationsX), r2 =
00975                 (int) TMath::Min(i, numberIterationsY);
00976             for (y = r2; y < ssizey - r2; y++) {
00977                for (x = r1; x < ssizex - r1; x++) {
00978                   a = spectrum[x][y];
00979                   b = -(spectrum[x - r1][y - r2] +
00980                          spectrum[x - r1][y + r2] + spectrum[x + r1][y -
00981                                                                      r2]
00982                          + spectrum[x + r1][y + r2]) / 4 +
00983                       (spectrum[x][y - r2] + spectrum[x - r1][y] +
00984                        spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
00985                   if (b < a && b > 0)
00986                      a = b;
00987                   working_space[x][y] = a;
00988                }
00989             }
00990             for (y = i; y < ssizey - i; y++) {
00991                for (x = i; x < ssizex - i; x++) {
00992                   spectrum[x][y] = working_space[x][y];
00993                }
00994             }
00995          }
00996       }
00997    }
00998    for (i = 0; i < ssizex; i++)
00999       delete[]working_space[i];
01000    delete[]working_space;
01001    return 0;
01002 }
01003 
01004 //_____________________________________________________________________________
01005 const char* TSpectrum2::SmoothMarkov(float **source, Int_t ssizex, Int_t ssizey, Int_t averWindow)
01006 {
01007 /////////////////////////////////////////////////////////////////////////////
01008 //   TWO-DIMENSIONAL MARKOV SPECTRUM SMOOTHING FUNCTION               
01009 //
01010 //   This function calculates smoothed spectrum from source spectrum    
01011 //      based on Markov chain method.                                     
01012 //   The result is placed in the array pointed by source pointer.      
01013 //
01014 //   Function parameters:
01015 //   source-pointer to the array of source spectrum
01016 //   ssizex-x length of source
01017 //   ssizey-y length of source
01018 //   averWindow-width of averaging smoothing window
01019 //
01020 /////////////////////////////////////////////////////////////////////////////
01021 //Begin_Html <!--
01022 /* -->
01023 <div class=Section1>
01024 
01025 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:20.0pt'>Smoothing</span></b></p>
01026 
01027 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:18.0pt'>&nbsp;</span></i></p>
01028 
01029 <p class=MsoNormal><i><span style='font-size:18.0pt'>Goal: Suppression of
01030 statistical fluctuations</span></i></p>
01031 
01032 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01033 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01034 </span></span><span style='font-size:16.0pt'>the algorithm is based on discrete
01035 Markov chain, which has very simple invariant distribution</span></p>
01036 
01037 <p class=MsoNormal>&nbsp;</p>
01038 
01039 <p class=MsoNormal>            <sub><img width=551 height=63
01040 src="gif/TSpectrum2_Smoothing1.gif"></sub><span style='font-size:16.0pt;
01041 font-family:Arial'>     </span></p>
01042 
01043 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt;
01044 font-family:Arial'>        </span><sub><img width=28 height=36
01045 src="gif/TSpectrum2_Smoothing2.gif"></sub><span style='font-size:16.0pt;
01046 font-family:Arial'>  being defined from the normalization condition </span><sub><img
01047 width=70 height=52 src="gif/TSpectrum2_Smoothing3.gif"></sub></p>
01048 
01049 <p class=MsoNormal>&nbsp;</p>
01050 
01051 <p class=MsoNormal><span style='font-size:16.0pt;font-family:Arial'>         n
01052 is the length of the smoothed spectrum and </span></p>
01053 
01054 <p class=MsoNormal>
01055 
01056 <table cellpadding=0 cellspacing=0 align=left>
01057  <tr>
01058   <td width=57 height=15></td>
01059  </tr>
01060  <tr>
01061   <td></td>
01062   <td><img width=258 height=60 src="gif/TSpectrum2_Smoothing4.gif"></td>
01063  </tr>
01064 </table>
01065 
01066 <span style='font-size:16.0pt;font-family:Arial'>&nbsp;</span></p>
01067 
01068 <p class=MsoNormal><span style='font-size:18.0pt'>&nbsp;</span></p>
01069 
01070 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>&nbsp;</span></p>
01071 
01072 <br clear=ALL>
01073 
01074 <p class=MsoNormal style='margin-left:34.2pt;text-align:justify'><span
01075 style='font-size:16.0pt;font-family:Arial'>is the probability of the change of
01076 the peak position from channel i to the channel i+1. </span> <sub><img
01077 width=28 height=36 src="gif/TSpectrum2_Smoothing5.gif"></sub><span
01078 style='font-size:16.0pt;font-family:Arial'>is the normalization constant so
01079 that </span><span style='font-family:Arial'><sub><img width=133 height=34
01080 src="gif/TSpectrum2_Smoothing6.gif"></sub> </span><span style='font-size:16.0pt;
01081 font-family:Arial'>and m is a width of smoothing window. We have extended this
01082 algortihm to two dimensions. </span></p>
01083 
01084 <p class=MsoNormal><i><span style='font-size:18.0pt'>&nbsp;</span></i></p>
01085 
01086 <p class=MsoNormal><i><span style='font-size:18.0pt'>Function:</span></i></p>
01087 
01088 <p class=MsoNormal><b><span style='font-size:18.0pt'>const <a
01089 href="http://root.cern.ch/root/html/ListOfTypes.html#char" target="_parent">char</a>*
01090 </span></b><span style='font-size:18.0pt'><a
01091 href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b>TSpectrum2::SmoothMarkov</b></a><b>(<a
01092 href="http://root.cern.ch/root/html/ListOfTypes.html#float" target="_parent">float</a>
01093 **fSpectrum, <a href="http://root.cern.ch/root/html/ListOfTypes.html#int"
01094 target="_parent">int</a> ssizex, <a
01095 href="http://root.cern.ch/root/html/ListOfTypes.html#int" target="_parent">int</a>
01096 ssizey,  <a href="http://root.cern.ch/root/html/ListOfTypes.html#int"
01097 target="_parent">int</a> averWindow)  </b></span></p>
01098 
01099 <p class=MsoNormal>&nbsp;</p>
01100 
01101 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>This
01102 function calculates smoothed spectrum from the source spectrum based on Markov
01103 chain method. The result is placed in the vector pointed by source pointer. On
01104 successful completion it returns 0. On error it returns pointer to the string
01105 describing error.</span></p>
01106 
01107 <p class=MsoNormal>&nbsp;</p>
01108 
01109 <p class=MsoNormal><i><span style='font-size:16.0pt;color:red'>Parameters:</span></i></p>
01110 
01111 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>fSpectrum</span></b>-pointer
01112 to the matrix of source spectrum                  </p>
01113 
01114 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>ssizex, ssizey</span></b>
01115 -lengths of the spectrum matrix                                 </p>
01116 
01117 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>averWindow</span></b>-width
01118 of averaging smoothing window </p>
01119 
01120 <p class=MsoNormal>&nbsp;</p>
01121 
01122 <p class=MsoNormal><b><i><span style='font-size:18.0pt'>Reference:</span></i></b></p>
01123 
01124 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>[1]
01125 Z.K. Silagadze, A new algorithm for automatic photopeak searches. NIM A 376
01126 (1996), 451<b>.</b>  </span></p>
01127 
01128 </div>
01129 
01130 <!-- */
01131 // --> End_Html
01132 //Begin_Html <!--
01133 /* -->
01134 <div class=Section1>
01135 
01136 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 4 – script Smooth.c
01137 :</span></i></p>
01138 
01139 <p class=MsoNormal><span style='font-size:16.0pt'><img width=300 height=209
01140 src="gif/TSpectrum2_Smoothing1.jpg"><img width=297 height=207
01141 src="gif/TSpectrum2_Smoothing2.jpg"></span></p>
01142 
01143 <p class=MsoNormal><b><span style='font-size:16.0pt'>Fig. 9 Original noisy
01144 spectrum.</span></b><b><span style='font-size:14.0pt'>    </span></b><b><span
01145 style='font-size:16.0pt'>Fig. 10 Smoothed spectrum m=3</span></b></p>
01146 
01147 <p class=MsoNormal><b><span style='font-size:16.0pt'>Peaks can hardly be
01148 observed.     Peaks become apparent.</span></b></p>
01149 
01150 <p class=MsoNormal><b><span style='font-size:14.0pt'><img width=293 height=203
01151 src="gif/TSpectrum2_Smoothing3.jpg"><img width=297 height=205
01152 src="gif/TSpectrum2_Smoothing4.jpg"></span></b></p>
01153 
01154 <p class=MsoNormal><b><span style='font-size:16.0pt'>Fig. 11 Smoothed spectrum
01155 m=5 Fig.12 Smoothed spectrum m=7</span></b></p>
01156 
01157 <p class=MsoNormal>&nbsp;</p>
01158 
01159 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
01160 
01161 <p class=MsoNormal>// Example to illustrate the Markov smoothing (class
01162 TSpectrum).</p>
01163 
01164 <p class=MsoNormal>// To execute this example, do</p>
01165 
01166 <p class=MsoNormal>// root &gt; .x Smooth.C</p>
01167 
01168 <p class=MsoNormal>#include &lt;TSpectrum&gt; </p>
01169 
01170 <p class=MsoNormal>void Smooth() {</p>
01171 
01172 <p class=MsoNormal>   Int_t i, j;</p>
01173 
01174 <p class=MsoNormal>   Double_t nbinsx = 256;</p>
01175 
01176 <p class=MsoNormal>   Double_t nbinsy = 256;   </p>
01177 
01178 <p class=MsoNormal>   Double_t xmin  = 0;</p>
01179 
01180 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
01181 
01182 <p class=MsoNormal>   Double_t ymin  = 0;</p>
01183 
01184 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
01185 
01186 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
01187 
01188 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
01189 
01190 <p class=MsoNormal>                                    source[i]=new
01191 float[nbinsy];     </p>
01192 
01193 <p class=MsoNormal>   TH2F *smooth = new
01194 TH2F(&quot;smooth&quot;,&quot;Background
01195 estimation&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
01196 
01197 <p class=MsoNormal>   TFile *f = new
01198 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
01199 
01200 <p class=MsoNormal>   smooth=(TH2F*) f-&gt;Get(&quot;smooth1;1&quot;);</p>
01201 
01202 <p class=MsoNormal>   TCanvas *Smoothing = new
01203 TCanvas(&quot;Smoothing&quot;,&quot;Markov smoothing&quot;,10,10,1000,700);</p>
01204 
01205 <p class=MsoNormal>   TSpectrum *s = new TSpectrum();</p>
01206 
01207 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01208 
01209 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
01210 
01211 <p class=MsoNormal>                source[i][j] = smooth-&gt;GetBinContent(i +
01212 1,j + 1); </p>
01213 
01214 <p class=MsoNormal>             }</p>
01215 
01216 <p class=MsoNormal>   }</p>
01217 
01218 <p class=MsoNormal>   s-&gt;SmoothMarkov(source,nbinsx,nbinsx,3);//5,7</p>
01219 
01220 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01221 
01222 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++)</p>
01223 
01224 <p class=MsoNormal>       smooth-&gt;SetBinContent(i + 1,j + 1,
01225 source[i][j]);   </p>
01226 
01227 <p class=MsoNormal>   }</p>
01228 
01229 <p class=MsoNormal>   smooth-&gt;Draw(&quot;SURF&quot;);  </p>
01230 
01231 <p class=MsoNormal>   }</p>
01232 
01233 </div>
01234 
01235 <!-- */
01236 // --> End_Html
01237    int xmin, xmax, ymin, ymax, i, j, l;
01238    double a, b, maxch;
01239    double nom, nip, nim, sp, sm, spx, spy, smx, smy, plocha = 0;
01240    if(averWindow <= 0)
01241       return "Averaging Window must be positive";      
01242    float **working_space = new float* [ssizex];
01243    for(i = 0; i < ssizex; i++)
01244       working_space[i] = new float[ssizey];      
01245    xmin = 0;
01246    xmax = ssizex - 1;
01247    ymin = 0;
01248    ymax = ssizey - 1;
01249    for(i = 0, maxch = 0; i < ssizex; i++){
01250       for(j = 0; j < ssizey; j++){
01251          working_space[i][j] = 0;
01252          if(maxch < source[i][j])
01253             maxch = source[i][j];
01254 
01255          plocha += source[i][j];
01256       }
01257    }
01258    if(maxch == 0) {
01259       delete [] working_space;
01260       return 0;
01261    }
01262 
01263    nom = 0;
01264    working_space[xmin][ymin] = 1;
01265    for(i = xmin; i < xmax; i++){
01266       nip = source[i][ymin] / maxch;
01267       nim = source[i + 1][ymin] / maxch;
01268       sp = 0,sm = 0;
01269       for(l = 1; l <= averWindow; l++){
01270          if((i + l) > xmax)
01271             a = source[xmax][ymin] / maxch;
01272 
01273          else
01274             a = source[i + l][ymin] / maxch;
01275          b = a - nip;
01276          if(a + nip <= 0)
01277             a = 1;
01278 
01279          else
01280             a = TMath::Sqrt(a + nip);            
01281          b = b / a;
01282          b = TMath::Exp(b);
01283          sp = sp + b;
01284          if(i - l + 1 < xmin)
01285             a = source[xmin][ymin] / maxch;
01286 
01287          else
01288             a = source[i - l + 1][ymin] / maxch;
01289          b = a - nim;
01290          if(a + nim <= 0)
01291             a = 1;
01292 
01293          else
01294             a = TMath::Sqrt(a + nim);            
01295          b = b / a;
01296          b = TMath::Exp(b);
01297          sm = sm + b;
01298       }
01299       a = sp / sm;
01300       a = working_space[i + 1][ymin] = a * working_space[i][ymin];
01301       nom = nom + a;
01302    }
01303    for(i = ymin; i < ymax; i++){
01304       nip = source[xmin][i] / maxch;
01305       nim = source[xmin][i + 1] / maxch;
01306       sp = 0,sm = 0;
01307       for(l = 1; l <= averWindow; l++){
01308          if((i + l) > ymax)
01309             a = source[xmin][ymax] / maxch;
01310 
01311          else
01312             a = source[xmin][i + l] / maxch;
01313          b = a - nip;
01314          if(a + nip <= 0)
01315             a = 1;
01316 
01317          else
01318             a = TMath::Sqrt(a + nip);            
01319          b = b / a;
01320          b = TMath::Exp(b);
01321          sp = sp + b;
01322          if(i - l + 1 < ymin)
01323             a = source[xmin][ymin] / maxch;
01324 
01325          else
01326             a = source[xmin][i - l + 1] / maxch;
01327          b = a - nim;
01328          if(a + nim <= 0)
01329             a = 1;
01330 
01331          else
01332             a = TMath::Sqrt(a + nim);            
01333          b = b / a;
01334          b = TMath::Exp(b);
01335          sm = sm + b;
01336       }
01337       a = sp / sm;
01338       a = working_space[xmin][i + 1] = a * working_space[xmin][i];
01339       nom = nom + a;
01340    }
01341    for(i = xmin; i < xmax; i++){
01342       for(j = ymin; j < ymax; j++){
01343          nip = source[i][j + 1] / maxch;
01344          nim = source[i + 1][j + 1] / maxch;
01345          spx = 0,smx = 0;
01346          for(l = 1; l <= averWindow; l++){
01347             if(i + l > xmax)
01348                a = source[xmax][j] / maxch;
01349 
01350             else
01351                a = source[i + l][j] / maxch;
01352             b = a - nip;
01353             if(a + nip <= 0)
01354                a = 1;
01355 
01356             else
01357                a = TMath::Sqrt(a + nip);            
01358             b = b / a;
01359             b = TMath::Exp(b);
01360             spx = spx + b;
01361             if(i - l + 1 < xmin)
01362                a = source[xmin][j] / maxch;
01363 
01364             else
01365                a = source[i - l + 1][j] / maxch;
01366             b = a - nim;
01367             if(a + nim <= 0)
01368                a = 1;
01369 
01370             else
01371                a = TMath::Sqrt(a + nim);            
01372             b = b / a;
01373             b = TMath::Exp(b);
01374             smx = smx + b;
01375          }
01376          spy = 0,smy = 0;
01377          nip = source[i + 1][j] / maxch;
01378          nim = source[i + 1][j + 1] / maxch;
01379          for (l = 1; l <= averWindow; l++) {
01380             if (j + l > ymax) a = source[i][ymax]/maxch;
01381             else              a = source[i][j + l] / maxch;
01382             b = a - nip;
01383             if (a + nip <= 0) a = 1;
01384             else              a = TMath::Sqrt(a + nip);            
01385             b = b / a;
01386             b = TMath::Exp(b);
01387             spy = spy + b;
01388             if (j - l + 1 < ymin) a = source[i][ymin] / maxch;
01389             else                  a = source[i][j - l + 1] / maxch;
01390             b = a - nim;
01391             if (a + nim <= 0) a = 1;
01392             else              a = TMath::Sqrt(a + nim);            
01393             b = b / a;
01394             b = TMath::Exp(b);
01395             smy = smy + b;
01396          }
01397          a = (spx * working_space[i][j + 1] + spy * working_space[i + 1][j]) / (smx +smy);
01398          working_space[i + 1][j + 1] = a;
01399          nom = nom + a;
01400       }
01401    }
01402    for(i = xmin; i <= xmax; i++){
01403       for(j = ymin; j <= ymax; j++){
01404          working_space[i][j] = working_space[i][j] / nom;
01405       }
01406    }
01407    for(i = 0;i < ssizex; i++){
01408       for(j = 0; j < ssizey; j++){
01409          source[i][j] = plocha * working_space[i][j];
01410       }
01411    }
01412    for (i = 0; i < ssizex; i++)
01413       delete[]working_space[i];
01414    delete[]working_space;   
01415    return 0;
01416 }
01417 
01418 //______________________________________________________________________________________________________________________________
01419 const char *TSpectrum2::Deconvolution(float **source, float **resp,
01420                                        Int_t ssizex, Int_t ssizey,
01421                                        Int_t numberIterations, 
01422                                        Int_t numberRepetitions,
01423                                        Double_t boost)                                        
01424 {   
01425 /////////////////////////////////////////////////////////////////////////////
01426 //   TWO-DIMENSIONAL DECONVOLUTION FUNCTION
01427 //   This function calculates deconvolution from source spectrum
01428 //   according to response spectrum
01429 //   The result is placed in the matrix pointed by source pointer.
01430 //
01431 //   Function parameters:
01432 //   source-pointer to the matrix of source spectrum
01433 //   resp-pointer to the matrix of response spectrum
01434 //   ssizex-x length of source and response spectra
01435 //   ssizey-y length of source and response spectra
01436 //   numberIterations, for details we refer to manual
01437 //   numberRepetitions, for details we refer to manual
01438 //   boost, boosting factor, for details we refer to manual
01439 //
01440 /////////////////////////////////////////////////////////////////////////////
01441 //Begin_Html <!--
01442 /* -->
01443 <div class=Section1>
01444 
01445 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:20.0pt'>Deconvolution</span></b></p>
01446 
01447 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:18.0pt'>&nbsp;</span></i></p>
01448 
01449 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:18.0pt'>Goal:
01450 Improvement of the resolution in spectra, decomposition of multiplets</span></i></p>
01451 
01452 <p class=MsoNormal><span style='font-size:16.0pt'>&nbsp;</span></p>
01453 
01454 <p class=MsoNormal><span style='font-size:16.0pt'>Mathematical formulation of
01455 the 2-dimensional convolution system is</span></p>
01456 
01457 <p class=MsoNormal style='margin-left:18.0pt'>
01458 
01459 <table cellpadding=0 cellspacing=0 align=left>
01460  <tr>
01461   <td width=0 height=18></td>
01462  </tr>
01463  <tr>
01464   <td></td>
01465   <td><img width=577 height=138 src="gif/TSpectrum2_Deconvolution1.gif"></td>
01466  </tr>
01467 </table>
01468 
01469 <span style='font-size:16.0pt'>&nbsp;</span></p>
01470 
01471 <p class=MsoNormal><span style='font-size:16.0pt'>&nbsp;</span></p>
01472 
01473 <p class=MsoNormal>&nbsp;</p>
01474 
01475 <p class=MsoNormal>&nbsp;</p>
01476 
01477 <p class=MsoNormal>&nbsp;</p>
01478 
01479 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>&nbsp;</span></p>
01480 
01481 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>&nbsp;</span></p>
01482 
01483 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>&nbsp;</span></p>
01484 
01485 <br clear=ALL>
01486 
01487 <p class=MsoNormal><span style='font-size:16.0pt'>where h(i,j) is the impulse
01488 response function, x, y are input and output matrices, respectively, <sub><img
01489 width=45 height=24 src="gif/TSpectrum2_Deconvolution2.gif"></sub> are the lengths
01490 of x and h matrices</span><i><span style='font-size:18.0pt'> </span></i></p>
01491 
01492 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01493 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01494 </span></span><span style='font-size:16.0pt'>let us assume that we know the
01495 response and the output matrices (spectra) of the above given system. </span></p>
01496 
01497 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01498 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01499 </span></span><span style='font-size:16.0pt'>the deconvolution represents
01500 solution of the overdetermined system of linear equations, i.e.,  the
01501 calculation of the matrix <b>x.</b></span></p>
01502 
01503 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01504 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01505 </span></span><span style='font-size:16.0pt'>from numerical stability point of
01506 view the operation of deconvolution is extremely critical (ill-posed  problem)
01507 as well as time consuming operation. </span></p>
01508 
01509 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01510 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01511 </span></span><span style='font-size:16.0pt'>the Gold deconvolution algorithm
01512 proves to work very well even for 2-dimensional systems. Generalization of the
01513 algorithm for 2-dimensional systems was presented in [1], [2].</span></p>
01514 
01515 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01516 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01517 </span></span><span style='font-size:16.0pt'>for Gold deconvolution algorithm
01518 as well as for boosted deconvolution algorithm we refer also to TSpectrum </span></p>
01519 
01520 <p class=MsoNormal><i><span style='font-size:18.0pt'>&nbsp;</span></i></p>
01521 
01522 <p class=MsoNormal><i><span style='font-size:18.0pt'>Function:</span></i></p>
01523 
01524 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:18.0pt'>const
01525 <a href="http://root.cern.ch/root/html/ListOfTypes.html#char">char</a>* </span></b><a
01526 name="TSpectrum:Deconvolution1"></a><a
01527 href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b><span
01528 style='font-size:18.0pt'>TSpectrum2::Deconvolution</span></b></a><b><span
01529 style='font-size:18.0pt'>(<a
01530 href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a> **source,
01531 const <a href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a>
01532 **resp, <a href="http://root.cern.ch/root/html/ListOfTypes.html#int">int</a> ssizex,
01533 <a href="http://root.cern.ch/root/html/ListOfTypes.html#int">int</a> ssizey, <a
01534 href="http://root.cern.ch/root/html/ListOfTypes.html#int">int</a> numberIterations,
01535 <a href="http://root.cern.ch/root/html/ListOfTypes.html#int">int</a> numberRepetitions,
01536 <a href="http://root.cern.ch/root/html/ListOfTypes.html#double">double</a></span></b><b><span
01537 style='font-size:16.0pt'> </span></b><b><span style='font-size:18.0pt'>boost)</span></b></p>
01538 
01539 <p class=MsoNormal>&nbsp;</p>
01540 
01541 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>This
01542 function calculates deconvolution from source spectrum according to response
01543 spectrum using Gold deconvolution algorithm. The result is placed in the matrix
01544 pointed by source pointer. On successful completion it returns 0. On error it
01545 returns pointer to the string describing error. If desired after every
01546 numberIterations one can apply boosting operation (exponential function with
01547 exponent given by boost coefficient) and repeat it numberRepetitions times.</span></p>
01548 
01549 <p class=MsoNormal>&nbsp;</p>
01550 
01551 <p class=MsoNormal><i><span style='font-size:16.0pt;color:red'>Parameters:</span></i></p>
01552 
01553 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>source</span></b>-pointer
01554 to the matrix of source spectrum                  </p>
01555 
01556 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>resp</span></b>-pointer
01557 to the matrix of response spectrum                  </p>
01558 
01559 <p class=MsoNormal>        <b><span style='font-size:14.0pt'>ssizex, ssizey</span></b>-lengths
01560 of the spectrum matrix                                 </p>
01561 
01562 <p class=MsoNormal style='text-align:justify'>        <b><span
01563 style='font-size:14.0pt'>numberIterations</span></b>-number of iterations </p>
01564 
01565 <p class=MsoNormal style='text-align:justify'>        <b><span
01566 style='font-size:14.0pt'>numberRepetitions</span></b>-number of repetitions
01567 for boosted deconvolution. It must be </p>
01568 
01569 <p class=MsoNormal style='text-align:justify'>        greater or equal to one.</p>
01570 
01571 <p class=MsoNormal style='text-align:justify'>        <b><span
01572 style='font-size:14.0pt'>boost</span></b>-boosting coefficient, applies only
01573 if numberRepetitions is greater than one.  </p>
01574 
01575 <p class=MsoNormal style='text-align:justify'>        <span style='font-size:
01576 14.0pt;color:fuchsia'>Recommended range &lt;1,2&gt;.</span></p>
01577 
01578 <p class=MsoNormal>&nbsp;</p>
01579 
01580 <p class=MsoNormal><b><i><span style='font-size:18.0pt'>References:</span></i></b></p>
01581 
01582 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'> [1]
01583 </span><span lang=SK style='font-size:16.0pt'>M. Morhá&#269;, J. Kliman, V.
01584 Matoušek, M. Veselský, I. Turzo</span><span style='font-size:16.0pt'>.:
01585 Efficient one- and two-dimensional Gold deconvolution and its application to
01586 gamma-ray spectra decomposition. NIM, A401 (1997) 385-408.</span></p>
01587 
01588 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>[2]
01589 Morhá&#269; M., Matoušek V., Kliman J., Efficient algorithm of multidimensional
01590 deconvolution and its application to nuclear data processing, Digital Signal
01591 Processing 13 (2003) 144. </span></p>
01592 
01593 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>&nbsp;</span></p>
01594 
01595 </div>
01596 
01597 <!-- */
01598 // --> End_Html
01599 //Begin_Html <!--
01600 /* -->
01601 <div class=Section1>
01602 
01603 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 5 – script Decon.c
01604 :</span></i></p>
01605 
01606 <p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
01607 -18.0pt'><span style='font-size:16.0pt'>•<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
01608 </span></span><span style='font-size:16.0pt'>response function (usually peak)
01609 should be shifted to the beginning of the coordinate system (see Fig. 13)</span></p>
01610 
01611 <p class=MsoNormal>&nbsp;</p>
01612 
01613 <p class=MsoNormal><img width=602 height=418
01614 src="gif/TSpectrum2_Deconvolution1.jpg"></p>
01615 
01616 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
01617 13 2-dimensional response spectrum</span></b></p>
01618 
01619 <p class=MsoNormal><img width=602 height=418
01620 src="gif/TSpectrum2_Deconvolution2.jpg"></p>
01621 
01622 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
01623 14 2-dimensional gamma-gamma-ray input spectrum (before deconvolution)</span></b></p>
01624 
01625 <p class=MsoNormal><img width=602 height=418
01626 src="gif/TSpectrum2_Deconvolution3.jpg"></p>
01627 
01628 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
01629 15 Spectrum from Fig. 14 after deconvolution (1000 iterations)</span></b></p>
01630 
01631 <p class=MsoNormal>&nbsp;</p>
01632 
01633 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
01634 
01635 <p class=MsoNormal>// Example to illustrate the Gold deconvolution (class
01636 TSpectrum2).</p>
01637 
01638 <p class=MsoNormal>// To execute this example, do</p>
01639 
01640 <p class=MsoNormal>// root &gt; .x Decon.C</p>
01641 
01642 <p class=MsoNormal>&nbsp;</p>
01643 
01644 <p class=MsoNormal>#include &lt;TSpectrum2&gt; </p>
01645 
01646 <p class=MsoNormal>&nbsp;</p>
01647 
01648 <p class=MsoNormal>void Decon() {</p>
01649 
01650 <p class=MsoNormal>   Int_t i, j;</p>
01651 
01652 <p class=MsoNormal>   Double_t nbinsx = 256;</p>
01653 
01654 <p class=MsoNormal>   Double_t nbinsy = 256;   </p>
01655 
01656 <p class=MsoNormal>   Double_t xmin  = 0;</p>
01657 
01658 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
01659 
01660 <p class=MsoNormal>   Double_t ymin  = 0;</p>
01661 
01662 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
01663 
01664 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
01665 
01666 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
01667 
01668 <p class=MsoNormal>                                    source[i]=new
01669 float[nbinsy];     </p>
01670 
01671 <p class=MsoNormal>   TH2F *decon = new TH2F(&quot;decon&quot;,&quot;Gold
01672 deconvolution&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
01673 
01674 <p class=MsoNormal>   TFile *f = new
01675 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
01676 
01677 <p class=MsoNormal>   decon=(TH2F*) f-&gt;Get(&quot;decon1;1&quot;);</p>
01678 
01679 <p class=MsoNormal>   Float_t ** response = new float *[nbinsx];   </p>
01680 
01681 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
01682 
01683 <p class=MsoNormal>                                    response[i]=new
01684 float[nbinsy];     </p>
01685 
01686 <p class=MsoNormal>   TH2F *resp = new TH2F(&quot;resp&quot;,&quot;Response
01687 matrix&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
01688 
01689 <p class=MsoNormal>   resp=(TH2F*) f-&gt;Get(&quot;resp1;1&quot;);   </p>
01690 
01691 <p class=MsoNormal>   TCanvas *Deconvol = new
01692 TCanvas(&quot;Deconvolution&quot;,&quot;Gold deconvolution&quot;,10,10,1000,700);</p>
01693 
01694 <p class=MsoNormal>   TSpectrum *s = new TSpectrum();</p>
01695 
01696 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01697 
01698 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
01699 
01700 <p class=MsoNormal>                source[i][j] = decon-&gt;GetBinContent(i +
01701 1,j + 1); </p>
01702 
01703 <p class=MsoNormal>             }</p>
01704 
01705 <p class=MsoNormal>   }</p>
01706 
01707 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01708 
01709 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
01710 
01711 <p class=MsoNormal>                response[i][j] = resp-&gt;GetBinContent(i +
01712 1,j + 1); </p>
01713 
01714 <p class=MsoNormal>             }</p>
01715 
01716 <p class=MsoNormal>   }   </p>
01717 
01718 <p class=MsoNormal>   s-&gt;Deconvolution(source,response,nbinsx,nbinsy,1000,1,1);  
01719 </p>
01720 
01721 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01722 
01723 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++)</p>
01724 
01725 <p class=MsoNormal>       decon-&gt;SetBinContent(i + 1,j + 1, source[i][j]);  
01726 </p>
01727 
01728 <p class=MsoNormal>   }</p>
01729 
01730 <p class=MsoNormal>   </p>
01731 
01732 <p class=MsoNormal>   decon-&gt;Draw(&quot;SURF&quot;);  </p>
01733 
01734 <p class=MsoNormal>   }</p>
01735 
01736 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 6 – script
01737 Decon2.c :</span></i></p>
01738 
01739 <p class=MsoNormal><img width=602 height=418
01740 src="gif/TSpectrum2_Deconvolution4.jpg"></p>
01741 
01742 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
01743 16 Response spectrum</span></b></p>
01744 
01745 <p class=MsoNormal><img width=602 height=418
01746 src="gif/TSpectrum2_Deconvolution5.jpg"></p>
01747 
01748 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
01749 17 Original synthetic input spectrum (before deconvolution). It is composed of
01750 17 peaks. 5 peaks are overlapping in the outlined multiplet and two peaks in
01751 doublet.</span></b></p>
01752 
01753 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
01754 width=602 height=418 src="gif/TSpectrum2_Deconvolution6.jpg"></span></b></p>
01755 
01756 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
01757 18 Spectrum from Fig. 17 after deconvolution (1000 iterations). Resolution is
01758 improved but the peaks in multiplet remained unresolved.</span></b></p>
01759 
01760 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
01761 
01762 <p class=MsoNormal>// Example to illustrate the Gold deconvolution (class
01763 TSpectrum2).</p>
01764 
01765 <p class=MsoNormal>// To execute this example, do</p>
01766 
01767 <p class=MsoNormal>// root &gt; .x Decon2.C</p>
01768 
01769 <p class=MsoNormal>&nbsp;</p>
01770 
01771 <p class=MsoNormal>#include &lt;TSpectrum2&gt; </p>
01772 
01773 <p class=MsoNormal>&nbsp;</p>
01774 
01775 <p class=MsoNormal>void Decon2() {</p>
01776 
01777 <p class=MsoNormal>   Int_t i, j;</p>
01778 
01779 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
01780 
01781 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
01782 
01783 <p class=MsoNormal>   Double_t xmin  = 0;</p>
01784 
01785 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
01786 
01787 <p class=MsoNormal>   Double_t ymin  = 0;</p>
01788 
01789 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
01790 
01791 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
01792 
01793 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
01794 
01795 <p class=MsoNormal>                                    source[i]=new
01796 float[nbinsy];     </p>
01797 
01798 <p class=MsoNormal>   TH2F *decon = new TH2F(&quot;decon&quot;,&quot;Gold
01799 deconvolution&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
01800 
01801 <p class=MsoNormal>   TFile *f = new TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
01802 
01803 <p class=MsoNormal>   decon=(TH2F*) f-&gt;Get(&quot;decon2;1&quot;);</p>
01804 
01805 <p class=MsoNormal>   Float_t ** response = new float *[nbinsx];   </p>
01806 
01807 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
01808 
01809 <p class=MsoNormal>                                    response[i]=new
01810 float[nbinsy];     </p>
01811 
01812 <p class=MsoNormal>   TH2F *resp = new TH2F(&quot;resp&quot;,&quot;Response
01813 matrix&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
01814 
01815 <p class=MsoNormal>   resp=(TH2F*) f-&gt;Get(&quot;resp2;1&quot;);   </p>
01816 
01817 <p class=MsoNormal>   TCanvas *Deconvol = new
01818 TCanvas(&quot;Deconvolution&quot;,&quot;Gold
01819 deconvolution&quot;,10,10,1000,700);</p>
01820 
01821 <p class=MsoNormal>   TSpectrum *s = new TSpectrum();</p>
01822 
01823 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01824 
01825 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
01826 
01827 <p class=MsoNormal>                source[i][j] = decon-&gt;GetBinContent(i +
01828 1,j + 1); </p>
01829 
01830 <p class=MsoNormal>             }</p>
01831 
01832 <p class=MsoNormal>   }</p>
01833 
01834 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01835 
01836 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
01837 
01838 <p class=MsoNormal>                response[i][j] = resp-&gt;GetBinContent(i +
01839 1,j + 1); </p>
01840 
01841 <p class=MsoNormal>             }</p>
01842 
01843 <p class=MsoNormal>   }   </p>
01844 
01845 <p class=MsoNormal>   s-&gt;Deconvolution(source,response,nbinsx,nbinsy,1000,1,1);  
01846 </p>
01847 
01848 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01849 
01850 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++)</p>
01851 
01852 <p class=MsoNormal>       decon-&gt;SetBinContent(i + 1,j + 1, source[i][j]);  
01853 </p>
01854 
01855 <p class=MsoNormal>   }</p>
01856 
01857 <p class=MsoNormal>   decon-&gt;Draw(&quot;SURF&quot;);  </p>
01858 
01859 <p class=MsoNormal>   }</p>
01860 
01861 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 7 – script
01862 Decon2HR.c :</span></i></p>
01863 
01864 <p class=MsoNormal><img width=602 height=418
01865 src="gif/TSpectrum2_Deconvolution7.jpg"></p>
01866 
01867 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
01868 19 Spectrum from Fig. 17 after boosted deconvolution (50 iterations repeated 20
01869 times, boosting coefficient was 1.2). All the peaks in multiplet as well as in
01870 doublet are completely decomposed.</span></b></p>
01871 
01872 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
01873 
01874 <p class=MsoNormal>// Example to illustrate boosted Gold deconvolution (class
01875 TSpectrum2).</p>
01876 
01877 <p class=MsoNormal>// To execute this example, do</p>
01878 
01879 <p class=MsoNormal>// root &gt; .x Decon2HR.C</p>
01880 
01881 <p class=MsoNormal>&nbsp;</p>
01882 
01883 <p class=MsoNormal>//#include &lt;TSpectrum2&gt; </p>
01884 
01885 <p class=MsoNormal>&nbsp;</p>
01886 
01887 <p class=MsoNormal>void Decon2HR() {</p>
01888 
01889 <p class=MsoNormal>   Int_t i, j;</p>
01890 
01891 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
01892 
01893 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
01894 
01895 <p class=MsoNormal>   Double_t xmin  = 0;</p>
01896 
01897 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
01898 
01899 <p class=MsoNormal>   Double_t ymin  = 0;</p>
01900 
01901 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
01902 
01903 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
01904 
01905 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
01906 
01907 <p class=MsoNormal>                                    source[i]=new
01908 float[nbinsy];     </p>
01909 
01910 <p class=MsoNormal>   TH2F *decon = new TH2F(&quot;decon&quot;,&quot;Boosted
01911 Gold deconvolution&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
01912 
01913 <p class=MsoNormal>   TFile *f = new TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
01914 
01915 <p class=MsoNormal>   decon=(TH2F*) f-&gt;Get(&quot;decon2;1&quot;);</p>
01916 
01917 <p class=MsoNormal>   Float_t ** response = new float *[nbinsx];   </p>
01918 
01919 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
01920 
01921 <p class=MsoNormal>                                    response[i]=new
01922 float[nbinsy];     </p>
01923 
01924 <p class=MsoNormal>   TH2F *resp = new TH2F(&quot;resp&quot;,&quot;Response
01925 matrix&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
01926 
01927 <p class=MsoNormal>   resp=(TH2F*) f-&gt;Get(&quot;resp2;1&quot;);   </p>
01928 
01929 <p class=MsoNormal>   TCanvas *Deconvol = new
01930 TCanvas(&quot;Deconvolution&quot;,&quot;Gold
01931 deconvolution&quot;,10,10,1000,700);</p>
01932 
01933 <p class=MsoNormal>   TSpectrum *s = new TSpectrum();</p>
01934 
01935 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01936 
01937 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
01938 
01939 <p class=MsoNormal>                source[i][j] = decon-&gt;GetBinContent(i +
01940 1,j + 1); </p>
01941 
01942 <p class=MsoNormal>             }</p>
01943 
01944 <p class=MsoNormal>   }</p>
01945 
01946 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01947 
01948 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
01949 
01950 <p class=MsoNormal>                response[i][j] = resp-&gt;GetBinContent(i +
01951 1,j + 1); </p>
01952 
01953 <p class=MsoNormal>             }</p>
01954 
01955 <p class=MsoNormal>   }   </p>
01956 
01957 <p class=MsoNormal>   s-&gt;Deconvolution(source,response,nbinsx,nbinsy,1000,1,1);  
01958 </p>
01959 
01960 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
01961 
01962 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++)</p>
01963 
01964 <p class=MsoNormal>       decon-&gt;SetBinContent(i + 1,j + 1, source[i][j]);  
01965 </p>
01966 
01967 <p class=MsoNormal>   }</p>
01968 
01969 <p class=MsoNormal>   decon-&gt;Draw(&quot;SURF&quot;);  </p>
01970 
01971 <p class=MsoNormal>   }</p>
01972 
01973 <p class=MsoNormal style='text-align:justify'>&nbsp;</p>
01974 
01975 </div>
01976 
01977 <!-- */
01978 // --> End_Html
01979    int i, j, lhx, lhy, i1, i2, j1, j2, k1, k2, lindex, i1min, i1max,
01980        i2min, i2max, j1min, j1max, j2min, j2max, positx = 0, posity = 0, repet;
01981    double lda, ldb, ldc, area, maximum = 0;
01982    if (ssizex <= 0 || ssizey <= 0)
01983       return "Wrong parameters";
01984    if (numberIterations <= 0)
01985       return "Number of iterations must be positive";
01986    if (numberRepetitions <= 0)
01987       return "Number of repetitions must be positive";   
01988    double **working_space = new double *[ssizex];
01989    for (i = 0; i < ssizex; i++)
01990       working_space[i] = new double[5 * ssizey];
01991    area = 0;
01992    lhx = -1, lhy = -1;
01993    for (i = 0; i < ssizex; i++) {
01994       for (j = 0; j < ssizey; j++) {
01995          lda = resp[i][j];
01996          if (lda != 0) {
01997             if ((i + 1) > lhx)
01998                lhx = i + 1;
01999             if ((j + 1) > lhy)
02000                lhy = j + 1;
02001          }
02002          working_space[i][j] = lda;
02003          area = area + lda;
02004          if (lda > maximum) {
02005             maximum = lda;
02006             positx = i, posity = j;
02007          }
02008       }
02009    }
02010    if (lhx == -1 || lhy == -1) {
02011       delete [] working_space;
02012       return ("Zero response data");
02013    }
02014    
02015 //calculate ht*y and write into p 
02016    for (i2 = 0; i2 < ssizey; i2++) {
02017       for (i1 = 0; i1 < ssizex; i1++) {
02018          ldc = 0;
02019          for (j2 = 0; j2 <= (lhy - 1); j2++) {
02020             for (j1 = 0; j1 <= (lhx - 1); j1++) {
02021                k2 = i2 + j2, k1 = i1 + j1;
02022                if (k2 >= 0 && k2 < ssizey && k1 >= 0 && k1 < ssizex) {
02023                   lda = working_space[j1][j2];
02024                   ldb = source[k1][k2];
02025                   ldc = ldc + lda * ldb;
02026                }
02027             }
02028          }
02029          working_space[i1][i2 + ssizey] = ldc;
02030       }
02031    }
02032    
02033 //calculate matrix b=ht*h 
02034    i1min = -(lhx - 1), i1max = lhx - 1;
02035    i2min = -(lhy - 1), i2max = lhy - 1;
02036    for (i2 = i2min; i2 <= i2max; i2++) {
02037       for (i1 = i1min; i1 <= i1max; i1++) {
02038          ldc = 0;
02039          j2min = -i2;
02040          if (j2min < 0)
02041             j2min = 0;
02042          j2max = lhy - 1 - i2;
02043          if (j2max > lhy - 1)
02044             j2max = lhy - 1;
02045          for (j2 = j2min; j2 <= j2max; j2++) {
02046             j1min = -i1;
02047             if (j1min < 0)
02048                j1min = 0;
02049             j1max = lhx - 1 - i1;
02050             if (j1max > lhx - 1)
02051                j1max = lhx - 1;
02052             for (j1 = j1min; j1 <= j1max; j1++) {
02053                lda = working_space[j1][j2];
02054                if (i1 + j1 < ssizex && i2 + j2 < ssizey)
02055                   ldb = working_space[i1 + j1][i2 + j2];
02056                else
02057                   ldb = 0;
02058                ldc = ldc + lda * ldb;
02059             }
02060          }
02061          working_space[i1 - i1min][i2 - i2min + 2 * ssizey ] = ldc;
02062       }
02063    }
02064    
02065 //initialization in x1 matrix 
02066    for (i2 = 0; i2 < ssizey; i2++) {
02067       for (i1 = 0; i1 < ssizex; i1++) {
02068          working_space[i1][i2 + 3 * ssizey] = 1;
02069          working_space[i1][i2 + 4 * ssizey] = 0;
02070       }
02071    }
02072    
02073    //START OF ITERATIONS 
02074    for (repet = 0; repet < numberRepetitions; repet++) {
02075       if (repet != 0) {
02076          for (i = 0; i < ssizex; i++) {
02077             for (j = 0; j < ssizey; j++) {
02078                working_space[i][j + 3 * ssizey] =
02079                    TMath::Power(working_space[i][j + 3 * ssizey], boost);
02080             }
02081          }
02082       }
02083       for (lindex = 0; lindex < numberIterations; lindex++) {
02084          for (i2 = 0; i2 < ssizey; i2++) {
02085             for (i1 = 0; i1 < ssizex; i1++) {
02086                ldb = 0;                 
02087                j2min = i2;
02088                if (j2min > lhy - 1)
02089                   j2min = lhy - 1;
02090                j2min = -j2min;
02091                j2max = ssizey - i2 - 1;
02092                if (j2max > lhy - 1)
02093                   j2max = lhy - 1;
02094                j1min = i1;
02095                if (j1min > lhx - 1)
02096                   j1min = lhx - 1;
02097                j1min = -j1min;
02098                j1max = ssizex - i1 - 1;
02099                if (j1max > lhx - 1)
02100                   j1max = lhx - 1;
02101                for (j2 = j2min; j2 <= j2max; j2++) {
02102                   for (j1 = j1min; j1 <= j1max; j1++) {
02103                      ldc =  working_space[j1 - i1min][j2 - i2min + 2 * ssizey];
02104                      lda = working_space[i1 + j1][i2 + j2 + 3 * ssizey];
02105                      ldb = ldb + lda * ldc;
02106                   }
02107                }
02108                lda = working_space[i1][i2 + 3 * ssizey];
02109                ldc = working_space[i1][i2 + 1 * ssizey];
02110                if (ldc * lda != 0 && ldb != 0) {
02111                   lda = lda * ldc / ldb;
02112                }
02113 
02114                else
02115                   lda = 0;
02116                working_space[i1][i2 + 4 * ssizey] = lda;
02117             }
02118          }
02119          for (i2 = 0; i2 < ssizey; i2++) {
02120             for (i1 = 0; i1 < ssizex; i1++)
02121                working_space[i1][i2 + 3 * ssizey] =
02122                    working_space[i1][i2 + 4 * ssizey];
02123          }
02124       }
02125    }
02126    for (i = 0; i < ssizex; i++) {
02127       for (j = 0; j < ssizey; j++)
02128          source[(i + positx) % ssizex][(j + posity) % ssizey] =
02129              area * working_space[i][j + 3 * ssizey];
02130    }
02131    for (i = 0; i < ssizex; i++)
02132       delete[]working_space[i];
02133    delete[]working_space;
02134    return 0;
02135 }
02136 
02137 //____________________________________________________________________________
02138 Int_t TSpectrum2::SearchHighRes(float **source,float **dest, Int_t ssizex, Int_t ssizey,
02139                                  Double_t sigma, Double_t threshold,
02140                                  Bool_t backgroundRemove,Int_t deconIterations,
02141                                  Bool_t markov, Int_t averWindow)
02142                                      
02143 {
02144 /////////////////////////////////////////////////////////////////////////////
02145 //   TWO-DIMENSIONAL HIGH-RESOLUTION PEAK SEARCH FUNCTION                  //
02146 //   This function searches for peaks in source spectrum                   //
02147 //      It is based on deconvolution method. First the background is       //
02148 //      removed (if desired), then Markov spectrum is calculated           //
02149 //      (if desired), then the response function is generated              //
02150 //      according to given sigma and deconvolution is carried out.         //
02151 //                                                                         //
02152 //   Function parameters:                                                  //
02153 //   source-pointer to the matrix of source spectrum                       //
02154 //   dest-pointer to the matrix of resulting deconvolved spectrum          //
02155 //   ssizex-x length of source spectrum                                    //
02156 //   ssizey-y length of source spectrum                                    //
02157 //   sigma-sigma of searched peaks, for details we refer to manual         //
02158 //   threshold-threshold value in % for selected peaks, peaks with         //
02159 //                amplitude less than threshold*highest_peak/100           //
02160 //                are ignored, see manual                                  //
02161 //      backgroundRemove-logical variable, set if the removal of           //
02162 //                background before deconvolution is desired               //
02163 //      deconIterations-number of iterations in deconvolution operation    //
02164 //      markov-logical variable, if it is true, first the source spectrum  //
02165 //             is replaced by new spectrum calculated using Markov         //
02166 //             chains method.                                              //
02167 //   averWindow-averanging window of searched peaks, for details           //
02168 //                  we refer to manual (applies only for Markov method)    //
02169 //                                                                         //
02170 /////////////////////////////////////////////////////////////////////////////
02171 //Begin_Html <!--
02172 /* -->
02173 <div class=Section1>
02174 
02175 <p class=MsoNormal><b><span style='font-size:20.0pt'>Peaks searching</span></b></p>
02176 
02177 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:18.0pt'>&nbsp;</span></i></p>
02178 
02179 <p class=MsoNormal style='text-align:justify'><i><span style='font-size:18.0pt'>Goal:
02180 to identify automatically the peaks in spectrum with the presence of the
02181 continuous background, one-fold coincidences (ridges) and statistical
02182 fluctuations - noise.</span></i><span style='font-size:18.0pt'> </span></p>
02183 
02184 <p class=MsoNormal><span style='font-size:16.0pt;font-family:Arial'>&nbsp;</span></p>
02185 
02186 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt;
02187 font-family:Arial'>The common problems connected with correct peak
02188 identification in two-dimensional coincidence spectra are</span></p>
02189 
02190 <ul style='margin-top:0mm' type=disc>
02191  <li class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt;
02192      font-family:Arial'>non-sensitivity to noise, i.e., only statistically
02193      relevant peaks should be identified</span></li>
02194  <li class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt;
02195      font-family:Arial'>non-sensitivity of the algorithm to continuous
02196      background</span></li>
02197  <li class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt;
02198      font-family:Arial'>non-sensitivity to one-fold coincidences (coincidences
02199      peak – background in both dimensions) and their crossings</span></li>
02200  <li class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt;
02201      font-family:Arial'>ability to identify peaks close to the edges of the
02202      spectrum region. Usually peak finders fail to detect them</span></li>
02203  <li class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt;
02204      font-family:Arial'>resolution, decomposition of doublets and multiplets.
02205      The algorithm should be able to recognize close positioned peaks.</span><span
02206      style='font-size:18.0pt'> </span></li>
02207  <li class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt;
02208      font-family:Arial'>ability to identify peaks with different sigma</span></li>
02209 </ul>
02210 
02211 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>&nbsp;</span></p>
02212 
02213 <p class=MsoNormal><i><span style='font-size:18.0pt'>Function:</span></i></p>
02214 
02215 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:18.0pt'><a
02216 href="http://root.cern.ch/root/html/ListOfTypes.html#Int_t">Int_t</a> </span></b><a
02217 name="TSpectrum:Search1HighRes"></a><a
02218 href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b><span
02219 style='font-size:18.0pt'>TSpectrum2::SearchHighRes</span></b></a><b><span
02220 style='font-size:18.0pt'> (<a
02221 href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a> **source,<a
02222 href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a> **dest, <a
02223 href="http://root.cern.ch/root/html/ListOfTypes.html#int">int</a> ssizex, <a
02224 href="http://root.cern.ch/root/html/ListOfTypes.html#int">int</a> ssizey, <a
02225 href="http://root.cern.ch/root/html/ListOfTypes.html#float">float</a> sigma, <a
02226 href="http://root.cern.ch/root/html/ListOfTypes.html#double">double</a> threshold,
02227 <a href="http://root.cern.ch/root/html/ListOfTypes.html#bool">bool</a> backgroundRemove,<a
02228 href="http://root.cern.ch/root/html/ListOfTypes.html#int">int</a> deconIterations,
02229 <a href="http://root.cern.ch/root/html/ListOfTypes.html#bool">bool</a> markov,
02230 <a href="http://root.cern.ch/root/html/ListOfTypes.html#int">int</a> averWindow)
02231   </span></b></p>
02232 
02233 <p class=MsoNormal>&nbsp;</p>
02234 
02235 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>This
02236 function searches for peaks in source spectrum. It is based on deconvolution
02237 method. First the background is removed (if desired), then Markov smoothed
02238 spectrum is calculated (if desired), then the response function is generated
02239 according to given sigma and deconvolution is carried out. The order of peaks
02240 is arranged according to their heights in the spectrum after background
02241 elimination. The highest peak is the first in the list. On success it returns
02242 number of found peaks.</span></p>
02243 
02244 <p class=MsoNormal>&nbsp;</p>
02245 
02246 <p class=MsoNormal><i><span style='font-size:16.0pt;color:red'>Parameters:</span></i></p>
02247 
02248 <p class=MsoNormal style='text-align:justify'>        <b><span
02249 style='font-size:14.0pt'>source</span></b>-pointer to the matrix of source
02250 spectrum                  </p>
02251 
02252 <p class=MsoNormal style='text-align:justify'>        <b><span
02253 style='font-size:14.0pt'>dest</span></b>-resulting spectrum after deconvolution</p>
02254 
02255 <p class=MsoNormal style='text-align:justify'>        <b><span
02256 style='font-size:14.0pt'>ssizex, ssizey</span></b>-lengths of the source and
02257 destination spectra                </p>
02258 
02259 <p class=MsoNormal style='text-align:justify'>        <b><span
02260 style='font-size:14.0pt'>sigma</span></b>-sigma of searched peaks</p>
02261 
02262 <p class=MsoNormal style='margin-left:22.8pt;text-align:justify'><b><span
02263 style='font-size:14.0pt'>threshold</span></b>-<span style='font-size:16.0pt'> </span>threshold
02264 value in % for selected peaks, peaks with amplitude less than
02265 threshold*highest_peak/100 are ignored</p>
02266 
02267 <p class=MsoNormal style='margin-left:22.8pt;text-align:justify'><b><span
02268 style='font-size:14.0pt'>backgroundRemove</span></b>-<span style='font-size:
02269 16.0pt'> </span>background_remove-logical variable, true if the removal of
02270 background before deconvolution is desired  </p>
02271 
02272 <p class=MsoNormal style='margin-left:22.8pt;text-align:justify'><b><span
02273 style='font-size:14.0pt'>deconIterations</span></b>-number of iterations in
02274 deconvolution operation</p>
02275 
02276 <p class=MsoNormal style='margin-left:22.8pt;text-align:justify'><b><span
02277 style='font-size:14.0pt'>markov</span></b>-logical variable, if it is true,
02278 first the source spectrum is replaced by new spectrum calculated using Markov
02279 chains method </p>
02280 
02281 <p class=MsoNormal style='margin-left:19.95pt;text-align:justify;text-indent:
02282 2.85pt'><b><span style='font-size:14.0pt'>averWindow</span></b>-width of
02283 averaging smoothing window </p>
02284 
02285 <p class=MsoNormal>&nbsp;</p>
02286 
02287 <p class=MsoNormal><b><i><span style='font-size:18.0pt'>References:</span></i></b></p>
02288 
02289 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>[1]
02290 M.A. Mariscotti: A method for identification of peaks in the presence of
02291 background and its application to spectrum analysis. NIM 50 (1967), 309-320.</span></p>
02292 
02293 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>[2]
02294 </span><span lang=SK style='font-size:16.0pt'> M. Morhá&#269;, J. Kliman, V.
02295 Matoušek, M. Veselský, I. Turzo</span><span style='font-size:16.0pt'>.:Identification
02296 of peaks in multidimensional coincidence gamma-ray spectra. NIM, A443 (2000)
02297 108-125.</span></p>
02298 
02299 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'>[3]
02300 Z.K. Silagadze, A new algorithm for automatic photopeak searches. NIM A 376
02301 (1996), 451.</span></p>
02302 
02303 </div>
02304 
02305 <!-- */
02306 // --> End_Html
02307 //Begin_Html <!--
02308 /* -->
02309 <div class=Section1>
02310 
02311 <p class=MsoNormal><b><span style='font-size:18.0pt'>Examples of peak searching
02312 method</span></b></p>
02313 
02314 <p class=MsoNormal><span style='font-size:16.0pt'>&nbsp;</span></p>
02315 
02316 <p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'><a
02317 href="http://root.cern.ch/root/html/src/TSpectrum.cxx.html#TSpectrum:Search1HighRes"
02318 target="_parent">SearchHighRes</a> function provides users with the possibility
02319 to vary the input parameters and with the access to the output deconvolved data
02320 in the destination spectrum. Based on the output data one can tune the
02321 parameters. </span></p>
02322 
02323 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 8 – script Src.c:</span></i></p>
02324 
02325 <p class=MsoNormal><span style='font-size:16.0pt'><img border=0 width=602
02326 height=455 src="gif/TSpectrum2_Searching1.jpg"></span></p>
02327 
02328 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02329 20 Two-dimensional spectrum with found peaks denoted by markers (<sub><img
02330 border=0 width=40 height=19 src="gif/TSpectrum2_Searching2.gif"></sub>,
02331 threshold=5%, 3 iterations steps in the deconvolution)</span></b></p>
02332 
02333 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
02334 border=0 width=602 height=455 src="gif/TSpectrum2_Searching3.jpg"></span></b></p>
02335 
02336 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02337 21 Spectrum from Fig. 20 after background elimination and deconvolution</span></b></p>
02338 
02339 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
02340 
02341 <p class=MsoNormal>// Example to illustrate high resolution peak searching
02342 function (class TSpectrum).</p>
02343 
02344 <p class=MsoNormal>// To execute this example, do</p>
02345 
02346 <p class=MsoNormal>// root &gt; .x Src.C</p>
02347 
02348 <p class=MsoNormal>&nbsp;</p>
02349 
02350 <p class=MsoNormal>#include &lt;TSpectrum2&gt;</p>
02351 
02352 <p class=MsoNormal>&nbsp;</p>
02353 
02354 <p class=MsoNormal>void Src() {</p>
02355 
02356 <p class=MsoNormal>   Int_t i, j, nfound;</p>
02357 
02358 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
02359 
02360 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
02361 
02362 <p class=MsoNormal>   Double_t xmin  = 0;</p>
02363 
02364 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
02365 
02366 <p class=MsoNormal>   Double_t ymin  = 0;</p>
02367 
02368 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
02369 
02370 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
02371 
02372 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02373 
02374 <p class=MsoNormal>                                    source[i]=new
02375 float[nbinsy];</p>
02376 
02377 <p class=MsoNormal>   Float_t ** dest = new float *[nbinsx];   </p>
02378 
02379 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02380 
02381 <p class=MsoNormal>                                    dest[i]=new
02382 float[nbinsy];</p>
02383 
02384 <p class=MsoNormal>   TH2F *search = new TH2F(&quot;search&quot;,&quot;High
02385 resolution peak searching&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
02386 
02387 <p class=MsoNormal>   TFile *f = new TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
02388 
02389 <p class=MsoNormal>   search=(TH2F*) f-&gt;Get(&quot;search4;1&quot;);</p>
02390 
02391 <p class=MsoNormal>   TCanvas *Searching = new
02392 TCanvas(&quot;Searching&quot;,&quot;High resolution peak
02393 searching&quot;,10,10,1000,700);</p>
02394 
02395 <p class=MsoNormal>   TSpectrum2 *s = new TSpectrum2();</p>
02396 
02397 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
02398 
02399 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
02400 
02401 <p class=MsoNormal>                source[i][j] = search-&gt;GetBinContent(i +
02402 1,j + 1); </p>
02403 
02404 <p class=MsoNormal>             }</p>
02405 
02406 <p class=MsoNormal>   }   </p>
02407 
02408 <p class=MsoNormal>   nfound = s-&gt;SearchHighRes(source, dest, nbinsx,
02409 nbinsy, 2, 5, kTRUE, 3, kFALSE, 3);   </p>
02410 
02411 <p class=MsoNormal>   printf(&quot;Found %d candidate peaks\n&quot;,nfound);</p>
02412 
02413 <p class=MsoNormal>   for(i=0;i&lt;nfound;i++)</p>
02414 
02415 <p class=MsoNormal>             printf(&quot;posx= %d, posy= %d, value=
02416 %d\n&quot;,(int)(fPositionX[i]+0.5), (int)(fPositionY[i]+0.5),
02417 (int)source[(int)(fPositionX[i]+0.5)][(int)(fPositionY[i]+0.5)]);        </p>
02418 
02419 <p class=MsoNormal>}</p>
02420 
02421 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 9 – script Src2.c:</span></i></p>
02422 
02423 <p class=MsoNormal><img border=0 width=602 height=455
02424 src="gif/TSpectrum2_Searching4.jpg"></p>
02425 
02426 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02427 22 Two-dimensional noisy spectrum with found peaks denoted by markers (<sub><img
02428 border=0 width=40 height=19 src="gif/TSpectrum2_Searching2.gif"></sub>,
02429 threshold=10%, 10 iterations steps in the deconvolution). One can observe that
02430 the algorithm is insensitive to the crossings of one-dimensional ridges. It
02431 identifies only two-cooincidence peaks.</span></b></p>
02432 
02433 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
02434 border=0 width=602 height=455 src="gif/TSpectrum2_Searching5.jpg"></span></b></p>
02435 
02436 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02437 23 Spectrum from Fig. 22 after background elimination and deconvolution</span></b></p>
02438 
02439 <p class=MsoNormal>&nbsp;</p>
02440 
02441 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
02442 
02443 <p class=MsoNormal>// Example to illustrate high resolution peak searching
02444 function (class TSpectrum).</p>
02445 
02446 <p class=MsoNormal>// To execute this example, do</p>
02447 
02448 <p class=MsoNormal>// root &gt; .x Src2.C</p>
02449 
02450 <p class=MsoNormal>&nbsp;</p>
02451 
02452 <p class=MsoNormal>#include &lt;TSpectrum2&gt;</p>
02453 
02454 <p class=MsoNormal>&nbsp;</p>
02455 
02456 <p class=MsoNormal>void Src2() {</p>
02457 
02458 <p class=MsoNormal>   Int_t i, j, nfound;</p>
02459 
02460 <p class=MsoNormal>   Double_t nbinsx = 256;</p>
02461 
02462 <p class=MsoNormal>   Double_t nbinsy = 256;   </p>
02463 
02464 <p class=MsoNormal>   Double_t xmin  = 0;</p>
02465 
02466 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
02467 
02468 <p class=MsoNormal>   Double_t ymin  = 0;</p>
02469 
02470 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
02471 
02472 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
02473 
02474 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02475 
02476 <p class=MsoNormal>                                    source[i]=new
02477 float[nbinsy];</p>
02478 
02479 <p class=MsoNormal>   Float_t ** dest = new float *[nbinsx];   </p>
02480 
02481 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02482 
02483 <p class=MsoNormal>                                    dest[i]=new
02484 float[nbinsy];</p>
02485 
02486 <p class=MsoNormal>   TH2F *search = new TH2F(&quot;search&quot;,&quot;High
02487 resolution peak searching&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
02488 
02489 <p class=MsoNormal>   TFile *f = new
02490 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
02491 
02492 <p class=MsoNormal>   search=(TH2F*) f-&gt;Get(&quot;back3;1&quot;);</p>
02493 
02494 <p class=MsoNormal>   TCanvas *Searching = new
02495 TCanvas(&quot;Searching&quot;,&quot;High resolution peak
02496 searching&quot;,10,10,1000,700);</p>
02497 
02498 <p class=MsoNormal>   TSpectrum2 *s = new TSpectrum2();</p>
02499 
02500 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
02501 
02502 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
02503 
02504 <p class=MsoNormal>                source[i][j] = search-&gt;GetBinContent(i +
02505 1,j + 1); </p>
02506 
02507 <p class=MsoNormal>             }</p>
02508 
02509 <p class=MsoNormal>   }   </p>
02510 
02511 <p class=MsoNormal>   nfound = s-&gt;SearchHighRes(source, dest, nbinsx,
02512 nbinsy, 2, 10, kTRUE, 10, kFALSE, 3);   </p>
02513 
02514 <p class=MsoNormal>   printf(&quot;Found %d candidate peaks\n&quot;,nfound);</p>
02515 
02516 <p class=MsoNormal>   for(i=0;i&lt;nfound;i++)</p>
02517 
02518 <p class=MsoNormal>             printf(&quot;posx= %d, posy= %d, value=
02519 %d\n&quot;,(int)(fPositionX[i]+0.5), (int)(fPositionY[i]+0.5),
02520 (int)source[(int)(fPositionX[i]+0.5)][(int)(fPositionY[i]+0.5)]);        </p>
02521 
02522 <p class=MsoNormal>}</p>
02523 
02524 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 10 – script Src3.c:</span></i></p>
02525 
02526 <p class=MsoNormal><img border=0 width=602 height=455
02527 src="gif/TSpectrum2_Searching6.jpg"></p>
02528 
02529 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02530 24 Two-dimensional spectrum with 15 found peaks denoted by markers. Some peaks
02531 are positioned close to each other. It is necessary to increase number of
02532 iterations in the deconvolution. In next 3 Figs. we shall study the influence
02533 of this parameter.</span></b></p>
02534 
02535 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
02536 border=0 width=602 height=455 src="gif/TSpectrum2_Searching7.jpg"></span></b></p>
02537 
02538 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02539 25 Spectrum from Fig. 24 after deconvolution (# of iterations = 3). Number of
02540 identified peaks = 13.</span></b></p>
02541 
02542 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
02543 border=0 width=602 height=455 src="gif/TSpectrum2_Searching8.jpg"></span></b></p>
02544 
02545 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02546 26 Spectrum from Fig. 24 after deconvolution (# of iterations = 10). Number of
02547 identified peaks = 13.</span></b></p>
02548 
02549 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
02550 border=0 width=602 height=455 src="gif/TSpectrum2_Searching9.jpg"></span></b></p>
02551 
02552 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02553 27 Spectrum from Fig. 24 after deconvolution (# of iterations = 100). Number of
02554 identified peaks = 15. Now the algorithm is able to decompose two doublets in
02555 the spectrum.</span></b></p>
02556 
02557 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>&nbsp;</span></b></p>
02558 
02559 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
02560 
02561 <p class=MsoNormal>// Example to illustrate high resolution peak searching
02562 function (class TSpectrum).</p>
02563 
02564 <p class=MsoNormal>// To execute this example, do</p>
02565 
02566 <p class=MsoNormal>// root &gt; .x Src3.C</p>
02567 
02568 <p class=MsoNormal>&nbsp;</p>
02569 
02570 <p class=MsoNormal>#include &lt;TSpectrum2&gt;</p>
02571 
02572 <p class=MsoNormal>&nbsp;</p>
02573 
02574 <p class=MsoNormal>void Src3() {</p>
02575 
02576 <p class=MsoNormal>   Int_t i, j, nfound;</p>
02577 
02578 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
02579 
02580 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
02581 
02582 <p class=MsoNormal>   Double_t xmin  = 0;</p>
02583 
02584 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
02585 
02586 <p class=MsoNormal>   Double_t ymin  = 0;</p>
02587 
02588 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
02589 
02590 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
02591 
02592 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02593 
02594 <p class=MsoNormal>                                    source[i]=new
02595 float[nbinsy];</p>
02596 
02597 <p class=MsoNormal>   Float_t ** dest = new float *[nbinsx];   </p>
02598 
02599 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02600 
02601 <p class=MsoNormal>                                    dest[i]=new
02602 float[nbinsy];</p>
02603 
02604 <p class=MsoNormal>   TH2F *search = new TH2F(&quot;search&quot;,&quot;High
02605 resolution peak searching&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
02606 
02607 <p class=MsoNormal>   TFile *f = new
02608 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
02609 
02610 <p class=MsoNormal>   search=(TH2F*) f-&gt;Get(&quot;search1;1&quot;);</p>
02611 
02612 <p class=MsoNormal>   TCanvas *Searching = new
02613 TCanvas(&quot;Searching&quot;,&quot;High resolution peak
02614 searching&quot;,10,10,1000,700);</p>
02615 
02616 <p class=MsoNormal>   TSpectrum2 *s = new TSpectrum2();</p>
02617 
02618 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
02619 
02620 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
02621 
02622 <p class=MsoNormal>                source[i][j] = search-&gt;GetBinContent(i +
02623 1,j + 1); </p>
02624 
02625 <p class=MsoNormal>             }</p>
02626 
02627 <p class=MsoNormal>   }   </p>
02628 
02629 <p class=MsoNormal>   nfound = s-&gt;SearchHighRes(source, dest, nbinsx,
02630 nbinsy, 2, 2, kFALSE, 3, kFALSE, 1);//3, 10, 100   </p>
02631 
02632 <p class=MsoNormal>   printf(&quot;Found %d candidate peaks\n&quot;,nfound);</p>
02633 
02634 <p class=MsoNormal> </p>
02635 
02636 <p class=MsoNormal>   for(i=0;i&lt;nfound;i++)</p>
02637 
02638 <p class=MsoNormal>             printf(&quot;posx= %d, posy= %d, value=
02639 %d\n&quot;,(int)(fPositionX[i]+0.5), (int)(fPositionY[i]+0.5),
02640 (int)source[(int)(fPositionX[i]+0.5)][(int)(fPositionY[i]+0.5)]);        </p>
02641 
02642 <p class=MsoNormal>}</p>
02643 
02644 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 11 – script Src4.c:</span></i></p>
02645 
02646 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
02647 border=0 width=602 height=455 src="gif/TSpectrum2_Searching10.jpg"></span></b></p>
02648 
02649 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02650 28 Two-dimensional spectrum with peaks with different sigma denoted by markers (<sub><img
02651 border=0 width=39 height=19 src="gif/TSpectrum2_Searching11.gif"></sub>,
02652 threshold=5%, 10 iterations steps in the deconvolution, Markov smoothing with
02653 window=3)</span></b></p>
02654 
02655 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
02656 border=0 width=602 height=455 src="gif/TSpectrum2_Searching12.jpg"></span></b></p>
02657 
02658 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02659 29 Spectrum from Fig. 28 after smoothing and deconvolution.</span></b></p>
02660 
02661 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>&nbsp;</span></b></p>
02662 
02663 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
02664 
02665 <p class=MsoNormal>// Example to illustrate high resolution peak searching
02666 function (class TSpectrum).</p>
02667 
02668 <p class=MsoNormal>// To execute this example, do</p>
02669 
02670 <p class=MsoNormal>// root &gt; .x Src4.C</p>
02671 
02672 <p class=MsoNormal>&nbsp;</p>
02673 
02674 <p class=MsoNormal>#include &lt;TSpectrum2&gt;</p>
02675 
02676 <p class=MsoNormal>&nbsp;</p>
02677 
02678 <p class=MsoNormal>void Src4() {</p>
02679 
02680 <p class=MsoNormal>   Int_t i, j, nfound;</p>
02681 
02682 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
02683 
02684 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
02685 
02686 <p class=MsoNormal>   Double_t xmin  = 0;</p>
02687 
02688 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
02689 
02690 <p class=MsoNormal>   Double_t ymin  = 0;</p>
02691 
02692 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
02693 
02694 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
02695 
02696 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02697 
02698 <p class=MsoNormal>                                    source[i]=new
02699 float[nbinsy];</p>
02700 
02701 <p class=MsoNormal>   Float_t ** dest = new float *[nbinsx];   </p>
02702 
02703 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02704 
02705 <p class=MsoNormal>                                    dest[i]=new
02706 float[nbinsy];</p>
02707 
02708 <p class=MsoNormal>   TH2F *search = new TH2F(&quot;search&quot;,&quot;High
02709 resolution peak searching&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
02710 
02711 <p class=MsoNormal>   TFile *f = new
02712 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
02713 
02714 <p class=MsoNormal>   search=(TH2F*) f-&gt;Get(&quot;search2;1&quot;);</p>
02715 
02716 <p class=MsoNormal>   TCanvas *Searching = new
02717 TCanvas(&quot;Searching&quot;,&quot;High resolution peak
02718 searching&quot;,10,10,1000,700);</p>
02719 
02720 <p class=MsoNormal>   TSpectrum2 *s = new TSpectrum2();</p>
02721 
02722 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
02723 
02724 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
02725 
02726 <p class=MsoNormal>                source[i][j] = search-&gt;GetBinContent(i +
02727 1,j + 1); </p>
02728 
02729 <p class=MsoNormal>             }</p>
02730 
02731 <p class=MsoNormal>   }   </p>
02732 
02733 <p class=MsoNormal>   nfound = s-&gt;SearchHighRes(source, dest, nbinsx,
02734 nbinsy, 3, 5, kFALSE, 10, kTRUE, 3);   </p>
02735 
02736 <p class=MsoNormal>   printf(&quot;Found %d candidate peaks\n&quot;,nfound);</p>
02737 
02738 <p class=MsoNormal>   for(i=0;i&lt;nfound;i++)</p>
02739 
02740 <p class=MsoNormal>             printf(&quot;posx= %d, posy= %d, value=
02741 %d\n&quot;,(int)(fPositionX[i]+0.5), (int)(fPositionY[i]+0.5),
02742 (int)source[(int)(fPositionX[i]+0.5)][(int)(fPositionY[i]+0.5)]);        </p>
02743 
02744 <p class=MsoNormal>}</p>
02745 
02746 <p class=MsoNormal><i><span style='font-size:16.0pt'>Example 12 – script Src5.c:</span></i></p>
02747 
02748 <p class=MsoNormal><img border=0 width=602 height=455
02749 src="gif/TSpectrum2_Searching13.jpg"></p>
02750 
02751 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02752 30 Two-dimensional spectrum with peaks positioned close to the edges denoted by
02753 markers (<sub><img border=0 width=40 height=19
02754 src="gif/TSpectrum2_Searching2.gif"></sub>, threshold=5%, 10 iterations
02755 steps in the deconvolution)</span></b></p>
02756 
02757 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'><img
02758 border=0 width=602 height=455 src="gif/TSpectrum2_Searching14.jpg"></span></b></p>
02759 
02760 <p class=MsoNormal style='text-align:justify'><b><span style='font-size:16.0pt'>Fig.
02761 31 Spectrum from Fig. 30 after deconvolution.</span></b></p>
02762 
02763 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>&nbsp;</span></b></p>
02764 
02765 <p class=MsoNormal><b><span style='font-size:16.0pt;color:#339966'>Script:</span></b></p>
02766 
02767 <p class=MsoNormal>// Example to illustrate high resolution peak searching
02768 function (class TSpectrum).</p>
02769 
02770 <p class=MsoNormal>// To execute this example, do</p>
02771 
02772 <p class=MsoNormal>// root &gt; .x Src5.C</p>
02773 
02774 <p class=MsoNormal>&nbsp;</p>
02775 
02776 <p class=MsoNormal>#include &lt;TSpectrum2&gt;</p>
02777 
02778 <p class=MsoNormal>&nbsp;</p>
02779 
02780 <p class=MsoNormal>void Src5() {</p>
02781 
02782 <p class=MsoNormal>   Int_t i, j, nfound;</p>
02783 
02784 <p class=MsoNormal>   Double_t nbinsx = 64;</p>
02785 
02786 <p class=MsoNormal>   Double_t nbinsy = 64;   </p>
02787 
02788 <p class=MsoNormal>   Double_t xmin  = 0;</p>
02789 
02790 <p class=MsoNormal>   Double_t xmax  = (Double_t)nbinsx;</p>
02791 
02792 <p class=MsoNormal>   Double_t ymin  = 0;</p>
02793 
02794 <p class=MsoNormal>   Double_t ymax  = (Double_t)nbinsy;   </p>
02795 
02796 <p class=MsoNormal>   Float_t ** source = new float *[nbinsx];   </p>
02797 
02798 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02799 
02800 <p class=MsoNormal>                                    source[i]=new
02801 float[nbinsy];</p>
02802 
02803 <p class=MsoNormal>   Float_t ** dest = new float *[nbinsx];   </p>
02804 
02805 <p class=MsoNormal>   for (i=0;i&lt;nbinsx;i++)</p>
02806 
02807 <p class=MsoNormal>                                    dest[i]=new
02808 float[nbinsy];</p>
02809 
02810 <p class=MsoNormal>   TH2F *search = new TH2F(&quot;search&quot;,&quot;High
02811 resolution peak searching&quot;,nbinsx,xmin,xmax,nbinsy,ymin,ymax);</p>
02812 
02813 <p class=MsoNormal>   TFile *f = new
02814 TFile(&quot;spectra2\\TSpectrum2.root&quot;);</p>
02815 
02816 <p class=MsoNormal>   search=(TH2F*) f-&gt;Get(&quot;search3;1&quot;);</p>
02817 
02818 <p class=MsoNormal>   TCanvas *Searching = new
02819 TCanvas(&quot;Searching&quot;,&quot;High resolution peak
02820 searching&quot;,10,10,1000,700);</p>
02821 
02822 <p class=MsoNormal>   TSpectrum2 *s = new TSpectrum2();</p>
02823 
02824 <p class=MsoNormal>   for (i = 0; i &lt; nbinsx; i++){</p>
02825 
02826 <p class=MsoNormal>     for (j = 0; j &lt; nbinsy; j++){</p>
02827 
02828 <p class=MsoNormal>                source[i][j] = search-&gt;GetBinContent(i +
02829 1,j + 1); </p>
02830 
02831 <p class=MsoNormal>             }</p>
02832 
02833 <p class=MsoNormal>   }   </p>
02834 
02835 <p class=MsoNormal>   nfound = s-&gt;SearchHighRes(source, dest, nbinsx,
02836 nbinsy, 2, 5, kFALSE, 10, kFALSE, 1);   </p>
02837 
02838 <p class=MsoNormal>   printf(&quot;Found %d candidate peaks\n&quot;,nfound);</p>
02839 
02840 <p class=MsoNormal>   for(i=0;i&lt;nfound;i++)</p>
02841 
02842 <p class=MsoNormal>             printf(&quot;posx= %d, posy= %d, value=
02843 %d\n&quot;,(int)(fPositionX[i]+0.5), (int)(fPositionY[i]+0.5),
02844 (int)source[(int)(fPositionX[i]+0.5)][(int)(fPositionY[i]+0.5)]);        </p>
02845 
02846 <p class=MsoNormal>}</p>
02847 
02848 </div>
02849 
02850 <!-- */
02851 // --> End_Html
02852    int number_of_iterations = (int)(4 * sigma + 0.5);
02853    int k, lindex, priz;
02854    double lda, ldb, ldc, area, maximum;
02855    int xmin, xmax, l, peak_index = 0, ssizex_ext = ssizex + 4 * number_of_iterations, ssizey_ext = ssizey + 4 * number_of_iterations, shift = 2 * number_of_iterations;
02856    int ymin, ymax, i, j;
02857    double a, b, ax, ay, maxch, plocha = 0;
02858    double nom, nip, nim, sp, sm, spx, spy, smx, smy;
02859    double p1, p2, p3, p4, s1, s2, s3, s4;
02860    int x, y;
02861    int lhx, lhy, i1, i2, j1, j2, k1, k2, i1min, i1max, i2min, i2max, j1min, j1max, j2min, j2max, positx, posity;
02862    if (sigma < 1) {
02863       Error("SearchHighRes", "Invalid sigma, must be greater than or equal to 1");
02864       return 0;
02865    }
02866  
02867    if(threshold<=0||threshold>=100){
02868       Error("SearchHighRes", "Invalid threshold, must be positive and less than 100");
02869       return 0;
02870    }
02871    
02872    j = (int) (5.0 * sigma + 0.5);
02873    if (j >= PEAK_WINDOW / 2) {
02874       Error("SearchHighRes", "Too large sigma");
02875       return 0;
02876    }
02877    
02878    if (markov == true) {
02879       if (averWindow <= 0) {
02880          Error("SearchHighRes", "Averanging window must be positive");
02881          return 0;
02882       }
02883    }
02884    if(backgroundRemove == true){
02885       if(ssizex_ext < 2 * number_of_iterations + 1 || ssizey_ext < 2 * number_of_iterations + 1){
02886          Error("SearchHighRes", "Too large clipping window");
02887          return 0;
02888       }
02889    }   
02890    i = (int)(4 * sigma + 0.5);
02891    i = 4 * i;
02892    double **working_space = new double *[ssizex + i];
02893    for (j = 0; j < ssizex + i; j++) {
02894       Double_t *wsk = working_space[j] = new double[16 * (ssizey + i)];
02895       for (k=0;k<16 * (ssizey + i);k++) wsk[k] = 0;
02896    }   
02897    for(j = 0; j < ssizey_ext; j++){
02898       for(i = 0; i < ssizex_ext; i++){
02899          if(i < shift){
02900             if(j < shift)
02901                   working_space[i][j + ssizey_ext] = source[0][0];
02902                   
02903             else if(j >= ssizey + shift)
02904                   working_space[i][j + ssizey_ext] = source[0][ssizey - 1];
02905                   
02906             else
02907                   working_space[i][j + ssizey_ext] = source[0][j - shift];
02908          }
02909          
02910          else if(i >= ssizex + shift){
02911             if(j < shift)
02912                working_space[i][j + ssizey_ext] = source[ssizex - 1][0];
02913                
02914             else if(j >= ssizey + shift)
02915                working_space[i][j + ssizey_ext] = source[ssizex - 1][ssizey - 1];
02916                
02917             else
02918                working_space[i][j + ssizey_ext] = source[ssizex - 1][j - shift];
02919          }
02920          
02921          else{
02922             if(j < shift)
02923                working_space[i][j + ssizey_ext] = source[i - shift][0];
02924                
02925             else if(j >= ssizey + shift)
02926                working_space[i][j + ssizey_ext] = source[i - shift][ssizey - 1];
02927                
02928             else
02929                working_space[i][j + ssizey_ext] = source[i - shift][j - shift];
02930          }
02931       }
02932    }
02933    if(backgroundRemove == true){
02934       for(i = 1; i <= number_of_iterations; i++){
02935          for(y = i; y < ssizey_ext - i; y++){
02936             for(x = i; x < ssizex_ext - i; x++){
02937                a = working_space[x][y + ssizey_ext];
02938                p1 = working_space[x - i][y + ssizey_ext - i];
02939                p2 = working_space[x - i][y + ssizey_ext + i];
02940                p3 = working_space[x + i][y + ssizey_ext - i];
02941                p4 = working_space[x + i][y + ssizey_ext + i];
02942                s1 = working_space[x][y + ssizey_ext - i];
02943                s2 = working_space[x - i][y + ssizey_ext];
02944                s3 = working_space[x + i][y + ssizey_ext];
02945                s4 = working_space[x][y + ssizey_ext + i];
02946                b = (p1 + p2) / 2.0;
02947                if(b > s2)
02948                   s2 = b;
02949                b = (p1 + p3) / 2.0;
02950                if(b > s1)
02951                   s1 = b;
02952                b = (p2 + p4) / 2.0;
02953                if(b > s4)
02954                   s4 = b;
02955                b = (p3 + p4) / 2.0;
02956                if(b > s3)
02957                   s3 = b;
02958                s1 = s1 - (p1 + p3) / 2.0;
02959                s2 = s2 - (p1 + p2) / 2.0;
02960                s3 = s3 - (p3 + p4) / 2.0;
02961                s4 = s4 - (p2 + p4) / 2.0;
02962                b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 + p3 + p4) / 4.0;
02963                if(b < a)
02964                   a = b;
02965                working_space[x][y] = a;
02966             }
02967          }
02968          for(y = i;y < ssizey_ext - i; y++){
02969             for(x = i; x < ssizex_ext - i; x++){
02970                working_space[x][y + ssizey_ext] = working_space[x][y];
02971             }
02972          }
02973       }
02974       for(j = 0;j < ssizey_ext; j++){
02975          for(i = 0; i < ssizex_ext; i++){
02976             if(i < shift){
02977                if(j < shift)
02978                   working_space[i][j + ssizey_ext] = source[0][0] - working_space[i][j + ssizey_ext];
02979 
02980                else if(j >= ssizey + shift)
02981                   working_space[i][j + ssizey_ext] = source[0][ssizey - 1] - working_space[i][j + ssizey_ext];
02982 
02983                else
02984                   working_space[i][j + ssizey_ext] = source[0][j - shift] - working_space[i][j + ssizey_ext];
02985             }
02986 
02987             else if(i >= ssizex + shift){
02988                if(j < shift)
02989                   working_space[i][j + ssizey_ext] = source[ssizex - 1][0] - working_space[i][j + ssizey_ext];
02990 
02991                else if(j >= ssizey + shift)
02992                   working_space[i][j + ssizey_ext] = source[ssizex - 1][ssizey - 1] - working_space[i][j + ssizey_ext];
02993 
02994                else
02995                   working_space[i][j + ssizey_ext] = source[ssizex - 1][j - shift] - working_space[i][j + ssizey_ext];
02996             }
02997 
02998             else{
02999                if(j < shift)
03000                   working_space[i][j + ssizey_ext] = source[i - shift][0] - working_space[i][j + ssizey_ext];
03001 
03002                else if(j >= ssizey + shift)
03003                   working_space[i][j + ssizey_ext] = source[i - shift][ssizey - 1] - working_space[i][j + ssizey_ext];
03004 
03005                else
03006                   working_space[i][j + ssizey_ext] = source[i - shift][j - shift] - working_space[i][j + ssizey_ext];
03007             }
03008          }
03009       }
03010    }
03011    for(j = 0; j < ssizey_ext; j++){
03012       for(i = 0; i < ssizex_ext; i++){
03013          working_space[i][j + 15*ssizey_ext] = working_space[i][j + ssizey_ext];
03014       }
03015    }
03016    if(markov == true){
03017       for(i = 0;i < ssizex_ext; i++){
03018          for(j = 0; j < ssizey_ext; j++)
03019          working_space[i][j + 2 * ssizex_ext] = working_space[i][ssizey_ext + j];
03020       }
03021       xmin = 0;
03022       xmax = ssizex_ext - 1;
03023       ymin = 0;
03024       ymax = ssizey_ext - 1;
03025       for(i = 0, maxch = 0; i < ssizex_ext; i++){
03026          for(j = 0; j < ssizey_ext; j++){
03027             working_space[i][j] = 0;
03028             if(maxch < working_space[i][j + 2 * ssizey_ext])
03029                maxch = working_space[i][j + 2 * ssizey_ext];
03030             plocha += working_space[i][j + 2 * ssizey_ext];
03031          }
03032       }
03033       if(maxch == 0) {
03034          delete [] working_space;
03035          return 0;
03036       }
03037 
03038       nom=0;
03039       working_space[xmin][ymin] = 1;
03040       for(i = xmin; i < xmax; i++){
03041          nip = working_space[i][ymin + 2 * ssizey_ext] / maxch;
03042          nim = working_space[i + 1][ymin + 2 * ssizey_ext] / maxch;
03043          sp = 0,sm = 0;
03044          for(l = 1;l <= averWindow; l++){
03045             if((i + l) > xmax)
03046                a = working_space[xmax][ymin + 2 * ssizey_ext] / maxch;
03047 
03048             else
03049                a = working_space[i + l][ymin + 2 * ssizey_ext] / maxch;
03050 
03051             b = a - nip;
03052             if(a + nip <= 0)
03053                a = 1;
03054 
03055             else
03056                a=TMath::Sqrt(a + nip);            
03057             b = b / a;
03058             b = TMath::Exp(b);
03059             sp = sp + b;
03060             if(i - l + 1 < xmin)
03061                a = working_space[xmin][ymin + 2 * ssizey_ext] / maxch;
03062 
03063             else
03064                a = working_space[i - l + 1][ymin + 2 * ssizey_ext] / maxch;
03065             b = a - nim;
03066             if(a + nim <= 0)
03067                a = 1;
03068 
03069             else
03070                a=TMath::Sqrt(a + nim);                        
03071             b = b / a;
03072             b = TMath::Exp(b);
03073             sm = sm + b;
03074          }
03075          a = sp / sm;
03076          a = working_space[i + 1][ymin] = a * working_space[i][ymin];
03077          nom = nom + a;
03078       }
03079       for(i = ymin; i < ymax; i++){
03080          nip = working_space[xmin][i + 2 * ssizey_ext] / maxch;
03081          nim = working_space[xmin][i + 1 + 2 * ssizey_ext] / maxch;
03082          sp = 0,sm = 0;
03083          for(l = 1; l <= averWindow; l++){
03084             if((i + l) > ymax)
03085                a = working_space[xmin][ymax + 2 * ssizey_ext] / maxch;
03086 
03087             else
03088                a = working_space[xmin][i + l + 2 * ssizey_ext] / maxch;
03089             b = a - nip;
03090             if(a + nip <= 0)
03091                a=1;
03092 
03093             else
03094                a=TMath::Sqrt(a + nip);            
03095             b = b / a;
03096             b = TMath::Exp(b);
03097             sp = sp + b;
03098             if(i - l + 1 < ymin)
03099                a = working_space[xmin][ymin + 2 * ssizey_ext] / maxch;
03100 
03101             else
03102                a = working_space[xmin][i - l + 1 + 2 * ssizey_ext] / maxch;
03103             b = a - nim;
03104             if(a + nim <= 0)
03105                a = 1;
03106 
03107             else
03108                a=TMath::Sqrt(a + nim);            
03109             b = b / a;
03110             b = TMath::Exp(b);
03111             sm = sm + b;
03112          }
03113          a = sp / sm;
03114          a = working_space[xmin][i + 1] = a * working_space[xmin][i];
03115          nom = nom + a;
03116       }
03117       for(i = xmin; i < xmax; i++){
03118          for(j = ymin; j < ymax; j++){
03119             nip = working_space[i][j + 1 + 2 * ssizey_ext] / maxch;
03120             nim = working_space[i + 1][j + 1 + 2 * ssizey_ext] / maxch;
03121             spx = 0,smx = 0;
03122             for(l = 1; l <= averWindow; l++){
03123                if(i + l > xmax)
03124                   a = working_space[xmax][j + 2 * ssizey_ext] / maxch;
03125 
03126                else
03127                   a = working_space[i + l][j + 2 * ssizey_ext] / maxch;
03128                b = a - nip;
03129                if(a + nip <= 0)
03130                   a = 1;
03131 
03132                else
03133                   a=TMath::Sqrt(a + nip);            
03134                b = b / a;
03135                b = TMath::Exp(b);
03136                spx = spx + b;
03137                if(i - l + 1 < xmin)
03138                   a = working_space[xmin][j + 2 * ssizey_ext] / maxch;
03139 
03140                else
03141                   a = working_space[i - l + 1][j + 2 * ssizey_ext] / maxch;
03142                b = a - nim;
03143                if(a + nim <= 0)
03144                   a=1;
03145 
03146                else
03147                   a=TMath::Sqrt(a + nim);            
03148                b = b / a;
03149                b = TMath::Exp(b);
03150                smx = smx + b;
03151             }
03152             spy = 0,smy = 0;
03153             nip = working_space[i + 1][j + 2 * ssizey_ext] / maxch;
03154             nim = working_space[i + 1][j + 1 + 2 * ssizey_ext] / maxch;
03155             for(l = 1; l <= averWindow; l++){
03156                if(j + l > ymax)
03157                   a = working_space[i][ymax + 2 * ssizey_ext] / maxch;
03158 
03159                else
03160                   a = working_space[i][j + l + 2 * ssizey_ext] / maxch;
03161                b = a - nip;
03162                if(a + nip <= 0)
03163                   a = 1;
03164 
03165                else
03166                   a=TMath::Sqrt(a + nip);            
03167                b = b / a;
03168                b = TMath::Exp(b);
03169                spy = spy + b;
03170                if(j - l + 1 < ymin)
03171                   a = working_space[i][ymin + 2 * ssizey_ext] / maxch;
03172 
03173                else
03174                   a = working_space[i][j - l + 1 + 2 * ssizey_ext] / maxch;
03175                b=a-nim;
03176                if(a + nim <= 0)
03177                   a = 1;
03178                else
03179                   a=TMath::Sqrt(a + nim);            
03180                b = b / a;
03181                b = TMath::Exp(b);
03182                smy = smy + b;
03183             }
03184             a = (spx * working_space[i][j + 1] + spy * working_space[i + 1][j]) / (smx + smy);
03185             working_space[i + 1][j + 1] = a;
03186             nom = nom + a;
03187          }
03188       }
03189       for(i = xmin; i <= xmax; i++){
03190          for(j = ymin; j <= ymax; j++){
03191             working_space[i][j] = working_space[i][j] / nom;
03192          }
03193       }
03194       for(i = 0; i < ssizex_ext; i++){
03195          for(j = 0; j < ssizey_ext; j++){
03196             working_space[i][j + ssizey_ext] = working_space[i][j] * plocha;
03197             working_space[i][2 * ssizey_ext + j] = working_space[i][ssizey_ext + j];
03198          }
03199       }
03200    }
03201    //deconvolution starts
03202    area = 0;
03203    lhx = -1,lhy = -1;
03204    positx = 0,posity = 0;
03205    maximum = 0;
03206    //generate response matrix
03207    for(i = 0; i < ssizex_ext; i++){
03208       for(j = 0; j < ssizey_ext; j++){
03209          lda = (double)i - 3 * sigma;
03210          ldb = (double)j - 3 * sigma;
03211          lda = (lda * lda + ldb * ldb) / (2 * sigma * sigma);
03212          k=(int)(1000 * TMath::Exp(-lda));
03213          lda = k;
03214          if(lda != 0){
03215             if((i + 1) > lhx)
03216                lhx = i + 1;
03217 
03218             if((j + 1) > lhy)
03219                lhy = j + 1;
03220          }
03221          working_space[i][j] = lda;
03222          area = area + lda;
03223          if(lda > maximum){
03224             maximum = lda;
03225             positx = i,posity = j;
03226          }
03227       }
03228    }
03229    //read source matrix
03230    for(i = 0;i < ssizex_ext; i++){
03231       for(j = 0;j < ssizey_ext; j++){
03232          working_space[i][j + 14 * ssizey_ext] = TMath::Abs(working_space[i][j + ssizey_ext]);
03233       }
03234    }
03235    //calculate matrix b=ht*h
03236    i = lhx - 1;
03237    if(i > ssizex_ext)
03238       i = ssizex_ext;
03239 
03240    j = lhy - 1;
03241    if(j>ssizey_ext)
03242       j = ssizey_ext;
03243 
03244    i1min = -i,i1max = i;
03245    i2min = -j,i2max = j;
03246    for(i2 = i2min; i2 <= i2max; i2++){
03247       for(i1 = i1min; i1 <= i1max; i1++){
03248          ldc = 0;
03249          j2min = -i2;
03250          if(j2min < 0)
03251             j2min = 0;
03252 
03253          j2max = lhy - 1 - i2;
03254          if(j2max > lhy - 1)
03255             j2max = lhy - 1;
03256 
03257          for(j2 = j2min; j2 <= j2max; j2++){
03258             j1min = -i1;
03259             if(j1min < 0)
03260                j1min = 0;
03261 
03262             j1max = lhx - 1 - i1;
03263             if(j1max > lhx - 1)
03264                j1max = lhx - 1;
03265 
03266             for(j1 = j1min; j1 <= j1max; j1++){
03267                lda = working_space[j1][j2];
03268                ldb = working_space[i1 + j1][i2 + j2];
03269                ldc = ldc + lda * ldb;
03270             }
03271          }
03272          k = (i1 + ssizex_ext) / ssizex_ext;
03273          working_space[(i1 + ssizex_ext) % ssizex_ext][i2 + ssizey_ext + 10 * ssizey_ext + k * 2 * ssizey_ext] = ldc;
03274       }
03275    }
03276    //calculate at*y and write into p
03277    i = lhx - 1;
03278    if(i > ssizex_ext)
03279       i = ssizex_ext;
03280 
03281    j = lhy - 1;
03282    if(j > ssizey_ext)
03283       j = ssizey_ext;
03284 
03285    i2min = -j,i2max = ssizey_ext + j - 1;
03286    i1min = -i,i1max = ssizex_ext + i - 1;
03287    for(i2 = i2min; i2 <= i2max; i2++){
03288       for(i1=i1min;i1<=i1max;i1++){
03289          ldc=0;
03290          for(j2 = 0; j2 <= (lhy - 1); j2++){
03291             for(j1 = 0; j1 <= (lhx - 1); j1++){
03292                k2 = i2 + j2,k1 = i1 + j1;
03293                if(k2 >= 0 && k2 < ssizey_ext && k1 >= 0 && k1 < ssizex_ext){
03294                   lda = working_space[j1][j2];
03295                   ldb = working_space[k1][k2 + 14 * ssizey_ext];
03296                   ldc = ldc + lda * ldb;
03297                }
03298             }
03299          }
03300          k = (i1 + ssizex_ext) / ssizex_ext;
03301          working_space[(i1 + ssizex_ext) % ssizex_ext][i2 + ssizey_ext + ssizey_ext + k * 3 * ssizey_ext] = ldc;
03302       }
03303    }
03304    //move matrix p
03305    for(i2 = 0; i2 < ssizey_ext; i2++){
03306       for(i1 = 0; i1 < ssizex_ext; i1++){
03307          k = (i1 + ssizex_ext) / ssizex_ext;
03308          ldb = working_space[(i1 + ssizex_ext) % ssizex_ext][i2 + ssizey_ext + ssizey_ext + k * 3 * ssizey_ext];
03309          working_space[i1][i2 + 14 * ssizey_ext] = ldb;
03310       }
03311    }
03312    //initialization in x1 matrix
03313    for(i2 = 0; i2 < ssizey_ext; i2++){
03314       for(i1 = 0; i1 < ssizex_ext; i1++){
03315          working_space[i1][i2 + ssizey_ext] = 1;
03316          working_space[i1][i2 + 2 * ssizey_ext] = 0;
03317       }
03318    }
03319    //START OF ITERATIONS
03320    for(lindex = 0; lindex < deconIterations; lindex++){
03321       for(i2 = 0; i2 < ssizey_ext; i2++){
03322          for(i1 = 0; i1 < ssizex_ext; i1++){
03323             lda = working_space[i1][i2 + ssizey_ext];
03324             ldc = working_space[i1][i2 + 14 * ssizey_ext];
03325             if(lda > 0.000001 && ldc > 0.000001){
03326                ldb=0;
03327                j2min=i2;
03328                if(j2min > lhy - 1)
03329                   j2min = lhy - 1;
03330 
03331                j2min = -j2min;
03332                j2max = ssizey_ext - i2 - 1;
03333                if(j2max > lhy - 1)
03334                   j2max = lhy - 1;
03335 
03336                j1min = i1;
03337                if(j1min > lhx - 1)
03338                   j1min = lhx - 1;
03339 
03340                j1min = -j1min;
03341                j1max = ssizex_ext - i1 - 1;
03342                if(j1max > lhx - 1)
03343                   j1max = lhx - 1;
03344 
03345                for(j2 = j2min; j2 <= j2max; j2++){
03346                   for(j1 = j1min; j1 <= j1max; j1++){
03347                      k = (j1 + ssizex_ext) / ssizex_ext;
03348                      ldc = working_space[(j1 + ssizex_ext) % ssizex_ext][j2 + ssizey_ext + 10 * ssizey_ext + k * 2 * ssizey_ext];
03349                      lda = working_space[i1 + j1][i2 + j2 + ssizey_ext];
03350                      ldb = ldb + lda * ldc;
03351                   }
03352                }
03353                lda = working_space[i1][i2 + ssizey_ext];
03354                ldc = working_space[i1][i2 + 14 * ssizey_ext];
03355                if(ldc * lda != 0 && ldb != 0){
03356                   lda =lda * ldc / ldb;
03357                }
03358 
03359                else
03360                   lda=0;
03361                working_space[i1][i2 + 2 * ssizey_ext] = lda;
03362             }
03363          }
03364       }
03365       for(i2 = 0; i2 < ssizey_ext; i2++){
03366          for(i1 = 0; i1 < ssizex_ext; i1++)
03367             working_space[i1][i2 + ssizey_ext] = working_space[i1][i2 + 2 * ssizey_ext];
03368       }
03369    }
03370    //looking for maximum
03371    maximum=0;
03372    for(i = 0; i < ssizex_ext; i++){
03373       for(j = 0; j < ssizey_ext; j++){
03374          working_space[(i + positx) % ssizex_ext][(j + posity) % ssizey_ext] = area * working_space[i][j + ssizey_ext];
03375          if(maximum < working_space[(i + positx) % ssizex_ext][(j + posity) % ssizey_ext])
03376             maximum = working_space[(i + positx) % ssizex_ext][(j + posity) % ssizey_ext];
03377 
03378       }
03379    }
03380    //searching for peaks in deconvolved spectrum
03381    for(i = 1; i < ssizex_ext - 1; i++){
03382       for(j = 1; j < ssizey_ext - 1; j++){
03383          if(working_space[i][j] > working_space[i - 1][j] && working_space[i][j] > working_space[i - 1][j - 1] && working_space[i][j] > working_space[i][j - 1] && working_space[i][j] > working_space[i + 1][j - 1] && working_space[i][j] > working_space[i + 1][j] && working_space[i][j] > working_space[i + 1][j + 1] && working_space[i][j] > working_space[i][j + 1] && working_space[i][j] > working_space[i - 1][j + 1]){
03384             if(i >= shift && i < ssizex + shift && j >= shift && j < ssizey + shift){
03385                if(working_space[i][j] > threshold * maximum / 100.0){
03386                   if(peak_index < fMaxPeaks){
03387                      for(k = i - 1,a = 0,b = 0; k <= i + 1; k++){
03388                         a += (double)(k - shift) * working_space[k][j];
03389                         b += working_space[k][j];
03390                      }
03391                      ax=a/b;
03392                      if(ax < 0)
03393                         ax = 0;
03394 
03395                      if(ax >= ssizex)
03396                         ax = ssizex - 1;
03397 
03398                      for(k = j - 1,a = 0,b = 0; k <= j + 1; k++){
03399                         a += (double)(k - shift) * working_space[i][k];
03400                         b += working_space[i][k];
03401                      }
03402                      ay=a/b;
03403                      if(ay < 0)
03404                         ay = 0;
03405 
03406                      if(ay >= ssizey)
03407                         ay = ssizey - 1;
03408 
03409                      if(peak_index == 0){
03410                         fPositionX[0] = ax;
03411                         fPositionY[0] = ay;                        
03412                         peak_index = 1; 
03413                      }
03414 
03415                      else{
03416                         for(k = 0, priz = 0; k < peak_index && priz == 0; k++){
03417                            if(working_space[shift+(int)(ax+0.5)][15 * ssizey_ext + shift + (int)(ay+0.5)] > working_space[shift+(int)(fPositionX[k]+0.5)][15 * ssizey_ext + shift + (int)(fPositionY[k]+0.5)])
03418                               priz = 1;
03419                         }
03420                         if(priz == 0){
03421                            if(k < fMaxPeaks){
03422                               fPositionX[k] = ax;
03423                               fPositionY[k] = ay;
03424                            }
03425                         }
03426 
03427                         else{
03428                            for(l = peak_index; l >= k; l--){
03429                               if(l < fMaxPeaks){
03430                                  fPositionX[l] = fPositionX[l - 1];
03431                                  fPositionY[l] = fPositionY[l - 1];
03432                               }
03433                            }
03434                            fPositionX[k - 1] = ax;
03435                            fPositionY[k - 1] = ay;
03436                         }
03437                         if(peak_index < fMaxPeaks)
03438                            peak_index += 1;
03439                      }
03440                   }
03441                }
03442             }
03443          }
03444       }
03445    }
03446    //writing back deconvolved spectrum 
03447    for(i = 0; i < ssizex; i++){
03448       for(j = 0; j < ssizey; j++){
03449          dest[i][j] = working_space[i + shift][j + shift];
03450       }
03451    }
03452    i = (int)(4 * sigma + 0.5);
03453    i = 4 * i;   
03454    for (j = 0; j < ssizex + i; j++)
03455       delete[]working_space[j];
03456    delete[]working_space;
03457    fNPeaks = peak_index;
03458    return fNPeaks;
03459 }
03460 
03461 
03462 // STATIC functions (called by TH1)
03463 
03464 //_______________________________________________________________________________
03465 Int_t TSpectrum2::StaticSearch(const TH1 *hist, Double_t sigma, Option_t *option, Double_t threshold)
03466 {
03467    //static function, interface to TSpectrum2::Search
03468    
03469    TSpectrum2 s;
03470    return s.Search(hist,sigma,option,threshold);
03471 }
03472 
03473 //_______________________________________________________________________________
03474 TH1 *TSpectrum2::StaticBackground(const TH1 *hist,Int_t niter, Option_t *option)
03475 {
03476    //static function, interface to TSpectrum2::Background
03477    
03478    TSpectrum2 s;
03479    return s.Background(hist,niter,option);
03480 }

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