From c0039d34b6991508961c82cdda2deb852d018f7c Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:04:48 -0500 Subject: [PATCH 1/8] style: formatting --- src/transformers/jq_transformer.ts | 26 +++-- src/transformers/transformer.ts | 160 ++++++++++++++++++++--------- 2 files changed, 132 insertions(+), 54 deletions(-) diff --git a/src/transformers/jq_transformer.ts b/src/transformers/jq_transformer.ts index 1da932d..f9c2865 100644 --- a/src/transformers/jq_transformer.ts +++ b/src/transformers/jq_transformer.ts @@ -11,21 +11,28 @@ import { toArray } from "../utils"; const filterStringsWrap = Object.fromEntries( fs.readdirSync(Path.resolve(`${__dirname}/../../data/jq/wrap`)).map(file => { const filePath = Path.resolve(`${__dirname}/../../data/jq/wrap/${file}`); - return [Path.parse(filePath).name, fs.readFileSync(filePath, { encoding: "utf8" })]; + return [ + Path.parse(filePath).name, + fs.readFileSync(filePath, { encoding: "utf8" }), + ]; }), ); const filterStringsPair = Object.fromEntries( fs.readdirSync(Path.resolve(`${__dirname}/../../data/jq/pair`)).map(file => { const filePath = Path.resolve(`${__dirname}/../../data/jq/pair/${file}`); - return [Path.parse(filePath).name, fs.readFileSync(filePath, { encoding: "utf8" })]; + return [ + Path.parse(filePath).name, + fs.readFileSync(filePath, { encoding: "utf8" }), + ]; }), ); export default class JQTransformer extends BaseTransformer { // TODO more specific typing? async wrap(res: JSONDoc | JSONDoc[]): Promise { - let filterString: string | undefined = this.config.wrap ?? filterStringsWrap[this.config.type]; + let filterString: string | undefined = + this.config.wrap ?? filterStringsWrap[this.config.type]; if (typeof filterString === "undefined") return super.wrap(res); filterString = generateFilterString(filterString); return JSON.parse( @@ -36,8 +43,10 @@ export default class JQTransformer extends BaseTransformer { } async pairCurieWithAPIResponse(): Promise { - let filterString: string | undefined = this.config.pair ?? filterStringsPair[this.config.type]; - if (typeof filterString === "undefined") return super.pairCurieWithAPIResponse(); + let filterString: string | undefined = + this.config.pair ?? filterStringsPair[this.config.type]; + if (typeof filterString === "undefined") + return super.pairCurieWithAPIResponse(); const data = { response: this.data.response, edge: { @@ -49,7 +58,8 @@ export default class JQTransformer extends BaseTransformer { type: this.edge.association.input_type, // input is array or is object with queryInputs curies: - Array.isArray(this.edge.input) || typeof this.edge.input === "string" + Array.isArray(this.edge.input) || + typeof this.edge.input === "string" ? toArray(this.edge.input) : toArray(this.edge.input.queryInputs), }, @@ -61,6 +71,8 @@ export default class JQTransformer extends BaseTransformer { }, }; filterString = `.edge as $edge | ${generateFilterString(filterString)}`; - return JSON.parse((await jq.run(filterString, data, { input: "json" })) as string); + return JSON.parse( + (await jq.run(filterString, data, { input: "json" })) as string, + ); } } diff --git a/src/transformers/transformer.ts b/src/transformers/transformer.ts index a07b4a4..02f1df3 100644 --- a/src/transformers/transformer.ts +++ b/src/transformers/transformer.ts @@ -24,9 +24,11 @@ export default class BaseTransformer { * Create an object with key representing input, and value representing the output of API */ async pairCurieWithAPIResponse() { - let input = generateCurie( + const input = generateCurie( this.edge.association.input_id, - this.edge.input.hasOwnProperty("queryInputs") ? this.edge.input["queryInputs"] : (this.edge.input as string), + this.edge.input.hasOwnProperty("queryInputs") + ? this.edge.input["queryInputs"] + : (this.edge.input as string), ); return { [input]: [this.data.response], @@ -71,12 +73,18 @@ export default class BaseTransformer { { prop: "ref_pmcid", prefix: "PMCID:", - urls: ["http://www.ncbi.nlm.nih.gov/pmc/articles/", "http://europepmc.org/articles/"], + urls: [ + "http://www.ncbi.nlm.nih.gov/pmc/articles/", + "http://europepmc.org/articles/", + ], }, { prop: "ref_clinicaltrials", prefix: "clinicaltrials:", - urls: ["https://clinicaltrials.gov/ct2/show/", "https://www.clinicaltrials.gov/ct2/show/"], + urls: [ + "https://clinicaltrials.gov/ct2/show/", + "https://www.clinicaltrials.gov/ct2/show/", + ], }, { prop: "ref_doi", @@ -88,29 +96,37 @@ export default class BaseTransformer { "http://onlinelibrary.wiley.com/doi/", ], }, - { prop: "ref_isbn", prefix: "isbn:", urls: ["https://www.isbn-international.org/identifier/"] }, + { + prop: "ref_isbn", + prefix: "isbn:", + urls: ["https://www.isbn-international.org/identifier/"], + }, ]; // handle URLs (which could be CURIEs) if ("ref_url" in mappedResponse) { - for (let publication of toArray(mappedResponse.ref_url)) { + for (const publication of toArray(mappedResponse.ref_url)) { if (typeof publication !== "string" || publication.length === 0) { continue; } let isCurie = false; - for (let publicationType of publicationTypes) { - for (let url of publicationType.urls) { + for (const publicationType of publicationTypes) { + for (const url of publicationType.urls) { if (publication.startsWith(url)) { isCurie = true; if (!mappedResponse[publicationType.prop]) { mappedResponse[publicationType.prop] = []; } else if (!Array.isArray(mappedResponse[publicationType.prop])) { - mappedResponse[publicationType.prop] = toArray(mappedResponse[publicationType.prop]); + mappedResponse[publicationType.prop] = toArray( + mappedResponse[publicationType.prop], + ); } - mappedResponse[publicationType.prop].push(publication.slice(url.length)); + mappedResponse[publicationType.prop].push( + publication.slice(url.length), + ); break; } @@ -128,7 +144,7 @@ export default class BaseTransformer { } delete mappedResponse.ref_url; - for (let publicationType of publicationTypes) { + for (const publicationType of publicationTypes) { if (publicationType.prop in mappedResponse) { for (let publication of toArray(mappedResponse[publicationType.prop])) { // handle numbers @@ -140,10 +156,19 @@ export default class BaseTransformer { continue; } - if (publication.toUpperCase().startsWith(publicationType.prefix.toUpperCase())) { - mappedResponse.publications.push(publicationType.prefix + publication.slice(publicationType.prefix.length)); + if ( + publication + .toUpperCase() + .startsWith(publicationType.prefix.toUpperCase()) + ) { + mappedResponse.publications.push( + publicationType.prefix + + publication.slice(publicationType.prefix.length), + ); } else { - mappedResponse.publications.push(publicationType.prefix + publication); + mappedResponse.publications.push( + publicationType.prefix + publication, + ); } } @@ -170,16 +195,26 @@ export default class BaseTransformer { _getSubject(subjectCurie: any) { //debug(`input: ${input}`); let subject = { - original: typeof this.edge.original_input === "undefined" ? undefined : this.edge.original_input[subjectCurie], + original: + typeof this.edge.original_input === "undefined" + ? undefined + : this.edge.original_input[subjectCurie], // normalizedInfo: // typeof this.edge.input_resolved_identifiers === "undefined" || typeof this.edge.original_input === "undefined" // ? undefined // : this.edge.input_resolved_identifiers[this.edge.original_input[subjectCurie]], }; - if (this.edge.input_resolved_identifiers && subject.original === undefined) { + if ( + this.edge.input_resolved_identifiers && + subject.original === undefined + ) { //try to find an equivalent ids object if the original input doesn't match (for ICEES) - for (let curie of Object.keys(this.edge.input_resolved_identifiers)) { - if (this.edge.input_resolved_identifiers[curie].equivalentIDs.includes(subjectCurie)) { + for (const curie of Object.keys(this.edge.input_resolved_identifiers)) { + if ( + this.edge.input_resolved_identifiers[curie].equivalentIDs.includes( + subjectCurie, + ) + ) { subject = { original: curie, // normalizedInfo: this.edge.input_resolved_identifiers[curie], @@ -204,7 +239,10 @@ export default class BaseTransformer { * @param {Object} mappedResponse - JSON response representing an output. */ async formatRecords(subjectCurie: string, mappedResponse: any) { - if (mappedResponse === undefined || Object.keys(mappedResponse).length === 0) { + if ( + mappedResponse === undefined || + Object.keys(mappedResponse).length === 0 + ) { return []; } @@ -222,16 +260,24 @@ export default class BaseTransformer { mappedResponse: { ...mappedResponse }, }; - let transformedRecords = await async.mapSeries(objectIDs, async (curie: string) => { - let copyRecord = { - ...frozenRecord, - object: { - original: curie, - apiLabel: outputName, - }, - }; - return new Record(copyRecord, this.config, this.edge.association, this.edge.reasoner_edge); - }); + const transformedRecords = await async.mapSeries( + objectIDs, + async (curie: string) => { + const copyRecord = { + ...frozenRecord, + object: { + original: curie, + apiLabel: outputName, + }, + }; + return new Record( + copyRecord, + this.config, + this.edge.association, + this.edge.reasoner_edge, + ); + }, + ); return transformedRecords; } @@ -239,25 +285,43 @@ export default class BaseTransformer { * Main function to transform API response */ async transform() { - let transformedRecords = []; - let responses = await this.pairCurieWithAPIResponse(); + const transformedRecords = []; + const responses = await this.pairCurieWithAPIResponse(); - await async.eachSeries(Object.entries(responses), async ([curie, curieResponses]) => { - if (Array.isArray(curieResponses) && curieResponses.length > 0) { - await async.eachSeries(curieResponses, async response => { - const predicateResponse = this.jsonTransform(await this.wrap(response)); - await async.eachSeries(Object.entries(predicateResponse), async ([predicate, mappedResponses]) => { - if (Array.isArray(mappedResponses) && mappedResponses.length > 0) { - await async.eachSeries(mappedResponses, async (mappedResponse: any[]) => { - transformedRecords.push(...(await this.formatRecords(curie, mappedResponse))); - }); - } else { - transformedRecords.push(...(await this.formatRecords(curie, mappedResponses))); - } + await async.eachSeries( + Object.entries(responses), + async ([curie, curieResponses]) => { + if (Array.isArray(curieResponses) && curieResponses.length > 0) { + await async.eachSeries(curieResponses, async response => { + const predicateResponse = this.jsonTransform( + await this.wrap(response), + ); + await async.eachSeries( + Object.entries(predicateResponse), + async ([predicate, mappedResponses]) => { + if ( + Array.isArray(mappedResponses) && + mappedResponses.length > 0 + ) { + await async.eachSeries( + mappedResponses, + async (mappedResponse: any[]) => { + transformedRecords.push( + ...(await this.formatRecords(curie, mappedResponse)), + ); + }, + ); + } else { + transformedRecords.push( + ...(await this.formatRecords(curie, mappedResponses)), + ); + } + }, + ); }); - }); - } - }); + } + }, + ); return transformedRecords; } @@ -271,6 +335,8 @@ export default class BaseTransformer { return []; } mappedResponse[output_id_type] = toArray(mappedResponse[output_id_type]); - return mappedResponse[output_id_type].map((id: string) => generateCurie(output_id_type, id)); + return mappedResponse[output_id_type].map((id: string) => + generateCurie(output_id_type, id), + ); } } From a2dea9f2701b9cee62809b4cc4af3e73f1ede8c5 Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:05:07 -0500 Subject: [PATCH 2/8] old biolink -> new monarch --- data/jq/pair/monarch.jq | 29 +++++++++++++++++++++++++++++ data/jq/wrap/biolink.jq | 18 ------------------ src/index.ts | 6 ++---- 3 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 data/jq/pair/monarch.jq delete mode 100644 data/jq/wrap/biolink.jq diff --git a/data/jq/pair/monarch.jq b/data/jq/pair/monarch.jq new file mode 100644 index 0000000..bf6d05a --- /dev/null +++ b/data/jq/pair/monarch.jq @@ -0,0 +1,29 @@ +generateCurie($edge.input.id; $edge.input.curies) as $input_curie +| .response.items = [ + .response.items[] + | select(. != null) + | select( + . as $item + | if $item.direction == "outgoing" + then $item.subject + else $item.object + end + | . as $input_curie + | if $item.direction == "outgoing" + then $item.object_namespace + else $item.subject_namespace + end + | . as $output_namespace + | $input_curie == $input_curie + and $output_namespace == $edge.output.id + ) + | .publications = [ + if .publications != null + then .publications + else [] + end + | .[] + | select(. | startswith("PMID:")) + ] +] +| { $input_curie: [.response] } diff --git a/data/jq/wrap/biolink.jq b/data/jq/wrap/biolink.jq deleted file mode 100644 index 696d9d1..0000000 --- a/data/jq/wrap/biolink.jq +++ /dev/null @@ -1,18 +0,0 @@ -.associations = ( - [ - ( - # take associations that aren't null - select(.associations != null) | .associations | .[] | - # split association object ids & take last (only for CHEMBL, REACT, HGNC) - select(.object.id != null) | (.object.id | split(":") | first) as $pref | .object[$pref] = (if $pref == "HGNC" or $pref == "NCBIGene" or $pref == "REACT" then (.object.id | split(":") | last) else .object.id end) | - # take publications with PMID & for IDs take last element after splitting by : - .publications = [foreach (.publications | .[]? | .id) as $pub ([]; []; if ($pub == null or ($pub | startswith("PMID") | not)) then empty else {id: ($pub | split(":") | last)} end)] - ) - # delete publications if empty array - | delifempty(.publications) - ] + - # include associations with null object ids - [select(.associations != null) | .associations | .[] | select(.object.id == null)] -) -# delete association if empty array -| delifempty(.associations) diff --git a/src/index.ts b/src/index.ts index 1337221..68b99fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import BiolinkTransformer from "./transformers/biolink_transformer"; import BioThingsTransformer from "./transformers/biothings_transformer"; // import CordTransformer from "./transformers/cord_transformer"; import CTDTransformer from "./transformers/ctd_transformer"; @@ -46,9 +45,8 @@ export default class Transformer { this.tf = new TRAPITransformer(this.data, this.config); } else if (api.startsWith("SEMMED")) { this.tf = new SemmedTransformer(this.data, this.config); - } else if (api === "BioLink API") { - // this.tf = new BiolinkTransformer(this.data, this.config); - this.tf = new JQTransformer(this.data, { ...this.config, type: "biolink" }); + } else if (api === "Monarch API") { + this.tf = new JQTransformer(this.data, { ...this.config, type: "monarch" }); } else if (api === "EBI Proteins API") { // this.tf = new EBIProteinTransformer(this.data, this.config) this.tf = new JQTransformer(this.data, { ...this.config, type: "ebi" }); From 1cddaf64cd5e1aa4a650710431847d188f1e8811 Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:15:57 -0800 Subject: [PATCH 3/8] feat: add response mapping to edge data --- src/transformers/jq_transformer.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transformers/jq_transformer.ts b/src/transformers/jq_transformer.ts index f9c2865..199df15 100644 --- a/src/transformers/jq_transformer.ts +++ b/src/transformers/jq_transformer.ts @@ -68,6 +68,7 @@ export default class JQTransformer extends BaseTransformer { id: this.edge.association.output_id, type: this.edge.association.output_type, }, + response_mapping: this.edge.response_mapping, }, }; filterString = `.edge as $edge | ${generateFilterString(filterString)}`; From a9551e95fbd749b0916e43e285fa2eda563e6c29 Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:16:10 -0800 Subject: [PATCH 4/8] feat: update monarch jq --- data/jq/pair/monarch.jq | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/data/jq/pair/monarch.jq b/data/jq/pair/monarch.jq index bf6d05a..a77ebf2 100644 --- a/data/jq/pair/monarch.jq +++ b/data/jq/pair/monarch.jq @@ -1,21 +1,15 @@ -generateCurie($edge.input.id; $edge.input.curies) as $input_curie -| .response.items = [ - .response.items[] +.response as $response +| generateCurie($edge.input.id; $edge.input.curies) as $input_curie +| if $edge.response_mapping[$edge.predicate].output_name | contains("object") + then "object_namespace" + else "subject_namespace" + end +| . as $output_namespace +| { $input_curie: [$response] } | .[$input_curie][0].items = [ + $response.items[] | select(. != null) | select( - . as $item - | if $item.direction == "outgoing" - then $item.subject - else $item.object - end - | . as $input_curie - | if $item.direction == "outgoing" - then $item.object_namespace - else $item.subject_namespace - end - | . as $output_namespace - | $input_curie == $input_curie - and $output_namespace == $edge.output.id + .[$output_namespace] == $edge.output.id ) | .publications = [ if .publications != null @@ -26,4 +20,3 @@ generateCurie($edge.input.id; $edge.input.curies) as $input_curie | select(. | startswith("PMID:")) ] ] -| { $input_curie: [.response] } From 33b79c039c05821f33cb0d2eb351d21f5f956a2e Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Thu, 15 Feb 2024 12:48:04 -0500 Subject: [PATCH 5/8] feat: provide $response variable to jq strings --- src/transformers/jq_transformer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/jq_transformer.ts b/src/transformers/jq_transformer.ts index 199df15..444429a 100644 --- a/src/transformers/jq_transformer.ts +++ b/src/transformers/jq_transformer.ts @@ -71,7 +71,7 @@ export default class JQTransformer extends BaseTransformer { response_mapping: this.edge.response_mapping, }, }; - filterString = `.edge as $edge | ${generateFilterString(filterString)}`; + filterString = `.edge as $edge | .response as $response | ${generateFilterString(filterString)}`; return JSON.parse( (await jq.run(filterString, data, { input: "json" })) as string, ); From cc21854e71e1e85db167c861a3431e7ab87ae229 Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Thu, 15 Feb 2024 12:48:30 -0500 Subject: [PATCH 6/8] feat: transform sources for BTE ingestion --- data/jq/pair/monarch.jq | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/data/jq/pair/monarch.jq b/data/jq/pair/monarch.jq index a77ebf2..d9bac72 100644 --- a/data/jq/pair/monarch.jq +++ b/data/jq/pair/monarch.jq @@ -1,5 +1,4 @@ -.response as $response -| generateCurie($edge.input.id; $edge.input.curies) as $input_curie +generateCurie($edge.input.id; $edge.input.curies) as $input_curie | if $edge.response_mapping[$edge.predicate].output_name | contains("object") then "object_namespace" else "subject_namespace" @@ -19,4 +18,32 @@ | .[] | select(. | startswith("PMID:")) ] + | .primary_knowledge_source as $primary_knowledge_source + | .sources = ( + if .primary_knowledge_source != null and .aggregator_knowledge_source != null + then + [ + { + resource_role: "primary_knowledge_source", + resource_id: $primary_knowledge_source + } + ] + + (.aggregator_knowledge_source | reverse | reduce .[] as $source ( + null; + if . == null + then [{ + resource_role: "aggregator_knowledge_source", + resource_id: $source, + upstream_resource_ids: [$primary_knowledge_source] + }] + else . + [{ + resource_role: "aggregator_knowledge_source", + resource_id: $source, + upstream_resource_ids: [.[-1].resource_id] + }] + end + )) + else [{ resource_role: "primary_knowledge_source", resource_id:"infores:monarchinitiative" }] + end + ) ] From 3534b23f1b6467eb464757e366414fe84a692233 Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:05:59 -0500 Subject: [PATCH 7/8] fix: record uses source in hash --- src/record.ts | 165 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 119 insertions(+), 46 deletions(-) diff --git a/src/record.ts b/src/record.ts index 7602d83..e1a7b2f 100644 --- a/src/record.ts +++ b/src/record.ts @@ -11,14 +11,21 @@ export class RecordNode { _qNode: QNode; _apiLabel: string; - constructor(node: FrozenNode | VerboseFrozenNode | MinimalFrozenNode, qNode: QNode) { + constructor( + node: FrozenNode | VerboseFrozenNode | MinimalFrozenNode, + qNode: QNode, + ) { this.original = node.original; - this.normalizedInfo = node.normalizedInfo ? node.normalizedInfo : this.makeFakeInfo(node); + this.normalizedInfo = node.normalizedInfo + ? node.normalizedInfo + : this.makeFakeInfo(node); this._qNode = qNode; this._apiLabel = node.apiLabel; } - makeFakeInfo(node: FrozenNode | VerboseFrozenNode | MinimalFrozenNode): NodeNormalizerResultObj { + makeFakeInfo( + node: FrozenNode | VerboseFrozenNode | MinimalFrozenNode, + ): NodeNormalizerResultObj { return { primaryID: node.curie, equivalentIDs: node.equivalentCuries ?? [], @@ -82,19 +89,30 @@ export class RecordNode { get UMLS(): string[] { return ( - this.normalizedInfo?.equivalentIDs.reduce((arr: string[], curie: string) => { - if (curie.includes("UMLS")) arr.push(curie.replace("UMLS:", "")); - return arr; - }, []) ?? [] + this.normalizedInfo?.equivalentIDs.reduce( + (arr: string[], curie: string) => { + if (curie.includes("UMLS")) arr.push(curie.replace("UMLS:", "")); + return arr; + }, + [], + ) ?? [] ); } get semanticType(): string[] { - return this.normalizedInfo?.primaryTypes.map(semanticType => `biolink:${semanticType}`) ?? []; + return ( + this.normalizedInfo?.primaryTypes.map( + semanticType => `biolink:${semanticType}`, + ) ?? [] + ); } get semanticTypes(): string[] { - return this.normalizedInfo?.semanticTypes.map(semanticType => `biolink:${semanticType}`) ?? []; + return ( + this.normalizedInfo?.semanticTypes.map( + semanticType => `biolink:${semanticType}`, + ) ?? [] + ); } get label(): string { @@ -157,30 +175,39 @@ export class Record { reversedAPIEdge.input_type = frozen.association.output_type; reversedAPIEdge.output_id = frozen.association.input_id; reversedAPIEdge.output_type = frozen.association.input_type; - const predicate = this.qEdge.getReversedPredicate(frozen.association.predicate); + const predicate = this.qEdge.getReversedPredicate( + frozen.association.predicate, + ); reversedAPIEdge.predicate = predicate; if (reversedAPIEdge.qualifiers) { const reversedQualifiers = Object.fromEntries( - Object.entries(reversedAPIEdge.qualifiers).map(([qualifierType, qualifier]) => { - let newQualifierType: string = qualifierType; - let newQualifier: string | string[] = qualifier; - if (qualifierType.includes("predicate")) { - if (Array.isArray(qualifier)) { - newQualifier = qualifier.map( - (str: string) => `biolink:${this.qEdge.getReversedPredicate(str.replace("biolink:", ""))}`, - ); - } else { - newQualifier = `biolink:${this.qEdge.getReversedPredicate(qualifier.replace("biolink:", ""))}`; + Object.entries(reversedAPIEdge.qualifiers).map( + ([qualifierType, qualifier]) => { + let newQualifierType: string = qualifierType; + let newQualifier: string | string[] = qualifier; + if (qualifierType.includes("predicate")) { + if (Array.isArray(qualifier)) { + newQualifier = qualifier.map( + (str: string) => + `biolink:${this.qEdge.getReversedPredicate( + str.replace("biolink:", ""), + )}`, + ); + } else { + newQualifier = `biolink:${this.qEdge.getReversedPredicate( + qualifier.replace("biolink:", ""), + )}`; + } } - } - if (qualifierType.includes("subject")) { - newQualifierType = qualifierType.replace("subject", "object"); - } - if (qualifierType.includes("object")) { - newQualifierType = qualifierType.replace("object", "subject"); - } - return [newQualifierType, newQualifier]; - }), + if (qualifierType.includes("subject")) { + newQualifierType = qualifierType.replace("subject", "object"); + } + if (qualifierType.includes("object")) { + newQualifierType = qualifierType.replace("object", "subject"); + } + return [newQualifierType, newQualifier]; + }, + ), ); reversedAPIEdge.qualifiers = reversedQualifiers; @@ -191,7 +218,13 @@ export class Record { const temp = frozen.subject; frozen.subject = frozen.object; frozen.object = temp; - return new Record(frozen, this.config, frozen.association, this.qEdge, !this.reverseToExecution); + return new Record( + frozen, + this.config, + frozen.association, + this.qEdge, + !this.reverseToExecution, + ); } queryDirection() { @@ -203,7 +236,9 @@ export class Record { } // for user-made records lacking qEdge - makeFakeQEdge(record: FrozenRecord | VerboseFrozenRecord | MinimalFrozenRecord): QEdge { + makeFakeQEdge( + record: FrozenRecord | VerboseFrozenRecord | MinimalFrozenRecord, + ): QEdge { return { getID(): string { return "fakeEdge"; @@ -244,14 +279,18 @@ export class Record { }; } - makeAPIEdge(record: FrozenRecord | VerboseFrozenRecord | MinimalFrozenRecord): Association { + makeAPIEdge( + record: FrozenRecord | VerboseFrozenRecord | MinimalFrozenRecord, + ): Association { return { predicate: record.predicate?.replace("biolink:", ""), qualifiers: record.qualifiers ? Object.fromEntries( - Object.entries(record.qualifiers).map(([qualifierType, qualifier]: [string, string]) => { - return [qualifierType.replace("biolink:", ""), qualifier]; - }), + Object.entries(record.qualifiers).map( + ([qualifierType, qualifier]: [string, string]) => { + return [qualifierType.replace("biolink:", ""), qualifier]; + }, + ), ) : undefined, api_name: record.api, @@ -267,8 +306,13 @@ export class Record { return records.map((record: Record): FrozenRecord => record.freeze()); } - public static unfreezeRecords(records: FrozenRecord[], config?: any): Record[] { - return records.map((record: FrozenRecord): Record => new Record(record, config)); + public static unfreezeRecords( + records: FrozenRecord[], + config?: any, + ): Record[] { + return records.map( + (record: FrozenRecord): Record => new Record(record, config), + ); } public static packRecords(records: Record[]): RecordPackage { @@ -281,7 +325,9 @@ export class Record { const apiEdgeHash = hash(JSON.stringify(record.association)); - let apiEdgeHashIndex = apiEdgeHashes.findIndex(hash => hash === apiEdgeHash); + let apiEdgeHashIndex = apiEdgeHashes.findIndex( + hash => hash === apiEdgeHash, + ); if (apiEdgeHashIndex === -1) { apiEdgeHashes.push(apiEdgeHash); @@ -298,7 +344,11 @@ export class Record { return [apiEdges, ...frozenRecords]; } - public static unpackRecords(recordPack: RecordPackage, qEdge: QEdge, config?: any): Record[] { + public static unpackRecords( + recordPack: RecordPackage, + qEdge: QEdge, + config?: any, + ): Record[] { const [apiEdges, ...frozenRecords] = recordPack; return frozenRecords.map((record: any): Record => { const apiEdge = apiEdges[record.apiEdge]; @@ -353,7 +403,10 @@ export class Record { return attributes ? attributes.reduce((arr: EdgeAttribute[], attribute: EdgeAttribute) => { attribute.attributes - ? arr.push(attribute, ...this._getFlattenedEdgeAttributes(attribute.attributes)) + ? arr.push( + attribute, + ...this._getFlattenedEdgeAttributes(attribute.attributes), + ) : arr.push(attribute); return arr; }, []) @@ -361,9 +414,13 @@ export class Record { } get _configuredEdgeAttributesForHash(): string { - return this._getFlattenedEdgeAttributes(this.mappedResponse["edge-attributes"]) + return this._getFlattenedEdgeAttributes( + this.mappedResponse["edge-attributes"], + ) .filter(attribute => { - return this.config?.EDGE_ATTRIBUTES_USED_IN_RECORD_HASH?.includes(attribute.attribute_type_id); + return this.config?.EDGE_ATTRIBUTES_USED_IN_RECORD_HASH?.includes( + attribute.attribute_type_id, + ); }) .reduce((acc, attribute) => { return [...acc, `${attribute.attribute_type_id}:${attribute.value}`]; @@ -378,10 +435,19 @@ export class Record { this.object.curie, Object.entries(this.qualifiers) .sort(([qTa, qVa], [qTb, qVb]) => qTa.localeCompare(qTb)) - .reduce((str, [qualifierType, qualifierValue]) => `${str};${qualifierType}:${qualifierValue}`, ""), + .reduce( + (str, [qualifierType, qualifierValue]) => + `${str};${qualifierType}:${JSON.stringify(qualifierValue)}`, + "", + ), this.api, this.metaEdgeSource, this._configuredEdgeAttributesForHash, + JSON.stringify( + this.provenanceChain.sort((sourceA, sourceB) => + sourceA.resource_id.localeCompare(sourceB.resource_id), + ), + ), ].join("-"); } @@ -399,11 +465,16 @@ export class Record { } return Object.fromEntries( Object.entries(this._qualifiers).map(([qualifierType, qualifier]) => { - const newQualifierType = `biolink:${qualifierType.replace("biolink:", "")}`; + const newQualifierType = `biolink:${qualifierType.replace( + "biolink:", + "", + )}`; let newQualifier = qualifier; if (qualifierType.includes("predicate")) { if (Array.isArray(qualifier)) { - newQualifier = qualifier.map(str => `biolink:${str.replace("biolink", "")}`); + newQualifier = qualifier.map( + str => `biolink:${str.replace("biolink", "")}`, + ); } else { newQualifier = `biolink:${qualifier.replace("biolink:", "")}`; } @@ -434,7 +505,9 @@ export class Record { returnValue = _.cloneDeep(this.mappedResponse.trapi_sources); } else { returnValue.push({ - resource_id: this.association.apiIsPrimaryKnowledgeSource ? this.apiInforesCurie : this.metaEdgeSource, + resource_id: this.association.apiIsPrimaryKnowledgeSource + ? this.apiInforesCurie + : this.metaEdgeSource, resource_role: "primary_knowledge_source", }); if (!this.association.apiIsPrimaryKnowledgeSource) { From e117b3710831be3cd05e49ccd15f56a0fbbb0314 Mon Sep 17 00:00:00 2001 From: tokebe <43009413+tokebe@users.noreply.github.com> Date: Wed, 21 Feb 2024 14:39:22 -0500 Subject: [PATCH 8/8] chore: rm check matching namespace (query handled) --- data/jq/pair/monarch.jq | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/jq/pair/monarch.jq b/data/jq/pair/monarch.jq index d9bac72..dc5e0ff 100644 --- a/data/jq/pair/monarch.jq +++ b/data/jq/pair/monarch.jq @@ -7,9 +7,9 @@ generateCurie($edge.input.id; $edge.input.curies) as $input_curie | { $input_curie: [$response] } | .[$input_curie][0].items = [ $response.items[] | select(. != null) - | select( - .[$output_namespace] == $edge.output.id - ) + # | select( + # .[$output_namespace] == $edge.output.id + # ) | .publications = [ if .publications != null then .publications