start()

in pathology/viewer/src/components/inspect-page/inspect-page.component.ts [207:306]


  start() {
    if (this.slideInfo === undefined || !this.slideInfo.levelMap) {
      this.errorMsg = 'Missing slide level map';
      return;
    }

    this.benchmarkRunning = true;
    this.benchmark.callComplete = 0;
    this.benchmark.tilesComplete = 0;
    this.errorMsg = '';
    this.ref.markForCheck();
    this.benchmark.latency = 0;
    const tilesToLoad: Tile[][] = [];

    let levelCount = 0;
    for (const level of this.slideInfo.levelMap) {
      const levelProp = level.properties[0];
      if (this.benchmark.realLayersOnly && level.downSampleMultiplier) continue;
      const numFramesAvailable = Math.ceil(
          levelProp.frames / Math.pow(level.downSampleMultiplier ?? 1, 2));
      const numFramesToLoadThisLayer = Math.min(
          Math.ceil(
              this.benchmark.numTilesToLoadBaseLayer / Math.pow(2, levelCount)),
          numFramesAvailable);
      const step = Math.floor(
          numFramesAvailable / this.benchmark.numFramesPerStride /
          numFramesToLoadThisLayer);
      // Add tiles in continous batches of numFramesPerStride.
      tilesToLoad[levelCount] = [];
      let currentFrame = 0;
      for (let tileCount = 0; tileCount < numFramesToLoadThisLayer;) {
        tilesToLoad[levelCount].push({
          instanceUid: levelProp.instanceUid,
          frame: currentFrame,
          downsample: level.downSampleMultiplier ?? 0,
          uid: levelCount.toString() + '_' + currentFrame.toString(),
        } as Tile);
        ++tileCount;
        currentFrame += tileCount % this.benchmark.numFramesPerStride ?
            1 :
            Math.max(step - this.benchmark.numFramesPerStride, 1);
      }
      ++levelCount;
    }

    this.drawCallTable(tilesToLoad);

    const startBenchmarkTime = performance.now();
    from(tilesToLoad)
        .pipe(
            mergeMap(
                arrOfTilesOfLevel =>
                    from(arrOfTilesOfLevel)
                        .pipe(bufferCount(this.benchmark.numTilesPerCall))),
            mergeMap(
                tilesToFetch => {
                  for (const tile of tilesToFetch) {
                    this.drawCallTileId(tile.uid, 'called');
                  }
                  return forkJoin({
                    startTime: of(performance.now()),
                    bytes: this.dicomwebService.getEncodedImageTiles(
                        this.urlSeriesUid, tilesToFetch[0].instanceUid,
                        tilesToFetch.map(t => t.frame + 1),
                        SELECTED_DICOM_STORE, tilesToFetch[0].downsample,
                        this.benchmark.icc ? IccProfileType.SRGB :
                                             IccProfileType.NONE,
                        this.benchmark.disableCache),
                    tileUids: of(tilesToFetch.map(tile => tile.uid)),
                  });
                },
                this.benchmark.concurency),
            map((result) => ({
                  tileUids: result.tileUids,
                  latency: performance.now() - result.startTime
                })),
            tap((out) => {
              ++this.benchmark.callComplete;
              this.benchmark.tilesComplete += out.tileUids.length;
              if (this.benchmark.first10TilesTime === 0 &&
                  this.benchmark.tilesComplete >= 10) {
                this.benchmark.first10TilesTime =
                    performance.now() - startBenchmarkTime;
              }
              for (const uid of out.tileUids) {
                this.drawCallTileId(uid, 'complete');
              }
            }),
            map(out => out.latency), toArray())
        .subscribe(
            (arr) => {
              this.benchmark.realTime = performance.now() - startBenchmarkTime;
              this.benchmarkRunning = false;
              this.benchmark.latency =
                  arr.reduce((a, b) => a + b) / this.benchmark.tilesComplete;
            },
            (err) => {
              this.errorHandle(err);
            });
  }