|
1 | NO CONTENT: new file 100755 |
|
1 | NO CONTENT: new file 100755 |
@@ -0,0 +1,17 | |||
|
1 | {% extends "base.html" %} | |
|
2 | ||
|
3 | {% block title %}Login{% endblock %} | |
|
4 | ||
|
5 | {% block content %} | |
|
6 | <center> | |
|
7 | <h4>Please login</h4> | |
|
8 | ||
|
9 | <div style="margin-top: 30px;"> | |
|
10 | <form method="POST"> | |
|
11 | {{ form.as_p }} | |
|
12 | {% csrf_token %} | |
|
13 | <button type="submit">Login</button> | |
|
14 | </form> | |
|
15 | </div> | |
|
16 | </center> | |
|
17 | {% endblock %} |
@@ -0,0 +1,9 | |||
|
1 | from django.conf.urls import url | |
|
2 | from . import views | |
|
3 | ||
|
4 | urlpatterns = [ | |
|
5 | url(r'^login/$', views.login_view, name='login'), | |
|
6 | url(r'^logout/$', views.logout_view, name='logout'), | |
|
7 | ] | |
|
8 | ||
|
9 | app_name = 'login' No newline at end of file |
@@ -0,0 +1,38 | |||
|
1 | from django.contrib.auth import authenticate | |
|
2 | from django.contrib.auth import login, logout | |
|
3 | from django.contrib.auth.forms import AuthenticationForm | |
|
4 | from django.shortcuts import render, redirect | |
|
5 | ||
|
6 | ''' Login to updata app for ROJ staff''' | |
|
7 | ||
|
8 | def login_view(request): | |
|
9 | ||
|
10 | form = AuthenticationForm() | |
|
11 | if request.method == "POST": | |
|
12 | form = AuthenticationForm(data=request.POST) | |
|
13 | ||
|
14 | if form.is_valid(): | |
|
15 | ||
|
16 | username = form.cleaned_data['username'] | |
|
17 | password = form.cleaned_data['password'] | |
|
18 | ||
|
19 | user = authenticate(username=username, password=password) | |
|
20 | ||
|
21 | if user is not None: | |
|
22 | ||
|
23 | if user.is_active: | |
|
24 | login(request, user) | |
|
25 | ||
|
26 | return redirect('/updata') | |
|
27 | else: | |
|
28 | return render(request, "login/login.html" ) | |
|
29 | else: | |
|
30 | context = {'error_login': "error"} | |
|
31 | return render(request, "login/login.html", context ) | |
|
32 | ||
|
33 | return render(request, "login/login.html", {'form': form}) | |
|
34 | ||
|
35 | def logout_view(request): | |
|
36 | ||
|
37 | logout(request) | |
|
38 | return redirect('/') No newline at end of file |
|
1 | NO CONTENT: new file 100755 |
@@ -0,0 +1,108 | |||
|
1 | from django import forms | |
|
2 | import django.utils.html | |
|
3 | import django.utils.safestring | |
|
4 | import django.template.defaulttags | |
|
5 | ||
|
6 | # third party imports | |
|
7 | import numpy | |
|
8 | ||
|
9 | # Madrigal imports | |
|
10 | import madrigal.metadata | |
|
11 | import madrigal.ui.web | |
|
12 | ||
|
13 | # madrigal imports | |
|
14 | import madrigal._derive | |
|
15 | import madrigal.metadata | |
|
16 | import madrigal.ui.web | |
|
17 | import madrigal.cedar | |
|
18 | import madrigal.isprint | |
|
19 | import madweb.forms | |
|
20 | ||
|
21 | import datetime, time | |
|
22 | ||
|
23 | def getSelection(keyword, args, kwargs): | |
|
24 | """getSelection returns '0' if keyword not a key in either args[0] or kwargs, | |
|
25 | otherwise the value | |
|
26 | ||
|
27 | args, kwargs - arguments as passed into SingleExpDefaultForm __init__ | |
|
28 | """ | |
|
29 | if len(args) == 0 and len(list(kwargs.keys())) == 0: | |
|
30 | return('0') # default case when no data passed in | |
|
31 | elif len(args) > 0: | |
|
32 | # args[0] is data dict argument to bind data | |
|
33 | if keyword in args[0]: | |
|
34 | return(args[0][keyword]) | |
|
35 | else: | |
|
36 | return('0') | |
|
37 | elif keyword in kwargs: | |
|
38 | return(kwargs[keyword]) | |
|
39 | elif 'data' in kwargs: | |
|
40 | if keyword in kwargs['data']: | |
|
41 | return(kwargs['data'][keyword]) | |
|
42 | else: | |
|
43 | return('0') | |
|
44 | else: | |
|
45 | return('0') | |
|
46 | ||
|
47 | def getExperimentList(args, kwargs, madWeb, header='Select experiment: '): | |
|
48 | ||
|
49 | instrumentsId= int(getSelection('instruments', args, kwargs)) | |
|
50 | ||
|
51 | kinstList = [int(instrumentsId)] | |
|
52 | startDate = datetime.datetime(1950,1,1) | |
|
53 | startDT = datetime.datetime(startDate.year, startDate.month, startDate.day, 0, 0, 0) | |
|
54 | now = datetime.datetime.now() | |
|
55 | endDate = datetime.datetime(now.year, 12, 31, 23, 59, 59) | |
|
56 | endDT = datetime.datetime(endDate.year, endDate.month, endDate.day, 23, 59, 59) | |
|
57 | experiments = madWeb.getExperimentList(kinstList,startDT, endDT, True) | |
|
58 | expListin = [('0', header),] | |
|
59 | for exp in experiments: | |
|
60 | expListin.append((exp[0], exp[2])) | |
|
61 | ||
|
62 | # Using set | |
|
63 | seen = set() | |
|
64 | ||
|
65 | # using list comprehension | |
|
66 | expList = [(a, b) for a, b in expListin | |
|
67 | if not (b in seen or seen.add(b))] | |
|
68 | ||
|
69 | return(expList) | |
|
70 | ||
|
71 | class UpdataForm(forms.Form): | |
|
72 | def __init__(self, *args, **kwargs): | |
|
73 | super(UpdataForm, self).__init__(*args, **kwargs) | |
|
74 | madDB = madrigal.metadata.MadrigalDB() | |
|
75 | madInstData = madrigal.metadata.MadrigalInstrumentData(madDB) | |
|
76 | instruments = madInstData.getInstruments(0, True) | |
|
77 | instList = [('0', "Select Instrument"), ] | |
|
78 | for kinst, instDesc, siteID in instruments: | |
|
79 | instList.append((str(kinst), instDesc)) | |
|
80 | ||
|
81 | instrumentSelection = getSelection('instruments', args, kwargs) | |
|
82 | self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateExp(this)'}), | |
|
83 | choices=instList, | |
|
84 | initial=instrumentSelection, | |
|
85 | label='Instrument:') | |
|
86 | ||
|
87 | madWebObj = madrigal.ui.web.MadrigalWeb(madDB) | |
|
88 | experimentSelection = getSelection('experiments', args, kwargs) | |
|
89 | self.fields['experiments'] = django.forms.ChoiceField(choices=getExperimentList(args, kwargs, madWebObj), | |
|
90 | initial=experimentSelection, | |
|
91 | required=False, label='Experiment:') | |
|
92 | ||
|
93 | description = forms.CharField(widget=forms.Textarea(attrs={'cols': 40,'rows': 3, 'style': 'resize:none'}), label='Description') | |
|
94 | type = forms.ChoiceField(choices=[('0', 'Public'),('1', 'Private')], initial=0,widget=forms.RadioSelect(attrs={'class': 'custom-radio'})) | |
|
95 | file = forms.FileField(label='Select Files', widget=forms.ClearableFileInput(attrs={'multiple': True})) | |
|
96 | ||
|
97 | class ExpForm(forms.Form): | |
|
98 | """SingleExpInstForm is a Form class for the instrument select field in the Single Experiment interface. | |
|
99 | Use this because its faster to create than the full SingleExpDefaultForm | |
|
100 | """ | |
|
101 | def __init__(self, *args, **kwargs): | |
|
102 | super(ExpForm, self).__init__(*args, **kwargs) | |
|
103 | madDB = madrigal.metadata.MadrigalDB() | |
|
104 | madWebObj = madrigal.ui.web.MadrigalWeb(madDB) | |
|
105 | experimentSelection = getSelection('experiments', args, kwargs) | |
|
106 | self.fields['experiments'] = django.forms.ChoiceField(choices=getExperimentList(args, kwargs, madWebObj), | |
|
107 | initial=experimentSelection, | |
|
108 | required=False, label='Experiment') |
|
1 | NO CONTENT: new file 100755 |
@@ -0,0 +1,9 | |||
|
1 | <div class="row"> | |
|
2 | {{ form.experiments.label }} | |
|
3 | </div> | |
|
4 | <!-- Instrument select is its own row in selections column --> | |
|
5 | <div class="row"> | |
|
6 | <div class="col-md-12"> | |
|
7 | {{ form.experiments }} | |
|
8 | </div> <!-- end span --> | |
|
9 | </div> <!-- end row --> No newline at end of file |
@@ -0,0 +1,102 | |||
|
1 | {% extends "base.html" %} | |
|
2 | {% block title %}Upload Data{% endblock %} | |
|
3 | ||
|
4 | {% block extra_head %} | |
|
5 | <script type="text/javascript"> | |
|
6 | function populateExp(select) { | |
|
7 | ||
|
8 | var kinst = select.options[select.selectedIndex].value; | |
|
9 | var url = "{% url 'updata:get_experiments' %}" + '?instruments=' + kinst; | |
|
10 | // first delete all forms that are now out of date | |
|
11 | divIndex = $(".single_form").index($("#experiments")) | |
|
12 | $(".single_form").slice(divIndex).empty() | |
|
13 | // second populate the categories html | |
|
14 | $(".single_form").slice(divIndex, divIndex + 1).load(url); | |
|
15 | } | |
|
16 | ||
|
17 | </script> | |
|
18 | ||
|
19 | <style> | |
|
20 | .custom-radio { | |
|
21 | list-style: none; | |
|
22 | margin: 0; | |
|
23 | padding: 0; | |
|
24 | } | |
|
25 | </style> | |
|
26 | {% endblock %} | |
|
27 | ||
|
28 | {% block content %} | |
|
29 | ||
|
30 | <center><h4>Upload Data</h4></center> | |
|
31 | <form method="post" enctype="multipart/form-data"> | |
|
32 | ||
|
33 | {% csrf_token %} | |
|
34 | ||
|
35 | {% block description %} | |
|
36 | <!-- subdivide selection column for instruments to be possibly filled in by ajax - single_form 0 --> | |
|
37 | <div class="col-md-12 single_form" id="description"> | |
|
38 | <div class="row"> | |
|
39 | {{ form.description.label }} | |
|
40 | </div> | |
|
41 | <!-- Instrument select is its own row in selections column --> | |
|
42 | <div class="row"> | |
|
43 | <div class="col-md-12"> | |
|
44 | {{ form.description }} | |
|
45 | </div> <!-- end span --> | |
|
46 | </div> <!-- end row --> | |
|
47 | </div> <!-- end subdivide --> | |
|
48 | ||
|
49 | {% endblock %} | |
|
50 | ||
|
51 | {% block file %} | |
|
52 | <div class="col-md-12 single_form" style="margin-top: 15px;" id="description"> | |
|
53 | <div class="row"> | |
|
54 | {{ form.file.label }} | |
|
55 | </div> | |
|
56 | <!-- Instrument select is its own row in selections column --> | |
|
57 | <div class="row"> | |
|
58 | <div class="col-md-12"> | |
|
59 | {{ form.file }} | |
|
60 | </div> <!-- end span --> | |
|
61 | </div> <!-- end row --> | |
|
62 | </div> <!-- end subdivide --> | |
|
63 | ||
|
64 | {% endblock %} | |
|
65 | ||
|
66 | {% block type %} | |
|
67 | <div class="col-md-12 single_form" style="margin-top: 15px;" id="description"> | |
|
68 | <!-- Instrument select is its own row in selections column --> | |
|
69 | <div class="row"> | |
|
70 | <div class="col-md-12"> | |
|
71 | {{ form.type }} | |
|
72 | </div> <!-- end span --> | |
|
73 | </div> <!-- end row --> | |
|
74 | </div> <!-- end subdivide --> | |
|
75 | ||
|
76 | {% endblock %} | |
|
77 | ||
|
78 | {% block instruments %} | |
|
79 | <!-- subdivide selection column for instruments to be possibly filled in by ajax - single_form 0 --> | |
|
80 | <div class="col-md-12 single_form" style="margin-top: 15px;" id="instruments"> | |
|
81 | ||
|
82 | {% if form.instruments %} | |
|
83 | {% include "madweb/instruments.html" %} | |
|
84 | {% endif %} | |
|
85 | ||
|
86 | </div> <!-- end subdivide --> | |
|
87 | {% endblock %} | |
|
88 | ||
|
89 | {% block experiments %} | |
|
90 | <!-- subdivide selection column for experiments to be possibly filled in by ajax - single_form 0 --> | |
|
91 | <div class="col-md-12 single_form" style="margin-top: 15px;" id="experiments"> | |
|
92 | ||
|
93 | {% if form.experiments %} | |
|
94 | {% include "updata/experiments.html" %} | |
|
95 | {% endif %} | |
|
96 | ||
|
97 | </div> <!-- end subdivide --> | |
|
98 | {% endblock %} | |
|
99 | <button style="margin-top: 15px;" type="submit">Load</button> | |
|
100 | ||
|
101 | </form> | |
|
102 | {% endblock %} No newline at end of file |
@@ -0,0 +1,9 | |||
|
1 | from django.conf.urls import url | |
|
2 | from . import views | |
|
3 | ||
|
4 | urlpatterns = [ | |
|
5 | url(r'^$',views.index, name='updata_index'), | |
|
6 | url(r'^getExperiments/?$', views.get_experiments, name='get_experiments'), | |
|
7 | ] | |
|
8 | ||
|
9 | app_name = 'updata' No newline at end of file |
@@ -0,0 +1,83 | |||
|
1 | ||
|
2 | from django.contrib.auth.decorators import login_required | |
|
3 | from django.shortcuts import render | |
|
4 | from .forms import UpdataForm, ExpForm | |
|
5 | from django.core.files.storage import FileSystemStorage | |
|
6 | from django.contrib import messages | |
|
7 | ||
|
8 | import os | |
|
9 | ||
|
10 | # madrigal imports | |
|
11 | import madrigal.metadata | |
|
12 | import madrigal.ui.web | |
|
13 | import madrigal.admin | |
|
14 | ||
|
15 | @login_required | |
|
16 | def index(request): | |
|
17 | ''' | |
|
18 | Uploading experiments data view. Allows user to upload experiment files | |
|
19 | ||
|
20 | ''' | |
|
21 | dbAdminObj = madrigal.admin.MadrigalDBAdmin() | |
|
22 | madDB = madrigal.metadata.MadrigalDB() | |
|
23 | madWebObj = madrigal.ui.web.MadrigalWeb(madDB) | |
|
24 | siteName, siteList = madWebObj.getSiteInfo() | |
|
25 | ||
|
26 | if request.method == 'POST': | |
|
27 | form = UpdataForm(request.POST, request.FILES) | |
|
28 | files = request.FILES.getlist('file') | |
|
29 | ||
|
30 | if form.is_valid(): | |
|
31 | try: | |
|
32 | description = form.cleaned_data['description'] | |
|
33 | instCode = int(form.cleaned_data['instruments']) | |
|
34 | expId = form.cleaned_data['experiments'] | |
|
35 | perm = int(form.cleaned_data['type']) | |
|
36 | ||
|
37 | #saving file | |
|
38 | for f in files: | |
|
39 | fs = FileSystemStorage(location='/tmp') | |
|
40 | fs.save(f.name, f) | |
|
41 | madExp = madrigal.metadata.MadrigalExperiment() | |
|
42 | filepath = os.path.join('/tmp', f.name) | |
|
43 | expTitle = madExp.getExpNameByExpId(expId) | |
|
44 | ||
|
45 | dbAdminObj.createMadrigalExperiment(filepath,expTitle, perm, description, instCode) | |
|
46 | ||
|
47 | ||
|
48 | madInstParams = madrigal.metadata.MadrigalInstrumentParameters() | |
|
49 | madInstKindats = madrigal.metadata.MadrigalInstrumentKindats() | |
|
50 | ||
|
51 | print('*** Updating local metadata ***') | |
|
52 | dbAdminObj.__updateLocalMetadata__() | |
|
53 | print('*** Rebuilding instParmTab.txt ***') | |
|
54 | madInstParams.rebuildInstParmTable() | |
|
55 | print('*** Rebuilding instKindatTab.txt ***') | |
|
56 | madInstKindats.rebuildInstKindatTable() | |
|
57 | messages.success( | |
|
58 | request, 'Experimento(s) creado(s) exitosamente') | |
|
59 | form = UpdataForm() | |
|
60 | ||
|
61 | except Exception as e: | |
|
62 | messages.error( | |
|
63 | request, str(e)) | |
|
64 | else: | |
|
65 | form = UpdataForm() | |
|
66 | ||
|
67 | return render(request, 'updata/index.html', { | |
|
68 | 'form': form, | |
|
69 | 'site_name': siteName, | |
|
70 | 'site_list': siteList, | |
|
71 | }) | |
|
72 | ||
|
73 | ||
|
74 | def get_experiments(request): | |
|
75 | """get_experiments is a Ajax call that returns the experiments select html to support the | |
|
76 | updata UI. Called when a user modifies the intruments select field. | |
|
77 | ||
|
78 | Inputs: | |
|
79 | request | |
|
80 | """ | |
|
81 | form = ExpForm(request.GET) | |
|
82 | ||
|
83 | return render(request, 'updata/experiments.html', {'form': form}) |
|
1 | NO CONTENT: new file 100755, binary diff hidden |
@@ -0,0 +1,50 | |||
|
1 | <div class="row" style="margin-bottom: 20px"> | |
|
2 | Select parameter: <br> | |
|
3 | {{ form.param_list1d.label }} | |
|
4 | {{ form.param_list1d }} | |
|
5 | {% if form.param_list2d %} | |
|
6 | {{ form.param_list2d.label }} | |
|
7 | {{ form.param_list2d }} | |
|
8 | {% endif %} | |
|
9 | ||
|
10 | </div> | |
|
11 | ||
|
12 | <script> | |
|
13 | $('#id_param_list2d').bind('change', function (e) { | |
|
14 | var expID = '{{ expID }}'; | |
|
15 | var param = $(this).val(); | |
|
16 | var url = '{% url 'plot' %}' + '?expID=' + expID + '¶m2d=' + param; | |
|
17 | console.log(url) | |
|
18 | // first delete all forms that are now out of date | |
|
19 | divIndex = $(".single_form").index($( "#file_plot" )) | |
|
20 | $(".single_form").slice(divIndex).empty() | |
|
21 | // second populate the file_plot html if '0' not selected | |
|
22 | if (param != '0') { | |
|
23 | $(".single_form").slice(divIndex,divIndex+1).html("<img src=\"static/loader.gif\" class=\"load_center\"/>").load(url); | |
|
24 | } | |
|
25 | }) | |
|
26 | $('#id_param_list1d').bind('change', function (e) { | |
|
27 | var expID = '{{ expID }}'; | |
|
28 | var param = $(this).val(); | |
|
29 | var url = '{% url 'plot' %}' + '?expID=' + expID + '¶m1d=' + param; | |
|
30 | console.log(url) | |
|
31 | // first delete all forms that are now out of date | |
|
32 | divIndex = $(".single_form").index($( "#file_plot" )) | |
|
33 | $(".single_form").slice(divIndex).empty() | |
|
34 | // second populate the file_plot html if '0' not selected | |
|
35 | if (param != '0') { | |
|
36 | $(".single_form").slice(divIndex,divIndex+1).html("<img src=\"static/loader.gif\" class =\"load_center\"/>").load(url); | |
|
37 | } | |
|
38 | }) | |
|
39 | </script> | |
|
40 | <style> | |
|
41 | .load_center { | |
|
42 | display: block; | |
|
43 | margin-left: auto; | |
|
44 | margin-right: auto; | |
|
45 | margin-top: 100px; | |
|
46 | margin-bottom: 100px; | |
|
47 | width: 4%; | |
|
48 | align-items: center; | |
|
49 | } | |
|
50 | </style> No newline at end of file |
@@ -12,13 +12,11 https://docs.djangoproject.com/en/1.7/ref/settings/ | |||
|
12 | 12 | import os |
|
13 | 13 | BASE_DIR = os.path.dirname(os.path.dirname(__file__)) |
|
14 | 14 | |
|
15 | ||
|
16 | ||
|
17 | 15 | # Quick-start development settings - unsuitable for production |
|
18 | 16 | # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ |
|
19 | 17 | |
|
20 | 18 | # SECURITY WARNING: keep the secret key used in production secret! |
|
21 | SECRET_KEY = '!wa!749ow0!%7t7tr6fr^fvkqyd7yc#mmvpfedr+f2pb!4r)wd' | |
|
19 | SECRET_KEY = '^c1l3d35+q28^66d2pc1qlu(k$wmw^*gg3rfitz^s)t=9eu1ui' | |
|
22 | 20 | |
|
23 | 21 | # SECURITY WARNING: don't run with debug turned on in production! |
|
24 | 22 | DEBUG = True |
@@ -38,7 +36,7 MANAGERS = (('Bill Rideout', 'brideout@haystack.mit.edu'),) | |||
|
38 | 36 | # Application definition |
|
39 | 37 | |
|
40 | 38 | INSTALLED_APPS = ( |
|
41 |
|
|
|
39 | 'django.contrib.admin', | |
|
42 | 40 | 'django.contrib.auth', |
|
43 | 41 | 'django.contrib.contenttypes', |
|
44 | 42 | 'django.contrib.sessions', |
@@ -46,18 +44,20 INSTALLED_APPS = ( | |||
|
46 | 44 | 'django.contrib.staticfiles', |
|
47 | 45 | 'madweb', |
|
48 | 46 | 'django_bootstrap_calendar', |
|
49 | 'bootstrap3' | |
|
47 | 'bootstrap3', | |
|
48 | 'apps.login', | |
|
49 | 'apps.updata', | |
|
50 | 50 | ) |
|
51 | 51 | |
|
52 |
MIDDLEWARE |
|
|
53 |
'django. |
|
|
54 | 'django.contrib.messages.middleware.MessageMiddleware', | |
|
52 | MIDDLEWARE = [ | |
|
53 | 'django.middleware.security.SecurityMiddleware', | |
|
55 | 54 | 'django.contrib.sessions.middleware.SessionMiddleware', |
|
56 | 55 | 'django.middleware.common.CommonMiddleware', |
|
57 | 56 | 'django.middleware.csrf.CsrfViewMiddleware', |
|
58 |
'django.contrib.auth.middleware. |
|
|
57 | 'django.contrib.auth.middleware.AuthenticationMiddleware', | |
|
58 | 'django.contrib.messages.middleware.MessageMiddleware', | |
|
59 | 59 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', |
|
60 | ) | |
|
60 | ] | |
|
61 | 61 | |
|
62 | 62 | ROOT_URLCONF = 'djangoMad.urls' |
|
63 | 63 | |
@@ -80,6 +80,7 TEMPLATES = [ | |||
|
80 | 80 | 'django.template.context_processors.static', |
|
81 | 81 | 'django.template.context_processors.tz', |
|
82 | 82 | 'django.contrib.messages.context_processors.messages', |
|
83 | 'django.template.context_processors.request', | |
|
83 | 84 | ], |
|
84 | 85 | }, |
|
85 | 86 | }, |
@@ -90,8 +91,13 TEMPLATES = [ | |||
|
90 | 91 | # https://docs.djangoproject.com/en/1.7/ref/settings/#databases |
|
91 | 92 | |
|
92 | 93 | DATABASES = { |
|
94 | 'default': { | |
|
95 | 'ENGINE': 'django.db.backends.sqlite3', | |
|
96 | 'NAME': 'madrigal.sqlite', | |
|
97 | } | |
|
93 | 98 | } |
|
94 | 99 | |
|
100 | ||
|
95 | 101 | # Internationalization |
|
96 | 102 | # https://docs.djangoproject.com/en/1.7/topics/i18n/ |
|
97 | 103 |
@@ -5,4 +5,7 import madweb.views | |||
|
5 | 5 | urlpatterns = [ |
|
6 | 6 | url(r'^', include('madweb.urls')), |
|
7 | 7 | url(r'^$', madweb.views.index), |
|
8 | url(r'^updata/', include('apps.updata.urls', namespace="updata")), | |
|
9 | url(r'^accounts/', include('apps.login.urls', namespace="login")), | |
|
10 | url(r'^admin/', admin.site.urls), | |
|
8 | 11 | ] |
@@ -12,7 +12,7 import madrigal.metadata | |||
|
12 | 12 | |
|
13 | 13 | madDB = madrigal.metadata.MadrigalDB() |
|
14 | 14 | os.environ['PYTHON_EGG_CACHE'] = os.path.join(madDB.getMadroot(), 'eggs') |
|
15 |
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoMad.settings |
|
|
15 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoMad.settings") | |
|
16 | 16 | |
|
17 | 17 | from django.core.wsgi import get_wsgi_application |
|
18 | 18 | application = get_wsgi_application() |
@@ -16,6 +16,7 import django.template.defaulttags | |||
|
16 | 16 | |
|
17 | 17 | # third party imports |
|
18 | 18 | import numpy |
|
19 | import h5py | |
|
19 | 20 | |
|
20 | 21 | # Madrigal imports |
|
21 | 22 | import madrigal.metadata |
@@ -637,6 +638,139 class SingleExpPlotsForm(django.forms.Form): | |||
|
637 | 638 | choices=plotList, |
|
638 | 639 | required=False) |
|
639 | 640 |
|
|
641 | '''get_params2 retrieves a list of 1d and 2d parameters of type 1 hdf5 files''' | |
|
642 | def get_params1(args, kwargs, madExpObj, madWebObj): | |
|
643 | ||
|
644 | expID = getSelection('experiment_list', args, kwargs) | |
|
645 | expDir = madExpObj.getExpDirByExpId(expID) | |
|
646 | fileList = madWebObj.getFileFromExpID(expID, False) | |
|
647 | ||
|
648 | firsttuple = [a_tuple[0] for a_tuple in fileList] | |
|
649 | basename = firsttuple[0] | |
|
650 | fullFilename = os.path.join(expDir, basename) | |
|
651 | f = h5py.File(fullFilename, "r") | |
|
652 | data = f[list(f.keys())[0]] | |
|
653 | array = data[list(data.keys())[0]] | |
|
654 | ||
|
655 | param1d = array[list(array.keys())[0]] | |
|
656 | param2d = array[list(array.keys())[1]] | |
|
657 | paramch1d = list(param1d.keys()) | |
|
658 | paramch2d = list(param2d.keys()) | |
|
659 | ||
|
660 | dataparameters = param1d[list(param1d.keys())[0]] | |
|
661 | paramch_mn_bin = list(dataparameters['mnemonic']) | |
|
662 | paramch_bin = list(dataparameters['description']) | |
|
663 | paramch_mn = list() | |
|
664 | paramch = list() | |
|
665 | ||
|
666 | for i in range(len(paramch_bin)): | |
|
667 | paramch_mn.append(paramch_mn_bin[i].decode("utf-8")) | |
|
668 | paramch.append(paramch_bin[i].decode("utf-8")) | |
|
669 | ||
|
670 | choices1d = ['Select parameter'] | |
|
671 | for ch in paramch1d[1:]: | |
|
672 | aux = paramch[paramch_mn.index(ch.upper())] | |
|
673 | choices1d.append(aux) | |
|
674 | ||
|
675 | ||
|
676 | dataparameters = param2d[list(param2d.keys())[0]] | |
|
677 | paramch_mn_bin = list(dataparameters['mnemonic']) | |
|
678 | paramch_mn = list() | |
|
679 | paramch_bin = list(dataparameters['description']) | |
|
680 | paramch = list() | |
|
681 | ||
|
682 | for i in range(len(paramch_bin)): | |
|
683 | paramch_mn.append(paramch_mn_bin[i].decode("utf-8")) | |
|
684 | paramch.append(paramch_bin[i].decode("utf-8")) | |
|
685 | ||
|
686 | choices2d = ['Select parameter'] | |
|
687 | for ch in paramch2d[1:]: | |
|
688 | aux = paramch[paramch_mn.index(ch.upper())] | |
|
689 | choices2d.append(aux) | |
|
690 | ||
|
691 | ||
|
692 | choices = [choices1d,choices2d] | |
|
693 | return choices | |
|
694 | ||
|
695 | ||
|
696 | '''get params2 retrieves a list of 1d parameters of type 2 of hdf5 files''' | |
|
697 | def get_params2(args, kwargs, madExpObj, madWebObj): | |
|
698 | ||
|
699 | expID = getSelection('experiment_list', args, kwargs) | |
|
700 | expDir = madExpObj.getExpDirByExpId(expID) | |
|
701 | fileList = madWebObj.getFileFromExpID(expID, False) | |
|
702 | ||
|
703 | firsttuple = [a_tuple[0] for a_tuple in fileList] | |
|
704 | basename = firsttuple[0] | |
|
705 | fullFilename = os.path.join(expDir, basename) | |
|
706 | f = h5py.File(fullFilename, "r") | |
|
707 | ||
|
708 | metadata = f[list(f.keys())[1]] | |
|
709 | table = metadata[list(metadata.keys())[0]] | |
|
710 | param_mn_bin = list(table['mnemonic']) | |
|
711 | param_mn = list() | |
|
712 | for p in param_mn_bin: | |
|
713 | param_mn.append(p.decode("utf")) | |
|
714 | ||
|
715 | index = param_mn.index('UT2_UNIX') | |
|
716 | params = list(table['description']) | |
|
717 | choices = ['Select parameter'] | |
|
718 | for p in params[index+1:]: | |
|
719 | choices.append(p.decode("utf-8")) | |
|
720 | ||
|
721 | return choices | |
|
722 | ||
|
723 | ||
|
724 | class SingleExpPlotsSelectionForm(django.forms.Form): | |
|
725 | """SingleExpPlotsSselectionForm is a Form class for the parameters selection for plotting in the Single Experiment interface. | |
|
726 | Use this because its faster to create than the full SingleExpDefaultForm | |
|
727 | """ | |
|
728 | ||
|
729 | def __init__(self, *args, **kwargs): | |
|
730 | super(SingleExpPlotsSelectionForm, self).__init__(*args, **kwargs) | |
|
731 | madDB = madrigal.metadata.MadrigalDB() | |
|
732 | madExpObj = madrigal.metadata.MadrigalExperiment(madDB) | |
|
733 | madWebObj = madrigal.ui.web.MadrigalWeb(madDB) | |
|
734 | expID = getSelection('experiment_list', args, kwargs) | |
|
735 | try: | |
|
736 | expID = int(expID) | |
|
737 | except ValueError: | |
|
738 | # convert expPath to expID | |
|
739 | expID = madWebObj.getExpIDFromExpPath(expID, True) | |
|
740 | expDir = madExpObj.getExpDirByExpId(expID) | |
|
741 | fileList = madWebObj.getFileFromExpID(expID, False) | |
|
742 | ||
|
743 | firsttuple = [a_tuple[0] for a_tuple in fileList] | |
|
744 | basename = firsttuple[0] | |
|
745 | fullFilename = os.path.join(expDir, basename) | |
|
746 | f = h5py.File(fullFilename, "r") | |
|
747 | data = f[list(f.keys())[0]] | |
|
748 | ||
|
749 | if 'Array Layout' in list(data.keys()): | |
|
750 | choices = get_params1(args, kwargs, madExpObj, madWebObj) | |
|
751 | params1d = choices[0] | |
|
752 | params2d = choices[1] | |
|
753 | ||
|
754 | index = list(range(len(params1d))) | |
|
755 | paramchoices1d = list(zip(index, params1d)) | |
|
756 | ||
|
757 | ||
|
758 | index = list(range(len(params2d))) | |
|
759 | paramchoices2d = list(zip(index, params2d)) | |
|
760 | ||
|
761 | ||
|
762 | self.fields['param_list2d'] = django.forms.ChoiceField(widget = django.forms.Select(), choices=paramchoices2d, label="2D Parameters", required=False) | |
|
763 | ||
|
764 | else: | |
|
765 | params1d = get_params2(args, kwargs, madExpObj, madWebObj) | |
|
766 | #if params1d[0] == 'ut2_unix': | |
|
767 | # params1d[0] = 'Select parameter' | |
|
768 | index = list(range(len(params1d))) | |
|
769 | paramchoices1d = list(zip(index, params1d)) | |
|
770 | ||
|
771 | self.fields['param_list1d'] = django.forms.ChoiceField(widget = django.forms.Select(), choices=paramchoices1d, label="1D Parameters", required=False) | |
|
772 | ||
|
773 | ||
|
640 | 774 | |
|
641 | 775 | class SingleExpDownloadAsIsForm(django.forms.Form): |
|
642 | 776 | """SingleExpDownloadAsIsForm is a Form class for the download as is field in the Single Experiment interface. |
@@ -56,4 +56,12 | |||
|
56 | 56 | {% include "madweb/show_plots.html" %} |
|
57 | 57 | {% endif %} |
|
58 | 58 | </div> <!-- end subdivide --> |
|
59 | {% endblock %} No newline at end of file | |
|
59 | ||
|
60 | <!-- file select div --> | |
|
61 | <div class="col-md-12 single_form" id="file_plot"> | |
|
62 | {% if form.show_plots %} | |
|
63 | {% include "madweb/parameter_selection.html" %} | |
|
64 | {% endif %} | |
|
65 | </div> <!-- end subdivide --> | |
|
66 | ||
|
67 | {% endblock %} No newline at end of file |
@@ -257,3 +257,12 | |||
|
257 | 257 | </div> <!-- end subdivide --> |
|
258 | 258 | {% endblock %} |
|
259 | 259 | |
|
260 | {% block file_plot %} | |
|
261 | <!-- file select div --> | |
|
262 | <div class="col-md-12 single_form" id="file_plot"> | |
|
263 | {% if form.show_plots %} | |
|
264 | {% include "madweb/parameter_selection.html" %} | |
|
265 | {% endif %} | |
|
266 | </div> <!-- end subdivide --> | |
|
267 | {% endblock %} | |
|
268 |
@@ -51,6 +51,9 urlpatterns = [ url(r'^$', | |||
|
51 | 51 | url(r'^showPlots/?$', |
|
52 | 52 | views.show_plots, |
|
53 | 53 | name='show_plots'), |
|
54 | url(r'^view_plot/?$', | |
|
55 | views.view_plot, | |
|
56 | name='plot'), | |
|
54 | 57 | url(r'^downloadAsIs/?$', |
|
55 | 58 | views.download_as_is, |
|
56 | 59 | name='download_as_is'), |
@@ -38,6 +38,9 from wsgiref.util import FileWrapper | |||
|
38 | 38 | |
|
39 | 39 | # third party imports |
|
40 | 40 | import numpy |
|
41 | import plotly.offline as py | |
|
42 | import plotly.graph_objs as go | |
|
43 | import h5py | |
|
41 | 44 | |
|
42 | 45 | |
|
43 | 46 | # madrigal imports |
@@ -336,16 +339,217 def show_plots(request): | |||
|
336 | 339 | Inputs: |
|
337 | 340 | request |
|
338 | 341 | """ |
|
342 | madDB = madrigal.metadata.MadrigalDB() | |
|
343 | madExpObj = madrigal.metadata.MadrigalExperiment(madDB) | |
|
344 | madWebObj = madrigal.ui.web.MadrigalWeb(madDB) | |
|
345 | ||
|
339 | 346 | try: |
|
340 | 347 | expID = int(request.GET['experiment_list']) |
|
341 | 348 | except ValueError: |
|
342 | 349 | # convert expPath to expID |
|
343 | madDB = madrigal.metadata.MadrigalDB() | |
|
344 | madWebObj = madrigal.ui.web.MadrigalWeb(madDB) | |
|
345 | 350 | expID = madWebObj.getExpIDFromExpPath(request.GET['experiment_list'], True) |
|
346 | form = madweb.forms.SingleExpPlotsForm(request.GET) | |
|
351 | plotList = madExpObj.getExpLinksByExpId(expID) | |
|
352 | if len(plotList) != 0: | |
|
353 | form = madweb.forms.SingleExpPlotsForm(request.GET) | |
|
354 | template = 'madweb/show_plots.html' | |
|
355 | context = {'form': form} | |
|
356 | else: | |
|
357 | template = 'madweb/parameter_selection.html' | |
|
358 | form = madweb.forms.SingleExpPlotsSelectionForm(request.GET) | |
|
359 | context = {'form': form, 'expID': expID} | |
|
360 | ||
|
361 | return render(request, template, context) | |
|
362 | ||
|
363 | ||
|
364 | def view_plot(request): | |
|
365 | ||
|
366 | param1d = int(request.GET.get('param1d','0')) | |
|
367 | param2d = int(request.GET.get('param2d','0')) | |
|
368 | ||
|
369 | madDB = madrigal.metadata.MadrigalDB() | |
|
370 | madWebObj = madrigal.ui.web.MadrigalWeb(madDB) | |
|
371 | madExpObj = madrigal.metadata.MadrigalExperiment(madDB) | |
|
372 | ||
|
373 | expID =int(request.GET['expID']) | |
|
374 | expDir = madExpObj.getExpDirByExpId(expID) | |
|
375 | if expDir is None: | |
|
376 | raise ValueError('No expDir found for exp_id %i' % (int(expID))) | |
|
347 | 377 | |
|
348 | return render(request, 'madweb/show_plots.html', {'form': form}) | |
|
378 | fileList = madWebObj.getFileFromExpID(expID, False) | |
|
379 | firsttuple = [a_tuple[0] for a_tuple in fileList] | |
|
380 | basename = firsttuple[0] | |
|
381 | fullFilename = os.path.join(expDir, basename) | |
|
382 | ||
|
383 | with h5py.File(fullFilename, "r") as f: | |
|
384 | ||
|
385 | # Get the data | |
|
386 | ||
|
387 | data = f[list(f.keys())[0]] | |
|
388 | ||
|
389 | if 'Array Layout' in list(data.keys()): | |
|
390 | array = data[list(data.keys())[0]] | |
|
391 | timestamps = array[list(array.keys())[4]] | |
|
392 | datatime = [datetime.datetime.fromtimestamp(t) for t in list(timestamps)] | |
|
393 | ||
|
394 | range = array[list(array.keys())[3]] | |
|
395 | datarange = list(range) | |
|
396 | ||
|
397 | ||
|
398 | if param1d==0: | |
|
399 | parameters_2d = array[list(array.keys())[1]] | |
|
400 | paramname = list(parameters_2d.keys())[param2d] | |
|
401 | param = parameters_2d[list(parameters_2d.keys())[param2d]] | |
|
402 | dataparam = list(param) | |
|
403 | plot = plot_heatmap(datatime,datarange,dataparam,paramname) | |
|
404 | ||
|
405 | else: | |
|
406 | parameters_1d = array[list(array.keys())[0]] | |
|
407 | paramname = list(parameters_1d.keys())[param1d] | |
|
408 | param = parameters_1d[list(parameters_1d.keys())[param1d]] | |
|
409 | dataparam = list(param) | |
|
410 | plot = plot_scatter(datatime,dataparam,paramname) | |
|
411 | ||
|
412 | else: | |
|
413 | table = data[list(data.keys())[0]] | |
|
414 | a = list(table.dtype.fields.keys()) | |
|
415 | index = a.index('ut2_unix') | |
|
416 | v = a[index:] | |
|
417 | paramname = v[param1d] | |
|
418 | dataparam = list(table[paramname]) | |
|
419 | datatime = [datetime.datetime.fromtimestamp(t) for t in list(table['ut2_unix'])] | |
|
420 | plot = plot_scatter(datatime,dataparam,paramname) | |
|
421 | ||
|
422 | return HttpResponse(plot) | |
|
423 | ||
|
424 | def plot_scatter(datatime,dataparam,paramname): | |
|
425 | if (numpy.isnan(dataparam).all()): | |
|
426 | plot = "There is no valid data available for this plot" | |
|
427 | ||
|
428 | else: | |
|
429 | fig = go.Figure() | |
|
430 | fig.add_trace(go.Scatter(x=datatime, y=dataparam)) | |
|
431 | fig.update_yaxes(title_text=paramname) | |
|
432 | ||
|
433 | delta = datatime[-1] - datatime[1] | |
|
434 | ||
|
435 | if (delta>datetime.timedelta(days=30)): | |
|
436 | # Add range slider | |
|
437 | fig.update_layout( | |
|
438 | xaxis=dict( | |
|
439 | rangeselector=dict( | |
|
440 | buttons=list([ | |
|
441 | dict(count=1, | |
|
442 | label="1m", | |
|
443 | step="month", | |
|
444 | stepmode="backward"), | |
|
445 | dict(count=6, | |
|
446 | label="6m", | |
|
447 | step="month", | |
|
448 | stepmode="backward"), | |
|
449 | dict(count=1, | |
|
450 | label="1y", | |
|
451 | step="year", | |
|
452 | stepmode="backward"), | |
|
453 | dict(step="all") | |
|
454 | ]) | |
|
455 | ), | |
|
456 | rangeslider=dict( | |
|
457 | visible=True | |
|
458 | ), | |
|
459 | type="date" | |
|
460 | ) | |
|
461 | ) | |
|
462 | ||
|
463 | ||
|
464 | plot = py.plot(fig, include_plotlyjs=False, output_type='div') | |
|
465 | ||
|
466 | ||
|
467 | return plot | |
|
468 | ||
|
469 | ||
|
470 | def plot_heatmap(datatime,datarange,dataparam,paramname): | |
|
471 | if (numpy.isnan(dataparam).all()): | |
|
472 | plot = "There is no valid data available for this plot" | |
|
473 | else: | |
|
474 | fig = go.Figure() | |
|
475 | fig.add_trace(go.Heatmap(x=datatime,y=datarange,z= dataparam,colorscale='Jet',colorbar={"title":paramname})) | |
|
476 | fig.update_yaxes(title_text="range") | |
|
477 | fig.update_layout( | |
|
478 | updatemenus=[ | |
|
479 | dict( | |
|
480 | buttons=list([ | |
|
481 | dict( | |
|
482 | args=["colorscale", "Jet"], | |
|
483 | label="Jet", | |
|
484 | method="restyle" | |
|
485 | ), | |
|
486 | dict( | |
|
487 | args=["colorscale", "RdBu"], | |
|
488 | label="Red-Blue", | |
|
489 | method="restyle" | |
|
490 | ), | |
|
491 | dict( | |
|
492 | args=["colorscale", "Viridis"], | |
|
493 | label="Viridis", | |
|
494 | method="restyle" | |
|
495 | ), | |
|
496 | dict( | |
|
497 | args=["colorscale", "Cividis"], | |
|
498 | label="Cividis", | |
|
499 | method="restyle" | |
|
500 | ), | |
|
501 | dict( | |
|
502 | args=["colorscale", "Greens"], | |
|
503 | label="Greens", | |
|
504 | method="restyle" | |
|
505 | ), | |
|
506 | ]), | |
|
507 | type = "dropdown", | |
|
508 | direction="down", | |
|
509 | pad={"r": 10, "t": 10}, | |
|
510 | showactive=True, | |
|
511 | x=0.1, | |
|
512 | xanchor="left", | |
|
513 | y=1.05, | |
|
514 | yanchor="top" | |
|
515 | ), | |
|
516 | dict( | |
|
517 | buttons=list([ | |
|
518 | dict( | |
|
519 | args=[{"contours.showlines": False, "type": "contour"}], | |
|
520 | label="Hide lines", | |
|
521 | method="restyle" | |
|
522 | ), | |
|
523 | dict( | |
|
524 | args=[{"contours.showlines": True, "type": "contour"}], | |
|
525 | label="Show lines", | |
|
526 | method="restyle" | |
|
527 | ), | |
|
528 | ]), | |
|
529 | direction="down", | |
|
530 | pad={"r": 10, "t": 10}, | |
|
531 | showactive=True, | |
|
532 | x=0.32, | |
|
533 | xanchor="left", | |
|
534 | y=1.05, | |
|
535 | yanchor="top" | |
|
536 | ), | |
|
537 | ] | |
|
538 | ) | |
|
539 | ||
|
540 | fig.update_layout( | |
|
541 | annotations=[ | |
|
542 | dict(text="Colorscale", showarrow=False, | |
|
543 | x=0, xref="paper", y=1.03, yref="paper", align="left"), | |
|
544 | dict(text="Lines", x=0.25, xref="paper", y=1.03, yref="paper", | |
|
545 | showarrow=False) | |
|
546 | ] | |
|
547 | ) | |
|
548 | ||
|
549 | ||
|
550 | plot = py.plot(fig, include_plotlyjs=False, output_type='div') | |
|
551 | ||
|
552 | return plot | |
|
349 | 553 | |
|
350 | 554 | |
|
351 | 555 | def download_as_is(request): |
@@ -22,6 +22,7 | |||
|
22 | 22 | <meta charset="UTF-8"> |
|
23 | 23 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
24 | 24 | <link rel="shortcut icon" type="image/png" href="/static/favicon.ico"/> |
|
25 | <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> | |
|
25 | 26 | <title>{% block title %}Madrigal Database{% endblock %}</title> |
|
26 | 27 | <style type="text/css"> |
|
27 | 28 | html body { |
@@ -74,6 +75,7 | |||
|
74 | 75 | {% block file_select %}{% endblock %} |
|
75 | 76 | {% block file_buttons %}{% endblock %} |
|
76 | 77 | {% block file_data %}{% endblock %} |
|
78 | {% block file_plot %}{% endblock %} | |
|
77 | 79 | </div> |
|
78 | 80 | |
|
79 | 81 | </div> |
@@ -124,7 +124,8 | |||
|
124 | 124 | {% endfor %} |
|
125 | 125 | </ul> |
|
126 | 126 | </li> |
|
127 |
<li><a href="http://cedar.openmadrigal.org/openmadrigal" data-toggle="tooltip" data-original-title="Click here to go to OpenMadrigal, where you can download API's in python, Matlab, and IDL to run Madrigal scripts, and access Madrigal's source code." data-placement="bottom">OpenMadrigal</a></li> |
|
|
127 | <li><a href="http://cedar.openmadrigal.org/openmadrigal" data-toggle="tooltip" data-original-title="Click here to go to OpenMadrigal, where you can download API's in python, Matlab, and IDL to run Madrigal scripts, and access Madrigal's source code." data-placement="bottom">OpenMadrigal</a></li> | |
|
128 | <li><a href="{% url 'updata:updata_index' %}" data-toggle="tooltip" data-original-title="Click here to upload data to Madrigal database." data-placement="bottom">Upload Madrigal Data</a></li> | |
|
128 | 129 | </ul> |
|
129 | 130 | </div> |
|
130 | 131 | </nav> No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now