Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat hp search recover from incomplete or missing series/stages #3538

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -382,12 +382,30 @@ export default class HangingProtocolService extends PubSubService {
return;
}

const matchedProtocol = this.protocolEngine.run({
let matchedProtocol = this.protocolEngine.run({
studies: this.studies,
activeStudy,
displaySets,
});
this._setProtocol(matchedProtocol);
let nthBestMatch = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should just throw the exception if a specific protocol is specified

const matchedProtocolSize = this.protocolEngine.getMatchedProtocolsSize();
let done = false;
while (!done && nthBestMatch <= matchedProtocolSize) {
try {
this._setProtocol(matchedProtocol);
done = true;
} catch (e) {
// something went wrong while setting current matchedProtocol, so we rollback and
// try again with next nth best matched protocol
nthBestMatch++;
matchedProtocol = this.protocolEngine.run({
studies: this.studies,
activeStudy,
displaySets,
nthBest: nthBestMatch
});
}
}
}

/**
Expand Down Expand Up @@ -856,26 +874,39 @@ export default class HangingProtocolService extends PubSubService {
options = null as HangingProtocol.SetProtocolOptions
) {
const stages = this.protocol.stages;
let failureCounter = 0;
for (let i = 0; i < stages.length; i++) {
const stage = stages[i];
try {
const stage = stages[i];

const { matchedViewports } = this._matchAllViewports(
stage,
options,
new Map()
);
const activation = stage.stageActivation || {};
if (this.matchActivation(matchedViewports, activation.passive, 0)) {
if (this.matchActivation(matchedViewports, activation.enabled, 1)) {
stage.status = 'enabled';
const { matchedViewports } = this._matchAllViewports(
stage,
options,
new Map()
) || {};
const activation = stage.stageActivation || {};

if (this.matchActivation(matchedViewports, activation.passive, 0)) {
if (this.matchActivation(matchedViewports, activation.enabled, 1)) {
stage.status = 'enabled';
} else {
stage.status = 'passive';
}
} else {
stage.status = 'passive';
stage.status = 'disabled';
}
} else {
stage.status = 'disabled';
} catch (e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should avoid touching this code here.

stages[i].status = 'passive';
failureCounter++;
console.warn(`The hanging protocol viewport is requesting to display the matching displaysets for ${stages[i]} but something went wrong and it could not be matched.`);
}
}

// it means there is no valid stage
if (failureCounter === stages.length) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you can just iterate over the stages and see if there is a passive or enabled one, rather than throwing.

throw new Error();
}

this._broadcastEvent(this.EVENTS.STAGE_ACTIVATION, {
protocol: this.protocol,
stages: this.protocol.stages,
Expand Down Expand Up @@ -1284,6 +1315,14 @@ export default class HangingProtocolService extends PubSubService {
);
}
});

// there is no displayset found for given protocol
if (!displaySetsInfo.length) {
throw new Error(
`Can't find a displaySet match for any viewport`
);
}

return {
viewportOptions,
displaySetsInfo,
Expand Down
42 changes: 32 additions & 10 deletions platform/core/src/services/HangingProtocolService/ProtocolEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ export default class ProtocolEngine {
* @param props.studies is a list of studies to compare against (for priors evaluation)
* @param props.activeStudy is the current metadata for the study to display.
* @param props.displaySets are the list of display sets which can be modified.
* @param props.nthBest is the nth best match from the existing options. In case of undefined it consider the first best.
*/
run({ studies, displaySets, activeStudy }) {
run({ studies, displaySets, activeStudy, nthBest }) {
this.studies = studies;
this.study = activeStudy || studies[0];
this.displaySets = displaySets;
return this.getBestProtocolMatch();
return this.getBestProtocolMatch(nthBest);
}

// /**
Expand All @@ -33,20 +34,32 @@ export default class ProtocolEngine {

/**
* Return the best matched Protocol to the current study or set of studies
* @param nthBest is the nth best match from the existing options. In case of undefined it consider the first best.
* @returns {*}
*/
getBestProtocolMatch() {
// Run the matching to populate matchedProtocols Set and Map
this.updateProtocolMatches();
getBestProtocolMatch(nthBest) {

if(!nthBest) {
// Run the matching to populate matchedProtocols Set and Map
this.updateProtocolMatches();
}

// Retrieve the highest scoring Protocol
const bestMatch = this._getHighestScoringProtocol();
const bestMatch = this._getHighestScoringProtocol(nthBest);

console.log('ProtocolEngine::getBestProtocolMatch bestMatch', bestMatch);

return bestMatch;
}

/**
* Returns the amount of matched protocols
*
* @returns number
*/
getMatchedProtocolsSize() {
return this.matchedProtocols.size;
}
/**
* Populates the MatchedProtocols Collection by running the matching procedure
*/
Expand Down Expand Up @@ -166,16 +179,25 @@ export default class ProtocolEngine {
this.matchedProtocolScores = {};
}

_largestKeyByValue(obj) {
return Object.keys(obj).reduce((a, b) => (obj[a] > obj[b] ? a : b));
_largestKeyByValue(obj, nth = 1) {
const sortedObj = Object.keys(obj).sort((a, b) => (obj[a] > obj[b]));

return sortedObj[nth - 1];
}

_getHighestScoringProtocol() {
/**
* Get the protocol with highest score.
* If nth is present return the nth best match.
* @param nth tells that we need the nth highest scoring protocol. Default if 1 (first).
*
*/
_getHighestScoringProtocol(nth) {
if (!Object.keys(this.matchedProtocolScores).length) {
return;
}
const highestScoringProtocolId = this._largestKeyByValue(
this.matchedProtocolScores
this.matchedProtocolScores,
nth
);
return this.matchedProtocols.get(highestScoringProtocolId);
}
Expand Down