From 7bce7604b7aa5f70c8b940ef046992d7245a5ae3 Mon Sep 17 00:00:00 2001 From: Shafayat Mahin Date: Tue, 4 Feb 2025 02:35:58 +0600 Subject: [PATCH 1/2] fix: change API address --- app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app.js b/app.js index 158abb4..0a77b65 100644 --- a/app.js +++ b/app.js @@ -296,7 +296,7 @@ async function getModelList(termMap) { //create link and fetch from API const api_url = - "https://vcellapi.cam.uchc.edu/biomodel?bmName=" + termMap["bmName"] + "&bmId=" + termMap["bmId"] + "&category=" + termMap["category"] + "&owner=" + termMap["owner"] + "&savedLow=" + termMap["savedLow"] + "&savedHigh=" + termMap["savedHigh"] + "&startRow=" + APIrow + "&maxRows=" + termMap['maxModels'] + "&orderBy=" + termMap["orderBy"]; + "https://vcell.cam.uchc.edu/api/v0/biomodel?bmName=" + termMap["bmName"] + "&bmId=" + termMap["bmId"] + "&category=" + termMap["category"] + "&owner=" + termMap["owner"] + "&savedLow=" + termMap["savedLow"] + "&savedHigh=" + termMap["savedHigh"] + "&startRow=" + APIrow + "&maxRows=" + termMap['maxModels'] + "&orderBy=" + termMap["orderBy"]; const fetch_response = await fetch(api_url); json = await fetch_response.json(); } @@ -423,7 +423,7 @@ app.get("/testCuratedList/:search", async (req, res) => { // main Dashboard for dynamic models selected from curated list page app.get("/curatedList/model/:name", (req, res) => { const api_url = - 'https://vcellapi.cam.uchc.edu/biomodel/' + req.params.name + '/biomodel.vcml'; + 'https://vcell.cam.uchc.edu/api/v0/biomodel/' + req.params.name + '/biomodel.vcml'; var parser = new xml2js.Parser(); fetch(api_url).then(function(response) { return response.text().then(function(text) { @@ -479,7 +479,7 @@ app.get("/test/:name", (req, res) => { app.get("/curatedList/printModel/:name", (req, res) => { modelName = req.params.name; const api_url = - 'https://vcellapi.cam.uchc.edu/biomodel/' + modelName + '/biomodel.vcml'; + 'https://vcell.cam.uchc.edu/api/v0/biomodel/' + modelName + '/biomodel.vcml'; var parser = new xml2js.Parser(); fetch(api_url).then(function(response) { return response.text().then(function(text) { From 9325f5a6e068a7f696cbc82e5c4fe44c495fb677 Mon Sep 17 00:00:00 2001 From: Shafayat Mahin Date: Thu, 6 Feb 2025 17:53:02 +0600 Subject: [PATCH 2/2] fix: change api and use async to load model --- app.js | 295 ++++++++++++++++++++++------------- public/json/annotations.json | 2 +- temp/modelTemplate.html | 2 +- views/model.hbs | 20 +-- views/printModel.hbs | 2 +- 5 files changed, 202 insertions(+), 119 deletions(-) diff --git a/app.js b/app.js index 0a77b65..2e69f16 100644 --- a/app.js +++ b/app.js @@ -11,27 +11,30 @@ const aPrs = require("./helpers/annotation-parser.js"); const PORT = process.env.PORT || 3000; var indexRouter = require("./routes/index"); +const { title } = require("process"); //todo: //fix column arrow search in biomodel name app.use(express.json()); +app.use(express.static(path.join(__dirname, "public"))); +app.use("/", indexRouter); //read publications and curated file and store for use in curated list //publications -var pubRaw = fs.readFileSync('json-data/publications.json'); +var pubRaw = fs.readFileSync("json-data/publications.json"); const pubs = JSON.parse(pubRaw); delete pubRaw; //curated -var curatedRaw = fs.readFileSync('json-data/curated.json'); +var curatedRaw = fs.readFileSync("json-data/curated.json"); const curated = JSON.parse(curatedRaw); delete curatedRaw; //education -var educationRaw = fs.readFileSync('json-data/education.json'); +var educationRaw = fs.readFileSync("json-data/education.json"); const education = JSON.parse(educationRaw); delete educationRaw; //map -var mapRaw = fs.readFileSync('json-data/pub-map.json'); +var mapRaw = fs.readFileSync("json-data/pub-map.json"); const pubMap = JSON.parse(mapRaw); delete mapRaw; @@ -43,26 +46,26 @@ const hbs = exphbs.create({ // create custom helper helpers: { //the pubmed solutiuon implemented assumes any 8 digit num in model name is a pubmed num - getPubmedModelNum: function(name) { + getPubmedModelNum: function (name) { try { let lastIndex = name.indexOf("::") - 1; if (!lastIndex || lastIndex < 0) { - throw 'No Pubmed Model Num'; + throw "No Pubmed Model Num"; } - let index = lastIndex + let index = lastIndex; //while char is not number while (!isNaN(name.charAt(index))) { - index --; + index--; } - if (name.slice(index - 2, index + 1) != '_MB') { - throw 'No Pubmed Model Num'; + if (name.slice(index - 2, index + 1) != "_MB") { + throw "No Pubmed Model Num"; } return name.slice(index + 1, lastIndex + 1); } catch (e) { return ""; } }, - getPubmedID: function(name, alternateID) { + getPubmedID: function (name, alternateID) { try { if (alternateID) { return alternateID; @@ -70,17 +73,17 @@ const hbs = exphbs.create({ let firstNum = 0; //while char is not number while (isNaN(name.charAt(firstNum))) { - firstNum ++; + firstNum++; if (firstNum > 10000) { - throw 'infinite loop in getPubmedID'; + throw "infinite loop in getPubmedID"; } } let lastNum = firstNum; //while char is number while (!isNaN(name.charAt(lastNum))) { - lastNum ++; + lastNum++; if (lastNum > 10000) { - throw 'infinite loop in getPubmedID'; + throw "infinite loop in getPubmedID"; } } let pubmedID = name.slice(firstNum, lastNum); @@ -90,12 +93,12 @@ const hbs = exphbs.create({ return false; } }, - getPubmedLink: function(pubmedID) { + getPubmedLink: function (pubmedID) { try { if (!pubmedID || pubmedID.length != 8) { - throw 'undefined pubmed id'; + throw "undefined pubmed id"; } - let link = "https://pubmed.ncbi.nlm.nih.gov/" + pubmedID + '/'; + let link = "https://pubmed.ncbi.nlm.nih.gov/" + pubmedID + "/"; return link; } catch (e) { return false; @@ -128,44 +131,44 @@ const hbs = exphbs.create({ let month = date.getMonth(); month += 1; month = month.toString(); - if(month.length === 1) { + if (month.length === 1) { month = "0" + month; } let day = date.getDate().toString(); - if(day.length === 1) { + if (day.length === 1) { day = "0" + day; } - return (month + "/" + day + "/" + year); + return month + "/" + day + "/" + year; }, convertSpace: function (s) { //convert spaces to %20 for use in URLs - return s.replace(/\s/g, '%20'); + return s.replace(/\s/g, "%20"); }, convertTrigger: function (eventObj) { let params = eventObj.Parameter; - let timeList = 'at times: ['; - let observable = 'Error'; + let timeList = "at times: ["; + let observable = "Error"; //loop through params for (let i = 0; i < params.length; i++) { let param = params[i]; let name = param.$.Name; - let val = param._ - if (name == 'triggerTime') { - return('at time ' + val); - } else if (name == 'threshold') { - return('when ' + observable + ' is above/below ' + val); - } else if (name == 'observable') { + let val = param._; + if (name == "triggerTime") { + return "at time " + val; + } else if (name == "threshold") { + return "when " + observable + " is above/below " + val; + } else if (name == "observable") { observable = val; - } else if (name == 'triggerFunction') { - return('on condition: ' + val); - } else if (param.$.Role == 'TimeListItem') { - timeList += val + ','; + } else if (name == "triggerFunction") { + return "on condition: " + val; + } else if (param.$.Role == "TimeListItem") { + timeList += val + ","; } } //only reach here for time list - timeList = timeList.slice(0, timeList.length - 1) + ']'; + timeList = timeList.slice(0, timeList.length - 1) + "]"; return timeList; }, nullCheck: function (inputString) { @@ -188,21 +191,21 @@ const hbs = exphbs.create({ }, initUnits: function (conc, count, volUnit, lumpUnit) { if (conc) { - let pair = volUnit.split('.'); + let pair = volUnit.split("."); return pair[0]; - } else if (count){ + } else if (count) { return lumpUnit; } else { - return 'unknown unit'; + return "unknown unit"; } }, - shortString: function (s, length, dots=false) { + shortString: function (s, length, dots = false) { if (dots) { if (s) { if (s.length > length - 3) { - return s.slice(0, length - 3) + '...'; + return s.slice(0, length - 3) + "..."; } else { - return s.slice(0, length) + '...'; + return s.slice(0, length) + "..."; } } else { return ""; @@ -210,7 +213,7 @@ const hbs = exphbs.create({ } else { if (s) { if (s.length > length - 3) { - return s.slice(0, length - 3) + '...'; + return s.slice(0, length - 3) + "..."; } else { return s.slice(0, length); } @@ -234,69 +237,93 @@ const hbs = exphbs.create({ } }, or: function (a, b) { - return (a || b); + return a || b; }, - not: function(a) { + not: function (a) { return !a; }, isNull: function (s) { - return (s == null); + return s == null; }, add: function (a, b) { - return (parseInt(a) + parseInt(b)); + return parseInt(a) + parseInt(b); }, sub: function (a, b) { - return (parseInt(a) - parseInt(b)); + return parseInt(a) - parseInt(b); }, greater: function (a, b) { - return (a > b); + return a > b; }, eq: function (a, b) { - return (a == b); + return a == b; }, includes: function (a, b) { - return (a.includes(b)); - } + return a.includes(b); + }, }, }); //function used in curated list to generate json model list async function getModelList(termMap) { //handle special case for publucations - if (termMap['category'] == 'publications') { + if (termMap["category"] == "publications") { //get index range - let page = termMap['page']; - let modelsPerPage = termMap['maxModels']; + let page = termMap["page"]; + let modelsPerPage = termMap["maxModels"]; let indexStart = (page - 1) * modelsPerPage; let indexEnd = page * modelsPerPage; //idk why pubs needs to be wrapped in async func, but it does - const func = async ()=> {return pubs.slice(indexStart, indexEnd);}; + const func = async () => { + return pubs.slice(indexStart, indexEnd); + }; var json = await func(); - } else if (termMap['category'] == 'curated') { + } else if (termMap["category"] == "curated") { //get index range - let page = termMap['page']; - let modelsPerPage = termMap['maxModels']; + let page = termMap["page"]; + let modelsPerPage = termMap["maxModels"]; let indexStart = (page - 1) * modelsPerPage; let indexEnd = page * modelsPerPage; //same as pubs above - const func = async ()=> {return curated.slice(indexStart, indexEnd);}; + const func = async () => { + return curated.slice(indexStart, indexEnd); + }; var json = await func(); - } else if (termMap['category'] == 'education') { + } else if (termMap["category"] == "education") { //get index range - let page = termMap['page']; - let modelsPerPage = termMap['maxModels']; + let page = termMap["page"]; + let modelsPerPage = termMap["maxModels"]; let indexStart = (page - 1) * modelsPerPage; let indexEnd = page * modelsPerPage; //same as pubs above - const func = async ()=> {return education.slice(indexStart, indexEnd);}; + const func = async () => { + return education.slice(indexStart, indexEnd); + }; var json = await func(); } else { //calculate row var API uses - const APIrow = termMap['page'] * termMap['maxModels'] - termMap['maxModels'] - 1; + const APIrow = + termMap["page"] * termMap["maxModels"] - termMap["maxModels"] - 1; //create link and fetch from API const api_url = - "https://vcell.cam.uchc.edu/api/v0/biomodel?bmName=" + termMap["bmName"] + "&bmId=" + termMap["bmId"] + "&category=" + termMap["category"] + "&owner=" + termMap["owner"] + "&savedLow=" + termMap["savedLow"] + "&savedHigh=" + termMap["savedHigh"] + "&startRow=" + APIrow + "&maxRows=" + termMap['maxModels'] + "&orderBy=" + termMap["orderBy"]; + "https://vcell.cam.uchc.edu/api/v0/biomodel?bmName=" + + termMap["bmName"] + + "&bmId=" + + termMap["bmId"] + + "&category=" + + termMap["category"] + + "&owner=" + + termMap["owner"] + + "&savedLow=" + + termMap["savedLow"] + + "&savedHigh=" + + termMap["savedHigh"] + + "&startRow=" + + APIrow + + "&maxRows=" + + termMap["maxModels"] + + "&orderBy=" + + termMap["orderBy"]; const fetch_response = await fetch(api_url); json = await fetch_response.json(); } @@ -339,12 +366,12 @@ app.get("/curatedList/:search", async (req, res) => { //if there are no models in list let isNotEmpty = true; - let modelsPerPage = termMap['maxModels']; + let modelsPerPage = termMap["maxModels"]; if (json.length == 0) { isNotEmpty = false; } //make json string for use in filters - let jsonString = (JSON.stringify(json)); + let jsonString = JSON.stringify(json); //replace / escape char in date param termMap["savedLow"] = termMap["savedLow"].replace(/%2F/g, "/"); @@ -373,8 +400,9 @@ app.get("/advancedSearch/:search", async (req, res) => { var termMap = Object.fromEntries(terms); //some vars for startRow and maxRow terms - const APIrow = termMap['page'] * termMap['maxModels'] - termMap['maxModels'] - 1; - let modelsPerPage = termMap['maxModels']; + const APIrow = + termMap["page"] * termMap["maxModels"] - termMap["maxModels"] - 1; + let modelsPerPage = termMap["maxModels"]; res.render("advancedSearch", { title: "ModelBricks - Search", @@ -386,7 +414,7 @@ app.get("/advancedSearch/:search", async (req, res) => { // Curated List offline copy for testing app.get("/testCuratedList/:search", async (req, res) => { //read list json file - var json = fs.readFileSync('json-data/offlineList.json'); + var json = fs.readFileSync("json-data/offlineList.json"); json = JSON.parse(json); //TODO how to get max num of pages? @@ -400,13 +428,14 @@ app.get("/testCuratedList/:search", async (req, res) => { var termMap = Object.fromEntries(terms); //some vars for startRow and maxRow terms - const APIrow = termMap['page'] * termMap['maxModels'] - termMap['maxModels'] - 1; + const APIrow = + termMap["page"] * termMap["maxModels"] - termMap["maxModels"] - 1; //const json = await fetch_response.json(); //if page is empty let isNotEmpty = true; - let modelsPerPage = termMap['maxModels']; + let modelsPerPage = termMap["maxModels"]; if (json.length == 0) { isNotEmpty = false; } @@ -421,35 +450,89 @@ app.get("/testCuratedList/:search", async (req, res) => { }); // main Dashboard for dynamic models selected from curated list page -app.get("/curatedList/model/:name", (req, res) => { - const api_url = - 'https://vcell.cam.uchc.edu/api/v0/biomodel/' + req.params.name + '/biomodel.vcml'; - var parser = new xml2js.Parser(); - fetch(api_url).then(function(response) { - return response.text().then(function(text) { - parser.parseString(text, (err, result) => { - data = result; - /*if (pubMap.hasOwnProperty(data.vcml.BioModel[0].Model[0].Version[0].$.KeyValue)) { - console.log(true); - } else { - console.log(false); - }*/ - let annoObj = new aPrs.AnnParser(data); - let annoData = annoObj.getString(); - let outputOptions = annoObj.getOutputOptions(); - let geometryList = annoObj.getGeometry(); - fs.writeFileSync("./public/json/" + "annotations" + ".json", annoData); - res.render("model", { - title: "ModelBricks - Model Page", - data, - outputOptions, - geometryList, - }); + +app.get("/curatedList/model/:name", async (req, res) => { + try { + console.log("I got Clicked"); + const modelName = req.params.name; + console.log("Model name:", modelName); + + // Validate that the model name is only numbers + if (!/^\d+$/.test(modelName)) { + console.error("Invalid model name:", modelName); + return res.status(400).send("Invalid model name"); + } + + const apiUrl = `https://vcell.cam.uchc.edu/api/v0/biomodel/${modelName}/biomodel.vcml`; + const parser = new xml2js.Parser(); + + // Fetch data + const response = await fetch(apiUrl); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + + // Parse text + const xmlText = await response.text(); + + // Parse XML + const data = await parser.parseStringPromise(xmlText); + + const modifiedData = { + vcml: { + BioModel: data.vcml?.BioModel || [], + }, + }; + + if (!modifiedData.vcml.BioModel?.[0]?.vcmetadata) { + throw new Error("BioModel structure is invalid or missing vcmetadata"); + } + + // Process data + let annoData, outputOptions, geometryList; + try { + const annoObj = new aPrs.AnnParser(modifiedData); + annoData = annoObj.getString(); + outputOptions = annoObj.getOutputOptions(); + geometryList = annoObj.getGeometry(); + } catch (parserError) { + console.error("Annotation parser error:", parserError); + throw new Error("Failed to parse model annotations"); + } + + console.log("Type of annoData:", typeof annoData); + + const outputDir = path.join(__dirname, "public/json"); + const outputPath = path.join(outputDir, "annotations.json"); + console.log("Writing to:", outputPath); // <-- Add this line + + try { + await fs.promises.writeFile(outputPath, annoData, "utf8"); + console.log("File written successfully"); + res.render("model", { + title: "ModelBricks - Model Page", + data, + outputOptions, + geometryList, }); - }); - }); + } catch (writeError) { + console.error("Error writing file:", writeError); + res.status(500).send("Failed to write annotations file"); + } + } catch (error) { + console.error("Error in endpoint:", error); + res.status(500).send(error.message); + } }); +// Render template +// res.render("test", { +// title: "ModelBricks - Model Page", +// data, +// outputOptions, +// geometryList, +// }); + //page for offline testing app.get("/test/:name", (req, res) => { var parser = new xml2js.Parser(); @@ -457,7 +540,7 @@ app.get("/test/:name", (req, res) => { parser.parseString(data, (err, result) => { data = result; if (!data) { - res.send('no filed named ' + req.params.name + ".vcml"); + res.send("no filed named " + req.params.name + ".vcml"); } else { let annoObj = new aPrs.AnnParser(data); let annoData = annoObj.getString(); @@ -470,7 +553,7 @@ app.get("/test/:name", (req, res) => { outputOptions, geometryList, }); - }; + } }); }); }); @@ -479,10 +562,12 @@ app.get("/test/:name", (req, res) => { app.get("/curatedList/printModel/:name", (req, res) => { modelName = req.params.name; const api_url = - 'https://vcell.cam.uchc.edu/api/v0/biomodel/' + modelName + '/biomodel.vcml'; + "https://vcell.cam.uchc.edu/api/v0/biomodel/" + + modelName + + "/biomodel.vcml"; var parser = new xml2js.Parser(); - fetch(api_url).then(function(response) { - return response.text().then(function(text) { + fetch(api_url).then(function (response) { + return response.text().then(function (text) { parser.parseString(text, (err, result) => { data = result; let annoObj = new aPrs.AnnParser(data); @@ -519,16 +604,14 @@ app.get("/static/:name", async (req, res) => { }); //Declaring static informative pages folder (Home, About, motivation etc) - public -app.use(express.static(path.join(__dirname, "public"))); // Routing of informative pages - routes/index.js -app.use("/", indexRouter); //catch all route, make sure its defined last app.get("*", async (req, res) => { let search = req.params; res.render("catch-all", { - search + search, }); }); diff --git a/public/json/annotations.json b/public/json/annotations.json index 0bbdca3..0990573 100644 --- a/public/json/annotations.json +++ b/public/json/annotations.json @@ -1 +1 @@ -{"BioModel":{"$":{"name":"PLACEHOLDER"},"math":[],"text":[{"$":{"name":"ReactionStep(activation of Rab7 by GEF7)"},"_":"Activation of RAB7_GDP by its own activated counterpart Rab7_GTP.\n\n \n\n \n\n Authors state that parameter values were sampled from reasonable ranges."},{"$":{"name":"ReactionStep(activation of Rab7 by GEF5)"},"_":"activation of Rab7_GDP catalyzed by activated Rab5_GTP.\n\n \n\n \n\n Authors state that parameter values were sampled from reasonable ranges."},{"$":{"name":"MolecularType(RAB5)"},"_":"Active Rab5 orchestrates the recruitment of a multi-effector protein \n machinery that performs various functions in endosome membrane tethering \n and fusion as well as microtubule- and actin-dependent motility"},{"$":{"name":"ReactionStep(Recruitment of Rab7_GDP)"},"_":"Rab7 is recruited for the proccess. \n\n \n\n \n\n Authors state that parameter values were sampled from reasonable ranges."},{"$":{"name":"Species(Rab7_GTP)"},"_":"GTP-bound Rab7 (active)"},{"$":{"name":"ReactionStep(Hydrolysis of Rab7_GTP)"},"_":"Hydrolysis of GTP to GDP on Rab7. \n\n\n\n \n\n Authors state that parameter values were sampled from reasonable ranges."},{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"This \n ModelBrick from the publication \"Membrane identity and GTPase cascades \n regulated by toggle and cut-out switches\" describes Rab activation and \n hydrolysis. According to this model, Rab5 activates Rab7 until Rab7 \n reaches a threshold upon which it inactivates Rab5 through a negative \n feedback loop."},{"$":{"name":"SimulationContext(Deterministic)"},"_":""},{"$":{"name":"MolecularType(GDP)"},"_":"GDP-bound Rab indicates the active form"},{"$":{"name":"Species(Rab5_GTP)"},"_":"Active Rab5 orchestrates the recruitment of a multi-effector protein \n machinery that performs various functions in endosome membrane tethering \n and fusion as well as microtubule- and actin-dependent motility"},{"$":{"name":"SpeciesContext(Rab7_GDP)"},"_":""},{"$":{"name":"MolecularType(GTP)"},"_":"GTP-bound Rab indicates the active form"},{"$":{"name":"ReactionStep(Extraction of Rab7_GDP)"},"_":"Degradation of Rab7_GDP. \n\n\n\n \n\n Authors state that parameter values were sampled from reasonable ranges."},{"$":{"name":"Species(Rab7_GDP)"},"_":"GDP-bound Rab7 (inactive)"}],"url":{"$011MolecularType(RAB5)":{"$":{"name":"MolecularType(RAB5)"},"_":"urn:miriam:uniprot:P20339","vcid":"MolecularType(RAB5)","qualifier":"(bio) is","literalQualifier":"is"},"$011MolecularType(Rab7)":{"$":{"name":"MolecularType(Rab7)"},"_":"urn:miriam:uniprot:P51149","vcid":"MolecularType(Rab7)","qualifier":"(bio) is","literalQualifier":"is"},"$011MolecularType(GTP)":{"$":{"name":"MolecularType(GTP)"},"_":"urn:miriam:chebi:CHEBI%3A15996","vcid":"MolecularType(GTP)","qualifier":"(bio) is","literalQualifier":"is"},"$011MolecularType(GDP)":{"$":{"name":"MolecularType(GDP)"},"_":"urn:miriam:chebi:CHEBI%3A17552","vcid":"MolecularType(GDP)","qualifier":"(bio) is","literalQualifier":"is"},"$011BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"http://identifiers.org/mamo/MAMO_0000046","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(bio) hasProperty","literalQualifier":"hasProperty"},"$012BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"http://identifiers.org/taxonomy/9606","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(bio) hasTaxon","literalQualifier":"hasTaxon"},"$013BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"urn:miriam:obo.go:GO%3A0043087","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$014BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"http://identifiers.org/biomodels.db/BIOMD0000000174","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(model) is","literalQualifier":"is"},"$114BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"http://identifiers.org/biomodels.db/MODEL5937037510","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(model) is","literalQualifier":"is"},"$015BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"http://identifiers.org/pubmed/10591225","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(model) isDerivedFrom","literalQualifier":"isDerivedFrom"},"$025BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"http://identifiers.org/pubmed/16890441","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(model) isDerivedFrom","literalQualifier":"isDerivedFrom"},"$016BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"urn:miriam:doi:10.1038%2Fmsb.2008.45+","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(model) isDescribedBy","literalQualifier":"isDescribedBy"},"$116BioModel(CM_PM18628746_MB2::Rab7_switch)":{"$":{"name":"BioModel(CM_PM18628746_MB2::Rab7_switch)"},"_":"http://identifiers.org/pubmed/18628746","vcid":"BioModel(CM_PM18628746_MB2::Rab7_switch)","qualifier":"(model) isDescribedBy","literalQualifier":"isDescribedBy"},"$011Structure(endosome)":{"$":{"name":"Structure(endosome)"},"_":"http://identifiers.org/go/GO:0010008","vcid":"Structure(endosome)","qualifier":"(bio) is","literalQualifier":"is"},"$011Species(Rab5_GTP)":{"$":{"name":"Species(Rab5_GTP)"},"_":"urn:miriam:chebi:CHEBI%3A15996","vcid":"Species(Rab5_GTP)","qualifier":"(bio) hasPart","literalQualifier":"hasPart"},"$111Species(Rab5_GTP)":{"$":{"name":"Species(Rab5_GTP)"},"_":"urn:miriam:uniprot:P20339","vcid":"Species(Rab5_GTP)","qualifier":"(bio) hasPart","literalQualifier":"hasPart"},"$012Species(Rab5_GTP)":{"$":{"name":"Species(Rab5_GTP)"},"_":"http://identifiers.org/go/GO:0031225","vcid":"Species(Rab5_GTP)","qualifier":"(bio) is","literalQualifier":"is"},"$011Species(Rab7_GDP)":{"$":{"name":"Species(Rab7_GDP)"},"_":"urn:miriam:uniprot:P51149","vcid":"Species(Rab7_GDP)","qualifier":"(bio) hasPart","literalQualifier":"hasPart"},"$012Species(Rab7_GDP)":{"$":{"name":"Species(Rab7_GDP)"},"_":"http://identifiers.org/go/GO:0031225","vcid":"Species(Rab7_GDP)","qualifier":"(bio) is","literalQualifier":"is"},"$013Species(Rab7_GDP)":{"$":{"name":"Species(Rab7_GDP)"},"_":"urn:miriam:chebi:CHEBI%3A17552","vcid":"Species(Rab7_GDP)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$011Species(Rab7_GTP)":{"$":{"name":"Species(Rab7_GTP)"},"_":"urn:miriam:uniprot:P51149","vcid":"Species(Rab7_GTP)","qualifier":"(bio) hasPart","literalQualifier":"hasPart"},"$111Species(Rab7_GTP)":{"$":{"name":"Species(Rab7_GTP)"},"_":"urn:miriam:chebi:CHEBI%3A15996","vcid":"Species(Rab7_GTP)","qualifier":"(bio) hasPart","literalQualifier":"hasPart"},"$012Species(Rab7_GTP)":{"$":{"name":"Species(Rab7_GTP)"},"_":"http://identifiers.org/go/GO:0031225","vcid":"Species(Rab7_GTP)","qualifier":"(bio) is","literalQualifier":"is"},"$011ReactionStep(Recruitment of Rab7_GDP)":{"$":{"name":"ReactionStep(Recruitment of Rab7_GDP)"},"_":"http://identifiers.org/go/GO:0045184","vcid":"ReactionStep(Recruitment of Rab7_GDP)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$011ReactionStep(activation of Rab7 by GEF7)":{"$":{"name":"ReactionStep(activation of Rab7 by GEF7)"},"_":"urn:miriam:reactome:R-HSA-8877451.2","vcid":"ReactionStep(activation of Rab7 by GEF7)","qualifier":"(bio) isPartOf","literalQualifier":"isPartOf"},"$012ReactionStep(activation of Rab7 by GEF7)":{"$":{"name":"ReactionStep(activation of Rab7 by GEF7)"},"_":"http://identifiers.org/go/GO:0017112","vcid":"ReactionStep(activation of Rab7 by GEF7)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$022ReactionStep(activation of Rab7 by GEF7)":{"$":{"name":"ReactionStep(activation of Rab7 by GEF7)"},"_":"http://identifiers.org/go/GO:0032858","vcid":"ReactionStep(activation of Rab7 by GEF7)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$011ReactionStep(activation of Rab7 by GEF5)":{"$":{"name":"ReactionStep(activation of Rab7 by GEF5)"},"_":"urn:miriam:reactome:R-HSA-8877451.2","vcid":"ReactionStep(activation of Rab7 by GEF5)","qualifier":"(bio) isPartOf","literalQualifier":"isPartOf"},"$012ReactionStep(activation of Rab7 by GEF5)":{"$":{"name":"ReactionStep(activation of Rab7 by GEF5)"},"_":"http://identifiers.org/go/GO:0032858","vcid":"ReactionStep(activation of Rab7 by GEF5)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$022ReactionStep(activation of Rab7 by GEF5)":{"$":{"name":"ReactionStep(activation of Rab7 by GEF5)"},"_":"http://identifiers.org/go/GO:0017112","vcid":"ReactionStep(activation of Rab7 by GEF5)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$011ReactionStep(Hydrolysis of Rab7_GTP)":{"$":{"name":"ReactionStep(Hydrolysis of Rab7_GTP)"},"_":"http://identifiers.org/go/GO:0003924","vcid":"ReactionStep(Hydrolysis of Rab7_GTP)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"}},"qualifier":"","literalQualifier":""}} \ No newline at end of file +{"BioModel":{"$":{"name":"PLACEHOLDER"},"math":[],"text":[{"$":{"name":"BioModel(CM_PM25628036_MB1::GEF_activation)"},"_":"This ModelBrick \n\n from the article, \"Positive regulation of Rho GTPase activity by \n\n RhoGDIs as a result of their direct interaction with GAPs\" describes \n\n the activation of GEF and the degradation of the activator. GDIs inhibit \n\n GEF and GAP activities by sequestering GTPase (kinetic law was adjusted \n\n to eliminate effect of GDI on both GEF and GAP)."},{"$":{"name":"MolecularType(RhoGEF)"},"_":"Seems to play a role in the regulation of RhoA GTPase by guanine \n\n nucleotide-binding alpha-12 (GNA12) and alpha-13 (GNA13) subunits \n\n (PubMed:9641915, PubMed:9641916). Acts as GTPase-activating protein (GAP) \n\n for GNA12 and GNA13, and as guanine nucleotide exchange factor (GEF) for \n\n RhoA GTPase (PubMed:9641915, PubMed:9641916, PubMed:8810315, \n\n PubMed:30521495). Activated G alpha 13/GNA13 stimulates the RhoGEF \n\n activity through interaction with the RGS-like domain (PubMed:9641916). \n\n This GEF activity is inhibited by binding to activated GNA12 \n\n (PubMed:9641916). Mediates angiotensin-2-induced RhoA activation \n\n (PubMed:20098430)."},{"$":{"name":"ReactionStep(GEF_activation)"},"_":"Activation of GEF.\n\n \n\n \n\n The forward reaction rate parameter (k1) is assigned an arbitrary value \n\n (1 uM-1min-1)."},{"$":{"name":"SpeciesContext(GEF)"},"_":"guanine nucleotide exchange factors: Activate small G proteins by \n\n promoting exchange of GDP for GTP"},{"$":{"name":"MolecularType(Activator)"},"_":"Receptor \n tyrosine kinase binding ligands of the EGF family and activating several \n signaling cascades to convert extracellular cues into appropriate cellular \n responses (PubMed:8404850). \n Known ligands include EGF, TGFA/TGF-alpha, AREG, epigen/EPGN, \n BTC/betacellulin, epiregulin/EREG and HBEGF/heparin-binding EGF. Ligand \n binding triggers receptor homo- and/or heterodimerization and \n autophosphorylation on key cytoplasmic residues. The phosphorylated \n receptor recruits adapter proteins like GRB2 which in turn activates \n complex downstream signaling cascades. Activates at least 4 major \n downstream signaling cascades including the RAS-RAF-MEK-ERK, PI3 \n kinase-AKT, PLCgamma-PKC and STATs modules. May also activate the \n NF-kappa-B signaling cascade. Also directly phosphorylates other proteins \n like RGS16, activating its GTPase activity and probably coupling the EGF \n receptor signaling to the G protein-coupled receptor signaling. Also \n phosphorylates MUC1 and increases its interaction with SRC and \n CTNNB1/beta-catenin (By similarity). Positively regulates cell migration \n via interaction with CCDC88A/GIV which retains EGFR at the cell membrane \n following ligand stimulation, promoting EGFR signaling which triggers cell \n migration (By similarity). Plays a role in enhancing learning and memory \n performance (PubMed:20639532)."},{"$":{"name":"ReactionStep(Activator_degradation)"},"_":"Activator degradation. \n\n \n\n \n\n The forward reaction rate parameter (k3) is assigned an arbitrary value \n\n (1 uM-1min-1)."},{"$":{"name":"Species(Active_GEF)"},"_":"guanine nucleotide exchange factor (GEF)- regulator of RhoGTPases. GEFs \n\n activate GTPases by promoting the exchange of GDP for GTP. GAPs inactivate \n\n GTPases by stimulating their intrinsic GTP-hydrolyzing activity. "},{"$":{"name":"ReactionStep(GEF_inactivation)"},"_":"Inactivation of GEF.\n\n \n\n \n\n The forward reaction rate parameter (k2) is assigned an arbitrary value \n\n (0.1 min-1)."},{"$":{"name":"Species(Activator)"},"_":"The authors used 1 uM for the cellular concentration of the activator \n (arbitrary value)."},{"$":{"name":"Species(GEF)"},"_":"guanine nucleotide exchange factor (GEF)- regulator of RhoGTPases. GEFs \n\n activate GTPases by promoting the exchange of GDP for GTP. GAPs inactivate \n\n GTPases by stimulating their intrinsic GTP-hydrolyzing activity. The \n\n authors used 0.31 uM for the cellular concentration of GEF (Aoki, 2007)."},{"$":{"name":"SimulationContext(Canonical Application)"},"_":""}],"url":{"$011ReactionStep(GEF_activation)":{"$":{"name":"ReactionStep(GEF_activation)"},"_":"urn:miriam:obo.go:GO%3A0005085","vcid":"ReactionStep(GEF_activation)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$011ReactionStep(GEF_inactivation)":{"$":{"name":"ReactionStep(GEF_inactivation)"},"_":"urn:miriam:obo.go:GO%3A0005085","vcid":"ReactionStep(GEF_inactivation)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$011MolecularType(RhoGEF)":{"$":{"name":"MolecularType(RhoGEF)"},"_":"urn:miriam:uniprot:Q92888","vcid":"MolecularType(RhoGEF)","qualifier":"(bio) hasVersion","literalQualifier":"hasVersion"},"$012MolecularType(RhoGEF)":{"$":{"name":"MolecularType(RhoGEF)"},"_":"urn:miriam:obo.go:GO%3A0005089","vcid":"MolecularType(RhoGEF)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$011Species(GEF)":{"$":{"name":"Species(GEF)"},"_":"urn:miriam:uniprot:Q92888","vcid":"Species(GEF)","qualifier":"(bio) hasVersion","literalQualifier":"hasVersion"},"$012Species(GEF)":{"$":{"name":"Species(GEF)"},"_":"urn:miriam:obo.go:GO%3A0005089","vcid":"Species(GEF)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$013Species(GEF)":{"$":{"name":"Species(GEF)"},"_":"urn:miriam:pubmed:17535963","vcid":"Species(GEF)","qualifier":"(model) isDerivedFrom","literalQualifier":"isDerivedFrom"},"$113Species(GEF)":{"$":{"name":"Species(GEF)"},"_":"urn:miriam:doi:10.1083%2Fjcb.200609017","vcid":"Species(GEF)","qualifier":"(model) isDerivedFrom","literalQualifier":"isDerivedFrom"},"$011Species(Active_GEF)":{"$":{"name":"Species(Active_GEF)"},"_":"urn:miriam:uniprot:Q92888","vcid":"Species(Active_GEF)","qualifier":"(bio) hasVersion","literalQualifier":"hasVersion"},"$012Species(Active_GEF)":{"$":{"name":"Species(Active_GEF)"},"_":"urn:miriam:obo.go:GO%3A0005089","vcid":"Species(Active_GEF)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$011BioModel(CM_PM25628036_MB1::GEF_activation)":{"$":{"name":"BioModel(CM_PM25628036_MB1::GEF_activation)"},"_":"urn:miriam:doi:10.1146%2Fannurev.cellbio.21.020604.150721","vcid":"BioModel(CM_PM25628036_MB1::GEF_activation)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$111BioModel(CM_PM25628036_MB1::GEF_activation)":{"$":{"name":"BioModel(CM_PM25628036_MB1::GEF_activation)"},"_":"urn:miriam:pubmed:16212495","vcid":"BioModel(CM_PM25628036_MB1::GEF_activation)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$211BioModel(CM_PM25628036_MB1::GEF_activation)":{"$":{"name":"BioModel(CM_PM25628036_MB1::GEF_activation)"},"_":"urn:miriam:obo.go:GO%3A0043087","vcid":"BioModel(CM_PM25628036_MB1::GEF_activation)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$311BioModel(CM_PM25628036_MB1::GEF_activation)":{"$":{"name":"BioModel(CM_PM25628036_MB1::GEF_activation)"},"_":"urn:miriam:reactome:R-HSA-194315.4","vcid":"BioModel(CM_PM25628036_MB1::GEF_activation)","qualifier":"(bio) isVersionOf","literalQualifier":"isVersionOf"},"$012BioModel(CM_PM25628036_MB1::GEF_activation)":{"$":{"name":"BioModel(CM_PM25628036_MB1::GEF_activation)"},"_":"urn:miriam:doi:10.1186%2Fs12918-015-0143-5","vcid":"BioModel(CM_PM25628036_MB1::GEF_activation)","qualifier":"(model) isDescribedBy","literalQualifier":"isDescribedBy"},"$112BioModel(CM_PM25628036_MB1::GEF_activation)":{"$":{"name":"BioModel(CM_PM25628036_MB1::GEF_activation)"},"_":"urn:miriam:pubmed:25628036","vcid":"BioModel(CM_PM25628036_MB1::GEF_activation)","qualifier":"(model) isDescribedBy","literalQualifier":"isDescribedBy"}},"qualifier":"","literalQualifier":""}} \ No newline at end of file diff --git a/temp/modelTemplate.html b/temp/modelTemplate.html index e661e4e..90a23d0 100644 --- a/temp/modelTemplate.html +++ b/temp/modelTemplate.html @@ -30,7 +30,7 @@

Reaction Diagram

{{#each data.vcml.BioModel}} {{#each this.Version}} reactionDiagram diff --git a/views/model.hbs b/views/model.hbs index 34b8ec1..ffd6282 100644 --- a/views/model.hbs +++ b/views/model.hbs @@ -163,7 +163,7 @@