diff --git a/benchmarks/forms.py b/benchmarks/forms.py
index d6836bcf..7644db76 100644
--- a/benchmarks/forms.py
+++ b/benchmarks/forms.py
@@ -46,6 +46,15 @@ class Meta:
fields = ('zip_file', 'public', 'competition')
+class UploadNWBMetadataForm(forms.Form):
+ json_file = forms.FileField(label="JSON", help_text='Required')
+ dandiset_file = forms.FileField(label="Optionally, you can also upload your DANDIset directly", required=False)
+
+ class Meta:
+ model = UploadPlaceHolder
+ fields = ('json_file', 'dandiset_file')
+
+
class ChangePasswordForm(PasswordChangeForm):
def __init__(self, *args, **kwargs):
super(ChangePasswordForm, self).__init__(*args, **kwargs)
diff --git a/benchmarks/templates/benchmarks/central_profile.html b/benchmarks/templates/benchmarks/central_profile.html
index 0e32438d..6bffc55a 100644
--- a/benchmarks/templates/benchmarks/central_profile.html
+++ b/benchmarks/templates/benchmarks/central_profile.html
@@ -40,6 +40,11 @@
Welcome, {{ user.email }}
{% endfor %}
+
+
+ Convert NWB data to a BrainScore data plugin here.
+
+
{% else %}
diff --git a/benchmarks/templates/benchmarks/convert_nwb.html b/benchmarks/templates/benchmarks/convert_nwb.html
new file mode 100644
index 00000000..4f984242
--- /dev/null
+++ b/benchmarks/templates/benchmarks/convert_nwb.html
@@ -0,0 +1,56 @@
+{% extends "benchmarks/components/app-view.html" %}
+{% load static %}
+
+{% block banner %}
+ Convert NWB Data
+Here you can convert your NWB data to a BrainScore Benchmark!
+{% endblock %}
+
+{% block info_section %}
+ {% include "benchmarks/tutorials/tutorial-info-section.html" %}
+{% endblock %}
+
+
+{% block content %}
+
+{% if user %}
+
+
To convert, upload a JSON file containing the required NWB metadata.
+
+
+
Feel free to download a reference template JSON file here,
+ and fill in the required values.
+
+
+
+
+
+
+{% else %}
+{% endif %}
+
+{% endblock %}
+
+
diff --git a/benchmarks/urls.py b/benchmarks/urls.py
index 6c50f393..a969ed85 100644
--- a/benchmarks/urls.py
+++ b/benchmarks/urls.py
@@ -43,6 +43,7 @@
path('profile/submit/', user.Upload.as_view(domain="vision"), name=f'vision-submit'),
path('profile/resubmit/', partial(user.resubmit, domain="vision"), name='vision-resubmit'),
path('profile/logout/', user.Logout.as_view(domain="vision"), name='vision-logout'),
+ path('profile/nwb/', user.ConvertNWB.as_view(domain="vision"), name=f'convert-nwb'),
# central tutorial page, constant across all Brain-Score domains
path('tutorials/', user.Tutorials.as_view(tutorial_type="tutorial"), name='tutorial'),
diff --git a/benchmarks/views/user.py b/benchmarks/views/user.py
index 4e5c5fb1..f318335d 100644
--- a/benchmarks/views/user.py
+++ b/benchmarks/views/user.py
@@ -17,7 +17,7 @@
from django.utils.encoding import force_bytes, force_str
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.views import View
-from benchmarks.forms import SignupForm, LoginForm, UploadFileForm
+from benchmarks.forms import SignupForm, LoginForm, UploadFileForm, UploadNWBMetadataForm
from benchmarks.models import Model, BenchmarkInstance, BenchmarkType
from benchmarks.tokens import account_activation_token
from benchmarks.views.index import get_context
@@ -234,6 +234,58 @@ def post(self, request):
_logger.debug("Job triggered successfully")
return render(request, 'benchmarks/success.html', {"domain": self.domain})
+class ConvertNWB(View):
+ domain = None
+
+ def get(self, request):
+ assert self.domain is not None
+ if request.user.is_anonymous:
+ return HttpResponseRedirect(f'../profile/{self.domain}')
+ form = UploadNWBMetadataForm()
+ return render(request, 'benchmarks/convert_nwb.html',
+ {'form': form, 'domain': self.domain, 'formatted': self.domain.capitalize()})
+
+ def post(self, request):
+ assert self.domain is not None
+ form = UploadNWBMetadataForm(request.POST, request.FILES)
+
+ metadata_json = form.files.get('json_file')
+ json_data = json.load(metadata_json)
+ with open('submission.json', 'w') as fp:
+ json.dump(json_data, fp)
+
+ user_instance = User.objects.get_by_natural_key(request.user.email)
+ json_info = {
+ "model_type": request.POST['model_type'] if "model_type" in form.base_fields else "BrainModel",
+ "user_id": user_instance.id,
+ "public": str('public' in request.POST),
+ "domain": self.domain
+ }
+
+ with open('result.json', 'w') as fp:
+ json.dump(json_info, fp)
+
+ _logger.debug(request.user.get_full_name())
+ _logger.debug(f"request user: {request.user.get_full_name()}")
+
+ # submit to jenkins
+ jenkins_url = "http://www.brain-score-jenkins.com:8080"
+ auth = get_secret("brainscore-website_jenkins_access_aws")
+ auth = (auth['user'], auth['password'])
+ request_url = f"{jenkins_url}/job/brainscore_nwb_converter/buildWithParameters" \
+ f"?TOKEN=trigger2convertNWB" \
+ f"&email={request.user.email}"
+ _logger.debug(f"request_url: {request_url}")
+ params = {'metadata.json': open('submission.json', 'rb'), 'submission.config': open('result.json', 'rb')}
+ if 'dandiset_file' in request.FILES:
+ params['dandiset.zip'] = request.FILES['dandiset_file']
+ response = requests.post(request_url, files=params, auth=auth)
+ _logger.debug(f"response: {response}")
+
+ # update frontend
+ response.raise_for_status()
+ _logger.debug("Job triggered successfully")
+ return render(request, 'benchmarks/success.html', {"domain": self.domain})
def is_submission_original_and_under_plugin_limit(file, submitter: User) -> Tuple[bool, Union[None, List[str]]]:
"""
diff --git a/static/benchmarks/example_json.json b/static/benchmarks/example_json.json
new file mode 100644
index 00000000..dfd5cfa7
--- /dev/null
+++ b/static/benchmarks/example_json.json
@@ -0,0 +1,16 @@
+{
+ "dandiset_id": "Dandiset id, i.e. 000788",
+ "nwb_file_path": "path to the NWB file within the overall Dandiset, i.e. for a Dandiset structure of 000788/sub-pico/sub-pico_ecephys.nwb, this value should be sub-pico/sub-pico_ecephys.nwb",
+ "identifier": "identifier for your data, i.e. DataGenerationTrial_emogan",
+ "assembly": {
+ "region": ["IT"],
+ "presentation": 8500,
+ "neuroid": 18,
+ "start_time_ms": 0,
+ "stop_time_ms": 300,
+ "tb_ms": 10
+ },
+ "stimulus_set": {
+ "length": 170
+ }
+}
\ No newline at end of file