From 9f4a24bb4732e3f60126d70ea488d623db1fb30e Mon Sep 17 00:00:00 2001 From: tmushayahama Date: Tue, 21 Jan 2025 20:38:06 -0800 Subject: [PATCH 1/3] Added the visited activities to know the stopping point --- .../@noctua.form/models/activity/cam.ts | 84 ---------------- .../@noctua.form/services/graph.service.ts | 98 ++++--------------- 2 files changed, 21 insertions(+), 161 deletions(-) diff --git a/src/globals/@noctua.form/models/activity/cam.ts b/src/globals/@noctua.form/models/activity/cam.ts index 2c4b63e..2177930 100644 --- a/src/globals/@noctua.form/models/activity/cam.ts +++ b/src/globals/@noctua.form/models/activity/cam.ts @@ -135,7 +135,6 @@ export class Cam { manualLayout = false; layoutChanged = false; - private _filteredActivities: Activity[] = []; activities: Activity[] = []; storedActivities: Activity[] = []; private _id: string; @@ -254,49 +253,6 @@ export class Cam { } - applyFilter() { - const self = this; - - self.clearHighlight(); - - if (self.queryMatch && self.queryMatch.terms.length > 0) { - self._filteredActivities = []; - self.matchedCount = 0; - - each(self.activities, (activity: Activity) => { - let match = false; - each(activity.nodes, (node: ActivityNode) => { - each(self.queryMatch.terms, (term) => { - - if (node.term.uuid === term.uuid) { - node.term.highlight = true; - node.term.activityDisplayId = term.activityDisplayId = activity.displayId; - - self.matchedCount += 1; - match = true; - } - }); - - each(node.predicate.evidence, (evidence: Evidence) => { - each(self.queryMatch.terms, (term) => { - - if (evidence.uuid === term.uuid) { - evidence.referenceEntity.highlight = true; - evidence.referenceEntity.activityDisplayId = term.activityDisplayId = activity.displayId; - - self.matchedCount += 1; - match = true; - } - }); - }); - }); - - if (match) { - self._filteredActivities.push(activity); - } - }); - } - } applyWeights(weight = 0) { const self = this; @@ -425,28 +381,6 @@ export class Cam { return result; } - tableCanDisplayEnabledBy(node: ActivityNode) { - return node.predicate.edge && node.predicate.edge.id === noctuaFormConfig.edge.enabledBy.id; - } - - tableDisplayExtension(node: ActivityNode) { - if (node.id === 'mf') { - return ''; - } else if (node.isComplement) { - return 'NOT ' + node.predicate.edge.label; - } else { - return node.predicate.edge.label; - } - } - - updateActivityDisplayNumber() { - const self = this; - - each(self.activities, (activity: Activity, key) => { - activity.displayNumber = self.displayNumber + '.' + (key + 1).toString(); - }); - } - updateProperties() { const self = this; @@ -457,23 +391,5 @@ export class Cam { this.sortBy.label = noctuaFormConfig.activitySortField.options[this.sortBy.field]?.label } - private _getGPText(a: Activity): string { - return a.presentation.gpText.toLowerCase() - } - - private _getMFText(a: Activity): string { - if (!a.mfNode) return '' - return a.mfNode.term.label; - } - private _getBPText(a: Activity): string { - if (!a.bpNode) return '' - return a.bpNode.term.label; - } - private _getCCText(a: Activity): string { - if (!a.ccNode) return '' - return a.ccNode.term.label; - } - - } diff --git a/src/globals/@noctua.form/services/graph.service.ts b/src/globals/@noctua.form/services/graph.service.ts index eff10cd..270d855 100644 --- a/src/globals/@noctua.form/services/graph.service.ts +++ b/src/globals/@noctua.form/services/graph.service.ts @@ -97,7 +97,7 @@ export class NoctuaGraphService { loadCam(cam: Cam) { const self = this; const activities = self.graphToActivities(cam.graph); - const molecules = self.graphToMolecules(cam.graph); + const molecules = self.graphToMolecules(cam.graph, activities.map((activity) => activity.id)); activities.push(...molecules); @@ -105,9 +105,6 @@ export class NoctuaGraphService { cam.updateProperties() cam.causalRelations = self.getCausalRelations(cam); - - cam.applyFilter(); - cam.updateActivityDisplayNumber(); } getNodeInfo(node) { @@ -283,67 +280,6 @@ export class NoctuaGraphService { subjectNode.hasRootType(EntityDefinition.GoMolecularEntity)) } - getTerms(camGraph): TermsSummary { - const self = this; - const termsSummary = new TermsSummary() - const nodes = [] - const frequency = {} - - each(camGraph.all_nodes(), (bbopNode) => { - const node = self.nodeToActivityNode(camGraph, bbopNode.id()); - node.id = node.uuid; - nodes.push(node) - frequency[node.term.id] = frequency[node.term.id] ? frequency[node.term.id] + 1 : 1; - - - if (node.hasRootType(EntityDefinition.GoMolecularEntity)) { - termsSummary.gp.frequency++; - } else if (node.hasRootType(EntityDefinition.GoMolecularFunction)) { - termsSummary.mf.frequency++; - } else if (node.hasRootType(EntityDefinition.GoBiologicalProcess)) { - termsSummary.bp.frequency++; - } else if (node.hasRootType(EntityDefinition.GoCellularComponent)) { - termsSummary.cc.frequency++; - } else if (node.hasRootType(EntityDefinition.GoEvidenceNode)) { - // continue - } else { - termsSummary.other.frequency++; - } - }); - - const uniqueNodes = chain(nodes) - .uniqWith(compareTerm) - .value(); - - each(uniqueNodes, (node: ActivityNode) => { - node.frequency = frequency[node.term.id] - - if (node.hasRootType(EntityDefinition.GoMolecularEntity)) { - node.type = ActivityNodeType.GoMolecularEntity - termsSummary.gp.append(node) - } else if (node.hasRootType(EntityDefinition.GoMolecularFunction)) { - node.type = ActivityNodeType.GoMolecularFunction - termsSummary.mf.append(node) - } else if (node.hasRootType(EntityDefinition.GoBiologicalProcess)) { - node.type = ActivityNodeType.GoBiologicalProcess - termsSummary.bp.append(node) - } else if (node.hasRootType(EntityDefinition.GoCellularComponent)) { - node.type = ActivityNodeType.GoCellularComponent - termsSummary.cc.append(node) - } else if (node.hasRootType(EntityDefinition.GoEvidenceNode)) { - // continue - } else { - termsSummary.other.append(node) - } - }) - - termsSummary.allTerms = uniqueNodes - - return termsSummary - } - - - getActivityPreset(subjectNode: Partial, objectNode: Partial, predicateId, bbopSubjectEdges): Activity { const self = this; let activityType = ActivityType.default; @@ -407,13 +343,17 @@ export class NoctuaGraphService { } - graphToMolecules(camGraph): Activity[] { + graphToMolecules(camGraph, visitedMFNodeIds?: string[]): Activity[] { const self = this; - const activities: Activity[] = []; + const mols: Activity[] = []; - each(camGraph.all_nodes(), (bbopNode) => { + for (const bbopNode of camGraph.all_nodes()) { const subjectNode = self.nodeToActivityNode(camGraph, bbopNode.id()); + if (visitedMFNodeIds.includes(bbopNode.id())) { + continue + } + if (subjectNode.hasRootType(EntityDefinition.GoChemicalEntity) && !subjectNode.hasRootType(EntityDefinition.GoMolecularEntity)) { const subjectEdges = camGraph.get_edges_by_subject(bbopNode.id()) const objectEdges = camGraph.get_edges_by_object(bbopNode.id()) @@ -431,15 +371,15 @@ export class NoctuaGraphService { subjectActivityNode.classExpression = subjectNode.classExpression; subjectActivityNode.uuid = bbopNode.id(); activity.id = bbopNode.id(); - self._graphToActivityDFS(camGraph, activity, subjectEdges, subjectActivityNode); + self._graphToActivityDFS(camGraph, activity, subjectEdges, subjectActivityNode, visitedMFNodeIds); //activity.postRunUpdate(); - activities.push(activity); + mols.push(activity); } } - }); + }; - return activities + return mols } @@ -477,13 +417,19 @@ export class NoctuaGraphService { } - private _graphToActivityDFS(camGraph, activity: Activity, bbopEdges, subjectNode: ActivityNode) { + private _graphToActivityDFS(camGraph, activity: Activity, bbopEdges, subjectNode: ActivityNode, visitedNodeIds: string[] = []): Activity { const self = this; for (const bbopEdge of bbopEdges) { - + const bbopObjectId = bbopEdge.object_id(); const bbopPredicateId = bbopEdge.predicate_id(); + console.log('object', bbopObjectId, 'predicate', bbopPredicateId, 'visitedNodeIds', visitedNodeIds) + + if (visitedNodeIds.includes(bbopObjectId)) { + continue + } + const allowedPredicate = this.noctuaFormConfigService.shapePredicates.find((predicate) => { return predicate === bbopPredicateId; }); @@ -505,8 +451,6 @@ export class NoctuaGraphService { if (!result.includes(bbopPredicateId)) continue; - - const bbopObjectId = bbopEdge.object_id(); const evidence = self.edgeToEvidence(camGraph, bbopEdge); const comments = self.edgeComments(bbopEdge); const partialObjectNode = self.nodeToActivityNode(camGraph, bbopObjectId); @@ -529,7 +473,7 @@ export class NoctuaGraphService { triple.predicate.evidence = evidence; triple.predicate.comments = comments; triple.predicate.uuid = bbopEdge.id(); - self._graphToActivityDFS(camGraph, activity, camGraph.get_edges_by_subject(bbopObjectId), triple.object); + self._graphToActivityDFS(camGraph, activity, camGraph.get_edges_by_subject(bbopObjectId), triple.object, visitedNodeIds); } } } From 184cb4090cad5a4a965540ece5f41c38e292704f Mon Sep 17 00:00:00 2001 From: tmushayahama Date: Tue, 21 Jan 2025 21:16:24 -0800 Subject: [PATCH 2/3] added option to filter CC out --- .../@noctua.form/services/graph.service.ts | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/globals/@noctua.form/services/graph.service.ts b/src/globals/@noctua.form/services/graph.service.ts index 270d855..aab46ac 100644 --- a/src/globals/@noctua.form/services/graph.service.ts +++ b/src/globals/@noctua.form/services/graph.service.ts @@ -3,14 +3,13 @@ import * as EntityDefinition from './../data/config/entity-definition'; import { noctuaFormConfig } from './../noctua-form-config'; import { NoctuaFormConfigService } from './noctua-form-config.service'; import { Activity, ActivityType } from './../models/activity/activity'; -import { find, each, chain } from 'lodash'; -import { ActivityNode, ActivityNodeType, compareTerm, GoCategory } from './../models/activity/activity-node'; -import { Cam, CamOperation } from './../models/activity/cam'; +import { find, each } from 'lodash'; +import { ActivityNode, GoCategory } from './../models/activity/activity-node'; +import { Cam } from './../models/activity/cam'; import { Entity } from './../models/activity/entity'; import { Evidence } from './../models/activity/evidence'; import { Predicate } from './../models/activity/predicate'; import { Triple } from './../models/activity/triple'; -import { TermsSummary } from './../models/activity/summary'; import moment from 'moment'; import { graph as bbopGraph } from 'bbop-graph-noctua'; import { DBXrefService } from '../../dbxref.service'; @@ -94,17 +93,23 @@ export class NoctuaGraphService { return cam; } - loadCam(cam: Cam) { - const self = this; - const activities = self.graphToActivities(cam.graph); - const molecules = self.graphToMolecules(cam.graph, activities.map((activity) => activity.id)); + loadCam(cam: Cam, removeCC: boolean = false) { + let activities = this.graphToActivities(cam.graph); + + if (removeCC) { + activities = activities?.filter((activity) => + activity.activityType === ActivityType.default || + activity.activityType === ActivityType.bpOnly || + activity.activityType === ActivityType.proteinComplex); + } + + const molecules = this.graphToMolecules(cam.graph, activities.map((activity) => activity.id)); activities.push(...molecules); cam.activities = activities; cam.updateProperties() - cam.causalRelations = self.getCausalRelations(cam); - + cam.causalRelations = this.getCausalRelations(cam); } getNodeInfo(node) { @@ -386,13 +391,13 @@ export class NoctuaGraphService { getCausalRelations(cam: Cam) { const self = this; const triples: Triple[] = []; + each(cam.activities, (subjectActivity: Activity) => { each(cam.graph.get_edges_by_subject(subjectActivity.id), (bbopEdge) => { const predicateId = bbopEdge.predicate_id(); const evidence = self.edgeToEvidence(cam.graph, bbopEdge); const objectId = bbopEdge.object_id(); const objectInfo = self.nodeToActivityNode(cam.graph, objectId); - const edges = noctuaFormConfig.allEdges const causalEdge = this.noctuaFormConfigService.findEdge(predicateId) if (objectInfo.hasRootType(EntityDefinition.GoMolecularFunction) @@ -424,8 +429,6 @@ export class NoctuaGraphService { const bbopObjectId = bbopEdge.object_id(); const bbopPredicateId = bbopEdge.predicate_id(); - console.log('object', bbopObjectId, 'predicate', bbopPredicateId, 'visitedNodeIds', visitedNodeIds) - if (visitedNodeIds.includes(bbopObjectId)) { continue } From cf39ec0ccc78f125a2670169047eeea30ade48c4 Mon Sep 17 00:00:00 2001 From: tmushayahama Date: Thu, 23 Jan 2025 14:37:21 -0800 Subject: [PATCH 3/3] bug with complex number and, --- src/components/gocam-viz/gocam-viz.tsx | 2 +- .../@noctua.form/models/activity/cam.ts | 214 +----------------- .../@noctua.form/services/graph.service.ts | 2 +- src/globals/relations.ts | 4 +- 4 files changed, 5 insertions(+), 217 deletions(-) diff --git a/src/components/gocam-viz/gocam-viz.tsx b/src/components/gocam-viz/gocam-viz.tsx index 367dd5b..fdc1770 100644 --- a/src/components/gocam-viz/gocam-viz.tsx +++ b/src/components/gocam-viz/gocam-viz.tsx @@ -405,7 +405,7 @@ export class GoCamViz { }); const truncatedGps = gps.slice(0, 3) - let geneString = gps.join(', ') + let geneString = truncatedGps.join(', ') if (gps.length > truncatedGps.length) { geneString += ' and ' + (gps.length - truncatedGps.length).toString() + ' more' diff --git a/src/globals/@noctua.form/models/activity/cam.ts b/src/globals/@noctua.form/models/activity/cam.ts index 2177930..f3951d3 100644 --- a/src/globals/@noctua.form/models/activity/cam.ts +++ b/src/globals/@noctua.form/models/activity/cam.ts @@ -1,14 +1,11 @@ import { noctuaFormConfig } from './../../noctua-form-config'; import { Activity, ActivitySortField, ActivityType } from './activity' -import { ActivityNode, ActivityNodeType } from './activity-node'; import { Group } from '../group'; import { Contributor } from '../contributor'; -import { Evidence } from './evidence'; import { Triple } from './triple'; import { Entity } from './entity'; -import { each, find, orderBy, groupBy } from 'lodash'; +import { each, find, groupBy } from 'lodash'; import { NoctuaFormUtils } from './../../utils/noctua-form-utils'; -import { PendingChange } from './pending-change'; export enum ReloadType { RESET = 'reset', @@ -152,15 +149,6 @@ export class Cam { this.displayId = NoctuaFormUtils.cleanID(id); } - updateSortBy(field: ActivitySortField, label: string) { - this.sortBy.field = field - this.sortBy.label = label - } - - toggleExpand() { - this.expanded = !this.expanded; - } - groupActivitiesByProcess() { const groupedActivities = groupBy(this.activities, (activity: Activity) => { if (activity.activityType === ActivityType.molecule) { @@ -173,57 +161,6 @@ export class Cam { return groupedActivities; } - - expandAllActivities(expand: boolean) { - const self = this; - - each(self.activities, (activity: Activity) => { - activity.expanded = expand; - }); - } - - getCausalRelation(subjectId: string, objectId: string): Triple { - const self = this; - - return self.causalRelations.find((triple: Triple) => { - if (triple.predicate?.isReverseLink) { - return triple.object?.id === subjectId && triple.object?.id === subjectId; - } - return triple.subject?.id === subjectId && triple.object?.id === objectId; - }) - } - - clearHighlight() { - const self = this; - - each(self.activities, (activity: Activity) => { - each(activity.nodes, (node: ActivityNode) => { - node.term.highlight = false; - each(node.predicate.evidence, (evidence: Evidence) => { - evidence.evidence.highlight = false; - evidence.referenceEntity.highlight = false; - evidence.withEntity.highlight = false; - }); - }); - }); - } - - findNodeById(uuid, activities: Activity[]): ActivityNode { - const self = this; - let found - each(activities, (activity) => { - found = find(activity.nodes, (node: ActivityNode) => { - return node.uuid === uuid; - }); - - if (found) { - return false; - } - }) - - return found; - } - findActivityById(id) { const self = this; @@ -232,155 +169,6 @@ export class Cam { }); } - findActivityByNodeUuid(nodeId): Activity[] { - const self = this; - - const result: Activity[] = []; - - each(self.activities, (activity: Activity) => { - each(activity.nodes, (node: ActivityNode) => { - if (node.uuid === nodeId) { - result.push(activity) - } - each(node.predicate.evidence, (evidence: Evidence) => { - if (evidence.uuid === nodeId) { - result.push(activity) - } - }); - }); - }); - return result; - } - - - - applyWeights(weight = 0) { - const self = this; - - if (self.queryMatch && self.queryMatch.terms.length > 0) { - - each(self.activities, (activity: Activity) => { - each(activity.nodes, (node: ActivityNode) => { - const matchNode = find(self.queryMatch.terms, { uuid: node.term.uuid }) as Entity; - - if (matchNode) { - matchNode.weight = node.term.weight = weight; - weight++; - } - - each(node.predicate.evidence, (evidence: Evidence) => { - const matchNode = find(self.queryMatch.terms, { uuid: evidence.referenceEntity.uuid }) as Entity; - - if (matchNode) { - matchNode.weight = evidence.referenceEntity.weight = weight; - weight++; - } - }); - }); - - }); - } - } - - addPendingChanges(findEntities: Entity[], replaceWith: string, category) { - const self = this; - - each(self.activities, (activity: Activity) => { - each(activity.nodes, (node: ActivityNode) => { - each(findEntities, (entity: Entity) => { - if (category.name === noctuaFormConfig.findReplaceCategory.options.reference.name) { - each(node.predicate.evidence, (evidence: Evidence, key) => { - if (evidence.uuid === entity.uuid) { - const oldReference = new Entity(evidence.reference, evidence.reference); - const newReference = new Entity(replaceWith, replaceWith); - - evidence.pendingReferenceChanges = new PendingChange(evidence.uuid, oldReference, newReference); - evidence.pendingReferenceChanges.uuid = evidence.uuid; - } - }); - } else { - if (node.term.uuid === entity.uuid) { - const newValue = new Entity(replaceWith, replaceWith); - node.pendingEntityChanges = new PendingChange(node.uuid, node.term, newValue); - } - } - }); - }); - }); - } - - getNodesByType(type: ActivityNodeType): any[] { - const self = this; - const result = []; - - each(self.activities, (activity: Activity) => { - result.push({ - activity, - title: activity.title, - activityNodes: activity.getNodesByType(type) - }); - }); - - return result; - } - - getNodesByTypeFlat(type: ActivityNodeType): ActivityNode[] { - const self = this; - const result = []; - - each(self.activities, (activity: Activity) => { - result.push(...activity.getNodesByType(type)); - }); - - return result; - } - - getTerms(formActivity: Activity) { - const self = this; - const result = []; - - if (formActivity && formActivity.nodes) { - each(formActivity.nodes, (node: ActivityNode) => { - result.push(node); - }); - } - - each(self.activities, (activity: Activity) => { - each(activity.nodes, (node: ActivityNode) => { - result.push(node); - }); - }); - - return result; - } - - getEvidences(formActivity?: Activity) { - const self = this; - const result = []; - - if (formActivity && formActivity.nodes) { - each(formActivity.nodes, (node: ActivityNode) => { - each(node.predicate.evidence, (evidence: Evidence) => { - if (evidence.hasValue()) { - result.push(evidence); - } - }); - }); - } - - each(self.activities, (activity: Activity) => { - each(activity.edges, (triple: Triple) => { - each(triple.predicate.evidence, (evidence: Evidence) => { - if (evidence.hasValue()) { - result.push(evidence); - } - }); - }); - }); - - return result; - } - updateProperties() { const self = this; diff --git a/src/globals/@noctua.form/services/graph.service.ts b/src/globals/@noctua.form/services/graph.service.ts index aab46ac..1b30b51 100644 --- a/src/globals/@noctua.form/services/graph.service.ts +++ b/src/globals/@noctua.form/services/graph.service.ts @@ -53,7 +53,7 @@ export class NoctuaGraphService { cam.modified = responseData['modified-p']; this.getMetadata(cam) - this.loadCam(cam) + this.loadCam(cam, true) return cam; } diff --git a/src/globals/relations.ts b/src/globals/relations.ts index c5e8f46..9a83aaa 100644 --- a/src/globals/relations.ts +++ b/src/globals/relations.ts @@ -7,8 +7,8 @@ export enum Relations { DIRECTLY_POSITIVELY_REGULATES = 'RO:0002629', HAS_INPUT = 'RO:0002233', HAS_OUTPUT = 'RO:0002234', - INDIRECTLY_NEGATIVELY_REGULATES = 'RO:0002407', - INDIRECTLY_POSITIVELY_REGULATES = 'RO:0002409', + INDIRECTLY_NEGATIVELY_REGULATES = 'RO:0002409', + INDIRECTLY_POSITIVELY_REGULATES = 'RO:0002407', IS_SMALL_MOLECULE_INHIBITOR_OF = 'RO:0012006', IS_SMALL_MOLECULE_ACTIVATOR_OF = 'RO:0012005', NEGATIVELY_REGULATES = 'RO:0002212',