@abi-software/map-utilities 1.6.1-beta.1 → 1.6.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/map-utilities",
3
- "version": "1.6.1-beta.1",
3
+ "version": "1.6.1-beta.3",
4
4
  "files": [
5
5
  "dist/*",
6
6
  "src/*",
@@ -171,44 +171,39 @@ async function queryPathsByDestination(flatmapAPI, knowledgeSource, featureId) {
171
171
  return [];
172
172
  }
173
173
 
174
- // Neuron populations from origin node(s) to destination node(s), via node(s)
175
- // API Label: Neuron populations that have source, via, and destination nodes
176
- async function queryPathsByRoute({ flatmapAPI, knowledgeSource, origins, destinations, vias }) {
177
- const originParam = {
178
- column: 'source_node_id',
179
- value: origins
180
- };
181
- const viaParam = {
182
- column: 'via_node_id',
183
- value: vias
184
- };
185
- const destinationParam = {
186
- column: 'dest_node_id',
187
- value: destinations
188
- };
189
- if (!origins.length) {
190
- originParam['negate'] = true;
191
- }
192
- if (!vias.length) {
193
- viaParam['negate'] = true;
194
- }
195
- if (!destinations.length) {
196
- destinationParam['negate'] = true;
174
+ function extractFeatureIds(inputArray) {
175
+ const result = [];
176
+
177
+ for (const itemString of inputArray) {
178
+ const item = JSON.parse(itemString);
179
+
180
+ if (Array.isArray(item) && item.length >= 2) {
181
+ if (Array.isArray(item[1]) && item[1].length === 0) {
182
+ result.push(item[0]);
183
+ }
184
+ }
197
185
  }
186
+ return result;
187
+ }
188
+
189
+ // Neuron populations as forward or backward connections of a neuron population
190
+ async function queryForwardBackwardConnections(flatmapAPI, knowledgeSource, pathIds) {
198
191
  const data = await competencyQuery({
199
- flatmapAPI: flatmapAPI,
200
- knowledgeSource: knowledgeSource,
201
- queryId: 24,
192
+ flatmapAPI,
193
+ knowledgeSource,
194
+ queryId: 26,
202
195
  parameters: [
203
- originParam,
204
- viaParam,
205
- destinationParam,
196
+ {
197
+ column: 'path_id',
198
+ value: pathIds
199
+ },
206
200
  ]
207
201
  });
208
202
  if (data?.results?.values) {
209
203
  const paths = data.results.values.map((value) => {
210
- // value => [ 'source_id', 'path_id', 'axon_terminal']
211
- return value[1];
204
+ // value => ["source_id", "base_path_id", "dest_path_id", "distance"]
205
+ // return dest_path_id
206
+ return value[2];
212
207
  });
213
208
  // remove duplicates
214
209
  return [...new Set(paths)];
@@ -216,6 +211,96 @@ async function queryPathsByRoute({ flatmapAPI, knowledgeSource, origins, destina
216
211
  return [];
217
212
  }
218
213
 
214
+ // Neuron populations from origin to destination, via
215
+ // Query 24: Neuron populations that have source, via, and destination nodes
216
+ // Query 25: Neuron populations that have source, via, and destination locations
217
+ async function queryPathsByRoute({ flatmapAPI, knowledgeSource, origins, destinations, vias }) {
218
+ const originFeatureIds = extractFeatureIds(origins);
219
+ const destinationFeatureIds = extractFeatureIds(destinations);
220
+ const viaFeatureIds = extractFeatureIds(vias);
221
+
222
+ const paramsF = [
223
+ {
224
+ column: 'source_feature_id',
225
+ value: originFeatureIds,
226
+ ...(originFeatureIds.length === 0 && { negate: true })
227
+ },
228
+ {
229
+ column: 'via_feature_id',
230
+ value: viaFeatureIds,
231
+ ...(viaFeatureIds.length === 0 && { negate: true })
232
+ },
233
+ {
234
+ column: 'dest_feature_id',
235
+ value: destinationFeatureIds,
236
+ ...(destinationFeatureIds.length === 0 && { negate: true })
237
+ }
238
+ ];
239
+
240
+ const params = [
241
+ {
242
+ column: 'source_node_id',
243
+ value: origins,
244
+ ...(origins.length === 0 && { negate: true })
245
+ },
246
+ {
247
+ column: 'via_node_id',
248
+ value: vias,
249
+ ...(vias.length === 0 && { negate: true })
250
+ },
251
+ {
252
+ column: 'dest_node_id',
253
+ value: destinations,
254
+ ...(destinations.length === 0 && { negate: true })
255
+ }
256
+ ];
257
+
258
+ const shouldCallDataF = paramsF.some(param =>
259
+ Array.isArray(param.value) && param.value.length > 0);
260
+
261
+ const promises = [
262
+ competencyQuery({
263
+ flatmapAPI,
264
+ knowledgeSource,
265
+ queryId: 24,
266
+ parameters: params
267
+ })
268
+ ];
269
+
270
+ if (shouldCallDataF) {
271
+ promises.push(
272
+ competencyQuery({
273
+ flatmapAPI,
274
+ knowledgeSource,
275
+ queryId: 25,
276
+ parameters: paramsF
277
+ })
278
+ );
279
+ }
280
+
281
+ const results = await Promise.all(promises);
282
+
283
+ let pathsF = [];
284
+ let data;
285
+ if (shouldCallDataF) {
286
+ const dataF = results[0];
287
+ data = results[1];
288
+ // value => [ 'source_id', 'path_id', 'axon_terminal']
289
+ pathsF = dataF?.results?.values?.map(value => value[1]) || [];
290
+ } else {
291
+ data = results[0];
292
+ }
293
+ // value => [ 'source_id', 'path_id', 'axon_terminal']
294
+ const paths = data?.results?.values?.map(value => value[1]) || [];
295
+ const combined = [...new Set([...pathsF, ...paths])];
296
+
297
+ // Continue to forward and backward connections
298
+ const additionalPaths = await queryForwardBackwardConnections(flatmapAPI, knowledgeSource, combined);
299
+ const total = [...new Set([...combined, ...additionalPaths])];
300
+
301
+ return total;
302
+ }
303
+
219
304
  export {
220
305
  competencyQuery,
221
306
  queryAllConnectedPaths,
@@ -223,4 +308,5 @@ export {
223
308
  queryPathsByViaLocation,
224
309
  queryPathsByDestination,
225
310
  queryPathsByRoute,
311
+ queryForwardBackwardConnections,
226
312
  };
@@ -106,14 +106,23 @@ function getPhenotypeItems(obj, prop) {
106
106
  return arr;
107
107
  }
108
108
 
109
- async function transformResults(flatmapAPI, results) {
109
+ async function transformResults(flatmapAPI, knowledgeSource, results) {
110
110
  const baseResults = Array.from(
111
111
  new Map(results.map(item => [JSON.stringify(item), item])).values()
112
112
  );
113
113
  const terms = baseResults.flat(Infinity);
114
114
  const uniqueTerms = [...new Set(terms)];
115
115
  const fetchResults = await fetchLabels(flatmapAPI, uniqueTerms);
116
- const objectResults = fetchResults.map((item) => JSON.parse(item[1]));
116
+ // const objectResults = fetchResults.map((item) => JSON.parse(item[1]));
117
+ const objectResults = fetchResults.reduce((arr, item) => {
118
+ const id = item[0];
119
+ const valObj = JSON.parse(item[1]);
120
+ if (valObj.source === knowledgeSource) {
121
+ arr.push({ id, label: valObj.label });
122
+ }
123
+ return arr;
124
+ }, []);
125
+ const nodes = [];
117
126
  const formattedResults = baseResults.map((item) => {
118
127
  const itemPair = item.flat();
119
128
  const labels = [];
@@ -121,6 +130,12 @@ async function transformResults(flatmapAPI, results) {
121
130
  const foundObj = objectResults.find((obj) => obj.id === itemPair[i])
122
131
  if (foundObj) {
123
132
  labels.push(foundObj.label);
133
+ if (i > 0) {
134
+ nodes.push({
135
+ key: [itemPair[i], []],
136
+ label: foundObj.label,
137
+ });
138
+ }
124
139
  }
125
140
  }
126
141
  return {
@@ -128,10 +143,15 @@ async function transformResults(flatmapAPI, results) {
128
143
  label: labels.join(', '),
129
144
  };
130
145
  });
131
- return formattedResults;
146
+ // unique results by combining formattedResults and nodes
147
+ // but filter out duplicates based on the labels
148
+ const uniqueResults = [...formattedResults, ...nodes].filter((result, index, self) =>
149
+ index === self.findIndex((r) => r.label === result.label)
150
+ );
151
+ return uniqueResults;
132
152
  }
133
153
 
134
- async function extractOriginItems(flatmapAPI, knowledge) {
154
+ async function extractOriginItems(flatmapAPI, knowledgeSource, knowledge) {
135
155
  const results = [];
136
156
  knowledge.forEach(obj => {
137
157
  if (!Array.isArray(obj.connectivity) || obj.connectivity.length === 0) return;
@@ -141,10 +161,10 @@ async function extractOriginItems(flatmapAPI, knowledge) {
141
161
  if (connectivityItems.has(stringifyItem)) results.push(item);
142
162
  });
143
163
  });
144
- return await transformResults(flatmapAPI, results);
164
+ return await transformResults(flatmapAPI, knowledgeSource, results);
145
165
  }
146
166
 
147
- async function extractDestinationItems(flatmapAPI, knowledge) {
167
+ async function extractDestinationItems(flatmapAPI, knowledgeSource, knowledge) {
148
168
  const results = [];
149
169
  knowledge.forEach(obj => {
150
170
  if (!Array.isArray(obj.connectivity) || obj.connectivity.length === 0) return;
@@ -157,10 +177,10 @@ async function extractDestinationItems(flatmapAPI, knowledge) {
157
177
  if (connectivityItems.has(stringifyItem)) results.push(item);
158
178
  });
159
179
  });
160
- return await transformResults(flatmapAPI, results);
180
+ return await transformResults(flatmapAPI, knowledgeSource, results);
161
181
  }
162
182
 
163
- async function extractViaItems(flatmapAPI, knowledge) {
183
+ async function extractViaItems(flatmapAPI, knowledgeSource, knowledge) {
164
184
  const results = [];
165
185
  knowledge.forEach(obj => {
166
186
  if (!Array.isArray(obj.connectivity) || obj.connectivity.length === 0) return;
@@ -173,7 +193,7 @@ async function extractViaItems(flatmapAPI, knowledge) {
173
193
  if (connectivityItems.has(stringifyItem)) results.push(item);
174
194
  });
175
195
  });
176
- return await transformResults(flatmapAPI, results);
196
+ return await transformResults(flatmapAPI, knowledgeSource, results);
177
197
  }
178
198
 
179
199
  function findPathsByOriginItem(knowledge, originItems) {
@@ -15,6 +15,7 @@ import {
15
15
  queryPathsByViaLocation,
16
16
  queryPathsByDestination,
17
17
  queryPathsByRoute,
18
+ queryForwardBackwardConnections,
18
19
  } from "./CompetencyQueries/CompetencyQueries.js";
19
20
  import {
20
21
  filterOrigins,
@@ -47,6 +48,7 @@ export {
47
48
  queryPathsByViaLocation,
48
49
  queryPathsByDestination,
49
50
  queryPathsByRoute,
51
+ queryForwardBackwardConnections,
50
52
  filterOrigins,
51
53
  filterDestinations,
52
54
  filterViaLocations,