Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Sim Amend Revision #1036

Merged
merged 24 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3520a38
citation temp
van-go Feb 7, 2023
9f40b69
Merge branch 'main' of https://github.com/DesignSafe-CI/portal
van-go Feb 7, 2023
5b68e02
Merge branch 'main' of https://github.com/DesignSafe-CI/portal
van-go Mar 6, 2023
c7c6838
Merge remote-tracking branch 'origin/main'
van-go Mar 24, 2023
c90c264
Merge branch 'main' of https://github.com/DesignSafe-CI/portal
van-go Mar 29, 2023
e447f09
Merge remote-tracking branch 'origin/main'
van-go Apr 3, 2023
c8f3bd2
Merge branch 'main' into feature-sim-amend-revision
SilversunKSauri Apr 14, 2023
f90e62a
Merge branch 'main' into feature-sim-amend-revision
SilversunKSauri Apr 17, 2023
dac58dc
Merge branch 'main' into feature-sim-amend-revision
SilversunKSauri Apr 17, 2023
e19d539
Task/des2452 sim amends edit proj metadata (#1033)
van-go May 1, 2023
ee4ffe5
Merge branch 'main' into feature-sim-amend-revision
SilversunKSauri May 1, 2023
61a349a
unamendable fields
van-go May 1, 2023
62555d7
Merge branch 'main' into feature-sim-amend-revision
SilversunKSauri May 10, 2023
1373e16
Task/des 2454 version file data selection (#1040)
van-go May 17, 2023
e8b2d2b
Merge branch 'main' into feature-sim-amend-revision
SilversunKSauri May 17, 2023
4a5587d
adding note re using save on confirm authors pages
SilversunKSauri May 31, 2023
ace0ae7
Merge branch 'main' into feature-sim-amend-revision
SilversunKSauri Jun 1, 2023
5f3085f
Merge branch 'main' into feature-sim-amend-revision
jarosenb Jun 1, 2023
d86956b
Merge branch 'main' into feature-sim-amend-revision
jarosenb Jun 1, 2023
33dac4c
Merge branch 'main' into feature-sim-amend-revision
jarosenb Jun 1, 2023
0933009
Add Fedora ingest for simulations (#1060)
jarosenb Jun 1, 2023
9ef438b
Merge branch 'main' into feature-sim-amend-revision
jarosenb Jun 1, 2023
7ce6de3
Merge branch 'main' into feature-sim-amend-revision
jarosenb Jun 1, 2023
6c251e6
Merge branch 'main' into feature-sim-amend-revision
jarosenb Jun 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions designsafe/apps/api/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ def amend_publication_data(self, project_id, amendments=None, authors=None, revi
"""
from designsafe.apps.projects.managers import publication as PublicationManager
from designsafe.libs.fedora.fedora_operations import amend_project_fedora, ingest_project_experimental
from designsafe.libs.fedora.sim_operations import ingest_project_sim
try:
amended_pub = PublicationManager.amend_publication(project_id, amendments, authors, revision)
PublicationManager.amend_datacite_doi(amended_pub)
Expand All @@ -677,6 +678,8 @@ def amend_publication_data(self, project_id, amendments=None, authors=None, revi
amend_project_fedora(project_id, version=revision)
if amended_pub.project.value.projectType == 'experimental':
ingest_project_experimental(project_id, version=revision, amend=True)
if amended_pub.project.value.projectType == 'simulation':
ingest_project_sim(project_id, version=revision, amend=True)
except Exception as exc:
logger.error('Proj Id: %s. %s', project_id, exc, exc_info=True)
raise self.retry(exc=exc)
Expand Down Expand Up @@ -773,6 +776,10 @@ def save_to_fedora(self, project_id, revision=None):
from designsafe.libs.fedora.fedora_operations import ingest_project_experimental
ingest_project_experimental(project_id, version=revision)
return
if pub.project.value.projectType == 'simulation':
from designsafe.libs.fedora.sim_operations import ingest_project_sim
ingest_project_sim(project_id, version=revision)
return

_root = os.path.join('/corral-repl/tacc/NHERI/published', project_id)
fedora_base = 'http://fedoraweb01.tacc.utexas.edu:8080/fcrepo/rest/publications_01'
Expand Down
3 changes: 3 additions & 0 deletions designsafe/libs/fedora/fedora_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
"references": {
"@id": "http://purl.org/dc/elements/1.1/references"
},
"isReferencedBy": {
"@id": "http://purl.org/dc/elements/1.1/isReferencedBy"
},
"relation": {
"@id": "http://purl.org/dc/elements/1.1/relation"
},
Expand Down
305 changes: 305 additions & 0 deletions designsafe/libs/fedora/sim_operations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
import requests
from requests import HTTPError
from django.conf import settings
import json
import magic
import os
import hashlib
from urllib import parse
from io import StringIO
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from designsafe.apps.data.models.elasticsearch import IndexedPublication
from django.contrib.auth import get_user_model
from designsafe.apps.api.publications.operations import _get_user_by_username
from designsafe.libs.fedora.fedora_operations import format_metadata_for_fedora, fedora_post, fedora_update, create_fc_version, upload_manifest, generate_manifest
import logging
logger = logging.getLogger(__name__)


def walk_sim(project_id, version=None):
from urllib import parse
doc = IndexedPublication.from_id(project_id, revision=version)

relation_map = []
full_author_list = []

project_meta = format_metadata_for_fedora(project_id, version=version)
if version:
project_id = '{}v{}'.format(project_id, str(version))
license = project_meta.get('license', None)
print(project_id)

project_map = {
'uuid': doc.project.uuid,
'container_path': project_id,
'fedora_mapping': {**project_meta, 'generated': [], 'license': None},
'fileObjs': []
}

sims_list = doc.simulations
for sim in sims_list:
# Do stuff with experiment.
sim_container_path = "{}/{}".format(project_id, parse.quote(sim.value.title))
print('simulation ' + sim.value.title)
sim_doi = sim.doi
project_map['fedora_mapping']['generated'].append('Experiment: {}'.format(sim_doi))

sim_map = {
'uuid': sim.uuid,
'container_path': sim_container_path,
'fedora_mapping': {**format_sim(sim), 'license': license, 'wasGeneratedBy': project_id, 'generated': []},
'fileObjs': getattr(sim, 'fileObjs', [])
}

full_author_list += sim_map['fedora_mapping']['creator']


reports = filter(
lambda report: sim.uuid in report.value.simulations,
getattr(doc, 'reports', []))
for report in reports:
# Do stuff with report.
report_container_path = "{}/{}".format(sim_container_path, parse.quote(report.value.title))
print('\treport ' + report.value.title)
sim_map['fedora_mapping']['generated'].append('Report: {}'.format(report.value.title))

report_map = {
'uuid': report.uuid,
'fileObjs': report.fileObjs,
'container_path': report_container_path,
'fedora_mapping': {**format_report(report), 'wasGeneratedBy': 'Simulation: {}'.format(sim_doi)}
}
relation_map.append(report_map)


analysis_list = filter(
lambda analysis: sim.uuid in analysis.value.simulations,
getattr(doc, 'analysiss', []))
for analysis in analysis_list:
# Do stuff with report.
analysis_container_path = "{}/{}".format(sim_container_path, parse.quote(analysis.value.title))
print('\tanalysis ' + analysis.value.title)
sim_map['fedora_mapping']['generated'].append('Analysis: {}'.format(analysis.value.title))

analysis_map = {
'uuid': analysis.uuid,
'fileObjs': analysis.fileObjs,
'container_path': analysis_container_path,
'fedora_mapping': {**format_analysis(analysis), 'wasGeneratedBy': 'Simulation: {}'.format(sim_doi)}
}
relation_map.append(analysis_map)


models = filter(
lambda model: sim.uuid in model.value.simulations,
getattr(doc, 'models', [])
)
for model in models:
# Do stuff with model.
model_container_path = "{}/{}".format(sim_container_path, parse.quote(model.value.title))
print('\tmodel ' + model.value.title)
sim_map['fedora_mapping']['generated'].append('Simulation Model: {}'.format(model.value.title))

model_map = {
'uuid': model.uuid,
'fileObjs': model.fileObjs,
'container_path': model_container_path,
'fedora_mapping': {**format_model(model), 'wasGeneratedBy': 'Simulation: {}'.format(sim_doi)}
}

inputs = filter(
lambda input: model.uuid in input.value.modelConfigs,
getattr(doc, 'inputs', [])
)

for input in inputs:
input_container_path = "{}/{}".format(model_container_path, parse.quote(input.value.title))
print('\t\tinput ' + input.value.title)
sim_map['fedora_mapping']['generated'].append('Simulation Input: {}'.format(input.value.title))
input_map = {
'uuid': input.uuid,
'fileObjs': input.fileObjs,
'container_path': input_container_path,
'fedora_mapping': {**format_input(input),
'wasGeneratedBy': 'Simulation: {}'.format(sim_doi),
'wasDerivedFrom': 'Simulation Model: {}'.format(model.value.title),
'wasInfluencedBy': []}
}

outputs = filter(
lambda output: input.uuid in output.value.simInputs,
getattr(doc, 'outputs', [])
)

for output in outputs:
output_container_path = "{}/{}".format(input_container_path, parse.quote(output.value.title))
print('\t\t\toutput ' + output.value.title)
sim_map['fedora_mapping']['generated'].append('Simulation Input: {}'.format(output.value.title))
input_map['fedora_mapping']['wasInfluencedBy'].append('Simulation Output: {}'.format(output.value.title))
output_map = {
'uuid': output.uuid,
'fileObjs': output.fileObjs,
'container_path': output_container_path,
'fedora_mapping': {**format_output(output),
'wasGeneratedBy': 'Simulation: {}'.format(sim_doi),
'wasDerivedFrom': ['Simulation Model: {}'.format(model.value.title), 'Simulation Input: {}'.format(input.value.title)],
}
}

relation_map.append(output_map)

relation_map.append(input_map)

relation_map.append(model_map)

relation_map.append(sim_map)

project_map['fedora_mapping']['creator'] = list(set(full_author_list))
relation_map.append(project_map)
return relation_map[::-1]


def format_sim(sim):
"""
Map experiment to Datacite fields for Fedora.
"""
meta = sim.value

sim_type = meta.simulationType
if sim_type == 'other':
sim_type = getattr(meta, 'simulationTypeOther', 'other')


publication_date = str(sim.created)

try:
authors = sim.authors
creator = list(map(lambda author: "{lname}, {fname}".format(**author.to_dict()), authors))
except AttributeError:
creator = list(map(lambda username: _get_user_by_username(sim, username), meta.authors))

try:
dois = list(meta.dois)
except AttributeError:
dois = [sim.doi]


referenced_by = []
part_of = []
references = []

refs = getattr(meta, 'referencedData', [])
for ref in refs:
if ref['hrefType'] == 'URL':
ref_val = f"{ref['title']} ({ref['doi']})"
elif ref['hrefType'] == 'DOI':
ref_val = ref['doi']
references.append(ref_val)


related_work = getattr(meta, 'relatedWork', [])
for work in related_work:
if work['hrefType'] == 'URL':
work_val = f"{work['title']} ({work['href']})"
elif work['hrefType'] == 'DOI':
work_val = work['href']

if work['type'] == 'Linked Project':
part_of.append(work_val)

if work['type'] == 'Linked Dataset':
part_of.append(work_val)

if work['type'] == 'Context':
references.append(work_val)

if work['type'] == 'Cited By':
referenced_by.append(work_val)




return {
'type': sim_type,
'identifier': dois + [sim.uuid],
'creator': creator,
'title': meta.title,
'description': meta.description,
'available': publication_date,
'publisher': 'Designsafe',
'isReferencedBy': referenced_by,
'isPartOf': part_of,
'references': references
}


def format_report(report):
return {
'type': 'report',
'title': report.value.title,
'description': report.value.description,
'tags': getattr(report.value, 'tags', [])
}

def format_analysis(analysis):
return {
'type': 'analysis',
'title': analysis.value.title,
'description': analysis.value.description,
'tags': getattr(analysis.value, 'tags', [])
}

def format_model(model):
return {
'type': 'simulation model',
'title': model.value.title,
'description': model.value.description,
'tags': getattr(model.value, 'tags', [])
}

def format_input(input):
return {
'type': 'simulation input',
'title': input.value.title,
'description': input.value.description,
'tags': getattr(input.value, 'tags', [])
}

def format_output(output):
return {
'type': 'simulation output',
'title': output.value.title,
'description': output.value.description,
'tags': getattr(output.value, 'tags', [])
}


def generate_manifest_sim(project_id, version=None):
walk_result = walk_sim(project_id, version=version)
return generate_manifest(walk_result, project_id, version)


def upload_manifest_sim(project_id, version=None):
manifest_dict = generate_manifest_sim(project_id, version=version)
return upload_manifest(manifest_dict, project_id, version)


def ingest_project_sim(project_id, version=None, amend=False):
"""
Ingest a project into Fedora by creating a record in the repo, updating it
with the published metadata, and uploading its files.
"""
container_path = project_id
if version:
container_path = '{}v{}'.format(container_path, str(version))

walk_result = walk_sim(project_id, version=version)
for entity in walk_result:
if amend:
create_fc_version(entity['container_path'])
fedora_post(entity['container_path'])
fedora_update(entity['container_path'], entity['fedora_mapping'])

if not amend:
upload_manifest_sim(project_id, version=version)
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import {
import {
VersionExperimentSelectionComponent,
VersionFieldReconSelectionComponent,
VersionSimulationSelectionComponent,
VersionCitationComponent
} from './pipeline-version/pipeline-version.component';
import { VersionChangesComponent } from './pipeline-version/pipeline-version-changes.component';
import { AmendExperimentComponent, AmendFieldReconComponent } from './pipeline-amend/pipeline-amend.component';
import { AmendExperimentComponent, AmendFieldReconComponent, AmendSimulationComponent } from './pipeline-amend/pipeline-amend.component';
import { AmendOtherComponent } from './pipeline-amend/pipeline-amend-other.component';
import { AmendCitationComponent } from './pipeline-amend/pipeline-amend-citation.component';
import {
Expand Down Expand Up @@ -91,11 +92,13 @@ ddProjectsComponents.component('pipelineStart', PipelineStartComponent);
ddProjectsComponents.component('amendOther', AmendOtherComponent);
ddProjectsComponents.component('amendExperiment', AmendExperimentComponent);
ddProjectsComponents.component('amendFieldRecon', AmendFieldReconComponent);
ddProjectsComponents.component('amendSimulation', AmendSimulationComponent);
ddProjectsComponents.component('amendCitation', AmendCitationComponent);
ddProjectsComponents.component('versionOtherSelection', VersionOtherSelectionComponent);
ddProjectsComponents.component('versionOtherCitation', VersionOtherCitationComponent);
ddProjectsComponents.component('versionExperimentSelection', VersionExperimentSelectionComponent);
ddProjectsComponents.component('versionFieldReconSelection', VersionFieldReconSelectionComponent);
ddProjectsComponents.component('versionSimulationSelection', VersionSimulationSelectionComponent);
ddProjectsComponents.component('versionCitation', VersionCitationComponent);
ddProjectsComponents.component('versionChanges', VersionChangesComponent);
ddProjectsComponents.component('pipelineSelectExp', PipelineSelectionExpComponent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<div class="pipeline-header">
<h3>Confirm Author Order</h3>
<strong>You are required to confirm the list of Authors on your Citation(s) before continuing.</strong>
Click Save to confirm.
Your citation(s) will be updated to match what is shown in the preview.
<div ng-if="$ctrl.ui.loading">
<h3 class="text-center">
Expand Down
Loading