├── downloads └── .gitignore ├── favicon.ico ├── img └── ajax-loader.gif ├── js ├── jscolor │ ├── arrow.gif │ ├── cross.gif │ └── demo.html ├── swf │ ├── copy_csv_xls.swf │ └── copy_csv_xls_pdf.swf ├── ga.js ├── jquery.highlight-4.min.js ├── colorpick.js ├── DotsViewGeometryZoom.js ├── router.js ├── SelectionPanel.js ├── tour.js ├── jquery.highlight.js ├── functions.js ├── dataTables.bootstrap.js ├── download.js ├── clipboard.min.js ├── html5slider.js └── searchBar.js ├── .gitignore ├── fonts ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff └── glyphicons-halflings-regular.woff2 ├── toy ├── sider_proxy.php ├── bubble_chart_backbone.html ├── bubble_chart.html ├── test.html ├── tooltip.html ├── nav.html ├── se_canvas_old.html └── se_canvas.html ├── contact.html ├── browse_drug.php ├── login.php ├── info.php ├── data ├── download_metadata.json ├── graph.json ├── download_data.json └── side_effects_digraph.json ├── get_legend.php ├── json └── writing_jsons.php ├── browse_se.php ├── se_profile.php ├── get_stats.php ├── README.md ├── download.html ├── proxy.php ├── drug_profile.php ├── search.php ├── browse_se.html ├── css ├── tourist.css ├── simple-sidebar.css ├── main.css ├── visualizer5.css └── dataTables.bootstrap.css ├── browse_drug.html ├── python ├── gml2json.py ├── make_gmt.py ├── add_data_into_db.py ├── generate_download_data_meta.py ├── orm.py └── network_layout.py ├── search.html ├── functions.php ├── get_drug_se.php ├── stats.php ├── get_se_drug.php ├── get_se_drug_top.php ├── links.html ├── home.html ├── se_profile.html ├── drug_profile.html ├── index.html └── about.html /downloads/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/favicon.ico -------------------------------------------------------------------------------- /img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/img/ajax-loader.gif -------------------------------------------------------------------------------- /js/jscolor/arrow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/js/jscolor/arrow.gif -------------------------------------------------------------------------------- /js/jscolor/cross.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/js/jscolor/cross.gif -------------------------------------------------------------------------------- /js/swf/copy_csv_xls.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/js/swf/copy_csv_xls.swf -------------------------------------------------------------------------------- /js/swf/copy_csv_xls_pdf.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/js/swf/copy_csv_xls_pdf.swf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.png 2 | *.svg 3 | error_log 4 | *.pyc 5 | python/*.json 6 | data/*.gml 7 | *.sql 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaayanLab/SEP-L1000/HEAD/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /toy/sider_proxy.php: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /js/jscolor/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | jscolor demo 4 | 5 | 6 | 7 | 8 | 9 | Click here: 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /contact.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Please inquire: Avi Ma'ayan, PhD
5 | For website issues or suggestions, write to Zichen Wang 6 |
7 |
8 |
9 | -------------------------------------------------------------------------------- /js/ga.js: -------------------------------------------------------------------------------- 1 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 2 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 3 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 4 | })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); 5 | 6 | ga('create', 'UA-60506844-3', 'auto'); 7 | ga('send', 'pageview'); 8 | -------------------------------------------------------------------------------- /browse_drug.php: -------------------------------------------------------------------------------- 1 | connect_error) { 7 | trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 8 | } 9 | 10 | $query = "SELECT pert_id,pert_iname,pubchem_cid FROM drugs_lincs"; 11 | 12 | $rs_arr = query_mysql($query, $conn); 13 | 14 | $json = json_encode($rs_arr); 15 | echo $json; 16 | ?> 17 | 18 | -------------------------------------------------------------------------------- /login.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /info.php: -------------------------------------------------------------------------------- 1 | connect_error) { 8 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 9 | } 10 | 11 | $query = "SELECT * FROM side_effects WHERE umls_id = '$umls_id'"; 12 | $rs_arr = query_mysql($query, $conn); 13 | $conn->close(); 14 | 15 | echo "side effect: " . $rs_arr[0]['name'] . "
"; 16 | echo "synonyms: " . $rs_arr[0]['synonyms'] . "
"; 17 | 18 | $url = 'http://sideeffects.embl.de/se/' . $umls_id; 19 | 20 | ?> 21 | -------------------------------------------------------------------------------- /data/download_metadata.json: -------------------------------------------------------------------------------- 1 | [{"Rows": 20410, "Name": "meta_LINCS_strongest_signatures.csv", "Fields": ["pert_id", "ctrl distil_ids", "pert distil_ids", "strongest sig_id"], "Size(MB)": "31.8", "path": "downloads/meta_LINCS_strongest_signatures.csv", "Columns": 4, "md5": "5817de1affd74be4d120037d08630068"}, {"Rows": 20336, "Name": "meta_Probes_info.csv", "Fields": ["probe", "gene symbol"], "Size(MB)": "0.4", "path": "downloads/meta_Probes_info.csv", "Columns": 2, "md5": "a7ed98e6bb5e26f26c787fe29237c392"}, {"Rows": 41774, "Name": "meta_SMILES.csv", "Fields": ["pert_id", "pert_iname", "pubchem_cid", "SMILES"], "Size(MB)": "3.8", "path": "downloads/meta_SMILES.csv", "Columns": 4, "md5": "8f827b90d726361138431651d44d30ff"}] -------------------------------------------------------------------------------- /toy/bubble_chart_backbone.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /get_legend.php: -------------------------------------------------------------------------------- 1 | connect_error) { 7 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 8 | } 9 | 10 | if (isset($_GET['type'])) { 11 | $type = $_GET['type']; 12 | if ($type == 'side_effect_network.json') { 13 | $query = "SELECT name,CONCAT('#',color) AS color FROM soc"; 14 | } else { 15 | $query = "SELECT pert_icollection FROM drugs_lincs GROUP BY pert_icollection"; 16 | } 17 | } 18 | 19 | $result = query_mysql($query, $conn); 20 | $conn->close(); 21 | 22 | $json = json_encode($result); 23 | echo $json; 24 | ?> 25 | -------------------------------------------------------------------------------- /json/writing_jsons.php: -------------------------------------------------------------------------------- 1 | setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 5 | $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 6 | 7 | // $stmt = $db->query('SELECT umls_id,name FROM side_effects'); 8 | // $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); 9 | 10 | // $json = json_encode($rs); 11 | // echo $json; 12 | // file_put_contents('side_effects.json', $json); 13 | 14 | 15 | // $stmt = $db->query('SELECT pert_id,pert_iname FROM drugs_lincs'); 16 | // $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); 17 | 18 | // $json = json_encode($rs); 19 | // echo $json; 20 | // file_put_contents('drugs.json', $json); 21 | 22 | ?> -------------------------------------------------------------------------------- /browse_se.php: -------------------------------------------------------------------------------- 1 | connect_error) { 7 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 8 | } 9 | 10 | $query = "SELECT umls_id,name,synonyms FROM side_effects WHERE umls_id IS NOT NULL AND auroc IS NOT NULL"; 11 | $rs_arr = query_mysql($query, $conn); 12 | 13 | $conn->close(); 14 | 15 | $num_rows = count($rs_arr); 16 | $out_arr = array(); 17 | foreach ($rs_arr as $row) { 18 | $synonyms = explode("|", $row["synonyms"]); 19 | $row["synonyms"] = $synonyms; 20 | array_push($out_arr, $row); 21 | } 22 | $json = json_encode($out_arr); 23 | echo $json; 24 | ?> -------------------------------------------------------------------------------- /se_profile.php: -------------------------------------------------------------------------------- 1 | connect_error) { 9 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 10 | } 11 | 12 | // $query = "SELECT * FROM umls_ids INNER JOIN side_effects ON side_effects.umls_id=umls_ids.umls_id WHERE umls_ids.umls_id='$umls_id'"; 13 | $query = "SELECT * FROM side_effects WHERE umls_id='$umls_id'"; 14 | $rs_se = query_mysql($query, $conn); 15 | $rs_se[0]['synonyms'] = explode("|", $rs_se[0]["synonyms"]); 16 | 17 | $conn->close(); 18 | 19 | $json = json_encode($rs_se[0]); 20 | echo $json; 21 | 22 | ?> 23 | -------------------------------------------------------------------------------- /get_stats.php: -------------------------------------------------------------------------------- 1 | connect_error) { 7 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 8 | } 9 | 10 | function getCount($query, $conn) 11 | { 12 | $result = query_mysql($query, $conn); 13 | return $result[0]['COUNT(*)']; 14 | } 15 | 16 | $out_arr = array(); 17 | 18 | $out_arr['drugs'] = getCount("SELECT COUNT(*) FROM drugs_lincs", $conn); 19 | $out_arr['side_effects'] = getCount("SELECT COUNT(*) FROM side_effects WHERE auroc IS NOT NULL", $conn); 20 | // $out_arr['side_effects_predictable'] = getCount("SELECT COUNT(*) FROM side_effects WHERE auroc IS NOT NULL AND auroc > 0.7", $conn); 21 | 22 | echo json_encode($out_arr); 23 | 24 | $conn->close(); 25 | ?> -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Side effect prediction based on L1000 data 2 | This web portal is made to serve the adverse event predictions for the >20,000 LINCS compounds. 3 | 4 | ## About 5 | On the home page, a network of predictive ADRs was constructed based on their drug similarity and visualized using a stacked bubble chart. Each drug and ADR has a dedicated page with a list of the relevant predictions and external links to sites such as: [PubChem](https://pubchem.ncbi.nlm.nih.gov/), [lincscloud.org](lincscloud.org), LINCS Information Framework([LIFE](http://life.ccs.miami.edu/life/)) and [SIDER](http://sideeffects.embl.de/). 6 | 7 | ## Publication 8 | [Drug Induced Adverse Events Prediction with the LINCS L1000 Data.](http://bioinformatics.oxfordjournals.org/content/early/2016/04/01/bioinformatics.btw168.short) 9 | Wang Z, Clark NR, Ma'ayan A. _Bioinformatics_ 2016 10 | -------------------------------------------------------------------------------- /download.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 7 |
8 | 9 | 12 |
13 |
14 |
15 |
16 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /proxy.php: -------------------------------------------------------------------------------- 1 | connect_error) { 9 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 10 | } 11 | 12 | $query = "SELECT * FROM side_effects WHERE umls_id = ?"; 13 | 14 | $stmt = $conn->prepare($query); 15 | if($stmt === false) { 16 |   trigger_error('Wrong SQL query: ' . $query . ' Error: ' . $conn->error, E_USER_ERROR); 17 | } 18 | 19 | $stmt->bind_param('s', $umls_id); 20 | $stmt->execute(); 21 | 22 | $rs = $stmt->get_result(); 23 | $rs_arr = $rs->fetch_all(MYSQLI_ASSOC); 24 | $rs->free(); 25 | $stmt->close(); 26 | $conn->close(); 27 | 28 | // echo "side effect: " . $rs_arr[0]['name'] . "
"; 29 | // echo "synonyms: " . $rs_arr[0]['synonyms'] . "
"; 30 | 31 | $url = 'http://sideeffects.embl.de/se/' . $umls_id; 32 | $html = file_get_contents($url); 33 | echo $html; 34 | 35 | ?> 36 | -------------------------------------------------------------------------------- /js/jquery.highlight-4.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | highlight v4 4 | 5 | Highlights arbitrary terms. 6 | 7 | 8 | 9 | MIT license. 10 | 11 | Johann Burkard 12 | 13 | 14 | 15 | */ 16 | 17 | jQuery.fn.highlight=function(c){function e(b,c){var d=0;if(3==b.nodeType){var a=b.data.toUpperCase().indexOf(c);if(0<=a){d=document.createElement("span");d.className="highlight";a=b.splitText(a);a.splitText(c.length);var f=a.cloneNode(!0);d.appendChild(f);a.parentNode.replaceChild(d,a);d=1}}else if(1==b.nodeType&&b.childNodes&&!/(script|style)/i.test(b.tagName))for(a=0;aconnect_error) { 10 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 11 | } 12 | 13 | $query = "SELECT * FROM drugs_lincs WHERE pert_id='$pert_id'"; 14 | $rs_lincs = query_mysql($query, $conn); 15 | $drug_meta['drugs_lincs'] = $rs_lincs[0]; // to store info for the drug 16 | 17 | $pcid = $rs_lincs[0]['pubchem_cid']; 18 | 19 | // don't want to show info from drugbank and stitch 20 | // if (!is_null($pcid)) { 21 | // $tables = array("drugs_drugbank", "drugs_stitch"); 22 | // foreach ($tables as $table) { 23 | // $query = "SELECT * FROM $table WHERE pubchem_cid='$pcid'"; 24 | // $rs_arr = query_mysql($query, $conn); 25 | // if(count($rs_arr) == 1) { 26 | // $drug_meta[$table] = $rs_arr[0]; 27 | // } 28 | // } 29 | // } 30 | 31 | $conn->close(); 32 | 33 | $json = json_encode($drug_meta); 34 | echo $json; 35 | ?> -------------------------------------------------------------------------------- /search.php: -------------------------------------------------------------------------------- 1 | connect_error) { 7 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 8 | } 9 | 10 | if (isset($_GET['term'])) { 11 | $searchq = $_GET["term"]; 12 | $searchq = preg_replace("#[^0-9a-z-]#i", "", $searchq); 13 | $searchq = "%" . $searchq . "%"; 14 | 15 | $query1 = "SELECT pert_id, pert_iname, alt_name FROM drugs_lincs WHERE pert_id LIKE '$searchq' OR pert_iname LIKE '$searchq' OR alt_name LIKE '$searchq'"; 16 | $query2 = "SELECT umls_id, name, synonyms FROM side_effects WHERE umls_id LIKE '$searchq' OR name LIKE '$searchq' OR synonyms LIKE '$searchq'"; 17 | $rs_arr1 = query_mysql($query1, $conn); 18 | $rs_arr2 = query_mysql($query2, $conn); 19 | 20 | $count = count($rs_arr1) + count($rs_arr2); 21 | if ($count == 0) { 22 | $output = 'NULL'; 23 | } else { 24 | $rs_arr = array("drugs" => $rs_arr1, "se" => $rs_arr2); 25 | $output = $rs_arr; 26 | } 27 | $json = json_encode($output); 28 | echo $json; 29 | } 30 | 31 | ?> -------------------------------------------------------------------------------- /browse_se.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
UMLS Concept IDNameSynonyms
5 |
6 |
7 | 41 | -------------------------------------------------------------------------------- /js/colorpick.js: -------------------------------------------------------------------------------- 1 | 2 | //jscolor.color is customized at lines 377-379,582,583,586 3 | 4 | // var colorPicker = new jscolor.color(document.getElementById('colorPickerInput'), {}); 5 | 6 | var ColorPicker = Backbone.View.extend({ 7 | 8 | events:{ 9 | "change" : "updateColor", 10 | }, 11 | 12 | initialize: function(){ 13 | this.$el = $('#colorPickerInput'); 14 | this.el = this.$el[0]; 15 | this.picker = new jscolor.color(this.el, {}); 16 | this.currentSelectionBar = null; 17 | }, 18 | 19 | updateColor:function(){ 20 | var color = '#' + this.$el.val(); 21 | this.currentSelectionBar.$el.css('background-color',color); 22 | _.each(this.currentSelectionBar.highlights,function(highlight){ 23 | highlight.style('stroke',color); 24 | }); 25 | }, 26 | 27 | showPicker:function(event){ 28 | this.currentSelectionBar = event; 29 | var self = this; 30 | this.picker.showPicker(this.currentSelectionBar.$el[0]); 31 | var pickerLeft = parseFloat( $('#pickerBox').css('left') ); 32 | var pickerTop = parseFloat($('#pickerBox').css('top')); 33 | var okLeft = 187.5; 34 | var okTop = 121; 35 | $('#colorPickerButton').css('display','block') 36 | .css('left',okLeft+pickerLeft) 37 | .css('top',okTop+pickerTop) 38 | .click(function(){ 39 | self.picker.hidePicker(); 40 | $(this).css('display','none'); 41 | this.currentSelectionBar = null; 42 | }); 43 | }, 44 | 45 | }); 46 | 47 | -------------------------------------------------------------------------------- /css/tourist.css: -------------------------------------------------------------------------------- 1 | .tour-highlight{ 2 | background: transparent; 3 | -moz-box-shadow: 0px 0px 7px 0px rgba(0, 241, 255, 0.701961); 4 | -webkit-box-shadow: 0px 0px 7px 0px rgba(0, 241, 255, 0.701961); 5 | -o-box-shadow: 0px 0px 7px 0px rgba(0, 241, 255, 0.701961); 6 | box-shadow: 0px 0px 7px 0px rgba(0, 241, 255, 0.701961); 7 | border-radius: 2px; 8 | } 9 | 10 | .popover { 11 | background-color: #fff; 12 | } 13 | 14 | /* bootstrap styles */ 15 | .tourist-popover{ 16 | padding: 0; 17 | } 18 | .tourist-popover .popover-content{ 19 | padding: 10px 0 0 0; 20 | min-width: 200px; 21 | } 22 | .tourist-popover .popover-content p{ 23 | margin: 0 8px 10px 8px; 24 | color: black; 25 | } 26 | .tourist-popover .popover-content h5{ 27 | margin: 0 8px 10px 8px; 28 | color: black; 29 | } 30 | .tourist-popover .popover-content .action-label{ 31 | background: rgba(0, 111, 255, 0.168627); 32 | font-size: 14px; 33 | padding: 3px 10px; 34 | } 35 | .tourist-popover .popover-content .tour-counter{ 36 | margin: 0; padding: 0; 37 | position: absolute; 38 | left: 10px; bottom: 14px; 39 | font-size: 11px; 40 | color: #acacac; 41 | } 42 | .tourist-popover .tour-buttons{ 43 | padding: 8px 10px; 44 | min-height: 28px; 45 | background: #f5f5f5; 46 | border-radius: 0px 0px 6px 6px; 47 | box-sizing: content-box; 48 | } 49 | .tourist-popover .btn-close{ 50 | background: none; 51 | border: none; 52 | position: absolute; 53 | top: 4px; right: 7px; 54 | padding: 0; 55 | opacity: .3; 56 | } 57 | .tourist-popover .btn-close:hover{ 58 | opacity: .5; 59 | } 60 | -------------------------------------------------------------------------------- /browse_drug.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
pert_idNamePubchem Compound ID
4 |
5 |
6 | 7 | 42 | -------------------------------------------------------------------------------- /python/gml2json.py: -------------------------------------------------------------------------------- 1 | # to convert network in gml to json format for web visulization 2 | import json 3 | import networkx as nx 4 | from networkx.readwrite import json_graph 5 | 6 | import sys 7 | sys.path.append('/Users/zichen/Documents/bitbucket/maayanlab_utils') 8 | 9 | from fileIO import mysqlTable2dict 10 | d_sename_umls = mysqlTable2dict('sep', 'side_effects', 2,1) 11 | 12 | def gml2json(gml_fn, json_fn): 13 | G = nx.read_gml(gml_fn) 14 | print G.number_of_nodes(), G.number_of_edges() 15 | for node_id in G.nodes(): 16 | node_dict = G.node[node_id] 17 | if '|' in node_dict['label']: 18 | sl = node_dict['label'].split('|') 19 | label = '%s (%s)'%( sl[1], sl[0] ) 20 | G.node[node_id]['label'] = label 21 | 22 | # clean labels and add xref 23 | if node_dict['type'] == "SE": 24 | G.node[node_id]['type'] = 'triangle-up' 25 | G.node[node_id]['xref'] = d_sename_umls[node_dict['label']] # umls 26 | else: 27 | sl = G.node[node_id]['label'].split('(') 28 | xref = sl[-1] 29 | label = '('.join(sl[0:-1]) 30 | label = label.strip() 31 | xref = xref.strip(')') 32 | G.node[node_id]['label'] = label 33 | G.node[node_id]['xref'] = xref 34 | G.node[node_id]['type'] = 'circle' 35 | G.node[node_id]['id'] = node_dict['label'] 36 | G.node[node_id]['size'] = G.degree(node_id) 37 | data = json_graph.node_link_data(G,attrs={'source': 'source', 'target': 'target', 'key': 'key', 'id': 'label'}) 38 | json.dump(data, open(json_fn, 'wb')) 39 | 40 | 41 | gml2json('../data/uberpheno_ADR_AUC_0.65_encv10_fdr.gml', '../data/pheno_ADR_network.json') 42 | gml2json('../data/GO_SE_RLogit_75_0.35_new.gml', '../data/GO_ADR_network.json') 43 | 44 | -------------------------------------------------------------------------------- /search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | 39 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | prepare($query); 6 | // if($stmt === false) {trigger_error('Wrong SQL query: ' . $query . ' Error: ' . $conn->error, E_USER_ERROR);} 7 | // if (is_array($params)) { 8 | // $refs = array(); // convert $params to an array of references. 9 | // foreach ($params as $key => $value) { 10 | // $refs[$key] = &$params[$key]; 11 | // } 12 | // call_user_func_array(array($stmt, "bind_param"), array_merge(array($type), $refs)); 13 | // } else { 14 | // if ($params != '') { 15 | // $stmt->bind_param($type, $params); 16 | // } 17 | // } 18 | // $stmt->execute(); 19 | // $rs = $stmt->get_result(); 20 | // $arr = $rs->fetch_all(MYSQLI_ASSOC); 21 | // $rs->free(); 22 | // $stmt->close(); 23 | // return $arr; 24 | // } 25 | 26 | function query_mysql($query, $conn) 27 | { 28 | $rs = $conn->query($query); 29 | $arr = array(); 30 | while ($row = $rs->fetch_assoc()) { 31 | array_push($arr, $row); 32 | } 33 | $rs->close(); 34 | return $arr; 35 | } 36 | 37 | function send_get_data($url, $data) 38 | { 39 | $ch = curl_init($url); 40 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 41 | 'Content-Type: application/json', 42 | 'Content-Length: '.strlen($data)) ); 43 | 44 | curl_setopt($ch, CURLOPT_TIMEOUT, 5); 45 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 46 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 47 | curl_setopt($ch, CURLOPT_HTTPGET,true); 48 | $result = curl_exec($ch); 49 | if ($result === false) { 50 | print_r(curl_errno($ch)); 51 | } 52 | curl_close($ch); 53 | return $result; 54 | } 55 | ?> -------------------------------------------------------------------------------- /data/graph.json: -------------------------------------------------------------------------------- 1 | { 2 | "graph": [], 3 | "links": [ 4 | {"source": 0, "target": 1}, 5 | {"source": 0, "target": 2}, 6 | {"source": 0, "target": 3}, 7 | {"source": 0, "target": 4}, 8 | {"source": 0, "target": 5}, 9 | {"source": 0, "target": 6}, 10 | {"source": 1, "target": 3}, 11 | {"source": 1, "target": 4}, 12 | {"source": 1, "target": 5}, 13 | {"source": 1, "target": 6}, 14 | {"source": 2, "target": 4}, 15 | {"source": 2, "target": 5}, 16 | {"source": 2, "target": 6}, 17 | {"source": 3, "target": 5}, 18 | {"source": 3, "target": 6}, 19 | {"source": 5, "target": 6}, 20 | {"source": 0, "target": 7}, 21 | {"source": 1, "target": 8}, 22 | {"source": 2, "target": 9}, 23 | {"source": 3, "target": 10}, 24 | {"source": 4, "target": 11}, 25 | {"source": 5, "target": 12}, 26 | {"source": 6, "target": 13}], 27 | "nodes": [ 28 | {"size": 60, "score": 0, "id": "Androsynth", "type": "circle"}, 29 | {"size": 10, "score": 0.2, "id": "Chenjesu", "type": "circle"}, 30 | {"size": 60, "score": 0.4, "id": "Ilwrath", "type": "circle"}, 31 | {"size": 10, "score": 0.6, "id": "Mycon", "type": "circle"}, 32 | {"size": 60, "score": 0.8, "id": "Spathi", "type": "triangle-up"}, 33 | {"size": 10, "score": 1, "id": "Umgah", "type": "triangle-up"}, 34 | {"id": "VUX", "type": "circle"}, 35 | {"size": 60, "score": 0, "id": "Guardian", "type": "square"}, 36 | {"size": 10, "score": 0.2, "id": "Broodhmome", "type": "square"}, 37 | {"size": 60, "score": 0.4, "id": "Avenger", "type": "square"}, 38 | {"size": 10, "score": 0.6, "id": "Podship", "type": "square"}, 39 | {"size": 60, "score": 0.8, "id": "Eluder", "type": "square"}, 40 | {"size": 10, "score": 1, "id": "Drone", "type": "square"}, 41 | {"id": "Intruder", "type": "square"}], 42 | "directed": false, 43 | "multigraph": false 44 | } -------------------------------------------------------------------------------- /get_drug_se.php: -------------------------------------------------------------------------------- 1 | connect_error) { 8 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 9 | } 10 | // get SE assocated for the drug 11 | 12 | $query = "SELECT se_id,p_val FROM prediction INNER JOIN drugs_lincs ON prediction.drug_id = drugs_lincs.id WHERE pert_id='$pert_id'"; 13 | $side_effects = query_mysql($query, $conn); # all the predicted se_ids of the drug 14 | 15 | // get SE associated with this drug in SIDER 16 | $query = "SELECT se_id FROM sider_connections INNER JOIN drugs_lincs ON sider_connections.drug_id = drugs_lincs.id WHERE pert_id='$pert_id'"; 17 | $known_side_effects = query_mysql($query, $conn); 18 | 19 | $known_side_effect_ids = array(); // se_id of known connections 20 | foreach ($known_side_effects as $key => $line) { 21 | $id = $line['se_id']; 22 | array_push($known_side_effect_ids, $id); 23 | } 24 | 25 | $arr_out = array(); 26 | 27 | for ($i=0; $i < count($side_effects); $i++) { 28 | $se_id = $side_effects[$i]['se_id']; 29 | $query = "SELECT umls_id,name FROM side_effects WHERE id='$se_id'";//to get names of side effects 30 | $se_meta = query_mysql($query, $conn); 31 | if ($se_meta[0]['umls_id']) { // filter out se without umls_id 32 | $arr_out[$i]['name'] = $se_meta[0]['name']; 33 | $arr_out[$i]['umls_id'] = $se_meta[0]['umls_id']; 34 | $p_val = $side_effects[$i]['p_val']; 35 | $arr_out[$i]['p_val'] = sprintf('%0.2f', $p_val); 36 | if (in_array($se_id, $known_side_effect_ids)) { 37 | $arr_out[$i]['sider'] = 'yes'; 38 | } else { 39 | $arr_out[$i]['sider'] = 'no'; 40 | } 41 | } 42 | } 43 | 44 | $conn->close(); 45 | 46 | $json = json_encode($arr_out); 47 | echo $json; 48 | ?> -------------------------------------------------------------------------------- /js/DotsViewGeometryZoom.js: -------------------------------------------------------------------------------- 1 | var DotsViewGeometryZoom = DotsView.extend({ 2 | 3 | afterFetchInitialize: function(){ 4 | 5 | this.stageHeight = this.dots.transformRange(this.stageWidth, 6 | this.paddingWidth, this.sizeScale); 7 | 8 | this.zoomTransform = _.bind(this.zoomTransform,this); 9 | 10 | this.zoom_g = d3.select(this.el) 11 | .attr('width',this.stageWidth) 12 | .attr('height',this.stageHeight) 13 | .attr('class','svgBorder') 14 | .call(d3.behavior.zoom() 15 | .scaleExtent([1, this.maxScale]).on("zoom", this.zoomTransform)) 16 | .append('g'); 17 | 18 | this.currentScale = 1; 19 | this.addAll(); 20 | this.texts = this.svg.selectAll('text'); 21 | }, 22 | 23 | zoomTransform: function(){ 24 | 25 | var thres = this.textShowThres; 26 | if(d3.event.scale>=thres&&this.currentScalethres){ 32 | this.texts.attr('display','none'); 33 | this.currentScale = d3.event.scale; 34 | }; 35 | 36 | this.zoom_g.attr("transform","translate(" + 37 | d3.event.translate + ")scale(" + d3.event.scale + ")"); 38 | }, 39 | 40 | highlightSearchTerm:function(event){ 41 | console.log(event.term); 42 | var self = this; 43 | this.zoom_g.selectAll('g') 44 | .filter(function(d){ return d[3]==event.term;}) 45 | .call(function(selection){ 46 | var D = selection.datum(); 47 | var currentTransform = selection.attr('transform'); 48 | var size = D[2] > 12 ? D[2]+1:12; 49 | self.zoom_g.append('g') 50 | .datum([D[0],D[1]]) 51 | .attr('transform',currentTransform) 52 | .append('rect') 53 | .attr('transform', 54 | 'translate(' + (-size/2) + "," + (-size/2) +')') 55 | .attr('width',size) 56 | .attr('height',size) 57 | .attr('class','highlight'); 58 | 59 | }); 60 | }, 61 | }); -------------------------------------------------------------------------------- /toy/bubble_chart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /stats.php: -------------------------------------------------------------------------------- 1 | connect_error) { 7 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 8 | } 9 | 10 | if (isset($_GET['type'])) { 11 | switch ($_GET['type']) { 12 | case 'pert_collections':// count numbers for different pert_collections 13 | $query = "SELECT pert_collection, COUNT(*) FROM drugs_lincs GROUP BY pert_collection"; 14 | $pert_collections = query_mysql($query, $conn); 15 | $conn->close(); 16 | $pert_collection_count = array(); 17 | foreach ($pert_collections as $key => $line) { 18 | if (is_null($line['pert_collection'])) { 19 | $pert_collection_count['NA'] = (int) $line['COUNT(*)']; 20 | } else { 21 | $pert_collection_count[$line['pert_collection']] = (int) $line['COUNT(*)']; 22 | } 23 | } 24 | echo json_encode($pert_collection_count); 25 | break; 26 | case 'fda_collections': // number of FDA approved drugs in collections 27 | $query = "SELECT pert_collection, COUNT(*) FROM drugs_lincs INNER JOIN drugs_drugbank ON drugs_lincs.pubchem_cid=drugs_drugbank.pubchem_cid OR drugs_lincs.pert_iname=drugs_drugbank.name GROUP BY pert_collection"; 28 | $rs = query_mysql($query, $conn); 29 | $conn->close(); 30 | $fda_approved_drug_count = array(); 31 | foreach ($rs as $key => $line) { 32 | if (is_null($line['pert_collection'])) { 33 | $fda_approved_drug_count['NA'] = (int) $line['COUNT(*)']; 34 | } else { 35 | $fda_approved_drug_count[$line['pert_collection']] = (int) $line['COUNT(*)']; 36 | } 37 | } 38 | echo json_encode($fda_approved_drug_count); 39 | break; 40 | case 'summary_count': 41 | $arr = array(); // container for all the output 42 | $tables = array('side_effects', 'drugs_lincs'); 43 | foreach ($tables as $table) { 44 | $query = "SELECT COUNT(*) FROM $table"; // get SE count and drug count 45 | $count = query_mysql($query, $conn); 46 | $arr[$table] = $count[0]['COUNT(*)']; 47 | } 48 | $conn->close(); 49 | echo json_encode($arr); 50 | } 51 | } 52 | ?> -------------------------------------------------------------------------------- /toy/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 19 | 20 |
21 | 71 | 72 | -------------------------------------------------------------------------------- /toy/tooltip.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 19 | 20 |
21 | 71 | 72 | -------------------------------------------------------------------------------- /get_se_drug.php: -------------------------------------------------------------------------------- 1 | connect_error) { 21 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 22 | } 23 | 24 | $query = "SELECT drug_id,p_val FROM prediction INNER JOIN side_effects ON prediction.se_id = side_effects.id WHERE umls_id='$umls_id' AND p_val>$probability"; 25 | $drugs = query_mysql($query, $conn); // drug_id and pvals 26 | 27 | // get drug associated with this SE in SIDER 28 | $query = "SELECT drug_id FROM sider_connections INNER JOIN side_effects ON sider_connections.se_id = side_effects.id WHERE umls_id='$umls_id'"; 29 | $known_drugs = query_mysql($query, $conn); 30 | 31 | $known_drug_ids = array(); 32 | foreach ($known_drugs as $key => $line) { 33 | $id = $line['drug_id']; 34 | array_push($known_drug_ids, $id); 35 | } 36 | 37 | $arr_out = array(); 38 | for ($i=0; $i < count($drugs); $i++) { 39 | $drug_id = $drugs[$i]['drug_id']; 40 | $write_this = True; // whether to write this drug out 41 | 42 | if (in_array($drug_id, $known_drug_ids) && $filter) { 43 | $write_this = False; 44 | } 45 | 46 | if ($write_this) { 47 | $query = "SELECT pert_id,pert_iname FROM drugs_lincs WHERE id='$drug_id'";//to get names of pert_ids 48 | $drug_meta = query_mysql($query, $conn); 49 | $arr_out[$i]['name'] = $drug_meta[0]['pert_iname']; 50 | $arr_out[$i]['pert_id'] = $drug_meta[0]['pert_id']; 51 | $p_val = $drugs[$i]['p_val']; 52 | $arr_out[$i]['p_val'] = sprintf('%0.2f', $p_val); 53 | if (!$filter) { 54 | if (in_array($drug_id, $known_drug_ids)) { 55 | $arr_out[$i]['sider'] = 'yes'; 56 | } else { 57 | $arr_out[$i]['sider'] = 'no'; 58 | } 59 | } 60 | } 61 | } 62 | 63 | $conn->close(); 64 | 65 | $json = json_encode($arr_out); 66 | header('Content-Type: application/json'); 67 | header('Content-Length: '.strlen($json)); 68 | echo $json; 69 | ?> -------------------------------------------------------------------------------- /get_se_drug_top.php: -------------------------------------------------------------------------------- 1 | connect_error) { 21 |   trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR); 22 | } 23 | 24 | // get drug associated with this SE in SIDER 25 | $query = "SELECT drug_id FROM sider_connections INNER JOIN side_effects ON sider_connections.se_id = side_effects.id WHERE umls_id='$umls_id'"; 26 | $known_drugs = query_mysql($query, $conn); 27 | 28 | if ($filter) { // want to reach topn after filtering out known drugs 29 | $topn = count($known_drugs) + $topn; 30 | } 31 | 32 | $query = "SELECT drug_id,p_val FROM prediction INNER JOIN side_effects ON prediction.se_id = side_effects.id WHERE umls_id='$umls_id' ORDER BY p_val DESC LIMIT $topn"; 33 | $drugs = query_mysql($query, $conn); // drug_id and pvals 34 | 35 | 36 | $known_drug_ids = array(); 37 | foreach ($known_drugs as $key => $line) { 38 | $id = $line['drug_id']; 39 | array_push($known_drug_ids, $id); 40 | } 41 | 42 | $arr_out = array(); 43 | for ($i=0; $i < count($drugs); $i++) { 44 | $drug_id = $drugs[$i]['drug_id']; 45 | $write_this = True; // whether to write this drug out 46 | 47 | if (in_array($drug_id, $known_drug_ids) && $filter) { 48 | $write_this = False; 49 | } 50 | 51 | if ($write_this) { 52 | $query = "SELECT pert_id,pert_iname FROM drugs_lincs WHERE id='$drug_id'";//to get names of pert_ids 53 | $drug_meta = query_mysql($query, $conn); 54 | $arr_out[$i]['name'] = $drug_meta[0]['pert_iname']; 55 | $arr_out[$i]['pert_id'] = $drug_meta[0]['pert_id']; 56 | $p_val = $drugs[$i]['p_val']; 57 | $arr_out[$i]['p_val'] = sprintf('%0.2f', $p_val); 58 | if (!$filter) { 59 | if (in_array($drug_id, $known_drug_ids)) { 60 | $arr_out[$i]['sider'] = 'yes'; 61 | } else { 62 | $arr_out[$i]['sider'] = 'no'; 63 | } 64 | } 65 | } 66 | } 67 | 68 | $conn->close(); 69 | 70 | $json = json_encode($arr_out); 71 | header('Content-Type: application/json'); 72 | header('Content-Length: '.strlen($json)); 73 | echo $json; 74 | 75 | ?> 76 | -------------------------------------------------------------------------------- /toy/nav.html: -------------------------------------------------------------------------------- 1 | 44 | -------------------------------------------------------------------------------- /links.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 6 | 10 |
11 | 12 |
13 | 16 | 21 |
22 | 23 | 35 | 36 |
37 | 40 | 44 |
45 | 46 |
47 | 50 | 54 |
55 |
56 | 59 |

Please contact Avi Ma’ayan and Zichen Wang for comments, suggestions, and support:

60 |

avi.maayan@mssm.edu

61 |

zichen.wang@mssm.edu

62 |
63 |
64 | -------------------------------------------------------------------------------- /js/router.js: -------------------------------------------------------------------------------- 1 | var removeActive = function(){ 2 | $("ul.navbar-nav").children().each(function() { 3 | $(this).removeClass('active'); 4 | }); 5 | }; 6 | 7 | var hideTour = function(){ // to hide 8 | $('.tourist-popover').css('display', 'none'); 9 | }; 10 | 11 | var Router = Backbone.Router.extend({ 12 | 13 | el: "#page-content", // selector to load page content 14 | 15 | routes: { 16 | '': 'home', 17 | 'browseDrugs': 'browseDrugs', 18 | 'browseSEs': 'browseSEs', 19 | 'about': 'about', 20 | 'links': 'links', 21 | 'drug/:id': 'drug', 22 | 'se/:id': 'se', 23 | 'search/:searchStr': 'search', 24 | 'network/:name': 'network', 25 | 'download': 'download' 26 | }, 27 | 28 | home: function(){ 29 | $(this.el).load("home.html", function() { 30 | removeActive(); 31 | $("#home").addClass("active"); 32 | }); 33 | }, 34 | 35 | browseDrugs: function(){ 36 | $(this.el).load("browse_drug.html", function() { 37 | hideTour(); 38 | removeActive(); 39 | $("#browse").addClass('active'); 40 | 41 | }); 42 | }, 43 | 44 | browseSEs: function(){ 45 | $(this.el).load("browse_se.html", function() { 46 | hideTour(); 47 | removeActive(); 48 | $("#browse").addClass('active'); 49 | }); 50 | }, 51 | 52 | about: function(){ 53 | $(this.el).load("about.html", function() { 54 | hideTour(); 55 | removeActive(); 56 | $("#about").addClass('active'); 57 | }); 58 | }, 59 | 60 | links: function(){ 61 | $(this.el).load("links.html", function() { 62 | hideTour(); 63 | removeActive(); 64 | $("#links").addClass('active'); 65 | }); 66 | }, 67 | 68 | drug: function(id){ 69 | $(this.el).load("drug_profile.html", function() { 70 | hideTour(); 71 | removeActive(); 72 | $("#browse").addClass('active'); 73 | }); 74 | }, 75 | 76 | se: function(id){ 77 | $(this.el).load("se_profile.html", function() { 78 | hideTour(); 79 | removeActive(); 80 | $("#browse").addClass('active'); 81 | }); 82 | }, 83 | 84 | search: function(searchStr){ 85 | hideTour(); 86 | $(this.el).load("search.html", function() { 87 | }); 88 | }, 89 | 90 | network: function(name){ 91 | if (name === 'GO'){ 92 | window.jsonFileName = 'data/GO_ADR_network.json'; 93 | } 94 | if (name === 'phenotype') { 95 | window.jsonFileName = 'data/pheno_ADR_network.json' 96 | } 97 | 98 | $(this.el).load("network.html", function() { 99 | hideTour(); 100 | removeActive(); 101 | $("#network").addClass('active'); 102 | }); 103 | }, 104 | 105 | download: function(){ 106 | $(this.el).load("download.html", function() { 107 | hideTour(); 108 | removeActive(); 109 | $("#download").addClass('active'); 110 | }); 111 | } 112 | 113 | }); 114 | 115 | var appRouter = new Router(); 116 | Backbone.history.start(); 117 | 118 | 119 | -------------------------------------------------------------------------------- /css/simple-sidebar.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Start Bootstrap - Simple Sidebar HTML Template (http://startbootstrap.com) 3 | * Code licensed under the Apache License v2.0. 4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0. 5 | source: 6 | https://github.com/IronSummitMedia/startbootstrap-simple-sidebar/blob/gh-pages/css/simple-sidebar.css 7 | */ 8 | 9 | /* Toggle Styles */ 10 | 11 | #wrapper { 12 | padding-left: 0; 13 | -webkit-transition: all 0.5s ease; 14 | -moz-transition: all 0.5s ease; 15 | -o-transition: all 0.5s ease; 16 | transition: all 0.5s ease; 17 | } 18 | 19 | #wrapper.toggled { 20 | padding-left: 350px; 21 | } 22 | 23 | #sidebar-wrapper { 24 | z-index: 1000; 25 | position: fixed; 26 | left: 350px; 27 | width: 0; 28 | height: 100%; 29 | margin-left: -350px; 30 | overflow-y: auto; 31 | /*background: #000;*/ 32 | -webkit-transition: all 0.5s ease; 33 | -moz-transition: all 0.5s ease; 34 | -o-transition: all 0.5s ease; 35 | transition: all 0.5s ease; 36 | } 37 | 38 | #wrapper.toggled #sidebar-wrapper { 39 | width: 350px; 40 | } 41 | 42 | #page-content-wrapper { 43 | width: 100%; 44 | position: absolute; 45 | padding: 15px; 46 | } 47 | 48 | #wrapper.toggled #page-content-wrapper { 49 | position: absolute; 50 | margin-right: -350px; 51 | } 52 | 53 | /* Sidebar Styles */ 54 | 55 | .sidebar-nav { 56 | position: absolute; 57 | top: 0; 58 | width: 350px; 59 | margin: 0; 60 | padding: 0; 61 | list-style: none; 62 | } 63 | 64 | .sidebar-nav li { 65 | text-indent: 20px; 66 | line-height: 40px; 67 | } 68 | 69 | .sidebar-nav li a { 70 | display: block; 71 | text-decoration: none; 72 | color: #999999; 73 | } 74 | 75 | .sidebar-nav li a:hover { 76 | text-decoration: none; 77 | color: #fff; 78 | background: rgba(255,255,255,0.2); 79 | } 80 | 81 | .sidebar-nav li a:active, 82 | .sidebar-nav li a:focus { 83 | text-decoration: none; 84 | } 85 | 86 | .sidebar-nav > .sidebar-brand { 87 | height: 65px; 88 | font-size: 18px; 89 | line-height: 60px; 90 | } 91 | 92 | .sidebar-nav > .sidebar-brand a { 93 | color: #999999; 94 | } 95 | 96 | .sidebar-nav > .sidebar-brand a:hover { 97 | color: #fff; 98 | background: none; 99 | } 100 | 101 | @media(min-width:768px) { 102 | #wrapper { 103 | padding-left: 350px; 104 | } 105 | 106 | #wrapper.toggled { 107 | padding-left: 0; 108 | } 109 | 110 | #sidebar-wrapper { 111 | width: 350px; 112 | } 113 | 114 | #wrapper.toggled #sidebar-wrapper { 115 | width: 0; 116 | } 117 | 118 | #page-content-wrapper { 119 | padding: 20px; 120 | position: relative; 121 | } 122 | 123 | #wrapper.toggled #page-content-wrapper { 124 | position: relative; 125 | margin-right: 0; 126 | } 127 | } -------------------------------------------------------------------------------- /js/SelectionPanel.js: -------------------------------------------------------------------------------- 1 | 2 | $('#selectionPanel').tooltip({ 3 | items: "[pathways]", 4 | content: function(){ 5 | var element = $(this); 6 | cc = element; 7 | if( element.is("[pathways]")){ 8 | return element.attr('pathways'); 9 | } 10 | }, 11 | hide:{ 12 | delay: 5, 13 | }, 14 | tooltipClass:"custom-ui-tooltip", 15 | // position:{ 16 | // my:"left bottom", 17 | // } 18 | }); 19 | 20 | 21 | var x; 22 | var SelectionPanel = Backbone.View.extend({ 23 | 24 | initialize: function(){ 25 | this.$el = $("#selectionPanel"); 26 | }, 27 | 28 | addBar:function(event){ 29 | // event is an object with "term" key, "autoCompleteOptions" key and 30 | // "highlights" key triggered in highlightSearchTerm function in 31 | // appPathway 32 | var selectionBar = new SelectionBar(event); 33 | this.$el.append(selectionBar.$el); 34 | this.trigger('selectionBarAppended',selectionBar); 35 | x = selectionBar; 36 | 37 | }, 38 | 39 | removeBar:function(event){ 40 | this.$el.remove() 41 | } 42 | 43 | }); 44 | 45 | 46 | var SelectionBar = Backbone.View.extend({ 47 | 48 | events:{ 49 | "click div.destroy" : "destroy", 50 | }, 51 | 52 | initialize:function(options){ 53 | // The options here passed parameter object 54 | this.term = options.term; 55 | options.trimmedTerm = this.trimTerm(options.term); 56 | // this.$el = $(_.template($('#selectionBar-template').html(),options)); 57 | this.el = this.$el[0]; 58 | this.highlights = options.highlights; 59 | 60 | }, 61 | 62 | destroy:function(){ 63 | console.log(this.highlights); 64 | _.each(this.highlights,function(highlight){ 65 | highlight.remove(); 66 | }); 67 | 68 | this.$el.remove(); 69 | }, 70 | 71 | trimTerm: function(term){ 72 | if(term.length>22) 73 | return term.slice(0,20) + '...'; 74 | else 75 | return term; 76 | }, 77 | 78 | absolutePosition:function(){ 79 | //reference webpage: 80 | //http://www.quirksmode.org/js/findpos.html 81 | 82 | //This function is for colorpick coordinates. 83 | 84 | var obj = this.el; 85 | var curleft = curtop = 0; 86 | if (obj.offsetParent) { 87 | do { 88 | curleft += obj.offsetLeft; 89 | curtop += obj.offsetTop; 90 | } while (obj = obj.offsetParent); 91 | return [curleft,curtop,this.$el.height()]; 92 | } 93 | }, 94 | 95 | }); 96 | 97 | 98 | 99 | 100 | // //test script !!!!!! 101 | // var test = new Test({term:'xx',autoCompleteOptions:['a','b','c']}); 102 | // $('body').append(test.$el); 103 | 104 | // var Test2 = Backbone.View.extend({ 105 | // id:'ff', 106 | // events:{ 107 | // "click" : "destroy", 108 | // }, 109 | 110 | // initialize:function(){ 111 | 112 | // this.$el.text('height'); 113 | // }, 114 | 115 | // destroy:function(){ 116 | // console.log('haha'); 117 | // console.log(this); 118 | // }, 119 | // }); 120 | // var test2 = new Test2; 121 | // $('body').append(test2.$el); 122 | 123 | // $ -------------------------------------------------------------------------------- /data/download_data.json: -------------------------------------------------------------------------------- 1 | [{"short_name":"FAERS","Name":"FAERS_offsides_PTs.csv.gz","Description":"Processed drug side effects data from FDA Adverse Event Report System (FAERS)<\/a> using Propensity Score Matching (PSM) based methods to correct for unknown or unmeasured covariates in the spontaneous reporting systems.","Rows":684,"Columns":9405,"Size(MB)":"0.4","md5":"268eeaa12dcbbc26f83435cbbf9bbcd6","Source":"https:\/\/www.pharmgkb.org\/downloads\/","Reference":"22422992","path":"downloads\/FAERS_offsides_PTs.csv.gz"},{"short_name":"GO","Name":"GO_transformed_signatures_PAEA.csv.gz","Description":"Gene Ontology (GO) transformed gene expression profiles of drug\/small molecule compound perturbations. Principal Angel Enrichment Analysis (PAEA)<\/a> was used to compute enrichment p-values for each CD signature in the space of all genes against gene sets created from the Gene Ontology including Biological Processes, Cellular Components and Molecular Function.","Rows":20338,"Columns":4439,"Size(MB)":"219.9","md5":"5bef6ddc06a3d0df15cf98fa04cc3f94","Source":null,"Reference":null,"path":"downloads\/GO_transformed_signatures_PAEA.csv.gz"},{"short_name":"LINCS","Name":"LINCS_Gene_Experssion_signatures_CD.csv.gz","Description":"Gene expression signatures for drugs\/small molecule compounds in the landmark gene space. The Characteristic Direction (CD)<\/a> method was used to compute gene expression signatures.","Rows":20339,"Columns":979,"Size(MB)":"38.6","md5":"539b34a82e2cb8244f925fc28ab098fa","Source":"http:\/\/www.lincscloud.org\/l1000\/","Reference":null,"path":"downloads\/LINCS_Gene_Experssion_signatures_CD.csv.gz"},{"short_name":"MACCS","Name":"MACCS_bitmatrix.csv.gz","Description":"166-bit MACCS chemical fingerprint matrix for drugs\/small molecule compounds computed using Open Babel<\/a>.","Rows":41774,"Columns":167,"Size(MB)":"1.2","md5":"e5281f6bcb9143a8e93717a5cf7c8475","Source":"http:\/\/api.lincscloud.org\/a2\/docs\/pertinfo","Reference":null,"path":"downloads\/MACCS_bitmatrix.csv.gz"},{"short_name":"MLPCN","Name":"MLPCN_morplological_profiles.csv.gz","Description":"Drug\/small molecule compound induced cell morphological profiles.","Rows":19864,"Columns":813,"Size(MB)":"52.9","md5":"3f6aebf4806798fac034e3952ef185e0","Source":"https:\/\/www.broadinstitute.org\/scientific-community\/science\/programs\/csoft\/therapeutics-platform\/mlpcn\/accessing-mlpcn-data","Reference":"24710340","path":"downloads\/MLPCN_morplological_profiles.csv.gz"},{"short_name":"SIDER","Name":"SIDER_PTs.csv.gz","Description":"Drug-ADR connections mined from drug package inserts from SIDER.","Rows":834,"Columns":3166,"Size(MB)":"0.2","md5":"c69e1438423faeae20e2e7d7ef383ed0","Source":"ftp:\/\/xi.embl.de\/SIDER\/2012-10-17\/","Reference":"20087340","path":"downloads\/SIDER_PTs.csv.gz"}] -------------------------------------------------------------------------------- /home.html: -------------------------------------------------------------------------------- 1 | 2 | 51 | 52 | 53 | 54 | 55 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 94 | -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | @media (min-width: 979px) { 2 | ul.nav li.dropdown:hover > ul.dropdown-menu { 3 | display: block; 4 | } 5 | } 6 | 7 | html, 8 | body { 9 | height: 100%; 10 | } 11 | 12 | #body{ 13 | overflow:hidden; 14 | margin:0; 15 | } 16 | 17 | #page-content { 18 | min-height: 100%; 19 | height: auto; 20 | /* Negative indent footer by its height */ 21 | margin: 0 auto -200px; 22 | /* Pad bottom by footer height */ 23 | padding: 0 0 200px; 24 | } 25 | 26 | #sidebar-wrapper { 27 | z-index: 10; 28 | width: 350px; 29 | position: absolute; 30 | top: 0; 31 | right: 0; 32 | background-color: #fff; 33 | font-size: 12px; 34 | } 35 | 36 | #sidebar-wrapper .panel-heading{ 37 | cursor: move; 38 | } 39 | 40 | .table-condensed { 41 | font-size: 10px; 42 | } 43 | 44 | #wrap { 45 | position: relative; 46 | margin-left: auto; 47 | margin-right: auto; } 48 | 49 | .overlay { 50 | fill: none; 51 | pointer-events: all; } 52 | 53 | text { 54 | cursor: default; } 55 | 56 | .highlight-legend { 57 | border-style: solid; 58 | border-color: black; 59 | } 60 | 61 | .highlight circle { 62 | stroke: black; 63 | stroke-width: 2; 64 | } 65 | 66 | #searchBox { 67 | border-color: #000; 68 | border-width: 2px; 69 | text-align: center; 70 | padding-bottom: 4px; 71 | border-style: solid; 72 | margin-bottom: 2px; 73 | margin-top: 2px; 74 | } 75 | 76 | #below { 77 | margin-top: 10px; } 78 | 79 | #selectionPanel { 80 | text-align: left; 81 | font-size: 0; } 82 | 83 | .selectionBar { 84 | background-color: #49b0c9; 85 | height: 18px; 86 | width: 151.2px; 87 | display: inline-block; 88 | text-align: left; 89 | font-size: 0px; } 90 | 91 | .selectionBarText { 92 | width: 136.2px; 93 | height: 18px; 94 | display: inline-block; 95 | text-align: center; 96 | font-size: 15px; 97 | cursor: default; } 98 | 99 | .destroy { 100 | position: relative; 101 | top: 2px; 102 | display: none; 103 | cursor: pointer; 104 | width: 13px; 105 | height: 13px; 106 | background: url(img/destroy.png) no-repeat; 107 | background-size: 100%; } 108 | 109 | .selectionBar:hover .destroy { 110 | display: inline-block; } 111 | 112 | .destroy:hover { 113 | background-position: 0 -13px; } 114 | 115 | .tooltipSpan { 116 | margin: 0; 117 | font-style: bold; 118 | color: white; } 119 | 120 | .tooltipUl { 121 | margin: 0; 122 | font-size: 0.6em; 123 | text-align: left; 124 | padding-left: 1.5em; 125 | color: white; } 126 | 127 | #colorPickerButton { 128 | position: absolute; 129 | top: 121; 130 | left: 187.5; 131 | width: 50; 132 | display: none; } 133 | 134 | #footer { 135 | background: #222222; 136 | border-top: 1px solid #222222; 137 | height: 200px; 138 | margin-top: 20px; 139 | padding: 20px 0 30px 0; 140 | } 141 | #footer h4 { 142 | color: #fff; 143 | } 144 | 145 | #footer ul { 146 | list-style-type: none; 147 | padding: 0; 148 | } 149 | 150 | #footer a, 151 | #footer p { 152 | color: #ddd; 153 | } 154 | #footer a:hover { 155 | color: #008cba; 156 | text-decoration: none; 157 | } 158 | #footer p { 159 | line-height: 120%; 160 | } 161 | #footer img { 162 | height: 30px; 163 | margin: 0 5px; 164 | } 165 | 166 | .d3-tooltip{ background-color: #eee; 167 | margin: 10px; 168 | padding: 10px; 169 | opacity: 1; 170 | } 171 | 172 | figure { 173 | display:inline-block; 174 | margin:10px; 175 | vertical-align:top; 176 | text-align: center ; 177 | } 178 | -------------------------------------------------------------------------------- /python/make_gmt.py: -------------------------------------------------------------------------------- 1 | # to make canvas/network of SEs based on predicted drugs 2 | import os, sys 3 | import MySQLdb 4 | import numpy as np 5 | 6 | from os.path import expanduser 7 | 8 | HOME = expanduser("~") 9 | sys.path.append(HOME + '/Documents/bitbucket/maayanlab_utils') 10 | from fileIO import read_df, mysqlTable2dict, write_gmt 11 | 12 | ## get known connections in SIDER 13 | d_umls_perts = {} 14 | conn = MySQLdb.connect(host='localhost',user='root', passwd='',db='maaya0_SEP') 15 | cur = conn.cursor() 16 | query = """SELECT * FROM `%s`""" %'sider_connections' 17 | cur.execute(query) 18 | for row in cur: 19 | pert_id, umls_id = row 20 | umls_id = umls_id.strip() 21 | if umls_id not in d_umls_perts: 22 | d_umls_perts[umls_id] = [pert_id] 23 | else: d_umls_perts[umls_id].append(pert_id) 24 | conn.close() 25 | 26 | d_pt_umls = mysqlTable2dict('sep', 'side_effects', 2, 1) 27 | # d_umls_pt = mysqlTable2dict('sep', 'side_effects', 1, 2) 28 | # for pt, umls in d_pt_umls.items(): 29 | # if umls is None: 30 | # print pt 31 | 32 | # p_vals from the latest prediction 33 | ## get AUC for each side_effect 34 | 35 | 36 | 37 | # aucs = np.loadtxt('D:/Zichen_Projects/drug_se_prediction/training_set_no_mfc/PTs/ExtraTrees100_RLogit_GO + MACCS_per-label_AUC_n794x1053.txt').mean(axis=1) 38 | aucs = np.loadtxt(HOME + '/Documents/Zichen_Projects/drug_se_prediction/ET100_balanced_BRLogit2_auto_GO + MACCS_per-label_AUC-S3folds_n794x1053_top_50_features.txt').mean(axis=1) 39 | print len(aucs) 40 | print np.percentile(aucs, 75) 41 | print aucs[aucs > 0.75].shape 42 | 43 | # mat, pert_ids, se_names = read_df('D:/Zichen_Projects/drug_se_prediction/training_set_no_mfc/PTs/PTs_ETs100_proba_df_n20338x1053.txt') 44 | mat, pert_ids, se_names = read_df(HOME + '/Documents/Zichen_Projects/drug_se_prediction/PTs_ET100_proba_df_n20338x1053.txt') 45 | AUC_CUTOFF = 0.78 46 | P_CUTOFF = 0.75 # probability cutoff 47 | print mat.shape 48 | 49 | m = aucs > AUC_CUTOFF 50 | mat = mat[:, m] 51 | se_names = np.array(se_names)[m] 52 | print mat.shape 53 | 54 | ## make gmt file with se as terms and drugs as genes 55 | ses_to_exclude = set() 56 | d_se_drugs = {} 57 | pert_ids = np.array(pert_ids) 58 | for se, p_vals in zip(se_names, mat.T): 59 | mask = p_vals > P_CUTOFF 60 | if mask.sum() > 5000: 61 | print se, mask.sum() 62 | ses_to_exclude.add(se) 63 | else: 64 | drugs = pert_ids[mask] 65 | umls = d_pt_umls[se] 66 | if umls is not None: 67 | # if umls in d_umls_perts: 68 | # known_drugs = d_umls_perts[umls] 69 | # drugs = set(drugs) - set(known_drugs) 70 | # if len(drugs) != 0: 71 | # d_se_drugs[umls] = drugs 72 | d_se_drugs[umls] = drugs 73 | 74 | print len(d_se_drugs) 75 | # for key, val in d_se_drugs.items(): 76 | # print len(val) 77 | # write_gmt(d_se_drugs, HOME+'/Documents/Zichen_Projects/drug_se_prediction/ET100_GOtCS_AUC_%s_proba_%s_prediction_only.gmt' %(AUC_CUTOFF, P_CUTOFF)) 78 | write_gmt(d_se_drugs, HOME+'/Documents/Zichen_Projects/drug_se_prediction/ET100_GOtCS_AUC_%s_proba_%s.gmt' %(AUC_CUTOFF, P_CUTOFF)) 79 | 80 | ## make gmt file with drug as term and se as genes 81 | # d_drug_ses = {} 82 | # for pert_id, p_vals in zip(pert_ids, mat): 83 | # mask = p_vals > P_CUTOFF 84 | # SEs = [d_pt_umls[pt] for pt in se_names[mask] if d_pt_umls[pt] is not None and pt not in ses_to_exclude] 85 | # if len(SEs) != 0: 86 | # d_drug_ses[pert_id] = SEs 87 | 88 | # write_gmt(d_drug_ses, HOME+'/Documents/N2C/Sets2Networks/ET100_GOtCS_AUC_%s_proba_%s.gmt' %(AUC_CUTOFF, P_CUTOFF)) 89 | 90 | 91 | -------------------------------------------------------------------------------- /python/add_data_into_db.py: -------------------------------------------------------------------------------- 1 | # to transfer data from the old database `maaya0_SEP` to the new one `sep` 2 | from orm import * 3 | 4 | import os, sys 5 | import MySQLdb 6 | import numpy as np 7 | import cPickle as pickle 8 | 9 | from os.path import expanduser 10 | 11 | HOME = expanduser("~") 12 | sys.path.append(HOME + '/Documents/bitbucket/maayanlab_utils') 13 | from fileIO import read_df, mysqlTable2dict 14 | 15 | 16 | def _strip_string(s): 17 | if type(s) == str: 18 | if s == 'NULL': 19 | return None 20 | else: 21 | return s.strip() 22 | else: 23 | return s 24 | 25 | 26 | def transfer_table(table_name, model, session): 27 | conn = MySQLdb.connect(host='localhost',user='root', passwd='',db='maaya0_SEP') 28 | cur = conn.cursor() 29 | query = """SELECT * FROM `%s`""" %table_name 30 | cur.execute(query) 31 | num_fields = len(cur.description) 32 | field_names = [i[0] for i in cur.description] 33 | 34 | for row in cur: 35 | row = map(_strip_string, row) 36 | kwargs = dict(zip(field_names, row)) 37 | instance = get_or_create(session, model, **kwargs) 38 | return 39 | 40 | ## transfer drug tables 41 | transfer_table('drugs_lincs', DrugLINCS, session) 42 | transfer_table('drugs_drugbank', DrugDrugbank, session) 43 | transfer_table('drugs_stitch', DrugStitch, session) 44 | 45 | 46 | # p_vals from the latest prediction 47 | ## get AUC for each side_effect 48 | 49 | # aucs = np.loadtxt(HOME + '/Documents/Zichen_Projects/drug_se_prediction/ExtraTrees100_RLogit_GO + MACCS_per-label_AUC_n794x1053.txt').mean(axis=1) 50 | aucs = np.loadtxt(HOME + '/Documents/Zichen_Projects/drug_se_prediction/ET100_balanced_BRLogit2_auto_GO + MACCS_per-label_AUC-S3folds_n794x1053_top_50_features.txt').mean(axis=1) 51 | print len(aucs) 52 | print np.percentile(aucs, 75) 53 | print aucs[aucs > 0.7].shape 54 | 55 | mat, pert_ids, se_names = read_df(HOME + '/Documents/Zichen_Projects/drug_se_prediction/PTs_RF1000_proba_df_n20338x1053.txt') 56 | print mat.shape 57 | se_names = np.array(se_names) 58 | 59 | d_se_auc = dict(zip(se_names, aucs)) 60 | d_umls_soc = pickle.load(open(HOME+'/Documents/Zichen_Projects/drug_se_prediction/d_umls_soc.p', 'rb')) 61 | d_soc_color = pickle.load(open(HOME+'/Documents/Zichen_Projects/drug_se_prediction/d_soc_color.p', 'rb')) 62 | 63 | ## add soc table from d_soc_color 64 | for soc, color in d_soc_color.items(): 65 | instance = get_or_create(session, SOC, name=soc, color=color) 66 | 67 | ## transfer side_effects and add AUROC 68 | conn = MySQLdb.connect(host='localhost',user='root', passwd='',db='maaya0_SEP') 69 | cur = conn.cursor() 70 | query = """SELECT * FROM `%s`""" %'side_effects' 71 | cur.execute(query) 72 | num_fields = len(cur.description) 73 | field_names = [i[0] for i in cur.description] 74 | 75 | for row in cur: 76 | row = map(_strip_string, row) 77 | kwargs = dict(zip(field_names, row)) 78 | if kwargs['name'] in d_se_auc: 79 | kwargs['auroc'] = d_se_auc[kwargs['name']] 80 | else: 81 | kwargs['auroc'] = None 82 | if kwargs['umls_id'] in d_umls_soc: 83 | kwargs['soc'] = d_umls_soc[kwargs['umls_id']] 84 | else: 85 | kwargs['soc'] = None 86 | instance = get_or_create(session, SideEffect, **kwargs) 87 | 88 | 89 | for pvals, pert_id in zip(mat, pert_ids): 90 | mask = pvals > 0.5 91 | se_names_pos = se_names[mask].tolist() 92 | aucs_pos = aucs[mask].tolist() 93 | pvals_pos = pvals[mask].tolist() 94 | add_predictions(se_names_pos, aucs_pos, pert_id, pvals_pos, session) 95 | 96 | 97 | 98 | ## transfer association tables 99 | # sider_connections 100 | d_pert_ids = mysqlTable2dict('maaya0_SEP', 'drugs_lincs', 0, 1) 101 | d_umls_id = mysqlTable2dict('maaya0_SEP', 'side_effects', 0, 1) 102 | 103 | conn = MySQLdb.connect(host='localhost',user='root', passwd='',db='maaya0_SEP') 104 | cur = conn.cursor() 105 | query = """SELECT * FROM `%s`""" %'sider_connections' 106 | cur.execute(query) 107 | d_pert_umls_ids = {} 108 | for row in cur: 109 | pert_id, umls_id = row 110 | if pert_id in d_pert_ids and umls_id in d_umls_id: 111 | if pert_id not in d_pert_umls_ids: 112 | d_pert_umls_ids[pert_id] = [umls_id] 113 | else: 114 | if umls_id not in d_pert_umls_ids[pert_id]: 115 | d_pert_umls_ids[pert_id].append(umls_id) 116 | conn.close() 117 | 118 | print len(d_pert_umls_ids) 119 | for pert_id, se_ids in d_pert_umls_ids.items(): 120 | add_associations(se_ids, pert_id, session) 121 | 122 | 123 | -------------------------------------------------------------------------------- /js/tour.js: -------------------------------------------------------------------------------- 1 | function initTour() { 2 | var steps = [ 3 | { 4 | content: [ 5 | '
The color legend
', 6 | '

Side effects are colored by their System Organ Class in MedDRA

', 7 | '

Click a legend to highlight all the corresponding side effects that belong to a class of side effects.

' 8 | ].join(''), 9 | highlightTarget: true, 10 | nextButton: true, 11 | closeButton: true, 12 | target: $('#colorLegend'), 13 | my: 'top left', 14 | at: 'bottom center', 15 | }, 16 | { 17 | content: [ 18 | '

Side effects in the bubble chart can be searched by name

', 19 | '

For example, type "Dysuria"

', 20 | '

Once searched, the dot representing the side effect will be centered.

' 21 | ].join(''), 22 | highlightTarget: true, 23 | nextButton: false, 24 | closeButton: true, 25 | target: $('#searchBox'), 26 | my: 'top center', 27 | at: 'bottom center', 28 | // only allow to continue after user typed a term 29 | setup: function(tour, options){ 30 | options.searchView.bind('searchTermSelected', this.myEvent); 31 | }, 32 | bind: ['myEvent'], 33 | teardown: function(tour, options){ 34 | options.searchView.unbind('searchTermSelected', this.myEvent) 35 | }, 36 | myEvent: function(tour, options, view){ 37 | tour.next(); 38 | } 39 | }, 40 | { 41 | content: [ 42 | '
Side effect information panel
', 43 | '

Drugs that are known/predicted to cause the selected side effect is displayed here.

', 44 | '

This panel can also be dragged around and minmized

' 45 | ].join(''), 46 | highlightTarget: true, 47 | nextButton: true, 48 | closeButton: true, 49 | target: $('#sidebar-wrapper'), 50 | my: 'bottom center', 51 | at: 'top center', 52 | setup: function(){ 53 | $(".panel-body").slideDown(250); 54 | } 55 | }, 56 | { 57 | content: [ 58 | '

Drugs and side effects are hyperlinked to their profile page for more information

' 59 | ].join(''), 60 | highlightTarget: true, 61 | nextButton: true, 62 | closeButton: true, 63 | target: $('#nodeInfo'), 64 | my: 'bottom center', 65 | at: 'top center', 66 | setup: function(){ 67 | $(".panel-body").slideDown(250); 68 | } 69 | }, 70 | { 71 | content: [ 72 | '
Side effect bubble chart
', 73 | '

You can also explore side effects by zooming and panning in this bubble chart. And display the information of side effects by clicking them.

' 74 | ].join(''), 75 | highlightTarget: true, 76 | nextButton: false, 77 | closeButton: true, 78 | target: $('#stage'), 79 | my: 'bottom center', 80 | at: 'top center', 81 | setup: function(tour, options){ 82 | options.graphView.bind('dotClicked', this.myEvent); 83 | }, 84 | bind: ['myEvent'], 85 | teardown: function(tour, options){ 86 | options.graphView.unbind('dotClicked', this.myEvent) 87 | }, 88 | myEvent: function(tour, options, view){ 89 | tour.next(); 90 | } 91 | }, 92 | { 93 | content: [ 94 | '

Drug and side effect profiles that are available on the site can be searched using this search box.

', 95 | '

For example, search "ibuprofen", or "Hepatitis".

' 96 | ].join(''), 97 | highlightTarget: true, 98 | nextButton: true, 99 | closeButton: true, 100 | target: $('.form-group'), 101 | my: 'top center', 102 | at: 'bottom center' 103 | } 104 | ]; 105 | 106 | tour = new Tourist.Tour({ 107 | steps: steps, 108 | tipClass: 'Bootstrap', 109 | tipOptions:{ showEffect: 'slidein' }, 110 | stepOptions: { 111 | searchView: searchView, 112 | graphView: graphView, 113 | } 114 | }); 115 | tour.start(); 116 | } 117 | 118 | $(document).ready(function() { 119 | $("#tour").click(function(){ 120 | window.setTimeout(initTour, 500); 121 | // $(".icon-remove").removeClass("icon icon-remove").addClass("glyphicon glyphicon-remove") 122 | }) 123 | }) -------------------------------------------------------------------------------- /js/jquery.highlight.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Highlight plugin 3 | * 4 | * Based on highlight v3 by Johann Burkard 5 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html 6 | * 7 | * Code a little bit refactored and cleaned (in my humble opinion). 8 | * Most important changes: 9 | * - has an option to highlight only entire words (wordsOnly - false by default), 10 | * - has an option to be case sensitive (caseSensitive - false by default) 11 | * - highlight element tag and class names can be specified in options 12 | * 13 | * Usage: 14 | * // wrap every occurrance of text 'lorem' in content 15 | * // with (default options) 16 | * $('#content').highlight('lorem'); 17 | * 18 | * // search for and highlight more terms at once 19 | * // so you can save some time on traversing DOM 20 | * $('#content').highlight(['lorem', 'ipsum']); 21 | * $('#content').highlight('lorem ipsum'); 22 | * 23 | * // search only for entire word 'lorem' 24 | * $('#content').highlight('lorem', { wordsOnly: true }); 25 | * 26 | * // don't ignore case during search of term 'lorem' 27 | * $('#content').highlight('lorem', { caseSensitive: true }); 28 | * 29 | * // wrap every occurrance of term 'ipsum' in content 30 | * // with 31 | * $('#content').highlight('ipsum', { element: 'em', className: 'important' }); 32 | * 33 | * // remove default highlight 34 | * $('#content').unhighlight(); 35 | * 36 | * // remove custom highlight 37 | * $('#content').unhighlight({ element: 'em', className: 'important' }); 38 | * 39 | * 40 | * Copyright (c) 2009 Bartek Szopka 41 | * 42 | * Licensed under MIT license. 43 | * 44 | */ 45 | 46 | jQuery.extend({ 47 | highlight: function (node, re, nodeName, className) { 48 | if (node.nodeType === 3) { 49 | var match = node.data.match(re); 50 | if (match) { 51 | var highlight = document.createElement(nodeName || 'span'); 52 | highlight.className = className || 'highlight'; 53 | var wordNode = node.splitText(match.index); 54 | wordNode.splitText(match[0].length); 55 | var wordClone = wordNode.cloneNode(true); 56 | highlight.appendChild(wordClone); 57 | wordNode.parentNode.replaceChild(highlight, wordNode); 58 | return 1; //skip added node in parent 59 | } 60 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children 61 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes 62 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted 63 | for (var i = 0; i < node.childNodes.length; i++) { 64 | i += jQuery.highlight(node.childNodes[i], re, nodeName, className); 65 | } 66 | } 67 | return 0; 68 | } 69 | }); 70 | 71 | jQuery.fn.unhighlight = function (options) { 72 | var settings = { className: 'highlight', element: 'span' }; 73 | jQuery.extend(settings, options); 74 | 75 | return this.find(settings.element + "." + settings.className).each(function () { 76 | var parent = this.parentNode; 77 | parent.replaceChild(this.firstChild, this); 78 | parent.normalize(); 79 | }).end(); 80 | }; 81 | 82 | jQuery.fn.highlight = function (words, options) { 83 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; 84 | jQuery.extend(settings, options); 85 | 86 | if (words.constructor === String) { 87 | words = [words]; 88 | } 89 | words = jQuery.grep(words, function(word, i){ 90 | return word != ''; 91 | }); 92 | words = jQuery.map(words, function(word, i) { 93 | return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 94 | }); 95 | if (words.length == 0) { return this; }; 96 | 97 | var flag = settings.caseSensitive ? "" : "i"; 98 | var pattern = "(" + words.join("|") + ")"; 99 | if (settings.wordsOnly) { 100 | pattern = "\\b" + pattern + "\\b"; 101 | } 102 | var re = new RegExp(pattern, flag); 103 | 104 | return this.each(function () { 105 | jQuery.highlight(this, re, settings.element, settings.className); 106 | }); 107 | }; 108 | 109 | -------------------------------------------------------------------------------- /se_profile.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 13 |
14 |
15 |
16 |
17 |
18 |
Predicted drugs associated with this side effect
19 |
20 |
21 |
22 |
23 | 89 |
90 | 91 | -------------------------------------------------------------------------------- /python/generate_download_data_meta.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Generate meta-data for data available for download 3 | ''' 4 | import os, sys, json 5 | import gzip 6 | import hashlib 7 | import numpy as np 8 | import pandas as pd 9 | 10 | 11 | fields = ['short_name', 'Name', 'Description', 'Rows', 'Columns', 12 | 'Size(MB)', 'md5', 'Source', 'Reference', 'path'] 13 | 14 | 15 | class DataFile(object): 16 | def __init__(self, fn): 17 | self.name = fn.split('/')[-1] 18 | 19 | self._path = '../downloads/' + fn 20 | self.desc = '' 21 | self.df = pd.read_csv(self._path, compression='gzip') 22 | self.rows, self.columns = self.df.shape 23 | 24 | self.md5 = hashlib.md5(open(self._path, 'rb').read()).hexdigest() 25 | self.size = os.path.getsize(self._path) 26 | self.size = '%.1f' % (self.size / (1024. * 1024)) # size in MB 27 | self.ref = '' 28 | self.source_url = '' 29 | self.path = 'downloads/' + fn 30 | 31 | def to_record(self): 32 | record = { 33 | 'short_name': self.name.split('_')[0], 34 | 'Name': self.name, 35 | 'Description': self.desc, 36 | 'Rows': self.rows, 37 | 'Columns': self.columns, 38 | 'Size(MB)': self.size, 39 | 'md5': self.md5, 40 | 'Source': self.source_url, 41 | 'Reference': self.ref, 42 | 'path': self.path, 43 | } 44 | return record 45 | 46 | 47 | class MetaDataFile(object): 48 | def __init__(self, fn): 49 | self.name = fn.split('/')[-1] 50 | self._path = '../downloads/' + fn 51 | df = pd.read_csv(self._path) 52 | self.fields = df.columns.tolist() 53 | self.rows, self.columns = df.shape 54 | self.md5 = hashlib.md5(open(self._path, 'rb').read()).hexdigest() 55 | self.size = os.path.getsize(self._path) 56 | self.size = '%.1f' % (self.size / (1024. * 1024)) # size in MB 57 | self.path = 'downloads/' + fn 58 | 59 | def to_record(self): 60 | record = { 61 | 'Name': self.name, 62 | 'Fields': self.fields, 63 | 'Rows': self.rows, 64 | 'Columns': self.columns, 65 | 'Size(MB)': self.size, 66 | 'md5': self.md5, 67 | 'path': self.path, 68 | } 69 | return record 70 | 71 | records = [] 72 | for fn in os.listdir('../downloads/'): 73 | if fn.endswith('.gz'): 74 | print fn 75 | d = DataFile(fn) 76 | record = d.to_record() 77 | records.append(record) 78 | 79 | meta_for_data = pd.DataFrame.from_records(records) 80 | meta_for_data = meta_for_data[fields] 81 | meta_for_data = meta_for_data.sort('Name') 82 | 83 | descs = [ 84 | 'Processed drug side effects data from FDA Adverse Event Report System (FAERS) using Propensity Score Matching (PSM) based methods to correct for unknown or unmeasured covariates in the spontaneous reporting systems.', 85 | 'Gene Ontology (GO) transformed gene expression profiles of drug/small molecule compound perturbations. Principal Angel Enrichment Analysis (PAEA) was used to compute enrichment p-values for each CD signature in the space of all genes against gene sets created from the Gene Ontology including Biological Processes, Cellular Components and Molecular Function.', 86 | 'Gene expression signatures for drugs/small molecule compounds in the landmark gene space. The Characteristic Direction (CD) method was used to compute gene expression signatures.', 87 | '166-bit MACCS chemical fingerprint matrix for drugs/small molecule compounds computed using Open Babel.', 88 | 'Drug/small molecule compound induced cell morphological profiles.', 89 | 'Drug-ADR connections mined from drug package inserts from SIDER.', 90 | ] 91 | 92 | urls = [ 93 | 'https://www.pharmgkb.org/downloads/', 94 | None, 95 | 'http://www.lincscloud.org/l1000/', 96 | 'http://api.lincscloud.org/a2/docs/pertinfo', 97 | 'https://www.broadinstitute.org/scientific-community/science/programs/csoft/therapeutics-platform/mlpcn/accessing-mlpcn-data', 98 | 'ftp://xi.embl.de/SIDER/2012-10-17/' 99 | ] 100 | 101 | pmids = [ 102 | '22422992', 103 | None, 104 | None, 105 | None, 106 | '24710340', 107 | '20087340' 108 | ] 109 | 110 | meta_for_data['Description'] = descs 111 | meta_for_data['Source'] = urls 112 | meta_for_data['Reference'] = pmids 113 | 114 | meta_for_data.to_json('../data/download_data.json', orient='records') 115 | 116 | ## get meta for metadata 117 | records = [] 118 | for fn in os.listdir('../downloads/'): 119 | if fn.startswith('meta_'): 120 | print fn 121 | mdf = MetaDataFile(fn) 122 | record = mdf.to_record() 123 | records.append(record) 124 | 125 | json.dump(records, open('../data/download_metadata.json', 'w')) 126 | 127 | -------------------------------------------------------------------------------- /js/functions.js: -------------------------------------------------------------------------------- 1 | function getQueryParams(qs) { 2 | qs = qs.split("+").join(" "); 3 | var params = {}, 4 | tokens, 5 | re = /[?&]?([^=]+)=([^&]*)/g; 6 | while (tokens = re.exec(qs)) { 7 | params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]); 8 | } 9 | return params; 10 | }; 11 | 12 | function obj2Table(obj) { 13 | var table = $('') 14 | $.each(obj, function(key, val){ 15 | var tr = $(''); 16 | var tdKey = $(''); 17 | var tdVal = $(''); 18 | tr.append(tdKey); 19 | tr.append(tdVal); 20 | table.append(tr); 21 | }); 22 | return table; 23 | }; 24 | 25 | function objs2TableRows(objs, keyToAddLink, baseUrl) { 26 | // convert an array of objects to table rows 27 | // and add links 28 | var table = $('') 29 | for (var i = 0; i < objs.length; i++) { 30 | var obj = objs[i]; 31 | var tr = $(''); 32 | $.each(obj, function(key, val){ 33 | var td = $(''); 34 | if (key === keyToAddLink) { 35 | $(td).wrapInner(''); 36 | }; 37 | tr.append(td); 38 | }); 39 | table.append(tr); 40 | }; 41 | return table; 42 | }; 43 | 44 | function objs2TableRowsWithStatus(objs, keyToAddLink, baseUrl, progressBarSelector) { 45 | // convert an array of objects to table rows 46 | // and add links 47 | var table = $(''); 48 | for (var i = 0; i < objs.length; i++) { 49 | var obj = objs[i]; 50 | var tr = $(''); 51 | $.each(obj, function(key, val){ 52 | var td = $(''); 53 | if (key === keyToAddLink) { 54 | $(td).wrapInner(''); 55 | }; 56 | tr.append(td); 57 | }); 58 | var progressValue = i*100/objs.length + '%'; 59 | $(progressBarSelector).css("width", progressValue) 60 | table.append(tr); 61 | }; 62 | return table; 63 | }; 64 | 65 | function addLinks(id, baseUrl){ 66 | $('#' + id + 'td:nth-child(2)').append('Here'); 67 | return; 68 | }; 69 | 70 | function searchAutocomplete(selector){ 71 | $(selector).autocomplete({ 72 | minLength : 4, 73 | source : function(request, response){ 74 | $.getJSON('search.php', request, function(json){ 75 | var outObjs = []; 76 | for (var i = 0; i < json['se'].length; i++) { 77 | var obj = {}; 78 | obj.label = json['se'][i]['umls_id'] + ':' + json['se'][i]['name']; 79 | obj.value = json['se'][i]['name']; 80 | outObjs.push(obj); 81 | }; 82 | for (var i = 0; i < json['drugs'].length; i++) { 83 | var obj = {}; 84 | obj.label = json['drugs'][i]['pert_id'] + ':' + json['drugs'][i]['pert_iname']; 85 | obj.value = json['drugs'][i]['pert_iname']; 86 | outObjs.push(obj); 87 | }; 88 | response(outObjs); 89 | }); 90 | } 91 | }); 92 | }; 93 | 94 | function drawPieChart(json, title, selector){ 95 | // draw interactive piechart with json data using d3pie 96 | var data = []; 97 | var total = 0; 98 | $.each(json, function(key, val){ 99 | data.push({"label": key, "value": val}); 100 | total += val; 101 | }); 102 | var pie = new d3pie(selector, { 103 | "header": { 104 | "title": { 105 | "text": title, 106 | "fontSize": 24, 107 | "font": "open sans" 108 | }, 109 | "subtitle": { 110 | "text": "Total: " + total, 111 | "color": "#999999", 112 | "fontSize": 12, 113 | "font": "open sans" 114 | }, 115 | "titleSubtitlePadding": 9 116 | }, 117 | "footer": { 118 | "color": "#999999", 119 | "fontSize": 10, 120 | "font": "open sans", 121 | "location": "bottom-left" 122 | }, 123 | "size": { 124 | "canvasWidth": 500, 125 | "canvasHeight": 500, 126 | }, 127 | "data": { 128 | "sortOrder": "value-desc", 129 | "content": data, 130 | }, 131 | "labels": { 132 | "outer": { 133 | "format": "label-value1", 134 | "pieDistance": 32 135 | }, 136 | "inner": { 137 | "hideWhenLessThanPercentage": 3 138 | }, 139 | "mainLabel": { 140 | "fontSize": 11 141 | }, 142 | "percentage": { 143 | "color": "#ffffff", 144 | "decimalPlaces": 0 145 | }, 146 | "value": { 147 | "color": "#adadad", 148 | "fontSize": 11 149 | }, 150 | "lines": { 151 | "enabled": true 152 | } 153 | }, 154 | "effects": { 155 | "pullOutSegmentOnClick": { 156 | "effect": "linear", 157 | "speed": 400, 158 | "size": 8 159 | } 160 | }, 161 | "misc": { 162 | "gradient": { 163 | "enabled": true, 164 | "percentage": 100 165 | } 166 | } 167 | }); 168 | }; 169 | -------------------------------------------------------------------------------- /python/orm.py: -------------------------------------------------------------------------------- 1 | # ORMs for the database behind SEP-L1000 2 | from sqlalchemy import create_engine 3 | from sqlalchemy.ext.declarative import declarative_base 4 | from sqlalchemy import ForeignKey, Column, Integer, String, Table, Float, Text, DATETIME 5 | from sqlalchemy.orm import backref, relationship 6 | from sqlalchemy.orm import sessionmaker 7 | 8 | 9 | db_config = 'mysql://root:@localhost/sep' 10 | engine = create_engine(db_config) 11 | Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) 12 | session = Session() 13 | 14 | ## ORMs of the database 15 | Base = declarative_base() 16 | 17 | 18 | class Prediction(Base): 19 | """predicted drug-se connection""" 20 | __tablename__ = 'prediction' 21 | drug_id = Column(Integer, ForeignKey('drugs_lincs.id'), primary_key=True) 22 | se_id = Column(Integer, ForeignKey('side_effects.id'), primary_key=True) 23 | p_val = Column(Float) 24 | side_effect = relationship("SideEffect") 25 | 26 | 27 | class KnownConnection(Base): 28 | """Known drug-se connection from SIDER""" 29 | __tablename__ = 'sider_connections' 30 | drug_id = Column(Integer, ForeignKey('drugs_lincs.id'), primary_key=True) 31 | se_id = Column(Integer, ForeignKey('side_effects.id'), primary_key=True) 32 | known_side_effect = relationship("SideEffect") 33 | 34 | 35 | class DrugLINCS(Base): 36 | __tablename__ = 'drugs_lincs' 37 | 38 | id = Column(Integer, primary_key=True) 39 | pert_id = Column(String(32), unique=True) 40 | alt_name = Column(String(255)) 41 | pert_iname = Column(String(255)) 42 | LSM_id = Column(String(16)) 43 | mls_id = Column(String(16)) 44 | ncgc_id = Column(String(16)) 45 | pert_collection = Column(String(16)) 46 | pert_icollection = Column(String(16)) 47 | pert_summary = Column(Text) 48 | pert_url = Column(Text) 49 | pubchem_cid = Column(String(16)) 50 | canonical_smiles = Column(Text) 51 | inchi_key = Column(Text) 52 | inchi_string = Column(Text) 53 | molecular_formula = Column(Text) 54 | molecular_wt = Column(Float) 55 | structure_url = Column(Text) 56 | 57 | side_effects = relationship('Prediction') 58 | known_side_effects = relationship('KnownConnection') 59 | 60 | def __repr__(self): 61 | return "" % (self.pert_id, self.pert_iname) 62 | 63 | 64 | class SideEffect(Base): 65 | __tablename__ = 'side_effects' 66 | 67 | id = Column(Integer, primary_key=True) 68 | umls_id = Column(String(16), unique=True) 69 | name = Column(String(256)) 70 | synonyms = Column(Text) 71 | auroc = Column(Float) 72 | soc = Column(String(128)) 73 | 74 | def __repr__(self): 75 | return "" % self.name 76 | 77 | 78 | ### below are classes that are not connected to other tables 79 | class SOC(Base): 80 | __tablename__ = 'soc' 81 | id = Column(Integer, primary_key=True) 82 | name = Column(String(128), unique=True) 83 | color = Column(String(8)) 84 | 85 | 86 | class DrugDrugbank(Base): 87 | __tablename__ = 'drugs_drugbank' 88 | 89 | id = Column(Integer, primary_key=True) 90 | drugbank_id = Column(String(32), unique=True) 91 | name = Column(String(64)) 92 | pubchem_cid = Column(String(32)) 93 | pharmgkb_id = Column(String(16)) 94 | 95 | 96 | class DrugStitch(Base): 97 | __tablename__ = 'drugs_stitch' 98 | 99 | id = Column(Integer, primary_key=True) 100 | stitch_id = Column(String(32), unique=True) 101 | name = Column(String(128)) 102 | smile_string = Column(Text) 103 | pubchem_cid = Column(String(32)) 104 | 105 | 106 | Base.metadata.create_all(engine) 107 | 108 | 109 | ## functions to add and retrieve objects 110 | def get_or_create(session, model, **kwargs): 111 | # init a instance if not exists 112 | # http://stackoverflow.com/questions/2546207/does-sqlalchemy-have-an-equivalent-of-djangos-get-or-create 113 | instance = session.query(model).filter_by(**kwargs).first() 114 | if instance: 115 | return instance 116 | else: 117 | instance = model(**kwargs) 118 | session.add(instance) 119 | session.commit() 120 | return instance 121 | 122 | def add_predictions(se_names, aucs, pert_id, coefs, session): 123 | # add predictions into the database 124 | drug = get_or_create(session, DrugLINCS, pert_id=pert_id) 125 | 126 | for coef, se_name, auc in zip(coefs, se_names, aucs): 127 | a = Prediction(p_val=coef) 128 | a.side_effect = get_or_create(session, SideEffect, name=se_name) 129 | if a.side_effect.auroc is None: 130 | a.side_effect.auroc = auc 131 | drug.side_effects.append(a) 132 | try: 133 | session.add(drug) 134 | session.commit() 135 | except Exception as e: 136 | session.rollback() 137 | print e 138 | pass 139 | return 140 | 141 | def add_associations(se_ids, pert_id, session): 142 | # add known associations into the database 143 | drug = get_or_create(session, DrugLINCS, pert_id=pert_id) 144 | 145 | for se_id in se_ids: 146 | a = KnownConnection() 147 | a.known_side_effect = get_or_create(session, SideEffect, umls_id=se_id) 148 | drug.known_side_effects.append(a) 149 | try: 150 | session.add(drug) 151 | session.commit() 152 | except Exception as e: 153 | session.rollback() 154 | print e 155 | pass 156 | return 157 | 158 | -------------------------------------------------------------------------------- /js/dataTables.bootstrap.js: -------------------------------------------------------------------------------- 1 | /*! DataTables Bootstrap integration 2 | * ©2011-2014 SpryMedia Ltd - datatables.net/license 3 | */ 4 | 5 | /** 6 | * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and 7 | * DataTables 1.10 or newer. 8 | * 9 | * This file sets the defaults and adds options to DataTables to style its 10 | * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap 11 | * for further information. 12 | */ 13 | (function(window, document, undefined){ 14 | 15 | var factory = function( $, DataTable ) { 16 | "use strict"; 17 | 18 | 19 | /* Set the defaults for DataTables initialisation */ 20 | $.extend( true, DataTable.defaults, { 21 | dom: 22 | "<'row'<'col-xs-6'l><'col-xs-6'f>r>"+ 23 | "t"+ 24 | "<'row'<'col-xs-6'i><'col-xs-6'p>>", 25 | renderer: 'bootstrap' 26 | } ); 27 | 28 | 29 | /* Default class modification */ 30 | $.extend( DataTable.ext.classes, { 31 | sWrapper: "dataTables_wrapper form-inline dt-bootstrap", 32 | sFilterInput: "form-control input-sm", 33 | sLengthSelect: "form-control input-sm" 34 | } ); 35 | 36 | 37 | /* Bootstrap paging button renderer */ 38 | DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) { 39 | var api = new DataTable.Api( settings ); 40 | var classes = settings.oClasses; 41 | var lang = settings.oLanguage.oPaginate; 42 | var btnDisplay, btnClass; 43 | 44 | var attach = function( container, buttons ) { 45 | var i, ien, node, button; 46 | var clickHandler = function ( e ) { 47 | e.preventDefault(); 48 | if ( e.data.action !== 'ellipsis' ) { 49 | api.page( e.data.action ).draw( false ); 50 | } 51 | }; 52 | 53 | for ( i=0, ien=buttons.length ; i 0 ? 72 | '' : ' disabled'); 73 | break; 74 | 75 | case 'previous': 76 | btnDisplay = lang.sPrevious; 77 | btnClass = button + (page > 0 ? 78 | '' : ' disabled'); 79 | break; 80 | 81 | case 'next': 82 | btnDisplay = lang.sNext; 83 | btnClass = button + (page < pages-1 ? 84 | '' : ' disabled'); 85 | break; 86 | 87 | case 'last': 88 | btnDisplay = lang.sLast; 89 | btnClass = button + (page < pages-1 ? 90 | '' : ' disabled'); 91 | break; 92 | 93 | default: 94 | btnDisplay = button + 1; 95 | btnClass = page === button ? 96 | 'active' : ''; 97 | break; 98 | } 99 | 100 | if ( btnDisplay ) { 101 | node = $('
  • ', { 102 | 'class': classes.sPageButton+' '+btnClass, 103 | 'aria-controls': settings.sTableId, 104 | 'tabindex': settings.iTabIndex, 105 | 'id': idx === 0 && typeof button === 'string' ? 106 | settings.sTableId +'_'+ button : 107 | null 108 | } ) 109 | .append( $('', { 110 | 'href': '#' 111 | } ) 112 | .html( btnDisplay ) 113 | ) 114 | .appendTo( container ); 115 | 116 | settings.oApi._fnBindAction( 117 | node, {action: button}, clickHandler 118 | ); 119 | } 120 | } 121 | } 122 | }; 123 | 124 | attach( 125 | $(host).empty().html('
  • ' + key + '' + val + '
    ' + val + '
    ' + val + '
    ').addClass('table table-striped table-hover table-condensed'); 25 | 26 | var thead = $(''); 27 | var tr = $('') 28 | 29 | $.each(headerLabels,function(i, headerLabel) { 30 | var w = widths[i]; 31 | tr.append(''); 32 | }); 33 | 34 | thead.append(tr) 35 | table.append(thead); 36 | $("#data").append(table); 37 | var columnsDef = [ 38 | { 39 | "data": "Name", 40 | "render": function(data, type, full, meta){ 41 | return ''+data+''; 42 | }, 43 | "className": "left" 44 | }, 45 | { 46 | "data": "Description", 47 | "className": "left" 48 | }, 49 | { "data": "Rows"}, 50 | { "data": "Columns"}, 51 | { "data": "Size(MB)"}, 52 | { 53 | "data": "md5", 54 | "render": function(data, type, full, meta){ 55 | var icon = ''; 56 | return '' + icon + ''; 57 | } 58 | }, 59 | { 60 | "data" : "Source", 61 | "render": function(data, type, full, meta){ 62 | var icon = '' 63 | if (data) { 64 | return ''+icon+''; 65 | }else{ 66 | return icon; 67 | }; 68 | }, 69 | }, 70 | { 71 | "data": "Reference", 72 | "render": function(data, type, full, meta){ 73 | var icon = '' 74 | if (data) { 75 | return ''+icon+''; 76 | }else{ 77 | return icon; 78 | } 79 | }, 80 | } 81 | ]; 82 | 83 | rctable = table.dataTable({ 84 | "data": results, 85 | "columns": columnsDef, 86 | "order": [[0, 'asc']], 87 | "deferRender": true, 88 | "bAutoWidth": false, 89 | "ordering": false, 90 | "fnInitComplete": function(oSettings, json){ //DataTables has finished its initialisation. 91 | $('[data-toggle="tooltip"]').tooltip(); 92 | }, 93 | }); 94 | 95 | }); 96 | 97 | // For metadata 98 | $.getJSON('data/download_metadata.json', function(results){ 99 | var headerLabels = ['Name', 'Fields', 'Rows', 'Columns', 'Size(MB)', 'md5']; 100 | var widths = ["20%", "40%", "10%", "10%", "10%", "10%"]; 101 | 102 | var table = $('
    ' + headerLabel + '
    ').addClass('table table-striped table-hover table-condensed'); 103 | 104 | var thead = $(''); 105 | var tr = $('') 106 | 107 | $.each(headerLabels,function(i, headerLabel) { 108 | var w = widths[i]; 109 | tr.append(''); 110 | }); 111 | 112 | thead.append(tr) 113 | table.append(thead); 114 | $("#metadata").append(table); 115 | var columnsDef = [ 116 | { 117 | "data": "Name", 118 | "render": function(data, type, full, meta){ 119 | return ''+data+''; 120 | }, 121 | "className": "left" 122 | }, 123 | { 124 | "data": "Fields", 125 | "render": function(data, type, full, meta){ 126 | var res = []; 127 | $.each(data, function(i, d){ 128 | res.push( ''+ d +'' ); 129 | }) 130 | return res.join(', ') 131 | }, 132 | "className": "left" 133 | }, 134 | { "data": "Rows", "className": "left"}, 135 | { "data": "Columns", "className": "left"}, 136 | { "data": "Size(MB)", "className": "left"}, 137 | { 138 | "data": "md5", 139 | "render": function(data, type, full, meta){ 140 | var icon = ''; 141 | return '' + icon + ''; 142 | }, 143 | "className": "left" 144 | }, 145 | ]; 146 | 147 | rctable = table.dataTable({ 148 | "data": results, 149 | "columns": columnsDef, 150 | "order": [[0, 'asc']], 151 | "deferRender": true, 152 | "bAutoWidth": false, 153 | "ordering": false, 154 | "fnInitComplete": function(oSettings, json){ //DataTables has finished its initialisation. 155 | $('[data-toggle="tooltip"]').tooltip(); 156 | }, 157 | }); 158 | 159 | }); 160 | -------------------------------------------------------------------------------- /toy/se_canvas.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Prediction of drug side effects 7 | 8 | 9 | 13 | 14 | 15 | 16 |
    17 |
    18 |
    19 |
    20 | 24 |
    25 |
    28 |
    29 |
    30 | 31 |
    32 |
    33 |
    Side Effect Network Visualization on a Canvas
    34 |
    35 | 36 | 46 | 47 |
    48 |

    Loading side-effect canvas

    49 |
    50 |
    51 |
    52 |
    53 |
    54 |
    55 |
    56 |
    Information of the selected tile
    57 |
    58 | Please click a tile on the canvas to display its information
    59 |
    60 |
    61 |
    62 |
    63 | 64 | 65 | 66 | 67 | 68 | 73 | 74 | 75 | 162 | 163 | -------------------------------------------------------------------------------- /css/visualizer5.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | text {font: 10px sans-serif; pointer-events: none;} 5 | 6 | body{ 7 | margin-left:0px; 8 | font-family:Arial; 9 | } 10 | 11 | a.linker{ 12 | text-decoration: none; 13 | } 14 | 15 | a.linker:hover{ 16 | text-decoration:none; 17 | } 18 | 19 | div#topbar{ 20 | position:absolute; 21 | top: 112px; 22 | left:0px; 23 | text-align: center; 24 | width: 1200px; 25 | } 26 | 27 | span.linker{ 28 | /*padding-left: 40px; 29 | padding-right:40px;*/ 30 | width:250px; 31 | display:inline-block; 32 | cursor: pointer; 33 | font-size:11px; 34 | } 35 | 36 | span.linker:hover{ 37 | background-color: #FFF; 38 | font-weight:700; 39 | 40 | } 41 | 42 | 43 | div#externalwrapper{ 44 | width:1000px; 45 | height:825px; 46 | margin-left:200px; 47 | margin-top:30px; 48 | padding:0px; 49 | 50 | } 51 | 52 | div#holdElements{ 53 | width:800px; 54 | height:800px; 55 | border: 1px solid; 56 | font-size:11px; 57 | border-radius:40px; 58 | -moz-border-radius:40px; /*Firefox*/ 59 | } 60 | 61 | div#header{ 62 | width:800px; 63 | height:100px; 64 | background-color:#CCC; 65 | border-radius:40px 40px 0px 0px; 66 | -moz-border-radius:40px 40px 0px 0px; /*Firefox*/ 67 | border-bottom: 1px solid; 68 | 69 | } 70 | 71 | div#footer{ 72 | font-size:11px; 73 | text-align:center; 74 | position:absolute; 75 | left: 200px; 76 | top: 850px; 77 | height: 25px; 78 | width: 800px; 79 | 80 | } 81 | 82 | a { 83 | color:#579; 84 | } 85 | 86 | a:visited{ 87 | color:#648; 88 | } 89 | 90 | div#menu.outputMenu{ 91 | position:absolute; 92 | top:131px; 93 | left:810px; 94 | width:190px; 95 | height:24px; 96 | border-style:solid; 97 | border-color: #000; 98 | border-width: 1px 0px 1px 1px; 99 | 100 | 101 | } 102 | div#outputDisplay1{ 103 | position:absolute; 104 | top:155px; 105 | left:810px; 106 | border-style: solid; 107 | border-color: #000; 108 | border-width: 0px 1px 1px 1px; 109 | border-radius:0px 0px 40px 0px; 110 | -moz-border-radius:0px 0px 40px 0px; 111 | width:190px; 112 | height:676px; 113 | text-align:center; 114 | font-size:12px; 115 | } 116 | 117 | div#outputDisplay2{ 118 | position:absolute; 119 | left:810px; 120 | top:155px; 121 | width: 190px; 122 | height:676px; 123 | border-style: solid; 124 | border-color: #000; 125 | border-width: 0px 1px 1px 1px; 126 | border-radius:0px 0px 40px 0px; 127 | -moz-border-radius:0px 0px 40px 0px; 128 | text-align:center; 129 | } 130 | 131 | div#enrichmentResults{ 132 | height:600px; 133 | width:185px; 134 | overflow-y:auto; 135 | overflow-x:visible; 136 | word-wrap:break-word; 137 | word-wrap:break-all; /*Chrome*/ 138 | } 139 | div#SD1{ 140 | width:175px; 141 | height:50px; 142 | border-radius:20px 20px 0px 0px; 143 | -moz-border-radius:20px 20px 0px 0px; /*Firefox*/ 144 | background-color:#CCC; 145 | font-weight:700; 146 | margin-bottom:25px; 147 | line-height:50px; 148 | } 149 | 150 | .displayTitle{ 151 | font-size:11px; 152 | font-weight:700px; 153 | } 154 | span#additTitle{ 155 | 156 | position:absolute; 157 | top:100px; 158 | left:10px; 159 | width:171px; 160 | font-size:11px; 161 | font-weight:700px; 162 | 163 | } 164 | span#SD1{ 165 | vertical-align:center; 166 | font-size:11px; 167 | } 168 | 169 | div#nodeInformation{ 170 | position:absolute; 171 | top:25px; 172 | width:191px; 173 | height:45px; 174 | word-wrap:break-word; 175 | margin-bottom:5px; 176 | } 177 | 178 | div#infoContainer{ 179 | border-top: 1px solid #CCC; 180 | padding-top:10px; 181 | padding-bottom:10px; 182 | border-bottom: 1px solid #CCC; 183 | position:absolute; 184 | top:135px; 185 | left:10px; 186 | width:171px; 187 | height:350px; 188 | overflow:auto; 189 | 190 | } 191 | 192 | /*Side Panel*/ 193 | 194 | div#menu{ 195 | background-color:#CCC; 196 | height:25px; 197 | line-height:25px; 198 | } 199 | 200 | div#menu span{ 201 | padding-left:15px; 202 | padding-right:15px; 203 | padding-top:1px; 204 | padding-bottom:4px; 205 | background-color:#FFF; 206 | vertical-align:-10%; 207 | border: 1px outset #DDD; 208 | border-bottom:none; 209 | font-weight:700; 210 | cursor:default; 211 | border-radius:7px 7px 0px 0px; 212 | -moz-border-radius:7px 7px 0px 0px; /*Firefox*/ 213 | } 214 | 215 | div#sidePanel{ 216 | padding-top:0px; 217 | width:200px; 218 | height:699px; 219 | text-align:center; 220 | border-right: 1px solid; 221 | } 222 | 223 | 224 | div#menu span#tab2{ 225 | font-weight:400; 226 | background-color:#CCC; 227 | } 228 | 229 | form#form1, form#form2{ 230 | height:380px; 231 | } 232 | form#form2{ 233 | display:none; 234 | } 235 | 236 | form#form3{ 237 | height:150px; 238 | } 239 | 240 | textArea#nodes{ 241 | width:150px; 242 | height:85px; 243 | vertical-align:middle; 244 | } 245 | div#sidePanel textarea#genes{ 246 | width:150px; 247 | height:100px; 248 | } 249 | 250 | span.canvasOptions{ 251 | padding-bottom:15px; 252 | } 253 | 254 | /*holdSVG Elements*/ 255 | 256 | div#holdSVG{ 257 | position:absolute; 258 | top:130px; 259 | left:401px; 260 | width:410px; 261 | height:500px; 262 | vertical-align:middle; 263 | text-align:center; 264 | 265 | } 266 | 267 | div#svgWrapper{ 268 | padding-top:25px; 269 | width:390px; 270 | } 271 | 272 | div#svgContainer, div#chartContainer{ 273 | padding-top:10px; 274 | text-align:center; 275 | } 276 | 277 | div#chartContainer{ 278 | display:none; 279 | } 280 | 281 | svg#mainSVG{ 282 | margin-top: 10px; 283 | vertical-align:middle; 284 | border: 1px solid; 285 | } 286 | 287 | svg#pvalueSVG{ 288 | margin-top:10px; 289 | border: 1px solid; 290 | } 291 | 292 | form#selectSVG{ 293 | padding-bottom:5px; 294 | font-size:11px; 295 | width:390px; 296 | text-align:center; 297 | } 298 | 299 | 300 | select{ 301 | text-align:left; 302 | } 303 | 304 | /*GSEA Elements*/ 305 | 306 | 307 | 308 | /*Manhattan Elements*/ 309 | 310 | div#selectionDisplay3{ 311 | position:absolute; 312 | left:401px; 313 | top:530px; 314 | height:200px; 315 | width:390px; 316 | text-align:center; 317 | 318 | } 319 | 320 | div#manhattan p{ 321 | font-style:italic; 322 | font-size:11px; 323 | } 324 | 325 | div#manhattan p#clusterTitle{ 326 | font-weight:700; 327 | font-style:normal; 328 | text-align:center; 329 | } 330 | 331 | 332 | div#manhattan table{ 333 | margin-left:auto; 334 | margin-right:auto; 335 | } 336 | 337 | svg#sample_gene, svg#sample { 338 | width: 20px; 339 | height: 20px; 340 | } 341 | 342 | table{ 343 | font-size:13px; 344 | } 345 | 346 | table.contain{ 347 | table-layout:fixed; 348 | width:180px; 349 | word-wrap:break-word; 350 | } 351 | 352 | table.containManhattan{ 353 | width:180px; 354 | } 355 | table.class{ 356 | width:100%; 357 | } 358 | 359 | 360 | th { 361 | padding:5px; 362 | padding-left:12px; 363 | padding-right:12px; 364 | font-size:11px; 365 | } 366 | 367 | td, tr{ 368 | padding-left: 10px; 369 | padding-right: 10px; 370 | font-size:10px; 371 | } 372 | 373 | td { 374 | text-align:center; 375 | 376 | } 377 | svg.chart{ 378 | margin-top: 10px; 379 | border-style: solid; 380 | border-width: 1px; 381 | font-size:12px; 382 | } 383 | 384 | 385 | span#title{ 386 | font-size:30px; 387 | vertical-align:center; 388 | 389 | } 390 | 391 | div#header{ 392 | text-align:center; 393 | line-height:100px; 394 | } 395 | 396 | 397 | .axis path, .axis line { 398 | fill:none; 399 | stroke-width: 1px; 400 | stroke: black; 401 | shape-rendering: crispEdges; 402 | } 403 | 404 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Prediction of drug side effects 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 27 | 28 | 29 | 86 |
    87 | 88 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /css/dataTables.bootstrap.css: -------------------------------------------------------------------------------- 1 | div.dataTables_length label { 2 | font-weight: normal; 3 | float: left; 4 | text-align: left; 5 | } 6 | 7 | div.dataTables_length select { 8 | width: 75px; 9 | } 10 | 11 | div.dataTables_filter label { 12 | font-weight: normal; 13 | float: right; 14 | } 15 | 16 | div.dataTables_filter input { 17 | width: 16em; 18 | } 19 | 20 | div.dataTables_info { 21 | padding-top: 8px; 22 | } 23 | 24 | div.dataTables_paginate { 25 | float: right; 26 | margin: 0; 27 | } 28 | 29 | div.dataTables_paginate ul.pagination { 30 | margin: 2px 0; 31 | white-space: nowrap; 32 | } 33 | 34 | table.dataTable td, 35 | table.dataTable th { 36 | -webkit-box-sizing: content-box; 37 | -moz-box-sizing: content-box; 38 | box-sizing: content-box; 39 | } 40 | 41 | 42 | table.dataTable { 43 | clear: both; 44 | margin-top: 6px !important; 45 | margin-bottom: 6px !important; 46 | max-width: none !important; 47 | } 48 | 49 | table.dataTable thead .sorting, 50 | table.dataTable thead .sorting_asc, 51 | table.dataTable thead .sorting_desc, 52 | table.dataTable thead .sorting_asc_disabled, 53 | table.dataTable thead .sorting_desc_disabled { 54 | cursor: pointer; 55 | } 56 | 57 | table.dataTable thead .sorting { background: url('../images/sort_both.png') no-repeat center right; } 58 | table.dataTable thead .sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; } 59 | table.dataTable thead .sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; } 60 | 61 | table.dataTable thead .sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; } 62 | table.dataTable thead .sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; } 63 | 64 | table.dataTable thead > tr > th { 65 | padding-left: 18px; 66 | padding-right: 18px; 67 | } 68 | 69 | table.dataTable th:active { 70 | outline: none; 71 | } 72 | 73 | /* Scrolling */ 74 | div.dataTables_scrollHead table { 75 | margin-bottom: 0 !important; 76 | border-bottom-left-radius: 0; 77 | border-bottom-right-radius: 0; 78 | } 79 | 80 | div.dataTables_scrollHead table thead tr:last-child th:first-child, 81 | div.dataTables_scrollHead table thead tr:last-child td:first-child { 82 | border-bottom-left-radius: 0 !important; 83 | border-bottom-right-radius: 0 !important; 84 | } 85 | 86 | div.dataTables_scrollBody table { 87 | border-top: none; 88 | margin-top: 0 !important; 89 | margin-bottom: 0 !important; 90 | } 91 | 92 | div.dataTables_scrollBody tbody tr:first-child th, 93 | div.dataTables_scrollBody tbody tr:first-child td { 94 | border-top: none; 95 | } 96 | 97 | div.dataTables_scrollFoot table { 98 | margin-top: 0 !important; 99 | border-top: none; 100 | } 101 | 102 | /* Frustratingly the border-collapse:collapse used by Bootstrap makes the column 103 | width calculations when using scrolling impossible to align columns. We have 104 | to use separate 105 | */ 106 | table.table-bordered.dataTable { 107 | border-collapse: separate !important; 108 | } 109 | table.table-bordered thead th, 110 | table.table-bordered thead td { 111 | border-left-width: 0; 112 | border-top-width: 0; 113 | } 114 | table.table-bordered tbody th, 115 | table.table-bordered tbody td { 116 | border-left-width: 0; 117 | border-bottom-width: 0; 118 | } 119 | table.table-bordered th:last-child, 120 | table.table-bordered td:last-child { 121 | border-right-width: 0; 122 | } 123 | div.dataTables_scrollHead table.table-bordered { 124 | border-bottom-width: 0; 125 | } 126 | 127 | 128 | 129 | 130 | /* 131 | * TableTools styles 132 | */ 133 | .table tbody tr.active td, 134 | .table tbody tr.active th { 135 | background-color: #08C; 136 | color: white; 137 | } 138 | 139 | .table tbody tr.active:hover td, 140 | .table tbody tr.active:hover th { 141 | background-color: #0075b0 !important; 142 | } 143 | 144 | .table tbody tr.active a { 145 | color: white; 146 | } 147 | 148 | .table-striped tbody tr.active:nth-child(odd) td, 149 | .table-striped tbody tr.active:nth-child(odd) th { 150 | background-color: #017ebc; 151 | } 152 | 153 | table.DTTT_selectable tbody tr { 154 | cursor: pointer; 155 | } 156 | 157 | div.DTTT .btn { 158 | color: #333 !important; 159 | font-size: 12px; 160 | } 161 | 162 | div.DTTT .btn:hover { 163 | text-decoration: none !important; 164 | } 165 | 166 | ul.DTTT_dropdown.dropdown-menu { 167 | z-index: 2003; 168 | } 169 | 170 | ul.DTTT_dropdown.dropdown-menu a { 171 | color: #333 !important; /* needed only when demo_page.css is included */ 172 | } 173 | 174 | ul.DTTT_dropdown.dropdown-menu li { 175 | position: relative; 176 | } 177 | 178 | ul.DTTT_dropdown.dropdown-menu li:hover a { 179 | background-color: #0088cc; 180 | color: white !important; 181 | } 182 | 183 | div.DTTT_collection_background { 184 | z-index: 2002; 185 | } 186 | 187 | /* TableTools information display */ 188 | div.DTTT_print_info.modal { 189 | height: 150px; 190 | margin-top: -75px; 191 | text-align: center; 192 | } 193 | 194 | div.DTTT_print_info h6 { 195 | font-weight: normal; 196 | font-size: 28px; 197 | line-height: 28px; 198 | margin: 1em; 199 | } 200 | 201 | div.DTTT_print_info p { 202 | font-size: 14px; 203 | line-height: 20px; 204 | } 205 | 206 | div.dataTables_processing { 207 | position: absolute; 208 | top: 50%; 209 | left: 50%; 210 | width: 100%; 211 | height: 40px; 212 | margin-left: -50%; 213 | margin-top: -25px; 214 | padding-top: 20px; 215 | text-align: center; 216 | font-size: 1.2em; 217 | background-color: white; 218 | background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0))); 219 | background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); 220 | background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); 221 | background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); 222 | background: -o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); 223 | background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); 224 | } 225 | 226 | 227 | 228 | /* 229 | * FixedColumns styles 230 | */ 231 | div.DTFC_LeftHeadWrapper table, 232 | div.DTFC_LeftFootWrapper table, 233 | div.DTFC_RightHeadWrapper table, 234 | div.DTFC_RightFootWrapper table, 235 | table.DTFC_Cloned tr.even { 236 | background-color: white; 237 | margin-bottom: 0; 238 | } 239 | 240 | div.DTFC_RightHeadWrapper table , 241 | div.DTFC_LeftHeadWrapper table { 242 | margin-bottom: 0 !important; 243 | border-top-right-radius: 0 !important; 244 | border-bottom-left-radius: 0 !important; 245 | border-bottom-right-radius: 0 !important; 246 | } 247 | 248 | div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child, 249 | div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child, 250 | div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child, 251 | div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child { 252 | border-bottom-left-radius: 0 !important; 253 | border-bottom-right-radius: 0 !important; 254 | } 255 | 256 | div.DTFC_RightBodyWrapper table, 257 | div.DTFC_LeftBodyWrapper table { 258 | border-top: none; 259 | margin: 0 !important; 260 | } 261 | 262 | div.DTFC_RightBodyWrapper tbody tr:first-child th, 263 | div.DTFC_RightBodyWrapper tbody tr:first-child td, 264 | div.DTFC_LeftBodyWrapper tbody tr:first-child th, 265 | div.DTFC_LeftBodyWrapper tbody tr:first-child td { 266 | border-top: none; 267 | } 268 | 269 | div.DTFC_RightFootWrapper table, 270 | div.DTFC_LeftFootWrapper table { 271 | border-top: none; 272 | } 273 | 274 | 275 | /* 276 | * FixedHeader styles 277 | */ 278 | div.FixedHeader_Cloned table { 279 | margin: 0 !important 280 | } 281 | 282 | -------------------------------------------------------------------------------- /python/network_layout.py: -------------------------------------------------------------------------------- 1 | ## make MDS plot to visualize network 2 | import os, sys 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | from sklearn import manifold 6 | import networkx as nx 7 | from networkx.readwrite import json_graph 8 | from sklearn.preprocessing import LabelBinarizer 9 | from sklearn.cluster import AgglomerativeClustering 10 | 11 | from matplotlib import rcParams 12 | rcParams['pdf.fonttype'] = 42 ## Output Type 3 (Type3) or Type 42 (TrueType) 13 | rcParams['font.sans-serif'] = 'Arial' 14 | 15 | import json 16 | import MySQLdb 17 | import cPickle as pickle 18 | from itertools import combinations 19 | from collections import Counter 20 | from pprint import pprint 21 | from scipy.stats import pearsonr 22 | 23 | from os.path import expanduser 24 | HOME = expanduser("~") 25 | sys.path.append(HOME + '/Documents/bitbucket/maayanlab_utils') 26 | from fileIO import read_df, read_gmt, mysqlTable2dict, write_gmt 27 | from plots import COLORS20, COLORS20b 28 | from GMTtools import jaccard_matrix, flip_gmt 29 | 30 | 31 | def mds(dissimilarity_matrix, plot=False): 32 | ## calc coordinates with MDS 33 | mds = manifold.MDS(n_components=2, dissimilarity="precomputed", n_init=4) 34 | nmds = manifold.MDS(metric=False, n_components=2, dissimilarity="precomputed", n_init=1) 35 | mds.fit(dissimilarity_matrix) 36 | pos = mds.embedding_ 37 | npos = nmds.fit_transform(dissimilarity_matrix, init=pos) 38 | 39 | ## get degrees for nodes 40 | adj_matrix = 1 - dissimilarity_matrix 41 | degrees = adj_matrix.sum(axis=0) - 1 42 | 43 | if plot: 44 | fig = plt.figure(figsize=(10,6)) 45 | ax1 = fig.add_subplot(121) 46 | ax2 = fig.add_subplot(122) 47 | ax1.scatter(pos[:,0], pos[:,1], s=degrees/50.) 48 | ax2.scatter(npos[:,0], npos[:,1], s=degrees/50.) 49 | plt.show() 50 | return npos, degrees 51 | 52 | 53 | def network_layout(gmt_fn, outfn=None): 54 | ## make a Graph object and write to gml for Gephi to 55 | ## do the layout 56 | 57 | d_gmt = read_gmt(gmt_fn) 58 | d_gmt_filt = {} 59 | for term, genes in d_gmt.items(): 60 | if len(genes) >= 5: 61 | d_gmt_filt[term] = genes 62 | d_gmt = d_gmt_filt 63 | 64 | print 'number of terms:', len(d_gmt) 65 | umls_ids_kept = d_gmt.keys() 66 | adj_matrix = jaccard_matrix(d_gmt) 67 | 68 | m = adj_matrix > 0.2 69 | # degrees = adj_matrix.sum(axis=0) 70 | adj_matrix = adj_matrix * m.astype(int) 71 | 72 | G = nx.from_numpy_matrix(adj_matrix) 73 | 74 | print 'G: ',G.number_of_edges(), G.number_of_nodes() 75 | 76 | for i in range(adj_matrix.shape[0]): 77 | # G.node[i]['size'] = degrees[i] 78 | # G.node[i]['size'] = len(d_gmt[umls_ids_kept[i]]) 79 | G.node[i]['size'] = G.degree(i) 80 | G.node[i]['id'] = umls_ids_kept[i] 81 | 82 | if outfn is not None: 83 | nx.write_gml(G, outfn) 84 | return G 85 | 86 | 87 | def make_network_json(layout_df, d_id_name, d_id_category, d_category_color, outfn=None): 88 | ## wrapper for making a json for viewing 89 | 90 | objs = [] 91 | 92 | i = 0 93 | all_categories = [] 94 | 95 | 96 | with open (layout_df) as f: 97 | header = next(f).split(',') 98 | id_idx = header.index('Id') 99 | size_idx = header.index('sizeFloat') 100 | x_idx = header.index('X-coordinateFloat') 101 | y_idx = header.index('Y-coordinateFloat') 102 | for line in f: 103 | sl = line.split(',') 104 | id = sl[id_idx] 105 | x = float(sl[x_idx]) 106 | y = float(sl[y_idx]) 107 | size = float(sl[size_idx]) * 35 108 | name = d_id_name[id] 109 | category = d_id_category[id] 110 | color = d_category_color[category] 111 | obj = {'id':id, 'x':x, 'y':y, 'size':size, 'label':name, 'color':color} 112 | objs.append(obj) 113 | json.dump(objs, open(outfn, 'wb')) 114 | return 115 | 116 | def make_directed_json_graph(gmt_fn, d_id_name, d_id_category, d_category_color, outfn=None): 117 | # perform HC and make a directed graph and write to json 118 | # for pack visualization 119 | d_gmt = read_gmt(gmt_fn) 120 | d_gmt_filt = {} 121 | for term, genes in d_gmt.items(): 122 | if len(genes) >= 5: 123 | d_gmt_filt[term] = genes 124 | d_gmt = d_gmt_filt 125 | 126 | print 'number of terms:', len(d_gmt) 127 | umls_ids_kept = d_gmt.keys() 128 | adj_matrix = jaccard_matrix(d_gmt) 129 | 130 | hc = AgglomerativeClustering(n_clusters=10) 131 | hc.fit(adj_matrix) 132 | 133 | m = adj_matrix > 0.2 134 | adj_matrix = adj_matrix * m.astype(int) 135 | Gu = nx.from_numpy_matrix(adj_matrix) # undirected Graph, to get size 136 | 137 | G = nx.DiGraph() 138 | print adj_matrix.shape, len(umls_ids_kept) 139 | for i in range(adj_matrix.shape[0]): 140 | cluster_label = hc.labels_[i] 141 | umls_id = umls_ids_kept[i] 142 | name = d_id_name[umls_id] 143 | G.add_edge('root', cluster_label) 144 | G.add_edge(cluster_label, umls_id) 145 | G.node[umls_id]['size'] = Gu.degree(i) 146 | G.node[umls_id]['label'] = name 147 | 148 | category = d_id_category[umls_id] 149 | color = d_category_color[category] 150 | G.node[umls_id]['color'] = color 151 | print G.number_of_nodes(), G.number_of_edges() 152 | graph_data = json_graph.tree_data(G,root='root') 153 | json.dump(graph_data, open(outfn, 'wb')) 154 | return 155 | 156 | def make_directed_json_graph_soc(gmt_fn, d_id_name, d_id_category, d_category_color, outfn=None): 157 | # make directed graph based on SOC - PT 158 | d_gmt = read_gmt(gmt_fn) 159 | d_gmt_filt = {} 160 | for term, genes in d_gmt.items(): 161 | if len(genes) >= 5: 162 | d_gmt_filt[term] = genes 163 | d_gmt = d_gmt_filt 164 | 165 | print 'number of terms:', len(d_gmt) 166 | umls_ids_kept = d_gmt.keys() 167 | adj_matrix = jaccard_matrix(d_gmt) 168 | m = adj_matrix > 0.2 169 | adj_matrix = adj_matrix * m.astype(int) 170 | Gu = nx.from_numpy_matrix(adj_matrix) # undirected Graph, to get size 171 | G = nx.DiGraph() 172 | for i in range(len(umls_ids_kept)): 173 | umls_id = umls_ids_kept[i] 174 | name = d_id_name[umls_id] 175 | category = d_id_category[umls_id] 176 | color = d_category_color[category] 177 | 178 | G.add_edge('root', category) 179 | G.add_edge(category, umls_id) 180 | 181 | G.node[umls_id]['size'] = Gu.degree(i) 182 | G.node[umls_id]['label'] = name 183 | G.node[umls_id]['color'] = color 184 | print G.number_of_nodes(), G.number_of_edges() 185 | graph_data = json_graph.tree_data(G,root='root') 186 | json.dump(graph_data, open(outfn, 'wb')) 187 | return 188 | 189 | 190 | 191 | # DF_FN = HOME+'/Documents/Zichen_Projects/drug_se_prediction/ET100_GOtCS_AUC_0.75_proba_0.75_significance_scores_matrix.txt' 192 | # DF_FN = HOME+'/Documents/Zichen_Projects/drug_se_prediction/Sets2Networks/ET100_GOtCS_AUC_0.7_proba_0.75_prediction_only_flipped_significance_scores_matrix.txt' 193 | # GMT_FN = HOME+'/Documents/Zichen_Projects/drug_se_prediction/Sets2Networks/ET100_GOtCS_AUC_0.7_proba_0.75_prediction_only.gmt' 194 | 195 | PREDICTION_DF = HOME + '/Documents/Zichen_Projects/drug_se_prediction/PTs_RF1000_proba_df_n20338x1053.txt' 196 | 197 | ## for side effects 198 | # GMT_FN = HOME+'/Documents/Zichen_Projects/drug_se_prediction/RF1000_GOtCS_AUC_0.7_proba_0.6_prediction_only.gmt' 199 | GMT_FN = HOME+'/Documents/Zichen_Projects/drug_se_prediction/ET100_GOtCS_AUC_0.76_proba_0.75.gmt' 200 | GML_FN = HOME+'/Documents/Zichen_Projects/drug_se_prediction/side_effect_network.gml' 201 | ## for drugs 202 | # GMT_FN = HOME+'/Documents/Zichen_Projects/drug_se_prediction/RF1000_GOtCS_AUC_0.7_proba_0.6_prediction_only_flipped.gmt' 203 | # GML_FN = HOME+'/Documents/Zichen_Projects/drug_se_prediction/drug_network.gml' 204 | 205 | CSV_FN = GML_FN.replace('.gml', '.csv') 206 | JSON_FN = CSV_FN.replace('.csv', '.json') 207 | 208 | ## retrieve meta data about SE 209 | d_umls_pt = mysqlTable2dict('sep', 'side_effects', 1, 2) 210 | d_pt_umls = mysqlTable2dict('sep', 'side_effects', 2, 1) 211 | d_soc_pt = read_gmt(HOME+'/Documents/bitbucket/pertid2trainingset/Y_matrix_no_mfc/SOC_to_pt.gmt') 212 | print len(d_soc_pt) 213 | d_umls_soc = {} 214 | for soc, pts in d_soc_pt.items(): 215 | for pt in pts: 216 | umls = d_pt_umls[pt] 217 | if umls is not None: 218 | if umls not in d_umls_soc: 219 | d_umls_soc[umls] = soc 220 | # else: 221 | # d_umls_soc[umls].append(soc) # one PT may have multiple SOCs 222 | 223 | # for pt in d_umls_soc: 224 | # if len(d_umls_soc[pt]) != 1: 225 | # print pt, d_umls_soc[pt] 226 | 227 | COLORS40 = COLORS20 + COLORS20b 228 | COLORS40 = map(lambda x : x[1:], COLORS40) # remove "#" 229 | d_soc_color = dict(zip(set(d_umls_soc.values()), COLORS40)) 230 | 231 | # pickle.dump(d_umls_soc, open(HOME+'/Documents/Zichen_Projects/drug_se_prediction/d_umls_soc.p', 'wb')) 232 | # pickle.dump(d_soc_color, open(HOME+'/Documents/Zichen_Projects/drug_se_prediction/d_soc_color.p', 'wb')) 233 | 234 | # d_gmt = read_gmt(GMT_FN) 235 | # d_gmtT = flip_gmt(d_gmt) 236 | # write_gmt(d_gmtT, HOME+'/Documents/Zichen_Projects/drug_se_prediction/RF1000_GOtCS_AUC_0.7_proba_0.6_prediction_only_flipped.gmt') 237 | 238 | 239 | # G = network_layout(GMT_FN, outfn=GML_FN) 240 | 241 | # make_network_json(CSV_FN, d_umls_pt, d_umls_soc, d_soc_color, outfn=JSON_FN) 242 | 243 | # make directed graph for predicted SEs 244 | make_directed_json_graph(GMT_FN, d_umls_pt, d_umls_soc, d_soc_color, 245 | outfn=HOME+'/Documents/Zichen_Projects/drug_se_prediction/side_effects_digraph_with_known.json') 246 | make_directed_json_graph_soc(GMT_FN, d_umls_pt, d_umls_soc, d_soc_color, 247 | outfn=HOME+'/Documents/Zichen_Projects/drug_se_prediction/side_effects_digraph_soc_with_known.json') 248 | 249 | 250 | -------------------------------------------------------------------------------- /js/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v1.5.9 3 | * https://zenorocha.github.io/clipboard.js 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function r(c,s){if(!n[c]){if(!e[c]){var a="function"==typeof require&&require;if(!s&&a)return a(c,!0);if(i)return i(c,!0);var l=new Error("Cannot find module '"+c+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[c]={exports:{}};e[c][0].call(u.exports,function(t){var n=e[c][1][t];return r(n?n:t)},u,u.exports,t,e,n,o)}return n[c].exports}for(var i="function"==typeof require&&require,c=0;co;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,c=o.length;c>i;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},e.exports=o},{}],8:[function(e,n,o){!function(r,i){if("function"==typeof t&&t.amd)t(["module","select"],i);else if("undefined"!=typeof o)i(n,e("select"));else{var c={exports:{}};i(c,r.select),r.clipboardAction=c.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var r=n(e),i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},c=function(){function t(t,e){for(var n=0;n for Firefox 4 and up 3 | https://github.com/fryn/html5slider 4 | 5 | Copyright (c) 2010-2011 Frank Yan, 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | */ 25 | 26 | (function() { 27 | 28 | // test for native support 29 | var test = document.createElement('input'); 30 | try { 31 | test.type = 'range'; 32 | if (test.type == 'range') 33 | return; 34 | } catch (e) { 35 | return; 36 | } 37 | 38 | // test for required property support 39 | if (!document.mozSetImageElement || !('MozAppearance' in test.style)) 40 | return; 41 | 42 | var scale; 43 | var isMac = navigator.platform == 'MacIntel'; 44 | var thumb = { 45 | radius: isMac ? 9 : 6, 46 | width: isMac ? 22 : 12, 47 | height: isMac ? 16 : 20 48 | }; 49 | var track = '-moz-linear-gradient(top, transparent ' + (isMac ? 50 | '6px, #999 6px, #999 7px, #ccc 9px, #bbb 11px, #bbb 12px, transparent 12px' : 51 | '9px, #999 9px, #bbb 10px, #fff 11px, transparent 11px') + 52 | ', transparent)'; 53 | var styles = { 54 | 'min-width': thumb.width + 'px', 55 | 'min-height': thumb.height + 'px', 56 | 'max-height': thumb.height + 'px', 57 | padding: 0, 58 | border: 0, 59 | 'border-radius': 0, 60 | cursor: 'default', 61 | 'text-indent': '-999999px' // -moz-user-select: none; breaks mouse capture 62 | }; 63 | var onChange = document.createEvent('HTMLEvents'); 64 | onChange.initEvent('change', true, false); 65 | 66 | if (document.readyState == 'loading') 67 | document.addEventListener('DOMContentLoaded', initialize, true); 68 | else 69 | initialize(); 70 | 71 | function initialize() { 72 | // create initial sliders 73 | Array.forEach(document.querySelectorAll('input[type=range]'), transform); 74 | // create sliders on-the-fly 75 | document.addEventListener('DOMNodeInserted', onNodeInserted, true); 76 | } 77 | 78 | function onNodeInserted(e) { 79 | check(e.target); 80 | if (e.target.querySelectorAll) 81 | Array.forEach(e.target.querySelectorAll('input'), check); 82 | } 83 | 84 | function check(input, async) { 85 | if (input.localName != 'input' || input.type == 'range'); 86 | else if (input.getAttribute('type') == 'range') 87 | transform(input); 88 | else if (!async) 89 | setTimeout(check, 0, input, true); 90 | } 91 | 92 | function transform(slider) { 93 | 94 | var isValueSet, areAttrsSet, isChanged, isClick, prevValue, rawValue, prevX; 95 | var min, max, step, range, value = slider.value; 96 | 97 | // lazily create shared slider affordance 98 | if (!scale) { 99 | scale = document.body.appendChild(document.createElement('hr')); 100 | style(scale, { 101 | '-moz-appearance': isMac ? 'scale-horizontal' : 'scalethumb-horizontal', 102 | display: 'block', 103 | visibility: 'visible', 104 | opacity: 1, 105 | position: 'fixed', 106 | top: '-999999px' 107 | }); 108 | document.mozSetImageElement('__sliderthumb__', scale); 109 | } 110 | 111 | // reimplement value and type properties 112 | var getValue = function() { return '' + value; }; 113 | var setValue = function setValue(val) { 114 | value = '' + val; 115 | isValueSet = true; 116 | draw(); 117 | delete slider.value; 118 | slider.value = value; 119 | slider.__defineGetter__('value', getValue); 120 | slider.__defineSetter__('value', setValue); 121 | }; 122 | slider.__defineGetter__('value', getValue); 123 | slider.__defineSetter__('value', setValue); 124 | slider.__defineGetter__('type', function() { return 'range'; }); 125 | 126 | // sync properties with attributes 127 | ['min', 'max', 'step'].forEach(function(prop) { 128 | if (slider.hasAttribute(prop)) 129 | areAttrsSet = true; 130 | slider.__defineGetter__(prop, function() { 131 | return this.hasAttribute(prop) ? this.getAttribute(prop) : ''; 132 | }); 133 | slider.__defineSetter__(prop, function(val) { 134 | val === null ? this.removeAttribute(prop) : this.setAttribute(prop, val); 135 | }); 136 | }); 137 | 138 | // initialize slider 139 | slider.readOnly = true; 140 | style(slider, styles); 141 | update(); 142 | 143 | slider.addEventListener('DOMAttrModified', function(e) { 144 | // note that value attribute only sets initial value 145 | if (e.attrName == 'value' && !isValueSet) { 146 | value = e.newValue; 147 | draw(); 148 | } 149 | else if (~['min', 'max', 'step'].indexOf(e.attrName)) { 150 | update(); 151 | areAttrsSet = true; 152 | } 153 | }, true); 154 | 155 | slider.addEventListener('mousedown', onDragStart, true); 156 | slider.addEventListener('keydown', onKeyDown, true); 157 | slider.addEventListener('focus', onFocus, true); 158 | slider.addEventListener('blur', onBlur, true); 159 | 160 | function onDragStart(e) { 161 | isClick = true; 162 | setTimeout(function() { isClick = false; }, 0); 163 | if (e.button || !range) 164 | return; 165 | var width = parseFloat(getComputedStyle(this, 0).width); 166 | var multiplier = (width - thumb.width) / range; 167 | if (!multiplier) 168 | return; 169 | // distance between click and center of thumb 170 | var dev = e.clientX - this.getBoundingClientRect().left - thumb.width / 2 - 171 | (value - min) * multiplier; 172 | // if click was not on thumb, move thumb to click location 173 | if (Math.abs(dev) > thumb.radius) { 174 | isChanged = true; 175 | this.value -= -dev / multiplier; 176 | } 177 | rawValue = value; 178 | prevX = e.clientX; 179 | this.addEventListener('mousemove', onDrag, true); 180 | this.addEventListener('mouseup', onDragEnd, true); 181 | } 182 | 183 | function onDrag(e) { 184 | var width = parseFloat(getComputedStyle(this, 0).width); 185 | var multiplier = (width - thumb.width) / range; 186 | if (!multiplier) 187 | return; 188 | rawValue += (e.clientX - prevX) / multiplier; 189 | prevX = e.clientX; 190 | isChanged = true; 191 | this.value = rawValue; 192 | } 193 | 194 | function onDragEnd() { 195 | this.removeEventListener('mousemove', onDrag, true); 196 | this.removeEventListener('mouseup', onDragEnd, true); 197 | } 198 | 199 | function onKeyDown(e) { 200 | if (e.keyCode > 36 && e.keyCode < 41) { // 37-40: left, up, right, down 201 | onFocus.call(this); 202 | isChanged = true; 203 | this.value = value + (e.keyCode == 38 || e.keyCode == 39 ? step : -step); 204 | } 205 | } 206 | 207 | function onFocus() { 208 | if (!isClick) 209 | this.style.boxShadow = !isMac ? '0 0 0 2px #fb0' : 210 | '0 0 2px 1px -moz-mac-focusring, inset 0 0 1px -moz-mac-focusring'; 211 | } 212 | 213 | function onBlur() { 214 | this.style.boxShadow = ''; 215 | } 216 | 217 | // determines whether value is valid number in attribute form 218 | function isAttrNum(value) { 219 | return !isNaN(value) && +value == parseFloat(value); 220 | } 221 | 222 | // validates min, max, and step attributes and redraws 223 | function update() { 224 | min = isAttrNum(slider.min) ? +slider.min : 0; 225 | max = isAttrNum(slider.max) ? +slider.max : 100; 226 | if (max < min) 227 | max = min > 100 ? min : 100; 228 | step = isAttrNum(slider.step) && slider.step > 0 ? +slider.step : 1; 229 | range = max - min; 230 | draw(true); 231 | } 232 | 233 | // recalculates value property 234 | function calc() { 235 | if (!isValueSet && !areAttrsSet) 236 | value = slider.getAttribute('value'); 237 | if (!isAttrNum(value)) 238 | value = (min + max) / 2;; 239 | // snap to step intervals (WebKit sometimes does not - bug?) 240 | value = Math.round((value - min) / step) * step + min; 241 | if (value < min) 242 | value = min; 243 | else if (value > max) 244 | value = min + ~~(range / step) * step; 245 | } 246 | 247 | // renders slider using CSS background ;) 248 | function draw(attrsModified) { 249 | calc(); 250 | if (isChanged && value != prevValue) 251 | slider.dispatchEvent(onChange); 252 | isChanged = false; 253 | if (!attrsModified && value == prevValue) 254 | return; 255 | prevValue = value; 256 | var position = range ? (value - min) / range * 100 : 0; 257 | var bg = '-moz-element(#__sliderthumb__) ' + position + '% no-repeat, '; 258 | style(slider, { background: bg + track }); 259 | } 260 | 261 | } 262 | 263 | function style(element, styles) { 264 | for (var prop in styles) 265 | element.style.setProperty(prop, styles[prop], 'important'); 266 | } 267 | 268 | })(); -------------------------------------------------------------------------------- /js/searchBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | A Backbone.View that exposes a custom search bar. The search bar provides autocomplete 3 | functionality for Connectivity Map pert\_inames and cell\_ids. When the user types in the 4 | search view's input, a "search:DidType" event is fired. 5 | 6 | @class PertSearchBar 7 | @constructor 8 | @extends Backbone.View 9 | **/ 10 | PertSearchBar = Backbone.View.extend({ 11 | initialize: function(){ 12 | var self = this; 13 | 14 | /** 15 | determines wether or not the search view will match cell lines for autocomplete 16 | 17 | @property match_cell_lines 18 | @default true 19 | @type Boolean 20 | **/ 21 | // determine wether or not we will match cell line strings in the autocomplete 22 | this.match_cell_lines = (this.options.match_cell_lines !== undefined) ? this.options.match_cell_lines : true; 23 | 24 | // grab cell_ids and store them as an atribute of the view 25 | var cellinfo = 'http://api.lincscloud.org/a2/cellinfo?callback=?'; 26 | var params = {q:'{"cell_id":{"$regex":""}}',d:"cell_id"}; 27 | $.getJSON(cellinfo,params,function(res){ 28 | self.cell_lines = res; 29 | self.render(); 30 | 31 | // once the view is rendered, bind a change event to trigger a "search:DidType" event from the view 32 | $("#search",self.el).bind('input propertychange change', function () { 33 | var val = $("#search",self.el).val(); 34 | var type = ""; 35 | if (self.cell_lines.indexOf(val) != -1 && self.match_cell_lines){ 36 | type = "cell"; 37 | } 38 | 39 | /** 40 | Fired when the text in the view's search box changes 41 | 42 | @event search:DidType 43 | @param {Object} [msg={val:"",type:""}] an object containing the message of the event 44 | @param {String} [msg.val=""] the string val of the views search bar at the time of the event 45 | @param {String} [msg.type=""] the type of message being passed, either "" or "cell". "cell" is passed, if the string matches a cell line and match\_cell\_lines is set 46 | **/ 47 | self.trigger("search:DidType",{val: val,type: type}); 48 | }); 49 | }); 50 | 51 | }, 52 | 53 | 54 | /** 55 | Gets the current text entered in the view's search bar 56 | 57 | @method get_val 58 | **/ 59 | get_val: function(){ 60 | return $("#search",this.el).val(); 61 | }, 62 | 63 | /** 64 | fills the view's search bar with a random pert_iname and triggers a "search:DidType" event 65 | 66 | @method random_val 67 | **/ 68 | random_val: function(){ 69 | var self = this; 70 | skip = Math.round(Math.random()*40000); 71 | var pertinfo = 'http://api.lincscloud.org/a2/pertinfo?callback=?'; 72 | params = {f:'{"pert_iname":1}', 73 | l:1, 74 | sk:skip}; 75 | $.getJSON(pertinfo,params,function(res){ 76 | var val = res[0].pert_iname; 77 | $("#search",this.el).val(val); 78 | self.trigger("search:DidType",{val: val,type: 'single'}); 79 | }); 80 | }, 81 | 82 | set_val: function(new_val){ 83 | $("#search",this.el).val(new_val); 84 | this.trigger("search:DidType",{val: new_val,type: 'single'}); 85 | }, 86 | 87 | /** 88 | the html template to be used as the views code 89 | 90 | @property template 91 | @default '
    Search 1,209,824 profiles
    ' 92 | @type String 93 | **/ 94 | template: function(template_string){ 95 | if (template_string === undefined){ 96 | template_string = '
    Search 1,209,824 profiles
    '; 97 | } 98 | var compiled_template = Handlebars.compile(template_string); 99 | return compiled_template; 100 | }, 101 | 102 | /** 103 | renders the view 104 | 105 | @method render 106 | **/ 107 | render: function(){ 108 | var self = this; 109 | // load the template into the view's el tag 110 | this.$el.html(this.template()); 111 | 112 | // configure the typeahead to autocomplete off of RESTful calls to pertinfo 113 | var auto_data = []; 114 | var pertinfo = 'http://api.lincscloud.org/a2/pertinfo?callback=?'; 115 | 116 | // instatiate an object to serve as a pert_iname to pert_type hash 117 | var object_map = {}; 118 | 119 | $('#search',this.$el).typeahead({ 120 | // only return 4 items at a time in the autocomplete dropdown 121 | items: 4, 122 | 123 | // custom source argument to pull results from pert_info 124 | source: function(query,process){ 125 | var val = $("#search",this.$el).val(); 126 | return $.getJSON(pertinfo,{q:'{"pert_iname":{"$regex":"' + val + '", "$options":"i"}}', 127 | f:'{"pert_iname":1,"pert_type":1}', 128 | l:100, 129 | s:'{"pert_iname":1}'}, 130 | function(response){ 131 | // for each item, pull out its pert_iname and use that for the 132 | // autocomplete value. Map its type to the pert_iname for use 133 | // in the highlighter function below 134 | response.forEach(function(element){ 135 | auto_data.push(element.pert_iname); 136 | object_map[element.pert_iname] = element; 137 | }); 138 | 139 | // make sure we only show unique items 140 | auto_data = _.uniq(auto_data); 141 | 142 | // add cell lines if required 143 | if (self.match_cell_lines){ 144 | auto_data = auto_data.concat(self.cell_lines); 145 | } 146 | 147 | // return the processed list of data for the autocomplete 148 | return process(auto_data); 149 | }); 150 | }, 151 | 152 | // custom highlighter argument to display matched types 153 | highlighter: function(item){ 154 | if (self.cell_lines.indexOf(item) != -1){ 155 | return '
    Cellular Context ' + item + '
    '; 156 | } 157 | if (object_map[item].pert_type === 'trt_sh' || object_map[item].pert_type === 'trt_oe'){ 158 | return '
    Genetic Reagent ' + item + '
    '; 159 | } 160 | if (object_map[item].pert_type === 'trt_cp' ){ 161 | return '
    Chemical Reagent ' + item + '
    '; 162 | } 163 | } 164 | 165 | }); 166 | } 167 | }); -------------------------------------------------------------------------------- /about.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |

    Abstract

    5 |

    6 | Motivation: 7 | Adverse Drug Reactions (ADRs) are a central consideration during drug development. Here we present a machine learning classifier to prioritize ADRs for approved drugs and pre-clinical small-molecule compounds by combining chemical structure (CS) and gene expression (GE) features. The GE data is from the Library of Integrated Network-based Cellular Signatures (LINCS) L1000 dataset that measured changes in GE before and after treatment of human cells with over 20,000 small molecule compounds including most of the FDA-approved drugs. Using various benchmarking methods, we show that the integration of GE data with the CS of the drugs can significantly improve the predictability of ADRs. Moreover, transforming GE features to enrichment vectors of biological terms further improves the predictive capability of the classifiers. The most predictive biological-term features can assist in understanding the drug mechanisms of action. Finally, we applied the classifier to all >20,000 small molecules profiled, and developed a web portal for browsing and searching predictive small-molecule/ADR connections. 8 |

    9 |

    10 | Availability: 11 | The interface for the adverse event predictions for the >20,000 LINCS compounds is available at http://maayanlab.net/SEP-L1000/. 12 |

    13 |
    14 |
    15 |
    16 |
    17 |

    Citation

    18 |

    19 | Zichen Wang, Neil R. Clark, and Avi Ma'ayan (2016) Drug Induced Adverse Events Prediction with the LINCS L1000 Data 20 | Bioinformatics 21 | doi:10.1093/bioinformatics/btw168 22 |

    23 |
    24 |
    25 |
    26 |
    27 |
    28 |

    Methods

    29 |
    30 | 31 |
    Figure 1. Workflow overview. (A) Venn diagram shows the overlap between drugs and small molecule compounds across different data sources. (B) Representation of the use of drug-feature matrices of different types to predict adverse drug reactions using multi-label classification.
    32 |
    33 | 34 |

    Collection of ADRs, biological and chemical attributes of drugs

    35 |

    36 | On-label ADRs of FDA-approved drugs were downloaded from SIDER [1], which covers 996 marketed drugs, 4,192 ADRs and 99,423 drug-ADR associations. Off-label ADRs were retrieved from the Offside table [2], which has processed data from the post-market ADR reports within the FDA Adverse Event Report System (FAERS), covering 1,322 drugs, 10,097 ADRs and 438,801 drug-ADR associations. 37 |

    38 | 39 |

    40 | The ADR terms are mapped to Preferred Terms (PTs) coded in MedDRA v16.0. The reference gold standard for the four clinically significant ADRs: upper gastrointestinal ulcer, acute liver failure, acute myocardial infarction and acute kidney failure were downloaded from the website of Observational Medical Outcomes Partnership (OMOP) web-site [3,4] (http://omop.org/ResearchArchive). 41 |

    42 | 43 |

    44 | The gene expression profiles from the 20,413 small molecule compound perturbations were gathered from the LINCS L1000 project. For each small molecule compounds, we chose the set of experiments with the strongest signature strength provided by the lincscloud.org API regardless of the cell type, dosage or time point of the drug perturbation. We then used the Characteristic Direction (CD) method [5] to compute gene expression signatures for drug perturbations for in the gene expression space of the 978 directly measured landmark genes as well as for in the space of all measured and imputed genes. 45 |

    46 | 47 |

    48 | A geometric extension of CD called Principal Angle Enrichment Analysis (PAEA) was used to compute enrichment p-values for each CD in the space of all genes against gene sets created from the in Gene Ontology including Biological Processes, Cellular Components and Molecular Functions. 49 |

    50 | 51 |

    52 | The cell morphological profiles were downloaded from the Molecular Libraries Probe Production Centers Network (MLPCN) project web-site hosted at the Broad institute [6, 7]. Each small molecule compound has 812 morphological feature descriptors with numerical values extracted from the cell painting images, representing the morphological changes of the cell upon treatment with drugs. 53 |

    54 | 55 |

    56 | The 2D chemical structures of small molecule compounds are represented using the simplified molecular-input line-entry system (SMILES) format. The SMILES strings for other small molecule compounds were provided in the metadata of the LINCS L1000 and MLPCN projects. We then computed the 166-bit Molecular ACCess System (MACCS) and the 881-bit CACTVS/PubChem chemical fingerprints using the Open Babel cheminformatic toolbox [8] and the RDKit (http://www.rdkit.org) package, respectively. 57 |

    58 | 59 |

    60 | To map marketed drugs to small molecule compounds profiled in the LINCS L1000 project and MLPCN project, SMILES strings of drugs were desaltinized and converted to the canonical SMILES strings using Open Babel; these were further used to map to the "pert_id" of small molecule compounds profiled in the LINCS L1000 and MLPCN projects. Drugs that we were unable to be mapped to pert_id were then mapped using names and synonyms retrieved from DrugBank [9]. 61 |

    62 | 63 |

    Prediction of ADRs using multi-label classification

    64 |

    65 | We formulated the problem of predicting multiple ADRs for each drug as a multi-label classification problem. Formally, the multi-label classification problem we are trying to solve is to find a model that maps inputs x to binary vectors y, where as x represents the attribute vector of a drug, and the label vector y is a vector of Boolean values describing whether the drug cause the corresponding ADRs. 66 |

    67 | 68 |

    69 | We employed a binary relevance method [10] to transform the multi-label classification problem to a set of independent single label classification tasks, and coupled these with various binary classifiers to construct the model. 70 |

    71 | 72 |

    73 | Drug attribute sets including gene expression, chemical structure, cell morphological profiles and GO enrichment vectors were combined by feature selection. Since binary relevance approach was chosen for multi-label classification, feature selection was also performed independently for each ADR. Briefly, stability selection [11] was used for each ADR to prioritize the top 50 best predictive features. 74 |

    75 | 76 |

    77 | Extremely randomized trees (ET) [12] classifiers were trained for each ADR and cross-validated using 3-fold cross-validation. The number of trees in the forest was set to 100. All the other parameters of ET were set to the default recommended settings in the Scikit-Learn Python package [13]. 78 |

    79 | 80 |

    81 | To evaluate the multi-label classification model, both instance-based and label-based metrics were used. Micro-averaged Receiver Operating Characteristic (ROC) curves and Hamming Loss were employed for instance-based evaluations to evaluate the performance of the multi-label classifiers in assigning the correct ADRs to individual drugs. Area under the ROC curves (AUROC) and area under the Matthews Correlation Coefficient (MCC)-Recall curves was used for label-based evaluations to evaluate the performance of the multi-label classifiers in assigning the correct drugs for individual ADRs. 82 |

    83 |
    84 |
    85 |

    References

    86 |
      87 |
    1. 88 | Kuhn M, Campillos M, Letunic I, Jensen LJ, Bork P: A side effect resource to capture phenotypic effects of drugs. Molecular systems biology 2010, 6(1). 89 |
    2. 90 |
    3. 91 | Tatonetti NP, Ye PP, Daneshjou R, Altman RB: Data-Driven Prediction of Drug Effects and Interactions. Science Translational Medicine 2012, 4(125):125ra131. 92 |
    4. 93 |
    5. 94 | Ryan PB, Madigan D, Stang PE, Schuemie MJ, Hripcsak G: Medication-Wide Association Studies. CPT: Pharmacometrics & Systems Pharmacology 2013, 2(9):1-12. 95 |
    6. 96 |
    7. 97 | Ryan PB, Madigan D, Stang PE, Marc Overhage J, Racoosin JA, Hartzema AG: Empirical assessment of methods for risk identification in healthcare data: results from the experiments of the Observational Medical Outcomes Partnership. Statistics in medicine 2012, 31(30):4401-4415. 98 |
    8. 99 |
    9. 100 | Clark N, Hu K, Feldmann A, Kou Y, Chen E, Duan Q, Ma'ayan A: The characteristic direction: a geometrical approach to identify differentially expressed genes. BMC bioinformatics 2014, 15(1):79. 101 |
    10. 102 |
    11. 103 | Wawer MJ, Jaramillo DE, Dančík V, Fass DM, Haggarty SJ, Shamji AF, Wagner BK, Schreiber SL, Clemons PA: Automated Structure–Activity Relationship Mining: Connecting Chemical Structure to Biological Profiles. Journal of Biomolecular Screening 2014, 19(5):738-748. 104 |
    12. 105 |
    13. 106 | Wawer MJ, Li K, Gustafsdottir SM, Ljosa V, Bodycombe NE, Marton MA, Sokolnicki KL, Bray M-A, Kemp MM, Winchester E et al: Toward performance-diverse small-molecule libraries for cell-based phenotypic screening using multiplexed high-dimensional profiling. Proceedings of the National Academy of Sciences 2014, 111(30):10911-10916. 107 |
    14. 108 |
    15. 109 | O'Boyle N, Banck M, James C, Morley C, Vandermeersch T, Hutchison G: Open Babel: An open chemical toolbox. Journal of Cheminformatics 2011, 3(1):33. 110 |
    16. 111 |
    17. 112 | Law V, Knox C, Djoumbou Y, Jewison T, Guo AC, Liu Y, Maciejewski A, Arndt D, Wilson M, Neveu V et al: DrugBank 4.0: shedding new light on drug metabolism. Nucleic Acids Research 2014, 42(D1):D1091-D1097. 113 |
    18. 114 |
    19. 115 | Grigorios T, Ioannis K: Multi-Label Classification: An Overview. International Journal of Data Warehousing and Mining (IJDWM) 2007, 3(3):1-13. 116 |
    20. 117 |
    21. 118 | Meinshausen N, Bühlmann P: Stability selection. Journal of the Royal Statistical Society: Series B (Statistical Methodology) 2010, 72(4):417-473. 119 |
    22. 120 |
    23. 121 | Geurts P, Ernst D, Wehenkel L: Extremely randomized trees. Mach Learn 2006, 63(1):3-42. 122 |
    24. 123 |
    25. 124 | Pedregosa F, Ga, #235, Varoquaux l, Gramfort A, Michel V, Thirion B, Grisel O, Blondel M, Prettenhofer P et al: Scikit-learn: Machine Learning in Python. J Mach Learn Res 2011, 12:2825-2830. 125 |
    26. 126 |
    127 |
    128 | 129 |
    130 |

    Presentation

    131 |

    A webinar discussing the project was presented by Zichen Wang on April 14th, 2015 and is available on YouTube

    132 |
    133 | 134 |
    135 |
    136 | 137 |
    138 |
    139 |
    140 | -------------------------------------------------------------------------------- /data/side_effects_digraph.json: -------------------------------------------------------------------------------- 1 | {"id": "root", "children": [{"id": 0, "children": [{"color": "98df8a", "size": 3, "id": "C0009319", "label": "Colitis"}, {"color": "98df8a", "size": 5, "id": "C1257843", "label": "Pseudomembranous colitis"}, {"color": "1f77b4", "size": 6, "id": "C0008370", "label": "Cholestasis"}, {"color": "9edae5", "size": 4, "id": "C0022658", "label": "Nephropathy"}, {"color": "f7b6d2", "size": 4, "id": "C0002878", "label": "Haemolytic anaemia"}, {"color": "f7b6d2", "size": 2, "id": "C0001824", "label": "Agranulocytosis"}, {"color": "f7b6d2", "size": 2, "id": "C0014457", "label": "Eosinophilia"}, {"color": "9467bd", "size": 4, "id": "C0042267", "label": "Vaginal inflammation"}, {"color": "bcbd22", "size": 2, "id": "C0006840", "label": "Candida infection"}, {"color": "f7b6d2", "size": 2, "id": "C0002874", "label": "Aplastic anaemia"}, {"color": "ff9896", "size": 2, "id": "C0014742", "label": "Erythema multiforme"}]}, {"id": 1, "children": [{"color": "9c9ede", "size": 2, "id": "C0015371", "label": "Extrapyramidal disorder"}, {"color": "2ca02c", "size": 2, "id": "C0024141", "label": "Systemic lupus erythematosus"}, {"color": "9edae5", "size": 2, "id": "C0341697", "label": "Renal impairment"}, {"color": "9edae5", "size": 2, "id": "C0041349", "label": "Tubulointerstitial nephritis"}, {"color": "6b6ecf", "size": 2, "id": "C0151636", "label": "Ventricular extrasystoles"}, {"color": "9c9ede", "size": 2, "id": "C0013384", "label": "Dyskinesia"}, {"color": "98df8a", "size": 2, "id": "C0037036", "label": "Salivary hypersecretion"}, {"color": "2ca02c", "size": 2, "id": "C0085593", "label": "Chills"}, {"color": "9edae5", "size": 2, "id": "C0242528", "label": "Azotaemia"}, {"color": "17becf", "size": 2, "id": "C0206062", "label": "Interstitial lung disease"}, {"color": "7f7f7f", "size": 2, "id": "C0027339", "label": "Nail disorder"}, {"color": "ffbb78", "size": 2, "id": "C0151766", "label": "Liver function test abnormal"}, {"color": "1f77b4", "size": 2, "id": "C0023895", "label": "Liver disorder"}, {"color": "98df8a", "size": 2, "id": "C0232492", "label": "Abdominal pain upper"}, {"color": "6b6ecf", "size": 2, "id": "C0042514", "label": "Ventricular tachycardia"}, {"color": "ff7f0e", "size": 2, "id": "C0042798", "label": "Visual impairment"}, {"color": "2ca02c", "size": 2, "id": "C0026858", "label": "Musculoskeletal pain"}, {"color": "8c564b", "size": 2, "id": "C0852733", "label": "Completed suicide"}, {"color": "ff7f0e", "size": 2, "id": "C0022073", "label": "Iridocyclitis"}, {"color": "98df8a", "size": 2, "id": "C0151596", "label": "Tongue discolouration"}, {"color": "6b6ecf", "size": 2, "id": "C0004245", "label": "Atrioventricular block"}, {"color": "dbdb8d", "size": 2, "id": "C0002622", "label": "Amnesia"}, {"color": "ff9896", "size": 2, "id": "C0014518", "label": "Toxic epidermal necrolysis"}, {"color": "98df8a", "size": 2, "id": "C0149745", "label": "Mouth ulceration"}, {"color": "f7b6d2", "size": 2, "id": "C0030312", "label": "Bone marrow failure"}, {"color": "2ca02c", "size": 2, "id": "C0030196", "label": "Pain in extremity"}, {"color": "7f7f7f", "size": 2, "id": "C0549567", "label": "Pigmentation disorder"}, {"color": "8c564b", "size": 2, "id": "C0575081", "label": "Gait disturbance"}, {"color": "9467bd", "size": 2, "id": "C0025323", "label": "Menorrhagia"}, {"color": "98df8a", "size": 2, "id": "C0017178", "label": "Gastrointestinal disorder"}, {"color": "9edae5", "size": 2, "id": "C0032617", "label": "Polyuria"}, {"color": "9c9ede", "size": 2, "id": "C0020580", "label": "Hypoaesthesia"}, {"color": "dbdb8d", "size": 2, "id": "C0338831", "label": "Mania"}, {"color": "9467bd", "size": 2, "id": "C2979982", "label": "Vaginal haemorrhage"}, {"color": "dbdb8d", "size": 2, "id": "C0439857", "label": "Dependence"}, {"color": "ff7f0e", "size": 2, "id": "C0022568", "label": "Keratitis"}]}, {"id": 2, "children": [{"color": "ffbb78", "size": 2, "id": "C0043096", "label": "Weight decreased"}, {"color": "dbdb8d", "size": 2, "id": "C0013362", "label": "Dysarthria"}, {"color": "bcbd22", "size": 2, "id": "C0027441", "label": "Nasopharyngitis"}, {"color": "6b6ecf", "size": 3, "id": "C0018799", "label": "Cardiac disorder"}, {"color": "8c564b", "size": 2, "id": "C0015376", "label": "Extravasation"}, {"color": "1f77b4", "size": 2, "id": "C0022346", "label": "Jaundice"}, {"color": "ff9896", "size": 2, "id": "C0002994", "label": "Angioedema"}, {"color": "bcbd22", "size": 2, "id": "C0032285", "label": "Pneumonia"}, {"color": "bcbd22", "size": 2, "id": "C0037199", "label": "Sinusitis"}, {"color": "ff9896", "size": 2, "id": "C0006266", "label": "Bronchospasm"}, {"color": "dbdb8d", "size": 2, "id": "C0037822", "label": "Speech disorder"}, {"color": "dbdb8d", "size": 2, "id": "C0234458", "label": "Abnormal dreams"}, {"color": "e377c2", "size": 2, "id": "C0034150", "label": "Purpura"}, {"color": "9edae5", "size": 2, "id": "C0018965", "label": "Haematuria"}, {"color": "8c564b", "size": 2, "id": "C0027540", "label": "Necrosis"}, {"color": "98df8a", "size": 2, "id": "C0030305", "label": "Pancreatitis"}, {"color": "ff7f0e", "size": 2, "id": "C0344232", "label": "Vision blurred"}, {"color": "6b6ecf", "size": 2, "id": "C0027051", "label": "Myocardial infarction"}, {"color": "6b6ecf", "size": 2, "id": "C0018801", "label": "Cardiac failure"}, {"color": "6b6ecf", "size": 2, "id": "C0018802", "label": "Cardiac failure congestive"}, {"color": "98df8a", "size": 2, "id": "C0016204", "label": "Flatulence"}, {"color": "98df8a", "size": 2, "id": "C0038362", "label": "Stomatitis"}, {"color": "e377c2", "size": 2, "id": "C0014591", "label": "Epistaxis"}, {"color": "1f77b4", "size": 2, "id": "C0019158", "label": "Hepatitis"}, {"color": "dbdb8d", "size": 2, "id": "C0027769", "label": "Nervousness"}, {"color": "bcbd22", "size": 2, "id": "C0042029", "label": "Urinary tract infection"}, {"color": "8c564b", "size": 2, "id": "C0041582", "label": "Ulcer"}, {"color": "aec7e8", "size": 2, "id": "C0020456", "label": "Hyperglycaemia"}, {"color": "9edae5", "size": 2, "id": "C0022660", "label": "Renal failure acute"}, {"color": "2ca02c", "size": 2, "id": "C0004604", "label": "Back pain"}, {"color": "aec7e8", "size": 2, "id": "C0740394", "label": "Hyperuricaemia"}, {"color": "9c9ede", "size": 2, "id": "C0027765", "label": "Nervous system disorder"}, {"color": "8c564b", "size": 2, "id": "C0004134", "label": "Ataxia"}, {"color": "e377c2", "size": 2, "id": "C0021308", "label": "Infarction"}, {"color": "bcbd22", "size": 2, "id": "C0021400", "label": "Influenza"}, {"color": "17becf", "size": 3, "id": "C0242184", "label": "Hypoxia"}, {"color": "9edae5", "size": 2, "id": "C0035078", "label": "Renal failure"}, {"color": "98df8a", "size": 2, "id": "C0031350", "label": "Pharyngitis"}, {"color": "8c564b", "size": 2, "id": "C0151828", "label": "Injection site pain"}, {"color": "9467bd", "size": 3, "id": "C0018418", "label": "Gynaecomastia"}, {"color": "6b6ecf", "size": 2, "id": "C0002962", "label": "Angina pectoris"}, {"color": "bcbd22", "size": 2, "id": "C0035455", "label": "Rhinitis"}, {"color": "8c564b", "size": 2, "id": "C1306577", "label": "Death"}, {"color": "dbdb8d", "size": 2, "id": "C0085631", "label": "Agitation"}, {"color": "bcbd22", "size": 2, "id": "C0243026", "label": "Sepsis"}, {"color": "dbdb8d", "size": 2, "id": "C0851578", "label": "Sleep disorder"}, {"color": "5254a3", "size": 2, "id": "C0040264", "label": "Tinnitus"}, {"color": "bcbd22", "size": 2, "id": "C0006277", "label": "Bronchitis"}, {"color": "ff9896", "size": 2, "id": "C0011606", "label": "Dermatitis exfoliative"}, {"color": "1f77b4", "size": 3, "id": "C0085605", "label": "Hepatic failure"}, {"color": "6b6ecf", "size": 2, "id": "C0030252", "label": "Palpitations"}, {"color": "9edae5", "size": 2, "id": "C0080274", "label": "Urinary retention"}, {"color": "aec7e8", "size": 2, "id": "C0020461", "label": "Hyperkalaemia"}, {"color": "ff9896", "size": 2, "id": "C0542571", "label": "Face oedema"}, {"color": "9edae5", "size": 2, "id": "C0013428", "label": "Dysuria"}, {"color": "98df8a", "size": 2, "id": "C0011168", "label": "Dysphagia"}, {"color": "8c564b", "size": 2, "id": "C0333355", "label": "Mucosal inflammation"}, {"color": "ff9896", "size": 2, "id": "C0002792", "label": "Anaphylactic shock"}, {"color": "aec7e8", "size": 2, "id": "C0085649", "label": "Oedema peripheral"}, {"color": "9c9ede", "size": 2, "id": "C0393593", "label": "Dystonia"}, {"color": "7f7f7f", "size": 2, "id": "C0002170", "label": "Alopecia"}, {"color": "ff7f0e", "size": 2, "id": "C0009763", "label": "Conjunctivitis"}, {"color": "9c9ede", "size": 2, "id": "C0040822", "label": "Tremor"}, {"color": "1f77b4", "size": 2, "id": "C0086565", "label": "Hepatic function abnormal"}, {"color": "6b6ecf", "size": 2, "id": "C0428977", "label": "Bradycardia"}, {"color": "bcbd22", "size": 2, "id": "C0041912", "label": "Upper respiratory tract infection"}, {"color": "dbdb8d", "size": 2, "id": "C0018524", "label": "Hallucination"}, {"color": "9467bd", "size": 2, "id": "C0242350", "label": "Erectile dysfunction"}, {"color": "9c9ede", "size": 2, "id": "C0031117", "label": "Neuropathy peripheral"}, {"color": "8c564b", "size": 2, "id": "C0746883", "label": "Febrile neutropenia"}, {"color": "8c564b", "size": 2, "id": "C0016382", "label": "Flushing"}, {"color": "e377c2", "size": 2, "id": "C0020651", "label": "Orthostatic hypotension"}]}, {"id": 3, "children": [{"color": "7f7f7f", "size": 10, "id": "C0026113", "label": "Miliaria"}, {"color": "7f7f7f", "size": 8, "id": "C0234894", "label": "Dermatitis acneiform"}, {"color": "7f7f7f", "size": 11, "id": "C0016436", "label": "Folliculitis"}, {"color": "7f7f7f", "size": 11, "id": "C0162835", "label": "Leukoderma"}, {"color": "7f7f7f", "size": 10, "id": "C0020555", "label": "Hypertrichosis"}, {"color": "8c564b", "size": 10, "id": "C0333641", "label": "Atrophy"}, {"color": "7f7f7f", "size": 11, "id": "C0151514", "label": "Skin atrophy"}, {"color": "7f7f7f", "size": 10, "id": "C0152459", "label": "Skin striae"}]}, {"id": 4, "children": [{"color": "98df8a", "size": 2, "id": "C2363731", "label": "Oropharyngeal pain"}, {"color": "7f7f7f", "size": 5, "id": "C0085932", "label": "Dermatitis bullous"}, {"color": "bcbd22", "size": 8, "id": "C0699744", "label": "Ear infection"}, {"color": "bcbd22", "size": 7, "id": "C0019372", "label": "Herpes virus infection"}, {"color": "2ca02c", "size": 3, "id": "C0151786", "label": "Muscular weakness"}, {"color": "c5b0d5", "size": 4, "id": "C0006826", "label": "Neoplasm malignant"}, {"color": "e377c2", "size": 2, "id": "C0013922", "label": "Embolism"}, {"color": "9edae5", "size": 5, "id": "C0392525", "label": "Nephrolithiasis"}, {"color": "ffbb78", "size": 5, "id": "C0852911", "label": "Blood alkaline phosphatase increased"}, {"color": "98df8a", "size": 4, "id": "C0000731", "label": "Abdominal distension"}, {"color": "17becf", "size": 2, "id": "C1527344", "label": "Dysphonia"}, {"color": "ff7f0e", "size": 3, "id": "C0152227", "label": "Lacrimation increased"}, {"color": "ffbb78", "size": 4, "id": "C0235431", "label": "Blood creatinine increased"}, {"color": "e377c2", "size": 2, "id": "C0149871", "label": "Deep vein thrombosis"}]}, {"id": 5, "children": [{"color": "e377c2", "size": 2, "id": "C0020538", "label": "Hypertension"}, {"color": "dbdb8d", "size": 2, "id": "C0009676", "label": "Confusional state"}, {"color": "2ca02c", "size": 2, "id": "C0231528", "label": "Myalgia"}, {"color": "7f7f7f", "size": 2, "id": "C0011603", "label": "Dermatitis"}, {"color": "dbdb8d", "size": 2, "id": "C0003467", "label": "Anxiety"}, {"color": "8c564b", "size": 2, "id": "C0020458", "label": "Hyperhidrosis"}, {"color": "8c564b", "size": 2, "id": "C0008031", "label": "Chest pain"}, {"color": "5254a3", "size": 2, "id": "C0042571", "label": "Vertigo"}, {"color": "7f7f7f", "size": 2, "id": "C0162830", "label": "Photosensitivity reaction"}, {"color": "6b6ecf", "size": 2, "id": "C0039231", "label": "Tachycardia"}, {"color": "e377c2", "size": 2, "id": "C0019080", "label": "Haemorrhage"}, {"color": "2ca02c", "size": 2, "id": "C0003862", "label": "Arthralgia"}, {"color": "f7b6d2", "size": 2, "id": "C0027947", "label": "Neutropenia"}, {"color": "7f7f7f", "size": 2, "id": "C0041834", "label": "Erythema"}, {"color": "2ca02c", "size": 2, "id": "C0037763", "label": "Muscle spasms"}, {"color": "9c9ede", "size": 2, "id": "C0009951", "label": "Convulsion"}, {"color": "bcbd22", "size": 2, "id": "C0021311", "label": "Infection"}, {"color": "98df8a", "size": 2, "id": "C0043352", "label": "Dry mouth"}, {"color": "17becf", "size": 2, "id": "C0010200", "label": "Cough"}, {"color": "8c564b", "size": 2, "id": "C0015672", "label": "Fatigue"}]}, {"id": 6, "children": [{"color": "7f7f7f", "size": 7, "id": "C0237849", "label": "Skin exfoliation"}, {"color": "ff9896", "size": 7, "id": "C0011616", "label": "Dermatitis contact"}, {"color": "ff9896", "size": 2, "id": "C1318520", "label": "Vasculitis necrotising"}, {"color": "ff9896", "size": 3, "id": "C0004096", "label": "Asthma"}, {"color": "7f7f7f", "size": 7, "id": "C0151908", "label": "Dry skin"}]}, {"id": 7, "children": [{"color": "8c564b", "size": 7, "id": "C0577559", "label": "Mass"}, {"color": "2ca02c", "size": 8, "id": "C0029445", "label": "Osteonecrosis"}, {"color": "ffbb78", "size": 8, "id": "C0542213", "label": "Skin test positive"}, {"color": "aec7e8", "size": 7, "id": "C0342579", "label": "Electrolyte imbalance"}]}, {"id": 8, "children": [{"color": "9467bd", "size": 3, "id": "C0156404", "label": "Menstruation irregular"}, {"color": "8c564b", "size": 2, "id": "C0151692", "label": "Impaired healing"}, {"color": "2ca02c", "size": 9, "id": "C0029456", "label": "Osteoporosis"}, {"color": "aec7e8", "size": 2, "id": "C0011849", "label": "Diabetes mellitus"}, {"color": "ff7f0e", "size": 9, "id": "C0086543", "label": "Cataract"}]}, {"id": 9, "children": [{"color": "ffbb78", "size": 2, "id": "C0043094", "label": "Weight increased"}, {"color": "c5b0d5", "size": 2, "id": "C0027651", "label": "Neoplasm"}, {"color": "7f7f7f", "size": 3, "id": "C0702166", "label": "Acne"}, {"color": "c49c94", "size": 3, "id": "C0019572", "label": "Hirsutism"}, {"color": "1f77b4", "size": 4, "id": "C0022354", "label": "Jaundice cholestatic"}]}]} --------------------------------------------------------------------------------
    ' + headerLabel + '