From 31cb6192d0fc8e87628a161618ae08e47714b03e Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Thu, 10 Aug 2023 16:36:46 -0400 Subject: [PATCH] feat: use service provider as source where appropriate --- src/batch_edge_query.js | 9 ++-- src/edge_manager.js | 1 + src/index.js | 62 ++++++++++++++++----------- src/inferred_mode/inferred_mode.js | 2 +- src/results_assembly/query_results.js | 19 ++++++-- 5 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/batch_edge_query.js b/src/batch_edge_query.js index c9d9a7eb..aec2de56 100644 --- a/src/batch_edge_query.js +++ b/src/batch_edge_query.js @@ -11,11 +11,10 @@ module.exports = class BatchEdgeQueryHandler { this.subscribers = []; this.logs = []; this.caching = options && options.caching; - this.recordConfig = {}; + this.options = options; if (options && options.recordHashEdgeAttributes) { - this.recordConfig.EDGE_ATTRIBUTES_USED_IN_RECORD_HASH = options.recordHashEdgeAttributes; + this.options.EDGE_ATTRIBUTES_USED_IN_RECORD_HASH = options.recordHashEdgeAttributes; } - if (options && options.submitter) this.recordConfig.submitter = options.submitter; this.resolveOutputIDs = resolveOutputIDs; } @@ -45,7 +44,7 @@ module.exports = class BatchEdgeQueryHandler { * @private */ async _queryAPIEdges(APIEdges, unavailableAPIs = {}) { - let executor = new call_api(APIEdges, this.recordConfig); + let executor = new call_api(APIEdges, this.options); const records = await executor.query(this.resolveOutputIDs, unavailableAPIs); this.logs = [...this.logs, ...executor.logs]; return records; @@ -117,7 +116,7 @@ module.exports = class BatchEdgeQueryHandler { await this._rmEquivalentDuplicates(qEdges); debug('Node Update Success'); - const cacheHandler = new CacheHandler(this.caching, this.metaKG, this.recordConfig); + const cacheHandler = new CacheHandler(this.caching, this.metaKG, this.options); const { cachedRecords, nonCachedQEdges } = await cacheHandler.categorizeEdges(qEdges); this.logs = [...this.logs, ...cacheHandler.logs]; let queryRecords; diff --git a/src/edge_manager.js b/src/edge_manager.js index 2f54780d..c80b79d3 100644 --- a/src/edge_manager.js +++ b/src/edge_manager.js @@ -350,6 +350,7 @@ module.exports = class QueryEdgeManager { caching: this.options.caching, submitter: this.options.submitter, recordHashEdgeAttributes: config.EDGE_ATTRIBUTES_USED_IN_RECORD_HASH, + provenanceUsesServiceProvider: this.options.provenanceUsesServiceProvider, }); handler.setEdges(qEdge); return handler; diff --git a/src/index.js b/src/index.js index c4422bbb..0a65a8fb 100644 --- a/src/index.js +++ b/src/index.js @@ -34,6 +34,7 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { constructor(options = {}, smartAPIPath = undefined, predicatesPath = undefined, includeReasoner = true) { this.logs = []; this.options = options; + this.options.provenanceUsesServiceProvider = this.options.smartAPIID || this.options.teamName ? true : false; this.includeReasoner = includeReasoner; this.resolveOutputIDs = typeof this.options.enableIDResolution === 'undefined' ? true : this.options.enableIDResolution; @@ -145,7 +146,12 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { })[1]; subclassEdge.addSource([ { resource_id: source, resource_role: 'primary_knowledge_source' }, - { resource_id: 'infores:biothings-explorer', resource_role: 'aggregator_knowledge_source' }, + { + resource_id: this.options.provenanceUsesServiceProvider + ? 'infores:service-provider-trapi' + : 'infores:biothings-explorer', + resource_role: 'aggregator_knowledge_source', + }, ]); this.bteGraph.edges[subclassEdgeID] = subclassEdge; nodesToRebind[subject] = { newNode: object, subclassEdgeID }; @@ -186,7 +192,14 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { object: object, }); boundEdge.addAdditionalAttributes('biolink:support_graphs', [supportGraphID]); - boundEdge.addSource([{ resource_id: 'infores:biothings-explorer', resource_role: 'primary_knowledge_source' }]); + boundEdge.addSource([ + { + resource_id: this.options.provenanceUsesServiceProvider + ? 'infores:service-provider-trapi' + : 'infores:biothings-explorer', + resource_role: 'primary_knowledge_source', + }, + ]); this.bteGraph.edges[boundEdgeID] = boundEdge; } else { this.bteGraph.edges[boundEdgeID].attributes['biolink:support_graphs'].add(supportGraphID); @@ -206,7 +219,7 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { if (!boundIDs.has(binding.id)) { newBindings.push(binding); boundIDs.add(binding.id); - }; + } } else if (!boundIDs.has(nodesToRebind[binding.id].newNode)) { newBindings.push({ id: nodesToRebind[binding.id].newNode }); boundIDs.add(nodesToRebind[binding.id].newNode); @@ -245,9 +258,11 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { }); // Prune unused auxGraphs - auxGraphs = Object.fromEntries(Object.entries(auxGraphs).filter(([auxGraphID]) => { - return [...edgesIDsByAuxGraphID[auxGraphID]].some((edgeID => resultBoundEdgesWithAuxGraphs.has(edgeID))) - })) + auxGraphs = Object.fromEntries( + Object.entries(auxGraphs).filter(([auxGraphID]) => { + return [...edgesIDsByAuxGraphID[auxGraphID]].some((edgeID) => resultBoundEdgesWithAuxGraphs.has(edgeID)); + }), + ); this.auxGraphs = auxGraphs; this.finalizedResults = fixedResults; @@ -267,20 +282,19 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { const resolvedCuries = await id_resolver.resolveSRI({ unknown: curiesToResolve }); Object.entries(resolvedCuries).forEach(([originalCurie, resolvedEntity]) => { if (!this.bteGraph.nodes[resolvedEntity.primaryID]) { - const category = resolvedEntity.primaryTypes?.[0] ? `biolink:${resolvedEntity.primaryTypes[0]}` : qNodeIDsByOriginalID.get(originalCurie).categories?.[0]; - - this.bteGraph.nodes[resolvedEntity.primaryID] = new KGNode( - resolvedEntity.primaryID, - { - primaryCurie: resolvedEntity.primaryID, - qNodeID: qNodeIDsByOriginalID[originalCurie], - equivalentCuries: resolvedEntity.equivalentIDs, - names: resolvedEntity.labelAliases, - category: category ? [category] : ["biolink:NamedThing"], - attributes: resolvedEntity.attributes, - label: resolvedEntity.label, - }, - ); + const category = resolvedEntity.primaryTypes?.[0] + ? `biolink:${resolvedEntity.primaryTypes[0]}` + : qNodeIDsByOriginalID.get(originalCurie).categories?.[0]; + + this.bteGraph.nodes[resolvedEntity.primaryID] = new KGNode(resolvedEntity.primaryID, { + primaryCurie: resolvedEntity.primaryID, + qNodeID: qNodeIDsByOriginalID[originalCurie], + equivalentCuries: resolvedEntity.equivalentIDs, + names: resolvedEntity.labelAliases, + category: category ? [category] : ['biolink:NamedThing'], + attributes: resolvedEntity.attributes, + label: resolvedEntity.label, + }); } }); } @@ -349,7 +363,7 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { _initializeResponse() { this.knowledgeGraph = new KnowledgeGraph(this.options?.apiList?.include); - this.trapiResultsAssembler = new TrapiResultsAssembler(); + this.trapiResultsAssembler = new TrapiResultsAssembler(this.options); this.bteGraph = new Graph(); this.bteGraph.subscribe(this.knowledgeGraph); } @@ -589,7 +603,7 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { await this.addQueryNodes(); const span1 = Sentry?.getCurrentHub()?.getScope()?.getTransaction()?.startChild({ - description: "loadMetaKG" + description: 'loadMetaKG', }); debug('Start to load metakg.'); @@ -637,7 +651,7 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { if (this._queryUsesInferredMode()) { const span2 = Sentry?.getCurrentHub()?.getScope()?.getTransaction()?.startChild({ - description: "creativeExecution" + description: 'creativeExecution', }); await this._handleInferredEdges(); span2?.finish(); @@ -656,7 +670,7 @@ exports.TRAPIQueryHandler = class TRAPIQueryHandler { } const span3 = Sentry?.getCurrentHub()?.getScope()?.getTransaction()?.startChild({ - description: "resultsAssembly" + description: 'resultsAssembly', }); // update query graph diff --git a/src/inferred_mode/inferred_mode.js b/src/inferred_mode/inferred_mode.js index 454794f6..07f620d1 100644 --- a/src/inferred_mode/inferred_mode.js +++ b/src/inferred_mode/inferred_mode.js @@ -256,7 +256,7 @@ module.exports = class InferredQueryHandler { subject: resultCreativeSubjectID, object: resultCreativeObjectID, predicate: qEdge.predicates[0], - sources: [{ resource_id: 'infores:biothings-explorer', resource_role: 'primary_knowledge_source' }], + sources: [{ resource_id: this.parent.options.provenanceUsesServiceProvider ? 'infores:service-provider-trapi' : 'infores:biothings-explorer', resource_role: 'primary_knowledge_source' }], attributes: [{ attribute_type_id: 'biolink:support_graphs', value: [] }], }; } diff --git a/src/results_assembly/query_results.js b/src/results_assembly/query_results.js index b8d17826..9d2825b4 100644 --- a/src/results_assembly/query_results.js +++ b/src/results_assembly/query_results.js @@ -43,13 +43,14 @@ module.exports = class TrapiResultsAssembler { /** * Create a QueryResult i9nstance. */ - constructor() { + constructor(options) { /** * @property {Result[]} _results - list of query results * @private */ this._results = []; this.logs = []; + this.options = options; } getResults() { @@ -374,7 +375,17 @@ module.exports = class TrapiResultsAssembler { recordHashes: new Set(), }; solutionRecords.forEach( - ({ inputQNodeID, outputQNodeID, inputPrimaryCurie, outputPrimaryCurie, inputUMLS, outputUMLS, isTextMined, qEdgeID, recordHash }) => { + ({ + inputQNodeID, + outputQNodeID, + inputPrimaryCurie, + outputPrimaryCurie, + inputUMLS, + outputUMLS, + isTextMined, + qEdgeID, + recordHash, + }) => { consolidatedSolutionRecord.inputPrimaryCuries.add(inputPrimaryCurie); consolidatedSolutionRecord.outputPrimaryCuries.add(outputPrimaryCurie); consolidatedSolutionRecord.inputUMLS.add(...inputUMLS); @@ -404,7 +415,9 @@ module.exports = class TrapiResultsAssembler { node_bindings: {}, analyses: [ { - resource_id: `infores:biothings-explorer`, + resource_id: this.options.provenanceUsesServiceProvider + ? `infores:service-provider-trapi` + : `infores:biothings-explorer`, edge_bindings: {}, score: score, },