Changeset 12924
- Timestamp:
- 02/22/12 19:09:14 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Mars/mcore/DrsCalib.h
r12503 r12924 155 155 } 156 156 157 void AddT(const int16_t *val, const int16_t *start)158 {159 // 1440 without tm, 1600 with tm160 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 changed182 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 201 157 static void ApplyCh(float *vec, const int16_t *val, int16_t start, uint32_t roi, 202 158 const int32_t *offset, const uint32_t scaleabs, … … 385 341 max[i] = *pmax; 386 342 } 387 388 343 } 389 344 … … 391 346 392 347 uint64_t GetNumEntries() const { return fNumEntries; } 348 }; 349 350 class DrsCalibrateTime 351 { 352 public: 353 uint64_t fNumEntries; 354 355 size_t fNumSamples; 356 size_t fNumChannels; 357 358 std::vector<std::pair<double, double>> fStat; 359 360 public: 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 } 393 574 }; 394 575
Note:
See TracChangeset
for help on using the changeset viewer.