Ignore:
Timestamp:
02/22/12 19:09:14 (13 years ago)
Author:
tbretz
Message:
Added DrsCalibrateTime; removed obsolete old AddT
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Mars/mcore/DrsCalib.h

    r12503 r12924  
    155155    }
    156156
    157     void AddT(const int16_t *val, const int16_t *start)
    158     {
    159         // 1440 without tm, 1600 with tm
    160         for (size_t ch=0; ch<fNumChannels; ch++)
    161         {
    162             const int16_t spos = start[ch];
    163             if (spos<0)
    164                 continue;
    165 
    166             const size_t pos = ch*fNumSamples;
    167 
    168             uint32_t nperiods = 0;
    169 
    170             for (size_t i=0; i<fNumSamples; i++)
    171             {
    172                 const size_t abs0 = pos + (spos+i  )%1024;
    173                 const size_t abs1 = pos + (spos+i+1)%1024;
    174 
    175                 const float &v0 = val[abs0];
    176                 const float &v1 = val[abs1];
    177 
    178                 // Has sign changed?
    179                 if (v0*v1>0)
    180                 {
    181                     // Sign has not changed
    182                     fSum[abs0]  += nperiods;
    183                     fSum2[abs0] += nperiods*nperiods;
    184                     continue;
    185                 }
    186 
    187                 const double p = v0==v1 ? 1 : v0/(v0-v1);
    188 
    189                 const double value = nperiods*p + (nperiods+1)*(1-p);
    190 
    191                 fSum[abs0]  += value;
    192                 fSum2[abs0] += value*value;
    193 
    194                 nperiods++;
    195             }
    196         }
    197 
    198         fNumEntries++;
    199     }
    200 
    201157    static void ApplyCh(float *vec, const int16_t *val, int16_t start, uint32_t roi,
    202158                        const int32_t *offset, const uint32_t scaleabs,
     
    385341            max[i] = *pmax;
    386342        }
    387 
    388343    }
    389344
     
    391346
    392347    uint64_t GetNumEntries() const { return fNumEntries; }
     348};
     349
     350class DrsCalibrateTime
     351{
     352public:
     353    uint64_t fNumEntries;
     354
     355    size_t fNumSamples;
     356    size_t fNumChannels;
     357
     358    std::vector<std::pair<double, double>> fStat;
     359
     360public:
     361    DrsCalibrateTime() : fNumEntries(0), fNumSamples(0), fNumChannels(0)
     362    {
     363        InitSize(160, 1024);
     364    }
     365
     366    DrsCalibrateTime(const DrsCalibrateTime &p) : fNumEntries(p.fNumEntries), fNumSamples(p.fNumSamples), fNumChannels(p.fNumChannels), fStat(p.fStat)
     367    {
     368    }
     369
     370    double Sum(uint32_t i) const { return fStat[i].first; }
     371    double W(uint32_t i) const { return fStat[i].second; }
     372
     373    void InitSize(uint16_t channels, uint16_t samples)
     374    {
     375        fNumChannels = channels;
     376        fNumSamples  = samples;
     377
     378        fNumEntries  = 0;
     379
     380        fStat.clear();
     381
     382        fStat.resize(samples*channels);
     383    }
     384
     385    void AddT(const float *val, const int16_t *start, signed char edge=0)
     386    {
     387        if (fNumSamples!=1024 || fNumChannels!=160)
     388            return;
     389
     390        // Rising or falling edge detection has the advantage that
     391        // we are much less sensitive to baseline shifts
     392
     393        for (size_t ch=0; ch<160; ch++)
     394        {
     395            const size_t tm = ch*9+8;
     396
     397            const int16_t spos = start[tm];
     398            if (spos<0)
     399                continue;
     400
     401            const size_t pos = ch*1024;
     402
     403            double  p_prev =  0;
     404            int32_t i_prev = -1;
     405
     406            for (size_t i=0; i<1024-1; i++)
     407            {
     408                const size_t rel = tm*1024 + i;
     409
     410                const float &v0 = val[rel];  //-avg;
     411                const float &v1 = val[rel+1];//-avg;
     412
     413                // Is rising edge?
     414                if (edge>0 && v0>0)
     415                    continue;
     416
     417                // Is falling edge?
     418                if (edge<0 && v0<0)
     419                    continue;
     420
     421                // Has sign changed?
     422                if ((v0<0 && v1<0) || (v0>0 && v1>0))
     423                    continue;
     424
     425                const double p = v0==v1 ? 0.5 : v0/(v0-v1);
     426
     427                const double l = i+p - (i_prev+p_prev);
     428
     429                if (i_prev>=0)
     430                {
     431                    const double w0 = 1-p_prev;
     432                    const double w1 = p;
     433
     434                    fStat[pos+(spos+i_prev)%1024].first  += w0*l;
     435                    fStat[pos+(spos+i_prev)%1024].second += w0;
     436
     437                    for (size_t k=i_prev+1; k<i; k++)
     438                    {
     439                        fStat[pos+(spos+k)%1024].first  += l;
     440                        fStat[pos+(spos+k)%1024].second += 1;
     441                    }
     442
     443                    fStat[pos+(spos+i)%1024].first  += w1*l;
     444                    fStat[pos+(spos+i)%1024].second += w1;
     445                }
     446
     447                p_prev = p;
     448                i_prev = i;
     449            }
     450        }
     451        fNumEntries++;
     452    }
     453
     454    void FillEmptyBins()
     455    {
     456        for (int ch=0; ch<160; ch++)
     457        {
     458            const auto beg = fStat.begin() + ch*1024;
     459            const auto end = beg + 1024;
     460
     461            double   avg = 0;
     462            uint32_t num = 0;
     463            for (auto it=beg; it!=end; it++)
     464            {
     465                if (it->second<fNumEntries-0.5)
     466                    continue;
     467
     468                avg += it->first / it->second;
     469                num++;
     470            }
     471            avg /= num;
     472
     473            for (auto it=beg; it!=end; it++)
     474            {
     475                if (it->second>=fNumEntries-0.5)
     476                    continue;
     477
     478                // {
     479                //     result[i+1].first  = *is2;
     480                //     result[i+1].second = *iw2;
     481                // }
     482                // else
     483                // {
     484                it->first  = avg*fNumEntries;
     485                it->second = fNumEntries;
     486                // }
     487            }
     488        }
     489    }
     490
     491    DrsCalibrateTime GetComplete() const
     492    {
     493        DrsCalibrateTime rc(*this);
     494        rc.FillEmptyBins();
     495        return rc;
     496    }
     497
     498    void CalcResult()
     499    {
     500        for (int ch=0; ch<160; ch++)
     501        {
     502            const auto beg = fStat.begin() + ch*1024;
     503            const auto end = beg + 1024;
     504
     505            // Calculate mean
     506            double s = 0;
     507            double w = 0;
     508
     509            for (auto it=beg; it!=end; it++)
     510            {
     511                s += it->first;
     512                w += it->second;
     513            }
     514
     515            s /= w;
     516
     517            double sumw = 0;
     518            double sumv = 0;
     519            int n = 0;
     520
     521            // Sums about many values are numerically less stable than
     522            // just sums over less. So we do the exercise from both sides.
     523            for (auto it=beg; it!=end-512; it++, n++)
     524            {
     525                const double v = it->first;
     526                const double w = it->second;
     527
     528                it->first = sumv>0 ? n*(1-s*sumw/sumv) :0;
     529
     530                sumw += w;
     531                sumv += v;
     532            }
     533
     534            sumw = 0;
     535            sumv = 0;
     536            n = 1;
     537
     538            for (auto it=end-1; it!=beg-1+512; it--, n++)
     539            {
     540                const double v = it->first;
     541                const double w = it->second;
     542
     543                sumw += w;
     544                sumv += v;
     545
     546                it->first = sumv>0 ? n*(s*sumw/sumv-1) : 0;
     547            }
     548        }
     549    }
     550
     551    DrsCalibrateTime GetResult() const
     552    {
     553        DrsCalibrateTime rc(*this);
     554        rc.CalcResult();
     555        return rc;
     556    }
     557
     558    double Offset(uint32_t ch, double pos) const
     559    {
     560        const auto p = fStat.begin() + ch*1024;
     561
     562        const uint32_t f = floor(pos);
     563
     564        const double v0 = p[f].first;
     565        const double v1 = p[(f+1)%1024].first;
     566
     567        return v0 + fmod(pos, 1)*(v1-v0);
     568    }
     569
     570    double Calib(uint32_t ch, double pos) const
     571    {
     572        return pos-Offset(ch, pos);
     573    }
    393574};
    394575
Note: See TracChangeset for help on using the changeset viewer.