Skip to content

Commit

Permalink
Merge pull request #2872 from ChrisWakefield/rc
Browse files Browse the repository at this point in the history
Add "View NG-CHM" button on OncoPrint Heatmap tab
  • Loading branch information
alisman authored Dec 19, 2019
2 parents 7074172 + 12eac09 commit a33a3a5
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/config/IAppConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface IServerConfig {
skin_title: string;
skin_authorization_message: string | null;
skin_patientview_filter_genes_profiled_all_samples: boolean;
show_mdacc_heatmap: boolean;
quick_search_enabled: boolean;
default_cross_cancer_study_list: string; // this has a default
default_cross_cancer_study_list_name: string; // this has a default
Expand Down
1 change: 1 addition & 0 deletions src/config/serverConfigDefaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const ServerConfigDefaults: Partial<IServerConfig> = {
'https://bioinformatics.mdanderson.org/study2url?studyid=',
mdacc_heatmap_study_url:
'https:// bioinformatics.mdanderson.org/TCGA/NGCHMPortal/?',
show_mdacc_heatmap: false,

mygene_info_url:
'https://mygene.info/v3/gene/<%= entrezGeneId %>?fields=uniprot',
Expand Down
40 changes: 40 additions & 0 deletions src/pages/resultsView/ResultsViewPageStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,46 @@ export class ResultsViewPageStore {
},
});


// remoteNgchmUrl queries mdanderson.org to test if there are NGCHMs for one selected
// study. The result is either the full URL to a portal page, or an empty string.
readonly remoteNgchmUrl = remoteData<string>({
await:()=>[this.studyIds],
invoke:async()=>{
var result = '';

if (this.studyIds.result!.length === 1) {

const queryData = {
studyid:this.studyIds.result![0],
format:"json"
};

var urlResponse;

try {
urlResponse = await request.get("https://bioinformatics.mdanderson.org/study2url")
.timeout(30000)
.query(queryData) as any;
} catch (err) {
// Just eat the exception. Result will be empty string.
}

if (urlResponse && urlResponse.body.fileContent) {
const parsedUrlResponse = JSON.parse(urlResponse.body.fileContent.trimEnd()) as any;

if (parsedUrlResponse.length >= 1) {
// This is faked out for now. study2url needs mods to include site url
result = "https://bioinformatics.mdanderson.org/TCGA/NGCHMPortal?" + parsedUrlResponse[0];
}
}
}

return Promise.resolve (result);
}
});


readonly molecularProfilesWithData = remoteData<MolecularProfile[]>({
await: () => [
this.molecularProfilesInStudies,
Expand Down
3 changes: 2 additions & 1 deletion src/pages/staticPages/tools/oncoprinter/Oncoprinter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ export default class Oncoprinter extends React.Component<IOncoprinterProps, {}>
},
onClickZoomOut:()=>{
this.oncoprint.setHorzZoom(this.oncoprint.getHorzZoom()*0.7);
}
},
onClickNGCHM:()=>{} // do nothing in oncoprinter mode
};
}

Expand Down
10 changes: 6 additions & 4 deletions src/pages/studyView/StudyViewPageStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2250,11 +2250,13 @@ export class StudyViewPageStore {
await: () => [this.queriedPhysicalStudyIds],
onError: (error => {}),
invoke: async () => {
let isSinglePhysicalStudy = this.queriedPhysicalStudyIds.result.length === 1;
if (isSinglePhysicalStudy) {
return await getHeatmapMeta(getMDAndersonHeatmapStudyMetaUrl(this.queriedPhysicalStudyIds.result[0]));
if (AppConfig.serverConfig.show_mdacc_heatmap) {
let isSinglePhysicalStudy = this.queriedPhysicalStudyIds.result.length === 1;
if (isSinglePhysicalStudy) {
return await getHeatmapMeta(getMDAndersonHeatmapStudyMetaUrl(this.queriedPhysicalStudyIds.result[0]));
}
}
return [];
return []; // if not enabled or conditions not met, just return default answer
}
}, []);

Expand Down
8 changes: 8 additions & 0 deletions src/shared/components/oncoprint/ResultsViewOncoprint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,11 @@ export default class ResultsViewOncoprint extends React.Component<IResultsViewOn
get heatmapIsDynamicallyQueried () {
return self.heatmapIsDynamicallyQueried;
},
get ngchmButtonActive() {
return (AppConfig.serverConfig.show_mdacc_heatmap &&
(self.props.store.remoteNgchmUrl.result &&
self.props.store.remoteNgchmUrl.result != '') ? true : false);
},
get heatmapGeneInputValue() {
return self.heatmapGeneInputValue;
},
Expand Down Expand Up @@ -583,6 +588,9 @@ export default class ResultsViewOncoprint extends React.Component<IResultsViewOn
onClickAddTreatmentsToHeatmap:(treatmentIds:string[])=>{
this.addHeatmapTracks(this.selectedHeatmapProfile, treatmentIds);
},
onClickNGCHM:()=>{
window.open(this.props.store.remoteNgchmUrl.result, '_blank');
},
onClickDownload:(type:string)=>{
switch(type) {
case "pdf":
Expand Down
53 changes: 53 additions & 0 deletions src/shared/components/oncoprint/controls/ConfirmNgchmModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as React from 'react';
import { Button, Modal } from 'react-bootstrap';
import {observer} from "mobx-react";
import {observable} from "mobx";

//
// NG-CHM are "Next-Generation Clustered Heat Maps", a highly interactive viewer of
// even very large heat maps, as described here:
// https://bioinformatics.mdanderson.org/public-software/ngchm/
// Source code for the viewer and other tools can be found at
// https://github.com/MD-Anderson-Bioinformatics
//

@observer
export default class ConfirmNgchmModal extends React.Component<{ show:boolean, onHide:()=>void, openNgchmWindow:()=>void }, {}> {

// CSS properties in img tag below should go in .css file?
// margin-right:20px; margin-bottom:20px;

render() {
return (
<Modal show={this.props.show} onHide={this.props.onHide} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Open new tab to MD Anderson NG-CHM?</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="oncoprint__controls__heatmap_menu mdacc-modal">
<p>Continue will open a tab or window to a different site (not cBioPortal).</p>
<img src={require("./mdandersonlogo260x85.png")} alt="MD Anderson Cancer Center logo" style={{width:153, height:50, margin:2, 'margin-right':20, 'margin-bottom':20, float:'left'}}/>
<p>
The University of Texas MD Anderson Cancer Center has created a
Next-Generation Clustered Heatmap compendium
based on the same dataset or a very similar dataset containing many of the
same TCGA samples. Continue will display a page of NG-CHM based on
this dataset.
</p>
<div style={{clear:'left'}}/>
Read details on the data processing used for this TCGA compendium <a
href="https://bioinformatics.mdanderson.org/public-datasets/about-the-tcga-compendium/"
target='_blank'
>
here
</a> (opens in a new tab).
</div>
</Modal.Body>
<Modal.Footer>
<Button onClick={()=>{this.props.openNgchmWindow(); this.props.onHide();}}>Continue</Button>
<Button onClick={this.props.onHide}>Cancel</Button>
</Modal.Footer>
</Modal>
);
}
}
29 changes: 26 additions & 3 deletions src/shared/components/oncoprint/controls/OncoprintControls.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from 'react';
import {observer, Observer} from 'mobx-react';
import {Button, ButtonGroup} from 'react-bootstrap';
import {Button, ButtonGroup, Modal} from 'react-bootstrap';
import CustomDropdown from './CustomDropdown';
import ConfirmNgchmModal from './ConfirmNgchmModal';
import ReactSelect from 'react-select1';
import {MobxPromise} from 'mobxpromise';
import {action, computed, IObservableObject, observable, ObservableMap, reaction, toJS,} from 'mobx';
Expand Down Expand Up @@ -65,13 +66,12 @@ export interface IOncoprintControlsHandlers {
onChangeSelectedClinicalTracks?: (
attributeIds: (string | SpecialAttribute)[]
) => void;

onClickAddGenesToHeatmap?: () => void;
onClickAddTreatmentsToHeatmap?: (treatments: string[]) => void;
onSelectHeatmapProfile?: (molecularProfileId: string) => void;
onChangeHeatmapGeneInputValue?: (value: string) => void;
onChangeHeatmapTreatmentInputValue?: (value: string) => void;

onClickNGCHM: () => void;
onSetHorzZoom: (z: number) => void;
onClickZoomIn: () => void;
onClickZoomOut: () => void;
Expand Down Expand Up @@ -116,6 +116,7 @@ export interface IOncoprintControlsState {
heatmapGeneInputValue?: string;
heatmapTreatmentInputValue?: string;
hideHeatmapMenu?: boolean;
ngchmButtonActive?: boolean;

customDriverAnnotationBinaryMenuLabel?: string;
customDriverAnnotationTiersMenuLabel?: string;
Expand Down Expand Up @@ -176,6 +177,7 @@ const EVENT_KEY = {
downloadOrder: '28',
downloadTabular: '29',
horzZoomSlider: '30',
viewNGCHM: '31',
addTreatmentsToHeatmap: '32',
};

Expand All @@ -189,6 +191,7 @@ export default class OncoprintControls extends React.Component<
@observable private _selectedTreatmentIds: string[] = [];
private textareaTreatmentText = '';
@observable treatmentFilter = '';
@observable showConfirmNgchmModal:boolean = false;

constructor(props: IOncoprintControlsProps) {
super(props);
Expand Down Expand Up @@ -444,6 +447,11 @@ export default class OncoprintControls extends React.Component<
this.props.handlers.onClickDownload &&
this.props.handlers.onClickDownload('tabular');
break;
case EVENT_KEY.viewNGCHM:
if (this.props.state.ngchmButtonActive && this.props.handlers.onClickNGCHM) {
this.showConfirmNgchmModal = true;
}
break;
}
}

Expand Down Expand Up @@ -695,6 +703,16 @@ export default class OncoprintControls extends React.Component<
Add Treatment Response to Heatmap
</button>,
]}

{this.props.state.ngchmButtonActive &&
(<DefaultTooltip overlay={<span>Open a new tab for NG-CHM with this study from MD Anderson Cancer Center compendium.</span>}>
<button
className={classNames("btn", "btn-sm", "btn-default")}
name={EVENT_KEY.viewNGCHM}
onClick={this.onButtonClick}
>View Next-Generation Clustered Heat Map (NG-CHM)</button>
</DefaultTooltip>)
}
</div>
);
}
Expand Down Expand Up @@ -1309,6 +1327,11 @@ export default class OncoprintControls extends React.Component<
<Observer>{this.getDownloadMenu}</Observer>
<Observer>{this.getHorzZoomControls}</Observer>
{this.minimapButton}
<ConfirmNgchmModal
show={this.showConfirmNgchmModal}
onHide={()=>this.showConfirmNgchmModal=false}
openNgchmWindow={this.props.handlers.onClickNGCHM}
/>
</ButtonGroup>
</div>
);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a33a3a5

Please sign in to comment.