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);
});
}