|
7 | 7 | from abc import ABC, abstractmethod
|
8 | 8 | from collections import Counter, defaultdict
|
9 | 9 | from contextlib import closing
|
10 |
| -from operator import attrgetter |
11 | 10 | from pathlib import Path
|
12 | 11 | from typing import Any
|
13 | 12 |
|
|
18 | 17 |
|
19 | 18 | from app.cli import curate, utils
|
20 | 19 | from app.cli.brain_region_data import BRAIN_ATLAS_REGION_VOLUMES
|
21 |
| -from app.cli.curation import electrical_cell_recording |
| 20 | +from app.cli.curation import cell_composition, electrical_cell_recording |
22 | 21 | from app.cli.types import ContentType
|
23 | 22 | from app.cli.utils import (
|
24 | 23 | AUTHORIZED_PUBLIC,
|
|
37 | 36 | BrainRegionHierarchy,
|
38 | 37 | CellComposition,
|
39 | 38 | DataMaturityAnnotationBody,
|
| 39 | + Derivation, |
40 | 40 | ElectricalCellRecording,
|
41 | 41 | EModel,
|
42 | 42 | Entity,
|
|
71 | 71 | from app.logger import L
|
72 | 72 | from app.schemas.base import ProjectContext
|
73 | 73 |
|
74 |
| -from app.cli.curation import electrical_cell_recording, cell_composition |
75 |
| -from app.cli.types import ContentType |
76 |
| - |
77 |
| - |
78 | 74 | BRAIN_ATLAS_NAME = "BlueBrain Atlas"
|
79 | 75 |
|
80 | 76 | REQUIRED_PATH = click.Path(exists=True, readable=True, dir_okay=False, resolve_path=True)
|
@@ -561,6 +557,75 @@ def ingest(
|
561 | 557 | db.commit()
|
562 | 558 |
|
563 | 559 |
|
| 560 | +class ImportEModelDerivations(Import): |
| 561 | + name = "EModelWorkflow" |
| 562 | + |
| 563 | + @staticmethod |
| 564 | + def is_correct_type(data): |
| 565 | + types = ensurelist(data["@type"]) |
| 566 | + return "EModelWorkflow" in types |
| 567 | + |
| 568 | + @staticmethod |
| 569 | + def ingest( |
| 570 | + db, |
| 571 | + project_context, |
| 572 | + data_list: list[dict], |
| 573 | + all_data_by_id: dict[str, dict], |
| 574 | + hierarchy_name: str, |
| 575 | + ): |
| 576 | + """Import emodel derivations from EModelWorkflow.""" |
| 577 | + legacy_emodel_ids = set() |
| 578 | + derivations = {} |
| 579 | + for data in tqdm(data_list, desc="EModelWorkflow"): |
| 580 | + legacy_emodel_id = utils.find_id_in_entity(data, "EModel", "generates") |
| 581 | + legacy_etc_id = utils.find_id_in_entity( |
| 582 | + data, "ExtractionTargetsConfiguration", "hasPart" |
| 583 | + ) |
| 584 | + if not legacy_emodel_id: |
| 585 | + L.warning("Not found EModel id in EModelWorkflow: {}", data["@id"]) |
| 586 | + continue |
| 587 | + if not legacy_etc_id: |
| 588 | + L.warning( |
| 589 | + "Not found ExtractionTargetsConfiguration id in EModelWorkflow: {}", data["@id"] |
| 590 | + ) |
| 591 | + continue |
| 592 | + if not (etc := all_data_by_id.get(legacy_etc_id)): |
| 593 | + L.warning("Not found ExtractionTargetsConfiguration with id {}", legacy_etc_id) |
| 594 | + continue |
| 595 | + if not (legacy_trace_ids := list(utils.find_ids_in_entity(etc, "Trace", "uses"))): |
| 596 | + L.warning( |
| 597 | + "Not found traces in ExtractionTargetsConfiguration with id {}", legacy_etc_id |
| 598 | + ) |
| 599 | + continue |
| 600 | + if legacy_emodel_id in legacy_emodel_ids: |
| 601 | + L.warning("Duplicated and ignored traces for EModel id {}", legacy_emodel_id) |
| 602 | + continue |
| 603 | + legacy_emodel_ids.add(legacy_emodel_id) |
| 604 | + if not (emodel := utils._find_by_legacy_id(legacy_emodel_id, EModel, db)): |
| 605 | + L.warning("Not found EModel with legacy id {}", legacy_emodel_id) |
| 606 | + continue |
| 607 | + if emodel.id in derivations: |
| 608 | + L.warning("Duplicated and ignored traces for EModel uuid {}", emodel.id) |
| 609 | + derivations[emodel.id] = [ |
| 610 | + utils._find_by_legacy_id(legacy_trace_id, ElectricalCellRecording, db).id |
| 611 | + for legacy_trace_id in legacy_trace_ids |
| 612 | + ] |
| 613 | + |
| 614 | + rows = [ |
| 615 | + Derivation(used_id=trace_id, generated_id=emodel_id) |
| 616 | + for emodel_id, trace_ids in derivations.items() |
| 617 | + for trace_id in trace_ids |
| 618 | + ] |
| 619 | + L.info( |
| 620 | + "Imported derivations for {} EModels from {} records", len(derivations), len(data_list) |
| 621 | + ) |
| 622 | + # delete everything from derivation table before adding the records |
| 623 | + query = sa.delete(Derivation) |
| 624 | + db.execute(query) |
| 625 | + db.add_all(rows) |
| 626 | + db.commit() |
| 627 | + |
| 628 | + |
564 | 629 | class ImportBrainAtlas(Import):
|
565 | 630 | name = "BrainAtlas"
|
566 | 631 |
|
@@ -1370,6 +1435,7 @@ def _do_import(db, input_dir, project_context, hierarchy_name):
|
1370 | 1435 | ImportBrainAtlas,
|
1371 | 1436 | ImportDistribution,
|
1372 | 1437 | ImportNeuronMorphologyFeatureAnnotation,
|
| 1438 | + ImportEModelDerivations, |
1373 | 1439 | ]
|
1374 | 1440 |
|
1375 | 1441 | for importer in importers:
|
|
0 commit comments