"Step 1" .. "Step 4" in the comments below refer to the canonical DC=START fallback chain documented in the public Doxygen of DeduceDecayCorrection() in mitkSUVCalculationHelper.h (Doxygen anchor: DCStartFallbackChain). Tests use the same numbering.
| 578 | // DeduceDecayCorrection() in mitkSUVCalculationHelper.h (Doxygen |
| 579 | // anchor: DCStartFallbackChain). Tests use the same numbering. |
| 580 | mitk::DecayCorrectionInfo mitk::DeduceDecayCorrection(const mitk::SlicedData* data, |
| 581 | double halfLifeSeconds, |
| 582 | DICOMReadPolicy policy) |
| 583 | { |
| 584 | if (nullptr == data) |
| 585 | { |
| 586 | mitkThrow() << "DeduceDecayCorrection: input data is null."; |
| 587 | } |
| 588 | |
| 589 | DecayCorrectionInfo info; |
| 590 | info.strategy = GetDecayCorrectionStrategy(data); |
| 591 | |
| 592 | switch (info.strategy) |
| 593 | { |
| 594 | case DecayCorrectionStrategy::Admin: |
| 595 | { |
| 596 | FillUniformDecayMap(data, 0.0, info.decayTimes); |
| 597 | return info; |
| 598 | } |
| 599 | |
| 600 | case DecayCorrectionStrategy::Start: |
| 601 | { |
| 602 | // Common: parse SeriesDate/Time and injection time. Required for |
| 603 | // every fallback step. |
| 604 | const std::string referenceDate = ResolveSeriesReferenceDate(data); |
| 605 | if (referenceDate.empty()) |
| 606 | { |
| 607 | mitkThrowException(MissingDICOMPropertyException) |
| 608 | << "Strategy START requires a series / acquisition date " |
| 609 | "(0008,0021 or 0008,0022) to assemble an absolute Series Time. " |
| 610 | "Neither tag was found."; |
| 611 | } |
| 612 | |
| 613 | const std::string seriesTime = |
| 614 | mitk::GetFirstDICOMValueAsString(data, DICOMTagPath(0x0008, 0x0031)); |
| 615 | if (seriesTime.empty()) |
| 616 | { |
| 617 | mitkThrowException(MissingDICOMPropertyException) |
| 618 | << "Strategy START requires (0008,0031) Series Time. Tag is missing."; |
| 619 | } |
| 620 | |
| 621 | OFDateTime ofSeriesTime; |
| 622 | if (!ConvertDICOMDateTimeString(referenceDate, seriesTime, ofSeriesTime)) |
| 623 | { |
| 624 | mitkThrowException(InvalidDICOMPropertyValueException) |
| 625 | << "Cannot parse Series Date+Time '" << referenceDate << seriesTime << "'."; |
| 626 | } |
| 627 | |
| 628 | const auto injection = ResolveInjectionDateTime(data, referenceDate); |
| 629 | const auto manuf = GetManufacturerFamily(data); |
| 630 | |
| 631 | // ---- Step 1: vendor private datetime (per slice via lifted property) ---- |
| 632 | // The PET reader (BaseDICOMReaderService) lifts these values out of |
| 633 | // the corresponding private creator blocks per file and stores them |
| 634 | // as a TemporoSpatialStringProperty keyed by (timestep, slice). See |
| 635 | // issue #783 for the design discussion. We read per-(t, s) so that |
| 636 | // multi-bed acquisitions whose private datetime varies per file are |
| 637 | // handled correctly; uniform-across-files data degenerates to the |
nothing calls this directly
no test coverage detected