void WsiToDcm::getSlideDownSamplingLevels()

in src/wsiToDcm.cpp [501:696]


void WsiToDcm::getSlideDownSamplingLevels(
std::vector<DownsamplingSlideState> *slideDownsampleState,
SlideLevelDim *startPyramidCreationDim) {
  int32_t levels;
  if (retile_) {
    double singleframe_downsample_width =
      static_cast<double>(largestSlideLevelWidth_) /
      static_cast<double>(wsiRequest_->frameSizeX);
    double singleframe_downsample_height =
       static_cast<double>(largestSlideLevelHeight_) /
       static_cast<double>(wsiRequest_->frameSizeY);
    double singleframe_downsample = std::max<double>(
                  singleframe_downsample_width, singleframe_downsample_height);
    if (wsiRequest_->downsamples.size() > 0 &&
        (wsiRequest_->stopDownsamplingAtSingleFrame ||
         wsiRequest_->includeSingleFrameDownsample)) {
      std::vector<int>::iterator ds_it = wsiRequest_->downsamples.begin();
      double largest_ds = *ds_it;
      for (; ds_it !=  wsiRequest_->downsamples.end(); ++ds_it) {
        if (*ds_it >= singleframe_downsample) {
          if (wsiRequest_->includeSingleFrameDownsample &&
              *ds_it > singleframe_downsample) {
            ds_it = wsiRequest_->downsamples.insert(ds_it,
                                                    singleframe_downsample);
          }
          largest_ds = *ds_it;
          if (wsiRequest_->stopDownsamplingAtSingleFrame) {
            wsiRequest_->downsamples.resize(1 +
                      std::distance(wsiRequest_->downsamples.begin(), ds_it));
          }
          break;
        }
        largest_ds = *ds_it;
     }
     if (largest_ds < singleframe_downsample &&
         wsiRequest_->includeSingleFrameDownsample) {
        wsiRequest_->downsamples.push_back(singleframe_downsample);
     }
    } else if (wsiRequest_->downsamples.size() == 0 &&
              wsiRequest_->retileLevels > 0) {
      int64_t single_frame_level = 1 + static_cast<int32_t>(std::ceil(
                                       log2(singleframe_downsample)));
      if ((wsiRequest_->stopDownsamplingAtSingleFrame &&
           wsiRequest_->includeSingleFrameDownsample) ||
          (wsiRequest_->stopDownsamplingAtSingleFrame &&
           wsiRequest_->retileLevels > single_frame_level) ||
          (wsiRequest_->includeSingleFrameDownsample &&
           wsiRequest_->retileLevels < single_frame_level)) {
        wsiRequest_->retileLevels = single_frame_level;
      }
    }
  }
  if (retile_) {
    if (wsiRequest_->downsamples.size() > 0) {
      levels = wsiRequest_->downsamples.size();
    } else {
      levels = wsiRequest_->retileLevels;
    }
  } else {
    levels = svsLevelCount_;
  }
  std::unique_ptr<SlideLevelDim> smallestSlideDim = nullptr;
  std::vector<std::unique_ptr<LevelProcessOrder>> levelOrderVec;
  SlideLevelDim *priorSlideLevelDim;
  if (startPyramidCreationDim == nullptr) {
    priorSlideLevelDim = nullptr;
  } else {
    priorSlideLevelDim = startPyramidCreationDim;
  }
  for (int32_t level = wsiRequest_->startOnLevel; level < levels &&
           (wsiRequest_->stopOnLevel < wsiRequest_->startOnLevel ||
                                 level <= wsiRequest_->stopOnLevel); level++) {
    BOOST_LOG_TRIVIAL(debug) << "Level: " << level;

    int64_t downsample = 1;
    if (retile_) {
      if (wsiRequest_->downsamples.size() > level &&
          wsiRequest_->downsamples[level] >= 1) {
        downsample = wsiRequest_->downsamples[level];
        if (level > 0 &&  downsample ==  wsiRequest_->downsamples[level - 1]) {
          continue;
        }
      } else if (wsiRequest_->downsamples.size() == 0) {
        downsample = pow(2, level);
      } else {
        continue;
      }
    }
    std::unique_ptr<SlideLevelDim> tempSlideLevelDim =
        std::move(getSlideLevelDim(downsample, priorSlideLevelDim));
    if (tempSlideLevelDim->downsampledLevelWidth == 0 ||
        tempSlideLevelDim->downsampledLevelHeight == 0) {
      // frame is being downsampled to nothing skip file.
      BOOST_LOG_TRIVIAL(debug) << "Layer has a 0 length dimension."
                                  " Skipping dcm generation for layer.";
      break;
    }
    smallestSlideDim = std::move(tempSlideLevelDim);
    const int64_t frameX = std::ceil(
          static_cast<double>(smallestSlideDim->downsampledLevelWidth) /
          static_cast<double>(smallestSlideDim->downsampledLevelFrameWidth));
    const int64_t frameY = std::ceil(
          static_cast<double>(smallestSlideDim->downsampledLevelHeight) /
          static_cast<double>(smallestSlideDim->downsampledLevelFrameHeight));
    const int64_t frameCount = frameX * frameY;
    BOOST_LOG_TRIVIAL(debug) << "Dimensions Level[" <<
                                level << "]: " <<
                                smallestSlideDim->downsampledLevelWidth <<
                                ", " <<
                                smallestSlideDim->downsampledLevelHeight;
    priorSlideLevelDim = smallestSlideDim.get();
    levelOrderVec.push_back(std::make_unique<LevelProcessOrder>(level,
                                              downsample,
                                              smallestSlideDim->readFromTiff));
    BOOST_LOG_TRIVIAL(debug) << "Level[" <<level << "] frames:" <<
                                frameX << ", " << frameY;
  }
  if (smallestSlideDim == nullptr) {
    return;
  }
  // Process process levels in order of area largest to smallest.
  const int32_t levelCount = static_cast<int32_t>(levelOrderVec.size());
  double sourceLevelDownsample =  1.0;
  int64_t instanceNumberCounter = 1;
  for (int32_t idx = 0; idx <  levelCount; ++idx) {
    DownsamplingSlideState slideState;
    const double next_cross_level_downsample =
      levelOrderVec[idx]->downsample() / sourceLevelDownsample;
    if (wsiRequest_->preferProgressiveDownsampling &&
        next_cross_level_downsample > 8.0) {
       slideState.saveDicom = false;
       slideState.generateCompressedRaw = true;
       slideState.instanceNumber = 0;
       if (idx == 0 && slideDownsampleState->size() == 0) {
         // create a virtual level for level 1.
         if (startPyramidCreationDim != nullptr) {
           slideState.downsample = 1.0;
           slideDownsampleState->push_back(slideState);
         } else {
           // if getting levels from openslide get largest starting level
           // which acquires imaging from highest magnification.
           double starting_downsample = openslide_get_level_downsample(
                                          getOpenSlidePtr(), 0);
           if (starting_downsample != sourceLevelDownsample) {
             slideState.downsample = starting_downsample;
             slideDownsampleState->push_back(slideState);
           }
         }
       }
       while (levelOrderVec[idx]->downsample() / sourceLevelDownsample > 8) {
          sourceLevelDownsample = sourceLevelDownsample * 8.0;
          slideState.downsample = sourceLevelDownsample;
          slideDownsampleState->push_back(slideState);
       }
    }
    sourceLevelDownsample = levelOrderVec[idx]->downsample();
    slideState.downsample = sourceLevelDownsample;
    slideState.instanceNumber = instanceNumberCounter;
    instanceNumberCounter += 1;
    slideState.saveDicom = true;
    slideState.generateCompressedRaw = false;
    if (sourceLevelDownsample == smallestSlideDim->downsample) {
      // if last slice do not save raw
      slideDownsampleState->push_back(slideState);
      break;
    }
    if (levelOrderVec[idx+1]->readLevelFromTiff()) {
      // memory & compute optimization
      // if next slice reads from tiff do save raw
      slideDownsampleState->push_back(slideState);
      continue;
    } else if ((startPyramidCreationDim == nullptr) &&
                (slideDownsampleState->size() == 0) &&
                !levelOrderVec[idx]->readLevelFromTiff() &&
                (0 == getOpenslideLevelForDownsample(
                levelOrderVec[idx+1]->downsample()))) {
      // Memory optimization, not reading from dicom.
      // if processing an image without downsampling &
      // openslide is being used to read the imaging
      // (!levelOrderVec[idx]->readLevelFromTiff()
      // no downsamples and reading downsample at level will also read the
      // highest resolution image.  Do not save compressed raw versions of
      // the highest resolution.  Start progressive downsampling from
      // downsample level 2 and on.
      slideDownsampleState->push_back(slideState);
      continue;
    } else {
      // Otherwise save compressed slice if progressive downsampling is
      // enabled.
      slideState.generateCompressedRaw = wsiRequest_->
                                            preferProgressiveDownsampling;
      slideDownsampleState->push_back(slideState);
      continue;
    }
  }
}