Changeset 8072 for trunk


Ignore:
Timestamp:
10/16/06 18:02:31 (18 years ago)
Author:
tbretz
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Mars
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/Changelog

    r8071 r8072  
    1919                                                 -*-*- END OF LINE -*-*-
    2020
     21 2006/10/16 Thomas Bretz
     22
     23   * mextralgo/MExtralgoDigitalFilter.[h,cc]:
     24     - Changed the extraction algorithm such that extraction of signal
     25       and time is iterated and should be as consistent as possible
     26       at the end of the algorithm.
     27     - changed the final offset in the calculation of the arrival time
     28       to match as best as it can so far.
     29     - Updates to the still preliminary calculation of the weights
     30
     31
     32
    2133 2006/10/15 Thomas Bretz
    2234
     
    2638
    2739   * star.cc, ganymed.c, callisto.cc:
    28      - implemented an error if the resource file doen't exist
     40     - implemented an error if the resource file doesn't exist
    2941       (returns 0xfe)
    3042
  • trunk/MagicSoft/Mars/mextralgo/MExtralgoDigitalFilter.cc

    r7942 r8072  
    3333using namespace std;
    3434
    35 Float_t MExtralgoDigitalFilter::ExtractNoise(Int_t iter, Int_t windowsize) const
    36 {
    37     Double_t sum, dummy;
    38     Eval(sum, dummy, windowsize, 0, iter-fWeightsPerBin/2);
    39     return sum;
    40 }
    41 
    42 void MExtralgoDigitalFilter::Extract(Int_t windowsize, Float_t timeshift)
     35Float_t MExtralgoDigitalFilter::ExtractNoise(Int_t iter) const
     36{
     37    return Eval(fWeightsAmp, 0, iter-fWeightsPerBin/2);
     38}
     39
     40#include <iostream>
     41void MExtralgoDigitalFilter::Extract()
    4342{
    4443    fSignal    =  0; // default is: no pulse found
     
    4948    // FIXME: How to handle saturation?
    5049
    51     Float_t maxamp  = -FLT_MAX;
    52     Float_t maxtime =  0;
    53     Int_t   maxp    = -1;
     50    Double_t maxamp = -FLT_MAX;
     51    Int_t    maxp   = -1;
    5452
    5553    //
    5654    // Calculate the sum of the first fWindowSize slices
    5755    //
    58     for (Int_t i=0; i<fNum-windowsize+1; i++)
    59     {
    60         Double_t sumamp, sumtime;
    61         Eval(sumamp, sumtime, windowsize, i);
    62 
     56
     57    // For the case of an even numberof weights/bin there is
     58    // no central bin.So we create an artificial central bin.
     59    for (Int_t i=0; i<fNum-fWindowSize+1; i++)
     60    {
     61        const Double_t sumamp = Eval(fWeightsAmp, i);
    6362        if (sumamp>maxamp)
    6463        {
    65             maxamp  = sumamp;
    66             maxtime = sumtime;
    67             maxp    = i;
    68         }
    69     }
    70 
     64            maxamp = sumamp;
     65            maxp   = i;
     66        }
     67    }
    7168    // The number of available slices were smaller than the
    7269    // extraction window size of the extractor
     
    8481        return;
    8582
    86     // This is the time offset from the extraction position
    87     const Float_t time = maxtime/maxamp;
     83    Int_t frac = 0;
     84    const Int_t shift = AlignExtractionWindow(maxp, frac, maxamp);
     85
     86    // For safety we do another iteration if we have
     87    // shifted the extraction window
     88    if (TMath::Abs(shift)>0)
     89        AlignExtractionWindow(maxp, frac);
     90
     91    // Now we have found the "final" position: extract time and charge
     92    const Double_t sumamp = Eval(fWeightsAmp, maxp, frac);
     93
     94    fSignal = sumamp;
     95    if (sumamp == 0)
     96        return;
     97
     98    const Double_t sumtime = Eval(fWeightsTime, maxp, frac);
    8899
    89100    // This is used to align the weights to bins between
    90101    // -0.5/fWeightsPerBin and 0.5/fWeightsPerBin instead of
    91102    // 0 and 1./fWeightsPerBin
    92     const Float_t halfres = 0.5/fWeightsPerBin;
    93 
    94     // move the extractor by an offset number of slices
    95     // determined by the extracted time
    96     const Int_t integ = TMath::FloorNint(time+halfres+0.5);
    97     maxp -= integ;
    98 
    99     // Convert the residual fraction of one slice into an
    100     // offset position in the extraction weights
    101     Int_t frac = TMath::FloorNint((time+halfres-integ)*fWeightsPerBin);
    102 
    103     // Align maxp into available range
    104     if (maxp < 0)
    105     {
    106         maxp = 0;
    107         frac = -fWeightsPerBin/2; // Assume peak at the beginning of the first slice
    108     }
    109     if (maxp+windowsize > fNum)
    110     {
    111         maxp = fNum-windowsize;
    112         frac = fWeightsPerBin/2-1; // Assume peak at the end of the last slice
    113     }
    114 
    115     Double_t sumamp, sumtime;
    116     Eval(sumamp, sumtime, windowsize, maxp, frac);
    117 
    118     fSignal = sumamp;
    119     if (sumamp == 0)
    120         return;
     103    const Double_t binoffset = TMath::Even(fWeightsPerBin) ? 0.5 : 0;
     104
     105    fTime = maxp /*- 0.5*/ -  Double_t(frac+binoffset)/fWeightsPerBin;
     106
     107    // To let the lowest value which can be safely extracted be>0:
     108    // Take also a possible offset from timefineadjust into account
     109    //  Sould it be: fTime += fWindowSize/2; ???
     110    fTime += 0.5 + 0.5/fWeightsPerBin;
     111    // In the ideal case the would never get <0
     112    // But timefineadjust can be >0.05 (in 60% of the cases)
     113
     114    // Define in each extractor a lowest and highest extracted value!
    121115
    122116    // here, the first high-gain slice is already included
    123117    // in the fTimeShiftHiGain this shifts the time to the
    124118    // start of the rising edge
    125     fTime = maxp - Float_t(frac)/fWeightsPerBin + timeshift;
     119
     120    // This is from MExtractTimeAndChargeDigitalFilter
     121    // fTime += 0.5 + 1./fWeightsPerBin;
     122
     123    // Now there is a difference between the rising edge and
     124    // the extracted time. This must be applied after
     125    // the randomization in case of wrog values
    126126
    127127    const Float_t timefineadjust = sumtime/sumamp;
    128128
    129129    // FIXME: Is 3 a good value?
    130     if (TMath::Abs(timefineadjust)*fWeightsPerBin < 3.)
     130    //if (TMath::Abs(timefineadjust)*fWeightsPerBin < 3.)
     131    //    fTime -= timefineadjust;
     132
     133    //    if (TMath::FloorNint(timefineadjust+0.5)==0)
     134
     135    //if (TMath::Abs(timefineadjust) < 0.2)
    131136        fTime -= timefineadjust;
    132137}
     138
     139#include <TH1.h>
     140#include <TH2.h>
     141#include <TMatrixD.h>
     142#include <TArrayF.h>
     143#include <iostream>
     144#include <TSpline.h>
     145#include <TProfile.h>
     146
     147Bool_t MExtralgoDigitalFilter::CalculateWeights(TH1 &shape, const TH2 &autocorr, TArrayF &weightsamp, TArrayF &weightstime, Int_t wpb)
     148{
     149    const Int_t weightsperbin = wpb<=0?shape.GetNbinsX()/autocorr.GetNbinsX():wpb;
     150
     151    if (wpb<=0 && weightsperbin*autocorr.GetNbinsX()!=shape.GetNbinsX())
     152    {
     153        cout << "ERROR - Number of bins mismatch..." << endl;
     154        cout << "        Shape: " << shape.GetNbinsX() << endl;
     155        cout << "        ACorr: " << autocorr.GetNbinsX() << endl;
     156        return kFALSE;
     157    }
     158
     159    const TAxis &axe = *shape.GetXaxis();
     160
     161    const Int_t first = axe.GetFirst()/weightsperbin;
     162    const Int_t last  = axe.GetLast() /weightsperbin;
     163
     164    const Int_t width = last-first;
     165
     166    cout << "Range:  " << first << " <= bin < " << last << endl;
     167    cout << "Window: " << width << endl;
     168    cout << "W/Bin:  " << weightsperbin << endl;
     169
     170    // ---------------------------------------------
     171
     172    const Float_t sum = shape.Integral(first*weightsperbin, last*weightsperbin-1)/weightsperbin;
     173    shape.Scale(1./sum);
     174
     175    cout << "Sum:    " << sum << endl;
     176
     177//    TGraph gr(&shape);
     178//    TSpline5 val("Signal", &gr);
     179
     180    // FIXME: DELETE!!!
     181    TH1 &derivative = *static_cast<TH1*>(shape.Clone());
     182    derivative.Reset();
     183
     184    for (int i=0; i<derivative.GetNbinsX(); i++)
     185    {
     186//       const Float_t x = derivative.GetBinCenter(i+1);
     187//       derivative.SetBinContent(i+1, val.Derivative(x));
     188
     189        const Float_t binm = shape.GetBinContent(i+1-1);
     190        const Float_t binp = shape.GetBinContent(i+1+1);
     191
     192        const Float_t der = (binp-binm)/2./shape.GetBinWidth(1);
     193
     194        derivative.SetBinContent(i+1, der);
     195
     196        if (derivative.InheritsFrom(TProfile::Class()))
     197            static_cast<TProfile&>(derivative).SetBinEntries(i+1,1);
     198    }
     199
     200    // ---------------------------------------------
     201
     202    TMatrixD B(width, width);
     203    for (Int_t i=0; i<width; i++)
     204        for (Int_t j=0; j<width; j++)
     205            B[i][j]=autocorr.GetBinContent(i+1/*first*/, j+1/*first*/);
     206
     207    const TMatrixD Binv(TMatrixD::kInverted, B);
     208
     209    // ---------------------------------------------
     210
     211    weightsamp.Set(width*weightsperbin);
     212    weightstime.Set(width*weightsperbin);
     213
     214    for (Int_t i=0; i<weightsperbin; i++)
     215    {
     216        TMatrixD g(width, 1);
     217        TMatrixD d(width, 1);
     218
     219        for (Int_t bin=0; bin<width; bin++)
     220        {
     221            const Int_t idx = weightsperbin*(bin+first) + i;
     222
     223            g[bin][0]=shape.GetBinContent(idx+1);
     224            d[bin][0]=derivative.GetBinContent(idx+1);
     225        }
     226
     227        const TMatrixD gT(TMatrixD::kTransposed, g);
     228        const TMatrixD dT(TMatrixD::kTransposed, d);
     229
     230        const TMatrixD denom  = (gT*(Binv*g))*(dT*(Binv*d)) - (dT*(Binv*g))*(dT*(Binv*g));
     231
     232        if (denom[0][0]==0)
     233        {
     234            cout << "ERROR - Division by zero: denom[0][0]==0 for i=" << i << "." << endl;
     235            return kFALSE;
     236        }
     237
     238        const TMatrixD w_amp  = (dT*(Binv*d))*(gT*Binv) - (gT*(Binv*d))*(dT*Binv);
     239        const TMatrixD w_time = (gT*(Binv*g))*(dT*Binv) - (gT*(Binv*d))*(gT*Binv);
     240
     241        for (Int_t bin=0; bin<width; bin++)
     242        {
     243            const Int_t idx = weightsperbin*bin + i;
     244
     245            weightsamp[idx]  = w_amp [0][bin]/denom[0][0];
     246            weightstime[idx] = w_time[0][bin]/denom[0][0];
     247        }
     248    }
     249
     250    return kTRUE;
     251}
     252
     253void MExtralgoDigitalFilter::CalculateWeights2(TH1F &shape, const TH2F &autocorr, TArrayF &weightsamp, TArrayF &weightstime, Int_t wpb)
     254{
     255    const Int_t weightsperbin = wpb<=0?shape.GetNbinsX()/autocorr.GetNbinsX():wpb;
     256
     257    if (wpb<=0 && weightsperbin*autocorr.GetNbinsX()!=shape.GetNbinsX())
     258    {
     259        cout << "ERROR - Number of bins mismatch..." << endl;
     260        cout << "        Shape: " << shape.GetNbinsX() << endl;
     261        cout << "        ACorr: " << autocorr.GetNbinsX() << endl;
     262        return;
     263    }
     264
     265    const TAxis &axe = *shape.GetXaxis();
     266
     267    const Int_t first = axe.GetFirst()/weightsperbin;
     268    const Int_t last  = axe.GetLast() /weightsperbin;
     269
     270    const Int_t width = last-first;
     271
     272    cout << "Range:  " << first << " <= bin < " << last << endl;
     273    cout << "Window: " << width << endl;
     274    cout << "W/Bin:  " << weightsperbin << endl;
     275
     276    // ---------------------------------------------
     277
     278    const Float_t sum = shape.Integral(first*weightsperbin, last*weightsperbin-1)/weightsperbin;
     279    shape.Scale(1./sum);
     280
     281    TGraph gr(&shape);
     282    TSpline5 val("Signal", &gr);
     283
     284    TH1F derivative(shape);
     285    derivative.Reset();
     286
     287    for (int i=0; i<derivative.GetNbinsX(); i++)
     288    {
     289        const Float_t x = derivative.GetBinCenter(i+1);
     290        derivative.SetBinContent(i+1, val.Derivative(x));
     291
     292     /*
     293        const Float_t binm = shape.GetBinContent(i+1-1);
     294        const Float_t binp = shape.GetBinContent(i+1+1);
     295
     296        const Float_t der = (binp-binm)/2./shape.GetBinWidth(1);
     297
     298        derivative.SetBinContent(i+1, der);
     299      */
     300    }
     301
     302    // ---------------------------------------------
     303
     304    TMatrixD B(width, width);
     305    for (Int_t i=0; i<width; i++)
     306        for (Int_t j=0; j<width; j++)
     307            B[i][j]=autocorr.GetBinContent(i+first, j+first);
     308    B.Invert();
     309
     310    // ---------------------------------------------
     311
     312    weightsamp.Set(width*weightsperbin);
     313    weightstime.Set(width*weightsperbin);
     314
     315    for (Int_t i=0; i<weightsperbin; i++)
     316    {
     317        TMatrixD g(width, 1);
     318        TMatrixD d(width, 1);
     319
     320        for (Int_t bin=0; bin<width; bin++)
     321        {
     322            const Int_t idx = weightsperbin*(bin+first) + i;
     323
     324            g[bin][0]=shape.GetBinContent(idx+1);
     325            d[bin][0]=derivative.GetBinContent(idx+1);
     326        }
     327
     328        const TMatrixD gT(TMatrixD::kTransposed, g);
     329        const TMatrixD dT(TMatrixD::kTransposed, d);
     330
     331        const TMatrixD denom  = (gT*(B*g))*(dT*(B*d)) - (dT*(B*g))*(dT*(B*g));
     332
     333        const TMatrixD w_amp  = (dT*(B*d))*(gT*B) - (gT*(B*d))*(dT*B);
     334        const TMatrixD w_time = (gT*(B*g))*(dT*B) - (gT*(B*d))*(gT*B);
     335
     336        for (Int_t bin=0; bin<width; bin++)
     337        {
     338            const Int_t idx = weightsperbin*bin + i;
     339
     340            weightsamp[idx]  = w_amp [0][bin]/denom[0][0];
     341            weightstime[idx] = w_time[0][bin]/denom[0][0];
     342        }
     343    }
     344}
     345/*
     346Int_t start = fBinningResolutionHiGain*(fSignalStartBinHiGain + 1);
     347for (Int_t i = -fBinningResolutionHiGain/2+1; i<=fBinningResolutionHiGain/2; i++)
     348{
     349    // i = -4...5
     350    for (Int_t count=0; count < fWindowSizeHiGain; count++)
     351    {
     352        // count=0: pos=10*(start+0) + 10 + i
     353        // count=1: pos=10*(start+1) + 10 + i
     354        // count=2: pos=10*(start+2) + 10 + i
     355        // count=3: pos=10*(start+3) + 10 + i
     356    }
     357
     358    for (Int_t count=0; count < fWindowSizeHiGain; count++)
     359    {
     360        // count=0: pos = 10*0 + 5 +i-1
     361        // count=1: pos = 10*1 + 5 +i-1
     362        // count=2: pos = 10*2 + 5 +i-1
     363        // count=3: pos = 10*3 + 5 +i-1
     364    }
     365}
     366
     367Int_t start = fBinningResolutionLoGain*fSignalStartBinLoGain + fBinningResolutionLoGain/2;
     368for (Int_t i = -fBinningResolutionLoGain/2+1; i<=fBinningResolutionLoGain/2; i++)
     369{
     370    // i=-4..5
     371    for (Int_t count=0; count < fWindowSizeLoGain; count++)
     372    {
     373        // count=0: pos = 10*(start+0) + 5 + i
     374        // count=1: pos = 10*(start+1) + 5 + i
     375        // count=2: pos = 10*(start+2) + 5 + i
     376        // count=3: pos = 10*(start+3) + 5 + i
     377    }
     378
     379    for (Int_t count=0; count < fWindowSizeLoGain; count++)
     380    {
     381        // count=0: pos = 10*0 + 5 +i-1
     382        // count=1: pos = 10*1 + 5 +i-1
     383        // count=2: pos = 10*2 + 5 +i-1
     384        // count=3: pos = 10*3 + 5 +i-1
     385    }
     386}
     387*/
  • trunk/MagicSoft/Mars/mextralgo/MExtralgoDigitalFilter.h

    r7942 r8072  
    55#include <TROOT.h>
    66#endif
     7
     8class TH1;
     9class TH2;
     10class TH1F;
     11class TH2F;
     12class TArrayF;
    713
    814class MExtralgoDigitalFilter
     
    1319    Int_t    fNum;
    1420
    15     Float_t *fWeightsAmp;
    16     Float_t *fWeightsTime;
     21    Float_t const *fWeightsAmp;
     22    Float_t const *fWeightsTime;
    1723
    18     Int_t   fWeightsPerBin; // Number of weights per data bin
     24    const Int_t fWeightsPerBin; // Number of weights per data bin
     25    const Int_t fWindowSize;
    1926
    2027    // Result
     
    2431    Float_t fSignalDev;
    2532
    26     inline void Eval(Double_t &sumamp, Double_t &sumtime, const Int_t windowsize, const Int_t startv, const Int_t startw=0) const
     33    // Weights: Weights to evaluate
     34    // Startv: Index of first bin of data
     35    // startw: Offset on the weights
     36    inline Double_t Eval(Float_t const *weights, const Int_t startv, const Int_t startw=0) const
    2737    {
    2838        //
     
    3040        // and multiply the entries with the corresponding weights
    3141        //
    32         sumamp = 0;
    33         sumtime = 0;
     42        Double_t sum = 0;
    3443
    3544        // Shift the start of the weight to the center of sample 0
    36         Float_t const *wa  = fWeightsAmp  + fWeightsPerBin/2 + startw;
    37         Float_t const *wt  = fWeightsTime + fWeightsPerBin/2 + startw;
     45        Float_t const *w = weights + startw;
     46
    3847        Float_t *const beg = fVal+startv;
     48        for (Float_t const *pex=beg; pex<beg+fWindowSize; pex++)
     49        {
     50            sum += *w * *pex;
     51            w += fWeightsPerBin;
     52        }
     53        return sum;
     54    }
    3955
    40         for (Float_t const *pex=beg; pex<beg+windowsize; pex++)
     56    inline void AlignIntoLimits(Int_t &maxp, Int_t &frac) const
     57    {
     58        // Align maxp into available range (TO BE CHECKED)
     59        if (maxp < 0)
    4160        {
    42             sumamp  += *wa * *pex;
    43             sumtime += *wt * *pex;
    44 
    45             // Step forward by one bin
    46             wa += fWeightsPerBin;
    47             wt += fWeightsPerBin;
     61            maxp = 0;
     62            frac = fWeightsPerBin/2-1; // Assume peak at the end of the last slice
     63        }
     64        if (maxp > fNum-fWindowSize)
     65        {
     66            maxp = fNum-fWindowSize;
     67            frac = -fWeightsPerBin/2; // Assume peak at the beginning of the first slice
    4868        }
    4969    }
    5070
     71    inline Int_t AlignExtractionWindow(Int_t &maxp, Int_t &frac, const Double_t ampsum)
     72    {
     73        // Align extraction window to signal position
     74
     75        const Double_t timesum = Eval(fWeightsTime, maxp, frac);
     76
     77        // Because fWeightsPerBin/2 doesn't correspond to the center
     78        // of a bin the time-values extracted are slightly positive.
     79        // They are roughly between -0.45 and 0.55
     80        const Double_t binoffset = TMath::Even(fWeightsPerBin) ? 0.5 : 0;
     81
     82        // This is the time offset from the extraction position
     83        Double_t tmoffset = (frac+binoffset)/fWeightsPerBin + timesum/ampsum;
     84
     85        // Convert the residual fraction of one slice into an
     86        // offset position in the extraction weights
     87        const Int_t integ = TMath::FloorNint(tmoffset+0.5);
     88
     89        /*
     90        if (integ>0)
     91            tmoffset=0.49-0.05;
     92        if (integ<0)
     93            tmoffset=-0.49-0.05;
     94        integ=0;
     95        */
     96
     97        // move the extractor by an offset number of slices
     98        // determined by the extracted time
     99        maxp -= integ;
     100
     101        frac  = TMath::FloorNint((tmoffset-integ)*fWeightsPerBin);
     102
     103        // Align maxp into available range (TO BE CHECKED)
     104        AlignIntoLimits(maxp, frac);
     105
     106        return integ;
     107    }
     108
     109    inline void AlignExtractionWindow(Int_t &maxp, Int_t &frac)
     110    {
     111        const Double_t amp = Eval(fWeightsAmp, maxp, frac);
     112        if (amp!=0)
     113            AlignExtractionWindow(maxp, frac, amp);
     114    }
     115
    51116public:
    52     MExtralgoDigitalFilter(Float_t *val, Int_t n, Float_t *wa, Float_t *wt)
    53         : fVal(val), fNum(n),
    54         fWeightsAmp(wa), fWeightsTime(wt), fTime(0), fTimeDev(-1), fSignal(0), fSignalDev(-1)
     117    MExtralgoDigitalFilter(Int_t res, Int_t windowsize, Float_t *wa, Float_t *wt)
     118        : fVal(0), fNum(0), fWeightsAmp(wa+res/2), fWeightsTime(wt+res/2),
     119        fWeightsPerBin(res), fWindowSize(windowsize),
     120        fTime(0), fTimeDev(-1), fSignal(0), fSignalDev(-1)
    55121    {
    56122    }
    57123
    58     void SetWeightsPerBin(Int_t res) { fWeightsPerBin=res; }
     124    void SetData(Int_t n, Float_t *val) { fNum=n; fVal=val; }
    59125
    60126    Float_t GetTime() const          { return fTime; }
     
    67133    void GetTime(Float_t &sig, Float_t &dsig) const   { sig=fTime; dsig=fTimeDev; }
    68134
    69     Float_t ExtractNoise(Int_t iter, Int_t windowsize) const;
    70     void Extract(Int_t windowsize, Float_t timeshift);
     135    Float_t ExtractNoise(Int_t iter) const;
     136    void Extract();
     137
     138    static Bool_t CalculateWeights(TH1 &shape, const TH2 &autocorr, TArrayF &wa, TArrayF &wt, Int_t wpb=-1);
     139    static void CalculateWeights2(TH1F &shape, const TH2F &autocorr, TArrayF &wa, TArrayF &wt, Int_t wpb=-1);
    71140};
    72141
Note: See TracChangeset for help on using the changeset viewer.