##// END OF EJS Templates
Add modules for interactive plots and upload data
jespinoza -
r2:98d277d09dd7
parent child
Show More
1 NO CONTENT: new file 100755
NO CONTENT: new file 100755
1 NO CONTENT: new file 100755
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
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
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
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 + '&param2d=' + 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 + '&param1d=' + 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
@@ -1,132 +1,138
1 """
1 """
2 Django settings for djangoMad project.
2 Django settings for djangoMad project.
3
3
4 For more information on this file, see
4 For more information on this file, see
5 https://docs.djangoproject.com/en/1.7/topics/settings/
5 https://docs.djangoproject.com/en/1.7/topics/settings/
6
6
7 For the full list of settings and their values, see
7 For the full list of settings and their values, see
8 https://docs.djangoproject.com/en/1.7/ref/settings/
8 https://docs.djangoproject.com/en/1.7/ref/settings/
9 """
9 """
10
10
11 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
11 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
12 import os
12 import os
13 BASE_DIR = os.path.dirname(os.path.dirname(__file__))
13 BASE_DIR = os.path.dirname(os.path.dirname(__file__))
14
14
15
16
17 # Quick-start development settings - unsuitable for production
15 # Quick-start development settings - unsuitable for production
18 # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
16 # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
19
17
20 # SECURITY WARNING: keep the secret key used in production secret!
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 # SECURITY WARNING: don't run with debug turned on in production!
21 # SECURITY WARNING: don't run with debug turned on in production!
24 DEBUG = True
22 DEBUG = True
25
23
26
24
27 ALLOWED_HOSTS = ['localhost:8000', '127.0.0.1', 'localhost']
25 ALLOWED_HOSTS = ['localhost:8000', '127.0.0.1', 'localhost']
28
26
29 ADMINS = (('Bill Rideout', 'brideout@haystack.mit.edu'),)
27 ADMINS = (('Bill Rideout', 'brideout@haystack.mit.edu'),)
30
28
31 EMAIL_HOST = 'hyperion.haystack.mit.edu'
29 EMAIL_HOST = 'hyperion.haystack.mit.edu'
32
30
33 SEND_BROKEN_LINK_EMAILS = True
31 SEND_BROKEN_LINK_EMAILS = True
34
32
35 MANAGERS = (('Bill Rideout', 'brideout@haystack.mit.edu'),)
33 MANAGERS = (('Bill Rideout', 'brideout@haystack.mit.edu'),)
36
34
37
35
38 # Application definition
36 # Application definition
39
37
40 INSTALLED_APPS = (
38 INSTALLED_APPS = (
41 #'django.contrib.admin',
39 'django.contrib.admin',
42 'django.contrib.auth',
40 'django.contrib.auth',
43 'django.contrib.contenttypes',
41 'django.contrib.contenttypes',
44 'django.contrib.sessions',
42 'django.contrib.sessions',
45 'django.contrib.messages',
43 'django.contrib.messages',
46 'django.contrib.staticfiles',
44 'django.contrib.staticfiles',
47 'madweb',
45 'madweb',
48 'django_bootstrap_calendar',
46 'django_bootstrap_calendar',
49 'bootstrap3'
47 'bootstrap3',
48 'apps.login',
49 'apps.updata',
50 )
50 )
51
51
52 MIDDLEWARE_CLASSES = (
52 MIDDLEWARE = [
53 'django.contrib.auth.middleware.AuthenticationMiddleware',
53 'django.middleware.security.SecurityMiddleware',
54 'django.contrib.messages.middleware.MessageMiddleware',
55 'django.contrib.sessions.middleware.SessionMiddleware',
54 'django.contrib.sessions.middleware.SessionMiddleware',
56 'django.middleware.common.CommonMiddleware',
55 'django.middleware.common.CommonMiddleware',
57 'django.middleware.csrf.CsrfViewMiddleware',
56 'django.middleware.csrf.CsrfViewMiddleware',
58 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
57 'django.contrib.auth.middleware.AuthenticationMiddleware',
58 'django.contrib.messages.middleware.MessageMiddleware',
59 'django.middleware.clickjacking.XFrameOptionsMiddleware',
59 'django.middleware.clickjacking.XFrameOptionsMiddleware',
60 )
60 ]
61
61
62 ROOT_URLCONF = 'djangoMad.urls'
62 ROOT_URLCONF = 'djangoMad.urls'
63
63
64 WSGI_APPLICATION = 'djangoMad.wsgi.application'
64 WSGI_APPLICATION = 'djangoMad.wsgi.application'
65
65
66
66
67 TEMPLATES = [
67 TEMPLATES = [
68 {
68 {
69 'BACKEND': 'django.template.backends.django.DjangoTemplates',
69 'BACKEND': 'django.template.backends.django.DjangoTemplates',
70 'DIRS': [
70 'DIRS': [
71 os.path.join(BASE_DIR, "templates"),
71 os.path.join(BASE_DIR, "templates"),
72 ],
72 ],
73 'APP_DIRS': True,
73 'APP_DIRS': True,
74 'OPTIONS': {
74 'OPTIONS': {
75 'context_processors': [
75 'context_processors': [
76 'django.contrib.auth.context_processors.auth',
76 'django.contrib.auth.context_processors.auth',
77 'django.template.context_processors.debug',
77 'django.template.context_processors.debug',
78 'django.template.context_processors.i18n',
78 'django.template.context_processors.i18n',
79 'django.template.context_processors.media',
79 'django.template.context_processors.media',
80 'django.template.context_processors.static',
80 'django.template.context_processors.static',
81 'django.template.context_processors.tz',
81 'django.template.context_processors.tz',
82 'django.contrib.messages.context_processors.messages',
82 'django.contrib.messages.context_processors.messages',
83 'django.template.context_processors.request',
83 ],
84 ],
84 },
85 },
85 },
86 },
86 ]
87 ]
87
88
88
89
89 # Database
90 # Database
90 # https://docs.djangoproject.com/en/1.7/ref/settings/#databases
91 # https://docs.djangoproject.com/en/1.7/ref/settings/#databases
91
92
92 DATABASES = {
93 DATABASES = {
94 'default': {
95 'ENGINE': 'django.db.backends.sqlite3',
96 'NAME': 'madrigal.sqlite',
93 }
97 }
98 }
99
94
100
95 # Internationalization
101 # Internationalization
96 # https://docs.djangoproject.com/en/1.7/topics/i18n/
102 # https://docs.djangoproject.com/en/1.7/topics/i18n/
97
103
98 LANGUAGE_CODE = 'en-us'
104 LANGUAGE_CODE = 'en-us'
99
105
100 TIME_ZONE = 'UTC'
106 TIME_ZONE = 'UTC'
101
107
102 USE_I18N = True
108 USE_I18N = True
103
109
104 USE_L10N = True
110 USE_L10N = True
105
111
106 USE_TZ = True
112 USE_TZ = True
107
113
108
114
109 # Absolute filesystem path to the directory that will hold user-uploaded files.
115 # Absolute filesystem path to the directory that will hold user-uploaded files.
110 # Example: "/home/media/media.lawrence.com/media/"
116 # Example: "/home/media/media.lawrence.com/media/"
111 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
117 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
112
118
113 # URL that handles the media served from MEDIA_ROOT. Make sure to use a
119 # URL that handles the media served from MEDIA_ROOT. Make sure to use a
114 # trailing slash.
120 # trailing slash.
115 # Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
121 # Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
116 MEDIA_URL = '/media/'
122 MEDIA_URL = '/media/'
117
123
118 # Absolute path to the directory static files should be collected to.
124 # Absolute path to the directory static files should be collected to.
119 # Don't put anything in this directory yourself; store your static files
125 # Don't put anything in this directory yourself; store your static files
120 # in apps' "static/" subdirectories and in STATICFILES_DIRS.
126 # in apps' "static/" subdirectories and in STATICFILES_DIRS.
121 # Example: "/home/media/media.lawrence.com/static/"
127 # Example: "/home/media/media.lawrence.com/static/"
122 # STATIC_ROOT = os.path.join(BASE_DIR, 'static')
128 # STATIC_ROOT = os.path.join(BASE_DIR, 'static')
123
129
124 # URL prefix for static files.
130 # URL prefix for static files.
125 # Example: "http://media.lawrence.com/static/"
131 # Example: "http://media.lawrence.com/static/"
126 STATIC_URL = '/static/'
132 STATIC_URL = '/static/'
127
133
128 BOOTSTRAP3 = {
134 BOOTSTRAP3 = {
129 # Include jQuery with Bootstrap JavaScript (affects django-bootstrap3 template tags)
135 # Include jQuery with Bootstrap JavaScript (affects django-bootstrap3 template tags)
130 'jquery_url': '/static/jquery.min.js',
136 'jquery_url': '/static/jquery.min.js',
131 'include_jquery': True,
137 'include_jquery': True,
132 }
138 }
@@ -1,8 +1,11
1 from django.conf.urls import include, url
1 from django.conf.urls import include, url
2 from django.contrib import admin
2 from django.contrib import admin
3 import madweb.views
3 import madweb.views
4
4
5 urlpatterns = [
5 urlpatterns = [
6 url(r'^', include('madweb.urls')),
6 url(r'^', include('madweb.urls')),
7 url(r'^$', madweb.views.index),
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 ]
@@ -1,18 +1,18
1 """
1 """
2 WSGI config for djangoMad project.
2 WSGI config for djangoMad project.
3
3
4 It exposes the WSGI callable as a module-level variable named ``application``.
4 It exposes the WSGI callable as a module-level variable named ``application``.
5
5
6 For more information on this file, see
6 For more information on this file, see
7 https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
7 https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
8 """
8 """
9
9
10 import os, os.path
10 import os, os.path
11 import madrigal.metadata
11 import madrigal.metadata
12
12
13 madDB = madrigal.metadata.MadrigalDB()
13 madDB = madrigal.metadata.MadrigalDB()
14 os.environ['PYTHON_EGG_CACHE'] = os.path.join(madDB.getMadroot(), 'eggs')
14 os.environ['PYTHON_EGG_CACHE'] = os.path.join(madDB.getMadroot(), 'eggs')
15 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoMad.settings_production")
15 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoMad.settings")
16
16
17 from django.core.wsgi import get_wsgi_application
17 from django.core.wsgi import get_wsgi_application
18 application = get_wsgi_application()
18 application = get_wsgi_application()
@@ -1,2129 +1,2263
1 """Forms for madweb application
1 """Forms for madweb application
2
2
3 $Id: forms.py 7288 2020-12-10 16:49:16Z brideout $
3 $Id: forms.py 7288 2020-12-10 16:49:16Z brideout $
4 """
4 """
5
5
6 # standard python imports
6 # standard python imports
7 import os.path
7 import os.path
8 import datetime
8 import datetime
9 import itertools
9 import itertools
10
10
11 # django imports
11 # django imports
12 import django.forms
12 import django.forms
13 import django.utils.html
13 import django.utils.html
14 import django.utils.safestring
14 import django.utils.safestring
15 import django.template.defaulttags
15 import django.template.defaulttags
16
16
17 # third party imports
17 # third party imports
18 import numpy
18 import numpy
19 import h5py
19
20
20 # Madrigal imports
21 # Madrigal imports
21 import madrigal.metadata
22 import madrigal.metadata
22 import madrigal.ui.web
23 import madrigal.ui.web
23
24
24 # temp only
25 # temp only
25 import logging
26 import logging
26
27
27 @django.template.defaulttags.register.filter
28 @django.template.defaulttags.register.filter
28 def get_item(dictionary, key):
29 def get_item(dictionary, key):
29 return(dictionary.get(key))
30 return(dictionary.get(key))
30
31
31 @django.template.defaulttags.register.filter
32 @django.template.defaulttags.register.filter
32 def modulo(num, val):
33 def modulo(num, val):
33 return(num % val == 0)
34 return(num % val == 0)
34
35
35 class HorizontalRadioSelect(django.forms.RadioSelect):
36 class HorizontalRadioSelect(django.forms.RadioSelect):
36 template_name = 'madweb/horizontal_select.html'
37 template_name = 'madweb/horizontal_select.html'
37
38
38
39
39
40
40 def getSelection(keyword, args, kwargs):
41 def getSelection(keyword, args, kwargs):
41 """getSelection returns '0' if keyword not a key in either args[0] or kwargs,
42 """getSelection returns '0' if keyword not a key in either args[0] or kwargs,
42 otherwise the value
43 otherwise the value
43
44
44 args, kwargs - arguments as passed into SingleExpDefaultForm __init__
45 args, kwargs - arguments as passed into SingleExpDefaultForm __init__
45 """
46 """
46 if len(args) == 0 and len(list(kwargs.keys())) == 0:
47 if len(args) == 0 and len(list(kwargs.keys())) == 0:
47 return('0') # default case when no data passed in
48 return('0') # default case when no data passed in
48 elif len(args) > 0:
49 elif len(args) > 0:
49 # args[0] is data dict argument to bind data
50 # args[0] is data dict argument to bind data
50 if keyword in args[0]:
51 if keyword in args[0]:
51 return(args[0][keyword])
52 return(args[0][keyword])
52 else:
53 else:
53 return('0')
54 return('0')
54 elif keyword in kwargs:
55 elif keyword in kwargs:
55 return(kwargs[keyword])
56 return(kwargs[keyword])
56 elif 'data' in kwargs:
57 elif 'data' in kwargs:
57 if keyword in kwargs['data']:
58 if keyword in kwargs['data']:
58 return(kwargs['data'][keyword])
59 return(kwargs['data'][keyword])
59 else:
60 else:
60 return('0')
61 return('0')
61 else:
62 else:
62 return('0')
63 return('0')
63
64
64
65
65 def getIsGlobal(args, kwargs):
66 def getIsGlobal(args, kwargs):
66 """getIsGlobal is a helper function returns True if 'isGlobal' not found in either args[0] or kwargs,
67 """getIsGlobal is a helper function returns True if 'isGlobal' not found in either args[0] or kwargs,
67 otherwise the bool of the value
68 otherwise the bool of the value
68
69
69 args, kwargs - arguments as passed into SingleExpDefaultForm __init__
70 args, kwargs - arguments as passed into SingleExpDefaultForm __init__
70 """
71 """
71 if len(args) == 0 and len(list(kwargs.keys())) == 0:
72 if len(args) == 0 and len(list(kwargs.keys())) == 0:
72 return(True) # default case when no data passed in
73 return(True) # default case when no data passed in
73 elif len(args) > 0:
74 elif len(args) > 0:
74 # args[0] is data dict argument to bind data
75 # args[0] is data dict argument to bind data
75 if 'isGlobal' in args[0]:
76 if 'isGlobal' in args[0]:
76 if args[0]['isGlobal'] == '0':
77 if args[0]['isGlobal'] == '0':
77 return(False)
78 return(False)
78 else:
79 else:
79 return(bool(args[0]['isGlobal']))
80 return(bool(args[0]['isGlobal']))
80 else:
81 else:
81 return(False)
82 return(False)
82 elif 'data' in kwargs:
83 elif 'data' in kwargs:
83 if 'isGlobal' in kwargs['data']:
84 if 'isGlobal' in kwargs['data']:
84 if kwargs['data']['isGlobal'] == '0':
85 if kwargs['data']['isGlobal'] == '0':
85 return(False)
86 return(False)
86 else:
87 else:
87 return(bool(kwargs['data']['isGlobal']))
88 return(bool(kwargs['data']['isGlobal']))
88 else:
89 else:
89 return(False)
90 return(False)
90 elif 'isGlobal' in kwargs:
91 elif 'isGlobal' in kwargs:
91 if kwargs['isGlobal'] == '0':
92 if kwargs['isGlobal'] == '0':
92 return(False)
93 return(False)
93 else:
94 else:
94 return(bool(kwargs['isGlobal']))
95 return(bool(kwargs['isGlobal']))
95 else:
96 else:
96 return(False)
97 return(False)
97
98
98
99
99 def getCategoryList(args, kwargs, madInstData, forList=False):
100 def getCategoryList(args, kwargs, madInstData, forList=False):
100 """getCategoryList is a helper function that returns the categories choices in
101 """getCategoryList is a helper function that returns the categories choices in
101 SingleExpDefaultForm.categories at runtime
102 SingleExpDefaultForm.categories at runtime
102
103
103 Inputs:
104 Inputs:
104 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used only to
105 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used only to
105 determine isGlobal
106 determine isGlobal
106 madInstData - madrigal.metadata.MadrigalInstrumentData object
107 madInstData - madrigal.metadata.MadrigalInstrumentData object
107 forList - if False (the default) category list if for single interface, If True, for List interface
108 forList - if False (the default) category list if for single interface, If True, for List interface
108 """
109 """
109 if not forList:
110 if not forList:
110 local = not getIsGlobal(args, kwargs)
111 local = not getIsGlobal(args, kwargs)
111 else:
112 else:
112 local = False
113 local = False
113 categories = madInstData.getCategories(local)
114 categories = madInstData.getCategories(local)
114 if forList:
115 if forList:
115 catList = [('0', 'All instrument categories'),]
116 catList = [('0', 'All instrument categories'),]
116 else:
117 else:
117 catList = [('0', 'Choose instrument type: '),]
118 catList = [('0', 'Choose instrument type: '),]
118 for catID, catDesc in categories:
119 for catID, catDesc in categories:
119 catList.append((str(catID), catDesc))
120 catList.append((str(catID), catDesc))
120 return(catList)
121 return(catList)
121
122
122
123
123
124
124 def getInstrumentList(args, kwargs, madInstData, header='Select an instrument: ', local=None, includeYears=False):
125 def getInstrumentList(args, kwargs, madInstData, header='Select an instrument: ', local=None, includeYears=False):
125 """getInstrumentList is a helper function that returns the instrument choices in
126 """getInstrumentList is a helper function that returns the instrument choices in
126 SingleExpDefaultForm.categories at runtime
127 SingleExpDefaultForm.categories at runtime
127
128
128 Inputs:
129 Inputs:
129 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used to
130 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used to
130 determine categoryId and local
131 determine categoryId and local
131 madInstData - madrigal.metadata.MadrigalInstrumentData object
132 madInstData - madrigal.metadata.MadrigalInstrumentData object
132 header - text of first item in selection
133 header - text of first item in selection
133 local - if None (the default), set local flag via args and kwargs. If boolean,
134 local - if None (the default), set local flag via args and kwargs. If boolean,
134 set local flag to arg.
135 set local flag to arg.
135 includeYear - if True, include data years in description. If False (the default), do not.
136 includeYear - if True, include data years in description. If False (the default), do not.
136 """
137 """
137 if local is None:
138 if local is None:
138 local = not getIsGlobal(args, kwargs)
139 local = not getIsGlobal(args, kwargs)
139 else:
140 else:
140 local = bool(local)
141 local = bool(local)
141 if header == 'Select an instrument: ':
142 if header == 'Select an instrument: ':
142 categoryId = int(getSelection('categories', args, kwargs))
143 categoryId = int(getSelection('categories', args, kwargs))
143 else:
144 else:
144 categoryId = 0
145 categoryId = 0
145 instruments = madInstData.getInstruments(categoryId, local)
146 instruments = madInstData.getInstruments(categoryId, local)
146 instList = [('0', header),]
147 instList = [('0', header),]
147 for kinst, instDesc, siteID in instruments:
148 for kinst, instDesc, siteID in instruments:
148 if includeYears:
149 if includeYears:
149 instYears = madInstData.getInstrumentYears(kinst)
150 instYears = madInstData.getInstrumentYears(kinst)
150 instList.append((str(kinst), '%s [%i-%i]' % (instDesc, instYears[0], instYears[-1])))
151 instList.append((str(kinst), '%s [%i-%i]' % (instDesc, instYears[0], instYears[-1])))
151 else:
152 else:
152 instList.append((str(kinst), instDesc))
153 instList.append((str(kinst), instDesc))
153 return(instList)
154 return(instList)
154
155
155
156
156 def getYearList(args, kwargs, madInstData):
157 def getYearList(args, kwargs, madInstData):
157 """getYearList is a helper function that returns the year choices in
158 """getYearList is a helper function that returns the year choices in
158 SingleExpDefaultForm.categories at runtime
159 SingleExpDefaultForm.categories at runtime
159
160
160 Inputs:
161 Inputs:
161 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used to
162 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used to
162 determine categoryId and local and kinst
163 determine categoryId and local and kinst
163 madInstData - madrigal.metadata.MadrigalInstrumentData object
164 madInstData - madrigal.metadata.MadrigalInstrumentData object
164 """
165 """
165 local = not getIsGlobal(args, kwargs)
166 local = not getIsGlobal(args, kwargs)
166 kinst = int(getSelection('instruments', args, kwargs))
167 kinst = int(getSelection('instruments', args, kwargs))
167 years = madInstData.getInstrumentYears(kinst)
168 years = madInstData.getInstrumentYears(kinst)
168 yearsList = [('0', 'Select a year: '),]
169 yearsList = [('0', 'Select a year: '),]
169 for thisYear in reversed(years):
170 for thisYear in reversed(years):
170 yearsList.append((str(thisYear), str(thisYear)))
171 yearsList.append((str(thisYear), str(thisYear)))
171 return(yearsList)
172 return(yearsList)
172
173
173
174
174 def getMonthList(args, kwargs, madWebObj):
175 def getMonthList(args, kwargs, madWebObj):
175 """getMonthList is a helper function that returns the month choices in
176 """getMonthList is a helper function that returns the month choices in
176 SingleExpDefaultForm.categories at runtime. Value is (month number,
177 SingleExpDefaultForm.categories at runtime. Value is (month number,
177 month name)
178 month name)
178
179
179 Inputs:
180 Inputs:
180 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used to
181 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used to
181 determine and kinst and year
182 determine and kinst and year
182 madWebObj - madrigal.ui.web.MadrigalWeb object
183 madWebObj - madrigal.ui.web.MadrigalWeb object
183 """
184 """
184 kinst = int(getSelection('instruments', args, kwargs))
185 kinst = int(getSelection('instruments', args, kwargs))
185 year = int(getSelection('years', args, kwargs))
186 year = int(getSelection('years', args, kwargs))
186 monthList = [('0', 'Select a month: '),]
187 monthList = [('0', 'Select a month: '),]
187 addedMonthList = madWebObj.getMonths(kinst, year)
188 addedMonthList = madWebObj.getMonths(kinst, year)
188 if len(addedMonthList) == 0:
189 if len(addedMonthList) == 0:
189 addedMonthList = madWebObj.getMonths(kinst, year, optimize=False)
190 addedMonthList = madWebObj.getMonths(kinst, year, optimize=False)
190 monthList += addedMonthList
191 monthList += addedMonthList
191 return([(str(monthNumber), monthName) for monthNumber, monthName in monthList])
192 return([(str(monthNumber), monthName) for monthNumber, monthName in monthList])
192
193
193
194
194 def getDayList():
195 def getDayList():
195 """always returns 1 ... 31
196 """always returns 1 ... 31
196 """
197 """
197 dayList = [(i, str(i)) for i in range(1,32)]
198 dayList = [(i, str(i)) for i in range(1,32)]
198 return(dayList)
199 return(dayList)
199
200
200
201
201 def getExpList(args, kwargs, madWebObj):
202 def getExpList(args, kwargs, madWebObj):
202 """getExpList is a helper function that returns the experiment choices in
203 """getExpList is a helper function that returns the experiment choices in
203 SingleExpDefaultForm.categories at runtime. Value is (expId,
204 SingleExpDefaultForm.categories at runtime. Value is (expId,
204 expDesc, expDir, pi_name, pi_email)
205 expDesc, expDir, pi_name, pi_email)
205
206
206 Inputs:
207 Inputs:
207 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used to
208 args, kwargs - arguments as passed into SingleExpDefaultForm __init__. Used to
208 determine and kinst, year, month, day
209 determine and kinst, year, month, day
209 madWebObj - madrigal.ui.web.MadrigalWeb object
210 madWebObj - madrigal.ui.web.MadrigalWeb object
210 """
211 """
211 kinst = int(getSelection('instruments', args, kwargs))
212 kinst = int(getSelection('instruments', args, kwargs))
212 year = int(getSelection('years', args, kwargs))
213 year = int(getSelection('years', args, kwargs))
213 month = int(getSelection('months', args, kwargs))
214 month = int(getSelection('months', args, kwargs))
214 day = int(getSelection('days', args, kwargs))
215 day = int(getSelection('days', args, kwargs))
215 expList = madWebObj.getExpsOnDate(kinst, year, month, day)
216 expList = madWebObj.getExpsOnDate(kinst, year, month, day)
216 if len(expList) == 0:
217 if len(expList) == 0:
217 expList = madWebObj.getExpsOnDate(kinst, year, month, day, optimize=False)
218 expList = madWebObj.getExpsOnDate(kinst, year, month, day, optimize=False)
218 return(expList)
219 return(expList)
219
220
220
221
221 def handle_registration(kwargs, user_email, expUrl, kinst, madDB):
222 def handle_registration(kwargs, user_email, expUrl, kinst, madDB):
222 """handle_registration causes the user to register or unregister interest in getting emails
223 """handle_registration causes the user to register or unregister interest in getting emails
223 when a particular experiment or instrument is updated
224 when a particular experiment or instrument is updated
224
225
225 Inputs:
226 Inputs:
226 kwargs - dictionary as passed into form
227 kwargs - dictionary as passed into form
227 user_email - users email address
228 user_email - users email address
228 expUrl - experiment url (part after /madtoc/)
229 expUrl - experiment url (part after /madtoc/)
229 kinst - instrument code
230 kinst - instrument code
230 madDB - madrigal.metadata.MadrigalDB object
231 madDB - madrigal.metadata.MadrigalDB object
231 """
232 """
232 # first find out if this exp or inst is already registered
233 # first find out if this exp or inst is already registered
233 madUserObj = madrigal.ui.userData.MadrigalUserData(madDB)
234 madUserObj = madrigal.ui.userData.MadrigalUserData(madDB)
234 expsRegistered = madUserObj.getRegisteredExperiments(user_email)
235 expsRegistered = madUserObj.getRegisteredExperiments(user_email)
235 if expUrl in expsRegistered:
236 if expUrl in expsRegistered:
236 thisExpRegistered = True
237 thisExpRegistered = True
237 else:
238 else:
238 thisExpRegistered = False
239 thisExpRegistered = False
239 instsRegistered = madUserObj.getRegisteredInstruments(user_email)
240 instsRegistered = madUserObj.getRegisteredInstruments(user_email)
240 if kinst in instsRegistered:
241 if kinst in instsRegistered:
241 thisInstRegistered = True
242 thisInstRegistered = True
242 else:
243 else:
243 thisInstRegistered = False
244 thisInstRegistered = False
244
245
245 # check registration status, update if needed, and let form know how to print this
246 # check registration status, update if needed, and let form know how to print this
246 # 0 - no registration, 1 - exp registered, 2 - inst registered
247 # 0 - no registration, 1 - exp registered, 2 - inst registered
247 if 'registerExp' in kwargs:
248 if 'registerExp' in kwargs:
248 if not thisExpRegistered:
249 if not thisExpRegistered:
249 madUserObj.registerExperiment(user_email, expUrl)
250 madUserObj.registerExperiment(user_email, expUrl)
250 return('1')
251 return('1')
251 elif 'registerInst' in kwargs:
252 elif 'registerInst' in kwargs:
252 if not thisInstRegistered:
253 if not thisInstRegistered:
253 madUserObj.registerInstrument(user_email, kinst)
254 madUserObj.registerInstrument(user_email, kinst)
254 return('2')
255 return('2')
255 elif 'unregisterExp' in kwargs:
256 elif 'unregisterExp' in kwargs:
256 if thisExpRegistered:
257 if thisExpRegistered:
257 madUserObj.unregisterExperiment(user_email, expUrl)
258 madUserObj.unregisterExperiment(user_email, expUrl)
258 return('0')
259 return('0')
259 elif 'unregisterInst' in kwargs:
260 elif 'unregisterInst' in kwargs:
260 if thisInstRegistered:
261 if thisInstRegistered:
261 madUserObj.unregisterInstrument(user_email, kinst)
262 madUserObj.unregisterInstrument(user_email, kinst)
262 return('0')
263 return('0')
263 elif thisExpRegistered:
264 elif thisExpRegistered:
264 return('1')
265 return('1')
265 elif thisInstRegistered:
266 elif thisInstRegistered:
266 return('2')
267 return('2')
267 else:
268 else:
268 return('0')
269 return('0')
269
270
270
271
271 def getFormatChoices(basename, expID):
272 def getFormatChoices(basename, expID):
272 """getFormatChoices returns a list with 3 tuples, where each tuple
273 """getFormatChoices returns a list with 3 tuples, where each tuple
273 is 1. filename with correct extension, 2. Format
274 is 1. filename with correct extension, 2. Format
274
275
275 Inputs:
276 Inputs:
276 basename - basename of Madrigal Hdf5 file
277 basename - basename of Madrigal Hdf5 file
277 expID - needed to determine if cached file available in near real time
278 expID - needed to determine if cached file available in near real time
278 """
279 """
279 madWebObj = madrigal.ui.web.MadrigalWeb()
280 madWebObj = madrigal.ui.web.MadrigalWeb()
280 formats = madWebObj.getFormatsAvailable(expID, basename)
281 formats = madWebObj.getFormatsAvailable(expID, basename)
281 fileName, fileExtension = os.path.splitext(basename)
282 fileName, fileExtension = os.path.splitext(basename)
282 retList = []
283 retList = []
283 retList.append((basename, 'Hdf5')) # file is assumed to be in Hdf5 format
284 retList.append((basename, 'Hdf5')) # file is assumed to be in Hdf5 format
284 if 'ascii' in formats:
285 if 'ascii' in formats:
285 retList.append((fileName + '.txt', 'Space-delimited ascii'))
286 retList.append((fileName + '.txt', 'Space-delimited ascii'))
286 if 'netCDF4' in formats:
287 if 'netCDF4' in formats:
287 retList.append((fileName + '.nc', 'netCDF4'))
288 retList.append((fileName + '.nc', 'netCDF4'))
288 return(retList)
289 return(retList)
289
290
290
291
291 class RegisterForm(django.forms.Form):
292 class RegisterForm(django.forms.Form):
292 """RegisterForm is the form class that supports the Register page
293 """RegisterForm is the form class that supports the Register page
293 """
294 """
294 def __init__(self, *args, **kwargs):
295 def __init__(self, *args, **kwargs):
295 super(RegisterForm, self).__init__(*args, **kwargs)
296 super(RegisterForm, self).__init__(*args, **kwargs)
296 self.fields['user_fullname'] = django.forms.CharField(label='Full name', min_length=2, max_length=256)
297 self.fields['user_fullname'] = django.forms.CharField(label='Full name', min_length=2, max_length=256)
297 self.fields['user_email'] = django.forms.EmailField(label='Email')
298 self.fields['user_email'] = django.forms.EmailField(label='Email')
298 self.fields['user_affiliation'] = django.forms.CharField(label='Affliation (type "None" if individual)', min_length=2, max_length=256)
299 self.fields['user_affiliation'] = django.forms.CharField(label='Affliation (type "None" if individual)', min_length=2, max_length=256)
299
300
300
301
301
302
302 class SingleExpDefaultForm(django.forms.Form):
303 class SingleExpDefaultForm(django.forms.Form):
303 """SingleExpDefaultForm is a Form class for the default fields in the Single Experiment interface
304 """SingleExpDefaultForm is a Form class for the default fields in the Single Experiment interface
304 (formally the Simple interface)
305 (formally the Simple interface)
305 """
306 """
306 def __init__(self, *args, **kwargs):
307 def __init__(self, *args, **kwargs):
307 super(SingleExpDefaultForm, self).__init__(*args, **kwargs)
308 super(SingleExpDefaultForm, self).__init__(*args, **kwargs)
308 madDB = madrigal.metadata.MadrigalDB()
309 madDB = madrigal.metadata.MadrigalDB()
309 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
310 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
310 user_email = getSelection('user_email', args, kwargs)
311 user_email = getSelection('user_email', args, kwargs)
311 self.fields['isGlobal'] = django.forms.BooleanField(widget = django.forms.CheckboxInput(attrs={"onChange":'populateCat(this)'}),
312 self.fields['isGlobal'] = django.forms.BooleanField(widget = django.forms.CheckboxInput(attrs={"onChange":'populateCat(this)'}),
312 required=False, label='Use all Madrigal sites: ',
313 required=False, label='Use all Madrigal sites: ',
313 initial=getIsGlobal(args, kwargs))
314 initial=getIsGlobal(args, kwargs))
314
315
315
316
316 categoriesSelection = getSelection('categories', args, kwargs)
317 categoriesSelection = getSelection('categories', args, kwargs)
317 self.fields['categories'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateInst(this)'}),
318 self.fields['categories'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateInst(this)'}),
318 choices=getCategoryList(args, kwargs, madInstData),
319 choices=getCategoryList(args, kwargs, madInstData),
319 initial=categoriesSelection,
320 initial=categoriesSelection,
320 label='Instrument category:')
321 label='Instrument category:')
321
322
322 # the following fields may or may not be populated. All are also available as individual classes
323 # the following fields may or may not be populated. All are also available as individual classes
323 # to allow AJAX calls to not need to create this full object
324 # to allow AJAX calls to not need to create this full object
324
325
325 if categoriesSelection != '0':
326 if categoriesSelection != '0':
326 instrumentSelection = getSelection('instruments', args, kwargs)
327 instrumentSelection = getSelection('instruments', args, kwargs)
327 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateYear(this)'}),
328 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateYear(this)'}),
328 choices=getInstrumentList(args, kwargs, madInstData),
329 choices=getInstrumentList(args, kwargs, madInstData),
329 initial=instrumentSelection,
330 initial=instrumentSelection,
330 required=False, label='Instrument:')
331 required=False, label='Instrument:')
331 else:
332 else:
332 return # no need to create any further fields
333 return # no need to create any further fields
333
334
334 if instrumentSelection != '0':
335 if instrumentSelection != '0':
335 yearSelection = getSelection('years', args, kwargs)
336 yearSelection = getSelection('years', args, kwargs)
336 self.fields['years'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateMonth(this)'}),
337 self.fields['years'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateMonth(this)'}),
337 choices=getYearList(args, kwargs, madInstData),
338 choices=getYearList(args, kwargs, madInstData),
338 initial=yearSelection,
339 initial=yearSelection,
339 required=False, label='Year:')
340 required=False, label='Year:')
340
341
341 else:
342 else:
342 return # no need to create any further fields
343 return # no need to create any further fields
343
344
344 if yearSelection != '0':
345 if yearSelection != '0':
345 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
346 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
346 monthSelection = getSelection('months', args, kwargs)
347 monthSelection = getSelection('months', args, kwargs)
347 self.fields['months'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateCalendar(this)'}),
348 self.fields['months'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateCalendar(this)'}),
348 choices=getMonthList(args, kwargs, madWebObj),
349 choices=getMonthList(args, kwargs, madWebObj),
349 initial=monthSelection, label='Month:')
350 initial=monthSelection, label='Month:')
350
351
351 else:
352 else:
352 return # no need to create any further fields
353 return # no need to create any further fields
353
354
354
355
355 if monthSelection != '0':
356 if monthSelection != '0':
356 daySelection = getSelection('days', args, kwargs)
357 daySelection = getSelection('days', args, kwargs)
357 # this field is only used to help display the calendar
358 # this field is only used to help display the calendar
358 self.fields['days'] = django.forms.ChoiceField(required=False, choices=getDayList())
359 self.fields['days'] = django.forms.ChoiceField(required=False, choices=getDayList())
359
360
360 else:
361 else:
361 return # no need to create any further fields
362 return # no need to create any further fields
362
363
363 if daySelection != '0':
364 if daySelection != '0':
364 expFullList = getExpList(args, kwargs, madWebObj)
365 expFullList = getExpList(args, kwargs, madWebObj)
365 expIdSelection = None
366 expIdSelection = None
366 if len(expFullList) > 1:
367 if len(expFullList) > 1:
367 expList = [('0', 'Select one of multiple experiments')] + [(items[0], items[1]) for items in expFullList]
368 expList = [('0', 'Select one of multiple experiments')] + [(items[0], items[1]) for items in expFullList]
368 expIdSelection = getSelection('experiment_list', args, kwargs)
369 expIdSelection = getSelection('experiment_list', args, kwargs)
369 self.fields['experiment_list'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateFile(this)'}),
370 self.fields['experiment_list'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateFile(this)'}),
370 choices=expList, initial=expIdSelection,
371 choices=expList, initial=expIdSelection,
371 required=False, label='Select experiment:')
372 required=False, label='Select experiment:')
372
373
373 if expIdSelection == '0':
374 if expIdSelection == '0':
374 # no need to create any further fields
375 # no need to create any further fields
375 return
376 return
376
377
377 if expIdSelection is None:
378 if expIdSelection is None:
378 expIdSelection = expFullList[0][0]
379 expIdSelection = expFullList[0][0]
379 expDir = expFullList[0][2]
380 expDir = expFullList[0][2]
380 else:
381 else:
381 expDir = None
382 expDir = None
382 for expId, thisExpDesc, thisExpDir in expFullList:
383 for expId, thisExpDesc, thisExpDir in expFullList:
383 if int(expIdSelection) == int(expId):
384 if int(expIdSelection) == int(expId):
384 expDir = thisExpDir
385 expDir = thisExpDir
385 break
386 break
386
387
387 fileList = madWebObj.getFileFromExpDir(expDir, int(instrumentSelection))
388 fileList = madWebObj.getFileFromExpDir(expDir, int(instrumentSelection))
388 fileList = [('0', 'Select file')] + fileList
389 fileList = [('0', 'Select file')] + fileList
389 fileSelection = getSelection('file_list', args, kwargs)
390 fileSelection = getSelection('file_list', args, kwargs)
390 self.fields['file_list'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'changeFile(this)'}),
391 self.fields['file_list'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'changeFile(this)'}),
391 choices=fileList, initial=fileSelection,
392 choices=fileList, initial=fileSelection,
392 required=False, label='Select file:')
393 required=False, label='Select file:')
393 self.fields['exp_id'] = django.forms.CharField(initial=str(expIdSelection),
394 self.fields['exp_id'] = django.forms.CharField(initial=str(expIdSelection),
394 widget=django.forms.HiddenInput(attrs={'value': str(expIdSelection)}),
395 widget=django.forms.HiddenInput(attrs={'value': str(expIdSelection)}),
395 required=False,
396 required=False,
396 label=str(expIdSelection))
397 label=str(expIdSelection))
397
398
398 pi_name, pi_email, expUrl, kinst, expDesc, kinstDesc = madWebObj.getExpInfoFromExpID(int(expIdSelection))
399 pi_name, pi_email, expUrl, kinst, expDesc, kinstDesc = madWebObj.getExpInfoFromExpID(int(expIdSelection))
399
400
400 self.fields['exp_desc'] = django.forms.CharField(initial=str(expDesc),
401 self.fields['exp_desc'] = django.forms.CharField(initial=str(expDesc),
401 widget=django.forms.HiddenInput(attrs={'value': str(expDesc)}),
402 widget=django.forms.HiddenInput(attrs={'value': str(expDesc)}),
402 required=False,
403 required=False,
403 label=str(expDesc))
404 label=str(expDesc))
404 self.fields['user_email'] = django.forms.CharField(initial=str(user_email),
405 self.fields['user_email'] = django.forms.CharField(initial=str(user_email),
405 widget=django.forms.HiddenInput(attrs={'value': str(user_email)}),
406 widget=django.forms.HiddenInput(attrs={'value': str(user_email)}),
406 required=False,
407 required=False,
407 label=str(user_email))
408 label=str(user_email))
408 self.fields['inst_desc'] = django.forms.CharField(initial=str(kinstDesc),
409 self.fields['inst_desc'] = django.forms.CharField(initial=str(kinstDesc),
409 widget=django.forms.HiddenInput(attrs={'value': str(kinstDesc)}),
410 widget=django.forms.HiddenInput(attrs={'value': str(kinstDesc)}),
410 required=False,
411 required=False,
411 label=str(kinstDesc))
412 label=str(kinstDesc))
412 self.fields['pi_name'] = django.forms.CharField(initial=pi_name,
413 self.fields['pi_name'] = django.forms.CharField(initial=pi_name,
413 widget=django.forms.HiddenInput(attrs={'value': pi_name}),
414 widget=django.forms.HiddenInput(attrs={'value': pi_name}),
414 required=False,
415 required=False,
415 label=pi_name)
416 label=pi_name)
416 self.fields['pi_email'] = django.forms.CharField(initial=pi_email,
417 self.fields['pi_email'] = django.forms.CharField(initial=pi_email,
417 widget=django.forms.HiddenInput(attrs={'value': pi_email}),
418 widget=django.forms.HiddenInput(attrs={'value': pi_email}),
418 required=False,
419 required=False,
419 label=pi_email)
420 label=pi_email)
420
421
421 # handle any needed registration or unregistration
422 # handle any needed registration or unregistration
422 register = handle_registration(args[0], user_email, expUrl, kinst, madDB)
423 register = handle_registration(args[0], user_email, expUrl, kinst, madDB)
423 self.fields['register'] = django.forms.CharField(initial=register,
424 self.fields['register'] = django.forms.CharField(initial=register,
424 widget=django.forms.HiddenInput(attrs={'value': register}),
425 widget=django.forms.HiddenInput(attrs={'value': register}),
425 required=False,
426 required=False,
426 label=register)
427 label=register)
427
428
428
429
429 else:
430 else:
430 return # no need to create any further fields
431 return # no need to create any further fields
431
432
432 if fileSelection != '0':
433 if fileSelection != '0':
433 self.fields['file_buttons'] = django.forms.CharField(initial='',
434 self.fields['file_buttons'] = django.forms.CharField(initial='',
434 widget=django.forms.HiddenInput(attrs={'value': ''}),
435 widget=django.forms.HiddenInput(attrs={'value': ''}),
435 required=False,
436 required=False,
436 label='')
437 label='')
437
438
438
439
439 else:
440 else:
440 return # no need to create any further fields
441 return # no need to create any further fields
441
442
442
443
443
444
444
445
445
446
446
447
447
448
448
449
449
450
450 class SingleExpInstForm(django.forms.Form):
451 class SingleExpInstForm(django.forms.Form):
451 """SingleExpInstForm is a Form class for the instrument select field in the Single Experiment interface.
452 """SingleExpInstForm is a Form class for the instrument select field in the Single Experiment interface.
452 Use this because its faster to create than the full SingleExpDefaultForm
453 Use this because its faster to create than the full SingleExpDefaultForm
453 """
454 """
454 def __init__(self, *args, **kwargs):
455 def __init__(self, *args, **kwargs):
455 super(SingleExpInstForm, self).__init__(*args, **kwargs)
456 super(SingleExpInstForm, self).__init__(*args, **kwargs)
456 madDB = madrigal.metadata.MadrigalDB()
457 madDB = madrigal.metadata.MadrigalDB()
457 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
458 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
458 instrumentSelection = getSelection('instruments', args, kwargs)
459 instrumentSelection = getSelection('instruments', args, kwargs)
459 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateYear(this)'}),
460 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateYear(this)'}),
460 choices=getInstrumentList(args, kwargs, madInstData),
461 choices=getInstrumentList(args, kwargs, madInstData),
461 initial=instrumentSelection,
462 initial=instrumentSelection,
462 label='Instrument:')
463 label='Instrument:')
463
464
464 class SingleExpYearForm(django.forms.Form):
465 class SingleExpYearForm(django.forms.Form):
465 """SingleExpYearForm is a Form class for the year select field in the Single Experiment interface.
466 """SingleExpYearForm is a Form class for the year select field in the Single Experiment interface.
466 Use this because its faster to create than the full SingleExpDefaultForm
467 Use this because its faster to create than the full SingleExpDefaultForm
467 """
468 """
468 def __init__(self, *args, **kwargs):
469 def __init__(self, *args, **kwargs):
469 super(SingleExpYearForm, self).__init__(*args, **kwargs)
470 super(SingleExpYearForm, self).__init__(*args, **kwargs)
470 madDB = madrigal.metadata.MadrigalDB()
471 madDB = madrigal.metadata.MadrigalDB()
471 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
472 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
472 yearSelection = getSelection('years', args, kwargs)
473 yearSelection = getSelection('years', args, kwargs)
473 self.fields['years'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateMonth(this)'}),
474 self.fields['years'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateMonth(this)'}),
474 choices=getYearList(args, kwargs, madInstData),
475 choices=getYearList(args, kwargs, madInstData),
475 initial=yearSelection, label='Year:')
476 initial=yearSelection, label='Year:')
476
477
477
478
478 class SingleExpMonthForm(django.forms.Form):
479 class SingleExpMonthForm(django.forms.Form):
479 """SingleExpMonthForm is a Form class for the month select field in the Single Experiment interface.
480 """SingleExpMonthForm is a Form class for the month select field in the Single Experiment interface.
480 Use this because its faster to create than the full SingleExpDefaultForm
481 Use this because its faster to create than the full SingleExpDefaultForm
481 """
482 """
482 def __init__(self, *args, **kwargs):
483 def __init__(self, *args, **kwargs):
483 super(SingleExpMonthForm, self).__init__(*args, **kwargs)
484 super(SingleExpMonthForm, self).__init__(*args, **kwargs)
484 madDB = madrigal.metadata.MadrigalDB()
485 madDB = madrigal.metadata.MadrigalDB()
485 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
486 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
486 monthSelection = getSelection('months', args, kwargs)
487 monthSelection = getSelection('months', args, kwargs)
487 self.fields['months'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateCalendar(this)'}),
488 self.fields['months'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'populateCalendar(this)'}),
488 choices=getMonthList(args, kwargs, madWebObj),
489 choices=getMonthList(args, kwargs, madWebObj),
489 initial=monthSelection, label='Month:')
490 initial=monthSelection, label='Month:')
490
491
491
492
492 class SingleExpCalendarForm(django.forms.Form):
493 class SingleExpCalendarForm(django.forms.Form):
493 """SingleExpCalendarForm is a Form class for the calendar field in the Single Experiment interface.
494 """SingleExpCalendarForm is a Form class for the calendar field in the Single Experiment interface.
494 Use this because its faster to create than the full SingleExpDefaultForm
495 Use this because its faster to create than the full SingleExpDefaultForm
495 """
496 """
496 def __init__(self, *args, **kwargs):
497 def __init__(self, *args, **kwargs):
497 super(SingleExpCalendarForm, self).__init__(*args, **kwargs)
498 super(SingleExpCalendarForm, self).__init__(*args, **kwargs)
498 madDB = madrigal.metadata.MadrigalDB()
499 madDB = madrigal.metadata.MadrigalDB()
499 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
500 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
500
501
501
502
502 class SingleExpFileForm(django.forms.Form):
503 class SingleExpFileForm(django.forms.Form):
503 """SingleExpFileForm is a Form class for the file select field in the Single Experiment interface.
504 """SingleExpFileForm is a Form class for the file select field in the Single Experiment interface.
504 Use this because its faster to create than the full SingleExpDefaultForm
505 Use this because its faster to create than the full SingleExpDefaultForm
505 """
506 """
506 def __init__(self, *args, **kwargs):
507 def __init__(self, *args, **kwargs):
507 super(SingleExpFileForm, self).__init__(*args, **kwargs)
508 super(SingleExpFileForm, self).__init__(*args, **kwargs)
508 madDB = madrigal.metadata.MadrigalDB()
509 madDB = madrigal.metadata.MadrigalDB()
509 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
510 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
510 expID = getSelection('experiment_list', args, kwargs)
511 expID = getSelection('experiment_list', args, kwargs)
511 try:
512 try:
512 expID = int(expID)
513 expID = int(expID)
513 except ValueError:
514 except ValueError:
514 # convert expPath to expID
515 # convert expPath to expID
515 expID = madWebObj.getExpIDFromExpPath(expID, True)
516 expID = madWebObj.getExpIDFromExpPath(expID, True)
516 user_email = getSelection('user_email', args, kwargs)
517 user_email = getSelection('user_email', args, kwargs)
517 include_non_default = getSelection('includeNonDefault', args, kwargs)
518 include_non_default = getSelection('includeNonDefault', args, kwargs)
518 if include_non_default == '0':
519 if include_non_default == '0':
519 include_non_default = False
520 include_non_default = False
520 fileList = madWebObj.getFileFromExpID(expID, include_non_default)
521 fileList = madWebObj.getFileFromExpID(expID, include_non_default)
521 fileList = [('0', 'Select file')] + fileList
522 fileList = [('0', 'Select file')] + fileList
522
523
523 fileSelection = getSelection('file_list', args, kwargs)
524 fileSelection = getSelection('file_list', args, kwargs)
524 self.fields['file_list'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'changeFile(this)'}),
525 self.fields['file_list'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={"onChange":'changeFile(this)'}),
525 choices=fileList, initial=fileSelection,
526 choices=fileList, initial=fileSelection,
526 required=False, label='Select file:')
527 required=False, label='Select file:')
527 if int(expID) != 0:
528 if int(expID) != 0:
528 self.fields['exp_id'] = django.forms.CharField(initial=str(expID),
529 self.fields['exp_id'] = django.forms.CharField(initial=str(expID),
529 widget=django.forms.HiddenInput(attrs={'value': str(expID)}),
530 widget=django.forms.HiddenInput(attrs={'value': str(expID)}),
530 required=False,
531 required=False,
531 label=str(expID))
532 label=str(expID))
532 pi_name, pi_email, expUrl, kinst, expDesc, kinstDesc = madWebObj.getExpInfoFromExpID(int(expID))
533 pi_name, pi_email, expUrl, kinst, expDesc, kinstDesc = madWebObj.getExpInfoFromExpID(int(expID))
533
534
534 self.fields['exp_desc'] = django.forms.CharField(initial=str(expDesc),
535 self.fields['exp_desc'] = django.forms.CharField(initial=str(expDesc),
535 widget=django.forms.HiddenInput(attrs={'value': str(expDesc)}),
536 widget=django.forms.HiddenInput(attrs={'value': str(expDesc)}),
536 required=False,
537 required=False,
537 label=str(expDesc))
538 label=str(expDesc))
538 self.fields['user_email'] = django.forms.CharField(initial=str(user_email),
539 self.fields['user_email'] = django.forms.CharField(initial=str(user_email),
539 widget=django.forms.HiddenInput(attrs={'value': str(user_email)}),
540 widget=django.forms.HiddenInput(attrs={'value': str(user_email)}),
540 required=False,
541 required=False,
541 label=str(user_email))
542 label=str(user_email))
542 self.fields['inst_desc'] = django.forms.CharField(initial=str(kinstDesc),
543 self.fields['inst_desc'] = django.forms.CharField(initial=str(kinstDesc),
543 widget=django.forms.HiddenInput(attrs={'value': str(kinstDesc)}),
544 widget=django.forms.HiddenInput(attrs={'value': str(kinstDesc)}),
544 required=False,
545 required=False,
545 label=str(kinstDesc))
546 label=str(kinstDesc))
546 self.fields['pi_name'] = django.forms.CharField(initial=pi_name,
547 self.fields['pi_name'] = django.forms.CharField(initial=pi_name,
547 widget=django.forms.HiddenInput(attrs={'value': pi_name}),
548 widget=django.forms.HiddenInput(attrs={'value': pi_name}),
548 required=False,
549 required=False,
549 label=pi_name)
550 label=pi_name)
550 self.fields['pi_email'] = django.forms.CharField(initial=pi_email,
551 self.fields['pi_email'] = django.forms.CharField(initial=pi_email,
551 widget=django.forms.HiddenInput(attrs={'value': pi_email}),
552 widget=django.forms.HiddenInput(attrs={'value': pi_email}),
552 required=False,
553 required=False,
553 label=pi_email)
554 label=pi_email)
554 self.fields['includeNonDefault'] = django.forms.BooleanField(widget = django.forms.CheckboxInput(attrs={"onChange":'reloadFiles(this)'}),
555 self.fields['includeNonDefault'] = django.forms.BooleanField(widget = django.forms.CheckboxInput(attrs={"onChange":'reloadFiles(this)'}),
555 required=False, label='Show non-default files: ',
556 required=False, label='Show non-default files: ',
556 initial=include_non_default)
557 initial=include_non_default)
557 # handle any needed registration or unregistration
558 # handle any needed registration or unregistration
558 register = handle_registration(args[0], user_email, expUrl, kinst, madDB)
559 register = handle_registration(args[0], user_email, expUrl, kinst, madDB)
559 self.fields['register'] = django.forms.CharField(initial=register,
560 self.fields['register'] = django.forms.CharField(initial=register,
560 widget=django.forms.HiddenInput(attrs={'value': register}),
561 widget=django.forms.HiddenInput(attrs={'value': register}),
561 required=False,
562 required=False,
562 label=register)
563 label=register)
563
564
564 if fileSelection != '0':
565 if fileSelection != '0':
565 self.fields['file_buttons'] = django.forms.CharField(initial='',
566 self.fields['file_buttons'] = django.forms.CharField(initial='',
566 widget=django.forms.HiddenInput(attrs={'value': ''}),
567 widget=django.forms.HiddenInput(attrs={'value': ''}),
567 required=False,
568 required=False,
568 label='')
569 label='')
569 self.fields['basename'] = django.forms.CharField(initial=str(fileSelection),
570 self.fields['basename'] = django.forms.CharField(initial=str(fileSelection),
570 widget=django.forms.HiddenInput(attrs={'value': str(fileSelection)}),
571 widget=django.forms.HiddenInput(attrs={'value': str(fileSelection)}),
571 required=False,
572 required=False,
572 label=str(fileSelection))
573 label=str(fileSelection))
573
574
574
575
575
576
576
577
577
578
578 class SingleExpButtonsForm(django.forms.Form):
579 class SingleExpButtonsForm(django.forms.Form):
579 """SingleExpButtonsForm is a Form class for the file buttons field in the Single Experiment interface.
580 """SingleExpButtonsForm is a Form class for the file buttons field in the Single Experiment interface.
580 Use this because its faster to create than the full SingleExpDefaultForm
581 Use this because its faster to create than the full SingleExpDefaultForm
581 """
582 """
582 def __init__(self, *args, **kwargs):
583 def __init__(self, *args, **kwargs):
583 super(SingleExpButtonsForm, self).__init__(*args, **kwargs)
584 super(SingleExpButtonsForm, self).__init__(*args, **kwargs)
584 madDB = madrigal.metadata.MadrigalDB()
585 madDB = madrigal.metadata.MadrigalDB()
585 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
586 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
586 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
587 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
587 expID = getSelection('experiment_list', args, kwargs)
588 expID = getSelection('experiment_list', args, kwargs)
588 try:
589 try:
589 expID = int(expID)
590 expID = int(expID)
590 except ValueError:
591 except ValueError:
591 # convert expPath to expID
592 # convert expPath to expID
592 expID = madWebObj.getExpIDFromExpPath(expID, True)
593 expID = madWebObj.getExpIDFromExpPath(expID, True)
593
594
594 fileSelection = getSelection('file_list', args, kwargs)
595 fileSelection = getSelection('file_list', args, kwargs)
595
596
596 expDir = madExpObj.getExpDirByExpId(int(expID))
597 expDir = madExpObj.getExpDirByExpId(int(expID))
597 filesize = os.path.getsize(os.path.join(expDir, str(fileSelection)))
598 filesize = os.path.getsize(os.path.join(expDir, str(fileSelection)))
598
599
599 self.fields['file_buttons'] = django.forms.CharField(initial='',
600 self.fields['file_buttons'] = django.forms.CharField(initial='',
600 widget=django.forms.HiddenInput(attrs={'value': ''}),
601 widget=django.forms.HiddenInput(attrs={'value': ''}),
601 required=False,
602 required=False,
602 label='')
603 label='')
603 self.fields['exp_id'] = django.forms.CharField(initial=str(expID),
604 self.fields['exp_id'] = django.forms.CharField(initial=str(expID),
604 widget=django.forms.HiddenInput(attrs={'value': str(expID)}),
605 widget=django.forms.HiddenInput(attrs={'value': str(expID)}),
605 required=False,
606 required=False,
606 label=str(expID))
607 label=str(expID))
607 self.fields['basename'] = django.forms.CharField(initial=str(fileSelection),
608 self.fields['basename'] = django.forms.CharField(initial=str(fileSelection),
608 widget=django.forms.HiddenInput(attrs={'value': str(fileSelection)}),
609 widget=django.forms.HiddenInput(attrs={'value': str(fileSelection)}),
609 required=False,
610 required=False,
610 label=str(fileSelection))
611 label=str(fileSelection))
611 self.fields['filesize'] = django.forms.IntegerField(initial=filesize,
612 self.fields['filesize'] = django.forms.IntegerField(initial=filesize,
612 widget=django.forms.HiddenInput(attrs={'value': filesize}),
613 widget=django.forms.HiddenInput(attrs={'value': filesize}),
613 required=False,
614 required=False,
614 label=str(filesize))
615 label=str(filesize))
615
616
616
617
617 class SingleExpPlotsForm(django.forms.Form):
618 class SingleExpPlotsForm(django.forms.Form):
618 """SingleExpPlotsForm is a Form class for the file data/show plots field in the Single Experiment interface.
619 """SingleExpPlotsForm is a Form class for the file data/show plots field in the Single Experiment interface.
619 Use this because its faster to create than the full SingleExpDefaultForm
620 Use this because its faster to create than the full SingleExpDefaultForm
620 """
621 """
621 def __init__(self, *args, **kwargs):
622 def __init__(self, *args, **kwargs):
622 super(SingleExpPlotsForm, self).__init__(*args, **kwargs)
623 super(SingleExpPlotsForm, self).__init__(*args, **kwargs)
623 madDB = madrigal.metadata.MadrigalDB()
624 madDB = madrigal.metadata.MadrigalDB()
624 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
625 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
625 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
626 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
626 expID = getSelection('experiment_list', args, kwargs)
627 expID = getSelection('experiment_list', args, kwargs)
627 try:
628 try:
628 expID = int(expID)
629 expID = int(expID)
629 except ValueError:
630 except ValueError:
630 # convert expPath to expID
631 # convert expPath to expID
631 expID = madWebObj.getExpIDFromExpPath(expID, True)
632 expID = madWebObj.getExpIDFromExpPath(expID, True)
632 plotList = madExpObj.getExpLinksByExpId(expID)
633 plotList = madExpObj.getExpLinksByExpId(expID)
633 if len(plotList) == 0:
634 if len(plotList) == 0:
634 plotList = [('No plots available', '')]
635 plotList = [('No plots available', '')]
635
636
636 self.fields['plot_list'] = django.forms.ChoiceField(widget = django.forms.Select(),
637 self.fields['plot_list'] = django.forms.ChoiceField(widget = django.forms.Select(),
637 choices=plotList,
638 choices=plotList,
638 required=False)
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 class SingleExpDownloadAsIsForm(django.forms.Form):
775 class SingleExpDownloadAsIsForm(django.forms.Form):
642 """SingleExpDownloadAsIsForm is a Form class for the download as is field in the Single Experiment interface.
776 """SingleExpDownloadAsIsForm is a Form class for the download as is field in the Single Experiment interface.
643 Use this because its faster to create than the full SingleExpDefaultForm
777 Use this because its faster to create than the full SingleExpDefaultForm
644 """
778 """
645 def __init__(self, *args, **kwargs):
779 def __init__(self, *args, **kwargs):
646 super(SingleExpDownloadAsIsForm, self).__init__(*args, **kwargs)
780 super(SingleExpDownloadAsIsForm, self).__init__(*args, **kwargs)
647 basename = getSelection('format_select', args, kwargs)
781 basename = getSelection('format_select', args, kwargs)
648 expID = int(getSelection('expID', args, kwargs))
782 expID = int(getSelection('expID', args, kwargs))
649 formatChoices = getFormatChoices(basename, expID)
783 formatChoices = getFormatChoices(basename, expID)
650
784
651 self.fields['format_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(attrs={"onChange":'changeFormat(this)'}),
785 self.fields['format_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(attrs={"onChange":'changeFormat(this)'}),
652 choices=formatChoices,
786 choices=formatChoices,
653 required=False)
787 required=False)
654
788
655
789
656
790
657
791
658 class IsprintChoiceField(django.forms.TypedMultipleChoiceField):
792 class IsprintChoiceField(django.forms.TypedMultipleChoiceField):
659 """IsprintChoiceField is subclass of TypedMultipleChoiceField
793 """IsprintChoiceField is subclass of TypedMultipleChoiceField
660 """
794 """
661 def __init__(self, *args, **kwargs):
795 def __init__(self, *args, **kwargs):
662 """__init__ allows all the arguments of TypedMultipleChoiceField, plus extra
796 """__init__ allows all the arguments of TypedMultipleChoiceField, plus extra
663 keyword arguments:
797 keyword arguments:
664 madWebObject madrigal.ui.web.MadrigalWeb object
798 madWebObject madrigal.ui.web.MadrigalWeb object
665 """
799 """
666 self.isDerivedDict = kwargs.pop('isDerivedDict')
800 self.isDerivedDict = kwargs.pop('isDerivedDict')
667 self.parmDescDict = kwargs.pop('parmDescDict')
801 self.parmDescDict = kwargs.pop('parmDescDict')
668 try:
802 try:
669 self.separateProlog = kwargs.pop('separateProlog')
803 self.separateProlog = kwargs.pop('separateProlog')
670 except:
804 except:
671 self.separateProlog = False
805 self.separateProlog = False
672
806
673 kwargs['widget'] = IsprintWidget(attrs={'isDerivedDict':self.isDerivedDict,
807 kwargs['widget'] = IsprintWidget(attrs={'isDerivedDict':self.isDerivedDict,
674 'parmDescDict':self.parmDescDict,
808 'parmDescDict':self.parmDescDict,
675 'separateProlog':self.separateProlog})
809 'separateProlog':self.separateProlog})
676 super(IsprintChoiceField, self).__init__(*args, **kwargs)
810 super(IsprintChoiceField, self).__init__(*args, **kwargs)
677 self.widget.set_parm_lists(self.isDerivedDict, self.parmDescDict, self.separateProlog)
811 self.widget.set_parm_lists(self.isDerivedDict, self.parmDescDict, self.separateProlog)
678
812
679
813
680
814
681
815
682 class IsprintWidget(django.forms.CheckboxSelectMultiple):
816 class IsprintWidget(django.forms.CheckboxSelectMultiple):
683 """IsprintWidget is a subclass of CheckboxSelectMultiple with additional parameters passed in
817 """IsprintWidget is a subclass of CheckboxSelectMultiple with additional parameters passed in
684 to modify rendering
818 to modify rendering
685 """
819 """
686 def __init__(self, *args, **kwargs):
820 def __init__(self, *args, **kwargs):
687 """__init__ allows all the arguments of CheckboxSelectMultiple, plus extra
821 """__init__ allows all the arguments of CheckboxSelectMultiple, plus extra
688 keyword arguments:
822 keyword arguments:
689 madWebObject madrigal.ui.web.MadrigalWeb object
823 madWebObject madrigal.ui.web.MadrigalWeb object
690 """
824 """
691 super(IsprintWidget, self).__init__(*args, **kwargs)
825 super(IsprintWidget, self).__init__(*args, **kwargs)
692 self.renderer = django.forms.CheckboxSelectMultiple
826 self.renderer = django.forms.CheckboxSelectMultiple
693 self.template_name = 'madweb/parameter_multiple.html'
827 self.template_name = 'madweb/parameter_multiple.html'
694
828
695
829
696 def set_parm_lists(self, isDerivedDict, parmDescDict, separateProlog=False):
830 def set_parm_lists(self, isDerivedDict, parmDescDict, separateProlog=False):
697 """set_parm_lists sets class variables used by the html renderer
831 """set_parm_lists sets class variables used by the html renderer
698
832
699 measParmList - parms in the file
833 measParmList - parms in the file
700 derivedParmList - parms derivable
834 derivedParmList - parms derivable
701 allParmList - above lists combined
835 allParmList - above lists combined
702 separateProlog - if true, create separate div tags so prolog parms can be hidden or not.
836 separateProlog - if true, create separate div tags so prolog parms can be hidden or not.
703 Default is False, in which case no div tags are used
837 Default is False, in which case no div tags are used
704 """
838 """
705 self.renderer.isDerivedDict = isDerivedDict
839 self.renderer.isDerivedDict = isDerivedDict
706 self.renderer.parmDescDict = parmDescDict
840 self.renderer.parmDescDict = parmDescDict
707 self.renderer.iterator = itertools.count()
841 self.renderer.iterator = itertools.count()
708 self.renderer.separateProlog = separateProlog
842 self.renderer.separateProlog = separateProlog
709
843
710
844
711
845
712
846
713 class IsprintForm(django.forms.Form):
847 class IsprintForm(django.forms.Form):
714 """IsprintForm is the form for the enhanced isprint page
848 """IsprintForm is the form for the enhanced isprint page
715 """
849 """
716 def __init__(self, *args, **kwargs):
850 def __init__(self, *args, **kwargs):
717
851
718 madFileObj = getSelection('madFileObj', args, kwargs)
852 madFileObj = getSelection('madFileObj', args, kwargs)
719 type = getSelection('type', args, kwargs)
853 type = getSelection('type', args, kwargs)
720 formatChoices = [('ascii', 'Space-delimited ascii')]
854 formatChoices = [('ascii', 'Space-delimited ascii')]
721 if type == 'download':
855 if type == 'download':
722 formatChoices.insert(0, ('netCDF4', 'netCDF4'))
856 formatChoices.insert(0, ('netCDF4', 'netCDF4'))
723 formatChoices.insert(0, ('Hdf5', 'Hdf5'))
857 formatChoices.insert(0, ('Hdf5', 'Hdf5'))
724 separateProlog = True
858 separateProlog = True
725 else:
859 else:
726 separateProlog = False
860 separateProlog = False
727
861
728 madDB = getSelection('madDB', args, kwargs)
862 madDB = getSelection('madDB', args, kwargs)
729 madParmObj = getSelection('madParmObj', args, kwargs)
863 madParmObj = getSelection('madParmObj', args, kwargs)
730 derivedParmList = getSelection('derivedParmList', args, kwargs)
864 derivedParmList = getSelection('derivedParmList', args, kwargs)
731 allParmList = getSelection('allParmList', args, kwargs)
865 allParmList = getSelection('allParmList', args, kwargs)
732 allParmDescList = getSelection('allParmDescList', args, kwargs)
866 allParmDescList = getSelection('allParmDescList', args, kwargs)
733 self.parmList = list(zip(allParmList, allParmDescList))
867 self.parmList = list(zip(allParmList, allParmDescList))
734 super(IsprintForm, self).__init__(*args, **kwargs)
868 super(IsprintForm, self).__init__(*args, **kwargs)
735
869
736 madCatObj = madrigal.metadata.MadrigalParmCategory(madDB)
870 madCatObj = madrigal.metadata.MadrigalParmCategory(madDB)
737
871
738 catList = madCatObj.getCategoryList()
872 catList = madCatObj.getCategoryList()
739 catDict = madParmObj.getCategoryDict(allParmList)
873 catDict = madParmObj.getCategoryDict(allParmList)
740
874
741 choices = []
875 choices = []
742 isDerivedDict = {}
876 isDerivedDict = {}
743 parmDescDict = {}
877 parmDescDict = {}
744 for catDesc, catID in catList:
878 for catDesc, catID in catList:
745 if catID not in list(catDict.keys()):
879 if catID not in list(catDict.keys()):
746 continue
880 continue
747 theseParms = []
881 theseParms = []
748 for parm in catDict[catID][1]:
882 for parm in catDict[catID][1]:
749 theseParms.append((parm, parm))
883 theseParms.append((parm, parm))
750 if parm in derivedParmList:
884 if parm in derivedParmList:
751 isDerivedDict[parm] = True
885 isDerivedDict[parm] = True
752 else:
886 else:
753 isDerivedDict[parm] = False
887 isDerivedDict[parm] = False
754 parmDescDict[parm] = madParmObj.getParmDescription(parm)
888 parmDescDict[parm] = madParmObj.getParmDescription(parm)
755 choices.append((catDesc, theseParms))
889 choices.append((catDesc, theseParms))
756
890
757 choices_with_null = [('None', 'None')] + choices
891 choices_with_null = [('None', 'None')] + choices
758
892
759 earliestTime = madFileObj.getEarliestTime()
893 earliestTime = madFileObj.getEarliestTime()
760 latestTime = madFileObj.getLatestTime()
894 latestTime = madFileObj.getLatestTime()
761 earliestDT = datetime.datetime(*earliestTime)
895 earliestDT = datetime.datetime(*earliestTime)
762 latestDT = datetime.datetime(*latestTime)
896 latestDT = datetime.datetime(*latestTime)
763 earliestStr = earliestDT.strftime('%Y-%m-%d %H:%M:%S')
897 earliestStr = earliestDT.strftime('%Y-%m-%d %H:%M:%S')
764 latestStr = latestDT.strftime('%Y-%m-%d %H:%M:%S')
898 latestStr = latestDT.strftime('%Y-%m-%d %H:%M:%S')
765
899
766 self.fields['fullFilename'] = django.forms.CharField(required=False, widget=django.forms.HiddenInput())
900 self.fields['fullFilename'] = django.forms.CharField(required=False, widget=django.forms.HiddenInput())
767 self.fields['type'] = django.forms.CharField(required=False, widget=django.forms.HiddenInput())
901 self.fields['type'] = django.forms.CharField(required=False, widget=django.forms.HiddenInput())
768
902
769 # format fields
903 # format fields
770 self.fields['formats'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(attrs={"onChange":'changeFormat(this)'}),
904 self.fields['formats'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(attrs={"onChange":'changeFormat(this)'}),
771 choices=formatChoices, initial='ascii',
905 choices=formatChoices, initial='ascii',
772 required=False, label='Select output format:')
906 required=False, label='Select output format:')
773
907
774 self.fields['showHeaders'] = django.forms.BooleanField(required=False, label='Show headers:',
908 self.fields['showHeaders'] = django.forms.BooleanField(required=False, label='Show headers:',
775 help_text="Select this to show a header line before each record")
909 help_text="Select this to show a header line before each record")
776
910
777 self.fields['missing'] = django.forms.CharField(required=False,
911 self.fields['missing'] = django.forms.CharField(required=False,
778 label='Missing value string: ',
912 label='Missing value string: ',
779 help_text='Modify this field to display something other than NaN for missing or assumed or known bad data.')
913 help_text='Modify this field to display something other than NaN for missing or assumed or known bad data.')
780
914
781 # form fields
915 # form fields
782 self.fields['parameters'] = IsprintChoiceField(choices=choices,
916 self.fields['parameters'] = IsprintChoiceField(choices=choices,
783 required=False,
917 required=False,
784 initial=['YEAR', 'MIN'],
918 initial=['YEAR', 'MIN'],
785 isDerivedDict=isDerivedDict,
919 isDerivedDict=isDerivedDict,
786 parmDescDict=parmDescDict,
920 parmDescDict=parmDescDict,
787 separateProlog=separateProlog,
921 separateProlog=separateProlog,
788 label = "")
922 label = "")
789
923
790 # time selection
924 # time selection
791 self.fields['start_date'] = django.forms.DateTimeField(input_formats=['%Y-%m-%dT%H:%M:%S'],
925 self.fields['start_date'] = django.forms.DateTimeField(input_formats=['%Y-%m-%dT%H:%M:%S'],
792 label='Start datetime',
926 label='Start datetime',
793 help_text='Modify this field to remove all records before this start time. Initial start datetime is the time of the first record.',
927 help_text='Modify this field to remove all records before this start time. Initial start datetime is the time of the first record.',
794 widget=django.forms.DateTimeInput(format='%Y-%m-%dT%H:%M:%S'),
928 widget=django.forms.DateTimeInput(format='%Y-%m-%dT%H:%M:%S'),
795 required=False)
929 required=False)
796
930
797 self.fields['end_date'] = django.forms.DateTimeField(input_formats=['%Y-%m-%dT%H:%M:%S'],
931 self.fields['end_date'] = django.forms.DateTimeField(input_formats=['%Y-%m-%dT%H:%M:%S'],
798 label='End datetime',
932 label='End datetime',
799 help_text='Modify this field to remove all records after this end time. Initial end datetime is the time of the last record.',
933 help_text='Modify this field to remove all records after this end time. Initial end datetime is the time of the last record.',
800 widget=django.forms.DateTimeInput(format='%Y-%m-%dT%H:%M:%S'),
934 widget=django.forms.DateTimeInput(format='%Y-%m-%dT%H:%M:%S'),
801 required=False)
935 required=False)
802
936
803 self.fields['parm_1'] = django.forms.ChoiceField(required=False,
937 self.fields['parm_1'] = django.forms.ChoiceField(required=False,
804 choices=choices_with_null)
938 choices=choices_with_null)
805 self.fields['parm_1_lower'] = django.forms.CharField(required=False, initial='')
939 self.fields['parm_1_lower'] = django.forms.CharField(required=False, initial='')
806 self.fields['parm_1_upper'] = django.forms.CharField(required=False, initial='')
940 self.fields['parm_1_upper'] = django.forms.CharField(required=False, initial='')
807
941
808 self.fields['parm_2'] = django.forms.ChoiceField(required=False,
942 self.fields['parm_2'] = django.forms.ChoiceField(required=False,
809 choices=choices_with_null)
943 choices=choices_with_null)
810 self.fields['parm_2_lower'] = django.forms.CharField(required=False, initial='')
944 self.fields['parm_2_lower'] = django.forms.CharField(required=False, initial='')
811 self.fields['parm_2_upper'] = django.forms.CharField(required=False, initial='')
945 self.fields['parm_2_upper'] = django.forms.CharField(required=False, initial='')
812
946
813 self.fields['parm_3'] = django.forms.ChoiceField(required=False,
947 self.fields['parm_3'] = django.forms.ChoiceField(required=False,
814 choices=choices_with_null)
948 choices=choices_with_null)
815 self.fields['parm_3_lower'] = django.forms.CharField(required=False, initial='')
949 self.fields['parm_3_lower'] = django.forms.CharField(required=False, initial='')
816 self.fields['parm_3_upper'] = django.forms.CharField(required=False, initial='')
950 self.fields['parm_3_upper'] = django.forms.CharField(required=False, initial='')
817
951
818 # add optional fields
952 # add optional fields
819 if 'GDALT' in allParmList:
953 if 'GDALT' in allParmList:
820 min_alt_value = getSelection('min_alt', args, kwargs)
954 min_alt_value = getSelection('min_alt', args, kwargs)
821 max_alt_value = getSelection('max_alt', args, kwargs)
955 max_alt_value = getSelection('max_alt', args, kwargs)
822 if min_alt_value != max_alt_value:
956 if min_alt_value != max_alt_value:
823 self.fields['min_alt'] = django.forms.CharField(required=False,
957 self.fields['min_alt'] = django.forms.CharField(required=False,
824 label='Min altitude:',
958 label='Min altitude:',
825 help_text='Modify this field to remove all data with altitudes below this level.')
959 help_text='Modify this field to remove all data with altitudes below this level.')
826 self.fields['max_alt'] = django.forms.CharField(required=False,
960 self.fields['max_alt'] = django.forms.CharField(required=False,
827 label='Max altitude:',
961 label='Max altitude:',
828 help_text='Modify this field to remove all data with altitudes above this level.')
962 help_text='Modify this field to remove all data with altitudes above this level.')
829
963
830 if 'AZM' in allParmList:
964 if 'AZM' in allParmList:
831 self.fields['min_az'] = django.forms.CharField(required=False,
965 self.fields['min_az'] = django.forms.CharField(required=False,
832 label='Min azimuth:',
966 label='Min azimuth:',
833 help_text='Modify this field to remove all azimuths (-180 to 180) below this value. You can also have two separate azimuth ranges by using the Azimuth 2 fields.')
967 help_text='Modify this field to remove all azimuths (-180 to 180) below this value. You can also have two separate azimuth ranges by using the Azimuth 2 fields.')
834 self.fields['max_az'] = django.forms.CharField(required=False,
968 self.fields['max_az'] = django.forms.CharField(required=False,
835 label='Max azimuth:',
969 label='Max azimuth:',
836 help_text='Modify this field to remove all azimuths (-180 to 180) above this value. You can also have two separate azimuth ranges by using the Azimuth 2 fields.')
970 help_text='Modify this field to remove all azimuths (-180 to 180) above this value. You can also have two separate azimuth ranges by using the Azimuth 2 fields.')
837 self.fields['min_az2'] = django.forms.CharField(required=False,
971 self.fields['min_az2'] = django.forms.CharField(required=False,
838 label='Min azimuth 2:',
972 label='Min azimuth 2:',
839 help_text='Modify this field to have a second allowed azimuth range. This would set the lower limit of the second range.')
973 help_text='Modify this field to have a second allowed azimuth range. This would set the lower limit of the second range.')
840 self.fields['max_az2'] = django.forms.CharField(required=False,
974 self.fields['max_az2'] = django.forms.CharField(required=False,
841 label='Max azimuth 2:',
975 label='Max azimuth 2:',
842 help_text='Modify this field to have a second allowed azimuth range. This would set the upper limit of the second range.')
976 help_text='Modify this field to have a second allowed azimuth range. This would set the upper limit of the second range.')
843
977
844 if 'ELM' in allParmList:
978 if 'ELM' in allParmList:
845 self.fields['min_el'] = django.forms.CharField(required=False,
979 self.fields['min_el'] = django.forms.CharField(required=False,
846 label='Min elevation:',
980 label='Min elevation:',
847 help_text='Modify this field to remove all elevations (0 to 90) below this value. You can also have two separate elevations ranges by using the Elevations 2 fields.')
981 help_text='Modify this field to remove all elevations (0 to 90) below this value. You can also have two separate elevations ranges by using the Elevations 2 fields.')
848 self.fields['max_el'] = django.forms.CharField(required=False,
982 self.fields['max_el'] = django.forms.CharField(required=False,
849 label='Max elevation:',
983 label='Max elevation:',
850 help_text='Modify this field to remove all elevations (0 to 90) above this value. You can also have two separate elevations ranges by using the Elevations 2 fields.')
984 help_text='Modify this field to remove all elevations (0 to 90) above this value. You can also have two separate elevations ranges by using the Elevations 2 fields.')
851 self.fields['min_el2'] = django.forms.CharField(required=False,
985 self.fields['min_el2'] = django.forms.CharField(required=False,
852 label='Min elevation 2:',
986 label='Min elevation 2:',
853 help_text='Modify this field to have a second allowed elevation range. This would set the lower limit of the second range.')
987 help_text='Modify this field to have a second allowed elevation range. This would set the lower limit of the second range.')
854 self.fields['max_el2'] = django.forms.CharField(required=False,
988 self.fields['max_el2'] = django.forms.CharField(required=False,
855 label='Max elevation 2:',
989 label='Max elevation 2:',
856 help_text='Modify this field to have a second allowed elevation range. This would set the upper limit of the second range.')
990 help_text='Modify this field to have a second allowed elevation range. This would set the upper limit of the second range.')
857
991
858 if 'PL' in allParmList:
992 if 'PL' in allParmList:
859 min_pl_value = getSelection('min_pl', args, kwargs)
993 min_pl_value = getSelection('min_pl', args, kwargs)
860 max_pl_value = getSelection('max_pl', args, kwargs)
994 max_pl_value = getSelection('max_pl', args, kwargs)
861 self.fields['min_pl'] = django.forms.CharField(required=False,
995 self.fields['min_pl'] = django.forms.CharField(required=False,
862 label='Min pulse len (microsec): ',
996 label='Min pulse len (microsec): ',
863 help_text='Modify this field to remove all pulse lengths in microsecs below this value.')
997 help_text='Modify this field to remove all pulse lengths in microsecs below this value.')
864 self.fields['max_pl'] = django.forms.CharField(required=False,
998 self.fields['max_pl'] = django.forms.CharField(required=False,
865 label='Max pulse len (microsec): ',
999 label='Max pulse len (microsec): ',
866 help_text='Modify this field to remove all pulse lengths in microsecs above this value.')
1000 help_text='Modify this field to remove all pulse lengths in microsecs above this value.')
867
1001
868
1002
869 def clean_fullFilename(self):
1003 def clean_fullFilename(self):
870 fullFilename = self.cleaned_data['fullFilename']
1004 fullFilename = self.cleaned_data['fullFilename']
871 # make sure the file exists
1005 # make sure the file exists
872 if not os.access(fullFilename, os.R_OK):
1006 if not os.access(fullFilename, os.R_OK):
873 raise django.forms.ValidationError('Invalid filename: %(value)s cannot be opened',
1007 raise django.forms.ValidationError('Invalid filename: %(value)s cannot be opened',
874 code='io_error',
1008 code='io_error',
875 params={'value': fullFilename})
1009 params={'value': fullFilename})
876
1010
877 return(fullFilename)
1011 return(fullFilename)
878
1012
879
1013
880 def clean_formats(self):
1014 def clean_formats(self):
881 formats = self.cleaned_data['formats']
1015 formats = self.cleaned_data['formats']
882 # make sure the format valid
1016 # make sure the format valid
883 if formats not in ('Hdf5', 'netCDF4', 'ascii'):
1017 if formats not in ('Hdf5', 'netCDF4', 'ascii'):
884 raise django.forms.ValidationError('Invalid format: %(value)s not legal format',
1018 raise django.forms.ValidationError('Invalid format: %(value)s not legal format',
885 code='invalid',
1019 code='invalid',
886 params={'value': formats})
1020 params={'value': formats})
887
1021
888 return(formats)
1022 return(formats)
889
1023
890
1024
891 def clean_min_alt(self):
1025 def clean_min_alt(self):
892 min_alt = self.cleaned_data['min_alt']
1026 min_alt = self.cleaned_data['min_alt']
893 if len(min_alt) != 0:
1027 if len(min_alt) != 0:
894 try:
1028 try:
895 min_alt_value = float(min_alt)
1029 min_alt_value = float(min_alt)
896 except:
1030 except:
897 raise django.forms.ValidationError('Invalid minimum altitude: %(value)s cannot be converted to a float',
1031 raise django.forms.ValidationError('Invalid minimum altitude: %(value)s cannot be converted to a float',
898 code='invalid',
1032 code='invalid',
899 params={'value': min_alt})
1033 params={'value': min_alt})
900 if min_alt_value < 0.0:
1034 if min_alt_value < 0.0:
901 raise django.forms.ValidationError('Invalid minimum altitude: %(value)s cannot be less than 0.0 kilometers',
1035 raise django.forms.ValidationError('Invalid minimum altitude: %(value)s cannot be less than 0.0 kilometers',
902 code='invalid',
1036 code='invalid',
903 params={'value': min_alt})
1037 params={'value': min_alt})
904 return(min_alt)
1038 return(min_alt)
905
1039
906 def clean_max_alt(self):
1040 def clean_max_alt(self):
907 max_alt = self.cleaned_data['max_alt']
1041 max_alt = self.cleaned_data['max_alt']
908 if len(max_alt) != 0:
1042 if len(max_alt) != 0:
909 try:
1043 try:
910 max_alt_value = float(max_alt)
1044 max_alt_value = float(max_alt)
911 except:
1045 except:
912 raise django.forms.ValidationError('Invalid maximum altitude: %(value)s cannot be converted to a float',
1046 raise django.forms.ValidationError('Invalid maximum altitude: %(value)s cannot be converted to a float',
913 code='invalid',
1047 code='invalid',
914 params={'value': max_alt})
1048 params={'value': max_alt})
915 if max_alt_value < 0.0:
1049 if max_alt_value < 0.0:
916 raise django.forms.ValidationError('Invalid maximum altitude: %(value)s cannot be less than 0.0 kilometers',
1050 raise django.forms.ValidationError('Invalid maximum altitude: %(value)s cannot be less than 0.0 kilometers',
917 code='invalid',
1051 code='invalid',
918 params={'value': max_alt})
1052 params={'value': max_alt})
919 return(max_alt)
1053 return(max_alt)
920
1054
921
1055
922 def clean_min_az(self):
1056 def clean_min_az(self):
923 min_az = self.cleaned_data['min_az']
1057 min_az = self.cleaned_data['min_az']
924 if len(min_az) != 0:
1058 if len(min_az) != 0:
925 try:
1059 try:
926 min_az_value = float(min_az)
1060 min_az_value = float(min_az)
927 except:
1061 except:
928 raise django.forms.ValidationError('Invalid minimum azimuth: %(value)s cannot be converted to a float',
1062 raise django.forms.ValidationError('Invalid minimum azimuth: %(value)s cannot be converted to a float',
929 code='invalid',
1063 code='invalid',
930 params={'value': min_az})
1064 params={'value': min_az})
931 if min_az_value < -180.0:
1065 if min_az_value < -180.0:
932 raise django.forms.ValidationError('Invalid minimum azimuth: %(value)s cannot be less than -180 degrees',
1066 raise django.forms.ValidationError('Invalid minimum azimuth: %(value)s cannot be less than -180 degrees',
933 code='invalid',
1067 code='invalid',
934 params={'value': min_az})
1068 params={'value': min_az})
935 if min_az_value > 180.0:
1069 if min_az_value > 180.0:
936 raise django.forms.ValidationError('Invalid minimum azimuth: %(value)s cannot be more than 180 degrees',
1070 raise django.forms.ValidationError('Invalid minimum azimuth: %(value)s cannot be more than 180 degrees',
937 code='invalid',
1071 code='invalid',
938 params={'value': min_az})
1072 params={'value': min_az})
939 return(min_az)
1073 return(min_az)
940
1074
941
1075
942 def clean_max_az(self):
1076 def clean_max_az(self):
943 max_az = self.cleaned_data['max_az']
1077 max_az = self.cleaned_data['max_az']
944 if len(max_az) != 0:
1078 if len(max_az) != 0:
945 try:
1079 try:
946 max_az_value = float(max_az)
1080 max_az_value = float(max_az)
947 except:
1081 except:
948 raise django.forms.ValidationError('Invalid maximum azimuth: %(value)s cannot be converted to a float',
1082 raise django.forms.ValidationError('Invalid maximum azimuth: %(value)s cannot be converted to a float',
949 code='invalid',
1083 code='invalid',
950 params={'value': max_az})
1084 params={'value': max_az})
951 if max_az_value < -180.0:
1085 if max_az_value < -180.0:
952 raise django.forms.ValidationError('Invalid maximum azimuth: %(value)s cannot be less than -180 degrees',
1086 raise django.forms.ValidationError('Invalid maximum azimuth: %(value)s cannot be less than -180 degrees',
953 code='invalid',
1087 code='invalid',
954 params={'value': max_az})
1088 params={'value': max_az})
955 if max_az_value > 180.0:
1089 if max_az_value > 180.0:
956 raise django.forms.ValidationError('Invalid maximum azimuth: %(value)s cannot be more than 180 degrees',
1090 raise django.forms.ValidationError('Invalid maximum azimuth: %(value)s cannot be more than 180 degrees',
957 code='invalid',
1091 code='invalid',
958 params={'value': max_az})
1092 params={'value': max_az})
959 return(max_az)
1093 return(max_az)
960
1094
961
1095
962 def clean_min_el(self):
1096 def clean_min_el(self):
963 min_el = self.cleaned_data['min_el']
1097 min_el = self.cleaned_data['min_el']
964 if len(min_el) != 0:
1098 if len(min_el) != 0:
965 try:
1099 try:
966 min_el_value = float(min_el)
1100 min_el_value = float(min_el)
967 except:
1101 except:
968 raise django.forms.ValidationError('Invalid minimum elevation: %(value)s cannot be converted to a float',
1102 raise django.forms.ValidationError('Invalid minimum elevation: %(value)s cannot be converted to a float',
969 code='invalid',
1103 code='invalid',
970 params={'value': min_el})
1104 params={'value': min_el})
971 if min_el_value < 0.0:
1105 if min_el_value < 0.0:
972 raise django.forms.ValidationError('Invalid minimum elevation: %(value)s cannot be less than 0 degrees',
1106 raise django.forms.ValidationError('Invalid minimum elevation: %(value)s cannot be less than 0 degrees',
973 code='invalid',
1107 code='invalid',
974 params={'value': min_el})
1108 params={'value': min_el})
975 if min_el_value > 90.0:
1109 if min_el_value > 90.0:
976 raise django.forms.ValidationError('Invalid minimum elevation: %(value)s cannot be more than 90 degrees',
1110 raise django.forms.ValidationError('Invalid minimum elevation: %(value)s cannot be more than 90 degrees',
977 code='invalid',
1111 code='invalid',
978 params={'value': min_el})
1112 params={'value': min_el})
979 return(min_el)
1113 return(min_el)
980
1114
981
1115
982 def clean_max_el(self):
1116 def clean_max_el(self):
983 max_el = self.cleaned_data['max_el']
1117 max_el = self.cleaned_data['max_el']
984 if len(max_el) != 0:
1118 if len(max_el) != 0:
985 try:
1119 try:
986 max_el_value = float(max_el)
1120 max_el_value = float(max_el)
987 except:
1121 except:
988 raise django.forms.ValidationError('Invalid maximum elevation: %(value)s cannot be converted to a float',
1122 raise django.forms.ValidationError('Invalid maximum elevation: %(value)s cannot be converted to a float',
989 code='invalid',
1123 code='invalid',
990 params={'value': max_el})
1124 params={'value': max_el})
991 if max_el_value < 0.0:
1125 if max_el_value < 0.0:
992 raise django.forms.ValidationError('Invalid maximum elevation: %(value)s cannot be less than 0 degrees',
1126 raise django.forms.ValidationError('Invalid maximum elevation: %(value)s cannot be less than 0 degrees',
993 code='invalid',
1127 code='invalid',
994 params={'value': max_el})
1128 params={'value': max_el})
995 if max_el_value > 90.0:
1129 if max_el_value > 90.0:
996 raise django.forms.ValidationError('Invalid maximum elevation: %(value)s cannot be more than 90 degrees',
1130 raise django.forms.ValidationError('Invalid maximum elevation: %(value)s cannot be more than 90 degrees',
997 code='invalid',
1131 code='invalid',
998 params={'value': max_el})
1132 params={'value': max_el})
999 return(max_el)
1133 return(max_el)
1000
1134
1001
1135
1002 def clean_min_az2(self):
1136 def clean_min_az2(self):
1003 min_az2 = self.cleaned_data['min_az2']
1137 min_az2 = self.cleaned_data['min_az2']
1004 if len(min_az2) != 0:
1138 if len(min_az2) != 0:
1005 try:
1139 try:
1006 min_az2_value = float(min_az2)
1140 min_az2_value = float(min_az2)
1007 except:
1141 except:
1008 raise django.forms.ValidationError('Invalid minimum azimuth 2: %(value)s cannot be converted to a float',
1142 raise django.forms.ValidationError('Invalid minimum azimuth 2: %(value)s cannot be converted to a float',
1009 code='invalid',
1143 code='invalid',
1010 params={'value': min_az2})
1144 params={'value': min_az2})
1011 if min_az2_value < -180.0:
1145 if min_az2_value < -180.0:
1012 raise django.forms.ValidationError('Invalid minimum azimuth 2: %(value)s cannot be less than -180 degrees',
1146 raise django.forms.ValidationError('Invalid minimum azimuth 2: %(value)s cannot be less than -180 degrees',
1013 code='invalid',
1147 code='invalid',
1014 params={'value': min_az2})
1148 params={'value': min_az2})
1015 if min_az2_value > 180.0:
1149 if min_az2_value > 180.0:
1016 raise django.forms.ValidationError('Invalid minimum azimuth 2: %(value)s cannot be more than 180 degrees',
1150 raise django.forms.ValidationError('Invalid minimum azimuth 2: %(value)s cannot be more than 180 degrees',
1017 code='invalid',
1151 code='invalid',
1018 params={'value': min_az2})
1152 params={'value': min_az2})
1019 return(min_az2)
1153 return(min_az2)
1020
1154
1021
1155
1022 def clean_max_az2(self):
1156 def clean_max_az2(self):
1023 max_az2 = self.cleaned_data['max_az2']
1157 max_az2 = self.cleaned_data['max_az2']
1024 if len(max_az2) != 0:
1158 if len(max_az2) != 0:
1025 try:
1159 try:
1026 max_az2_value = float(max_az2)
1160 max_az2_value = float(max_az2)
1027 except:
1161 except:
1028 raise django.forms.ValidationError('Invalid maximum azimuth 2: %(value)s cannot be converted to a float',
1162 raise django.forms.ValidationError('Invalid maximum azimuth 2: %(value)s cannot be converted to a float',
1029 code='invalid',
1163 code='invalid',
1030 params={'value': max_az2})
1164 params={'value': max_az2})
1031 if max_az2_value < -180.0:
1165 if max_az2_value < -180.0:
1032 raise django.forms.ValidationError('Invalid maximum azimuth 2: %(value)s cannot be less than -180 degrees',
1166 raise django.forms.ValidationError('Invalid maximum azimuth 2: %(value)s cannot be less than -180 degrees',
1033 code='invalid',
1167 code='invalid',
1034 params={'value': max_az2})
1168 params={'value': max_az2})
1035 if max_az2_value > 180.0:
1169 if max_az2_value > 180.0:
1036 raise django.forms.ValidationError('Invalid maximum azimuth 2: %(value)s cannot be more than 180 degrees',
1170 raise django.forms.ValidationError('Invalid maximum azimuth 2: %(value)s cannot be more than 180 degrees',
1037 code='invalid',
1171 code='invalid',
1038 params={'value': max_az2})
1172 params={'value': max_az2})
1039 return(max_az2)
1173 return(max_az2)
1040
1174
1041
1175
1042 def clean_min_el2(self):
1176 def clean_min_el2(self):
1043 min_el2 = self.cleaned_data['min_el2']
1177 min_el2 = self.cleaned_data['min_el2']
1044 if len(min_el2) != 0:
1178 if len(min_el2) != 0:
1045 try:
1179 try:
1046 min_el2_value = float(min_el2)
1180 min_el2_value = float(min_el2)
1047 except:
1181 except:
1048 raise django.forms.ValidationError('Invalid minimum elevation 2: %(value)s cannot be converted to a float',
1182 raise django.forms.ValidationError('Invalid minimum elevation 2: %(value)s cannot be converted to a float',
1049 code='invalid',
1183 code='invalid',
1050 params={'value': min_el2})
1184 params={'value': min_el2})
1051 if min_el2_value < 0.0:
1185 if min_el2_value < 0.0:
1052 raise django.forms.ValidationError('Invalid minimum elevation 2: %(value)s cannot be less than 0 degrees',
1186 raise django.forms.ValidationError('Invalid minimum elevation 2: %(value)s cannot be less than 0 degrees',
1053 code='invalid',
1187 code='invalid',
1054 params={'value': min_el2})
1188 params={'value': min_el2})
1055 if min_el2_value > 90.0:
1189 if min_el2_value > 90.0:
1056 raise django.forms.ValidationError('Invalid minimum elevation 2: %(value)s cannot be more than 90 degrees',
1190 raise django.forms.ValidationError('Invalid minimum elevation 2: %(value)s cannot be more than 90 degrees',
1057 code='invalid',
1191 code='invalid',
1058 params={'value': min_el2})
1192 params={'value': min_el2})
1059 return(min_el2)
1193 return(min_el2)
1060
1194
1061
1195
1062 def clean_max_el2(self):
1196 def clean_max_el2(self):
1063 max_el2 = self.cleaned_data['max_el2']
1197 max_el2 = self.cleaned_data['max_el2']
1064 if len(max_el2) != 0:
1198 if len(max_el2) != 0:
1065 try:
1199 try:
1066 max_el2_value = float(max_el2)
1200 max_el2_value = float(max_el2)
1067 except:
1201 except:
1068 raise django.forms.ValidationError('Invalid maximum elevation 2: %(value)s cannot be converted to a float',
1202 raise django.forms.ValidationError('Invalid maximum elevation 2: %(value)s cannot be converted to a float',
1069 code='invalid',
1203 code='invalid',
1070 params={'value': max_el2})
1204 params={'value': max_el2})
1071 if max_el2_value < 0.0:
1205 if max_el2_value < 0.0:
1072 raise django.forms.ValidationError('Invalid maximum elevation 2: %(value)s cannot be less than 0 degrees',
1206 raise django.forms.ValidationError('Invalid maximum elevation 2: %(value)s cannot be less than 0 degrees',
1073 code='invalid',
1207 code='invalid',
1074 params={'value': max_el2})
1208 params={'value': max_el2})
1075 if max_el2_value > 90.0:
1209 if max_el2_value > 90.0:
1076 raise django.forms.ValidationError('Invalid maximum elevation 2: %(value)s cannot be more than 90 degrees',
1210 raise django.forms.ValidationError('Invalid maximum elevation 2: %(value)s cannot be more than 90 degrees',
1077 code='invalid',
1211 code='invalid',
1078 params={'value': max_el2})
1212 params={'value': max_el2})
1079 return(max_el2)
1213 return(max_el2)
1080
1214
1081
1215
1082 def clean_min_pl(self):
1216 def clean_min_pl(self):
1083 min_pl = self.cleaned_data['min_pl']
1217 min_pl = self.cleaned_data['min_pl']
1084 if len(min_pl) != 0:
1218 if len(min_pl) != 0:
1085 try:
1219 try:
1086 min_pl_value = float(min_pl)
1220 min_pl_value = float(min_pl)
1087 except:
1221 except:
1088 raise django.forms.ValidationError('Invalid lower limit for pulse length: %(value)s cannot be converted to a float',
1222 raise django.forms.ValidationError('Invalid lower limit for pulse length: %(value)s cannot be converted to a float',
1089 code='invalid',
1223 code='invalid',
1090 params={'value': min_pl})
1224 params={'value': min_pl})
1091 return(min_pl)
1225 return(min_pl)
1092
1226
1093
1227
1094 def clean_max_pl(self):
1228 def clean_max_pl(self):
1095 max_pl = self.cleaned_data['max_pl']
1229 max_pl = self.cleaned_data['max_pl']
1096 if len(max_pl) != 0:
1230 if len(max_pl) != 0:
1097 try:
1231 try:
1098 max_pl_value = float(max_pl)
1232 max_pl_value = float(max_pl)
1099 except:
1233 except:
1100 raise django.forms.ValidationError('Invalid upper limit for pulse length: %(value)s cannot be converted to a float',
1234 raise django.forms.ValidationError('Invalid upper limit for pulse length: %(value)s cannot be converted to a float',
1101 code='invalid',
1235 code='invalid',
1102 params={'value': max_pl})
1236 params={'value': max_pl})
1103 return(max_pl)
1237 return(max_pl)
1104
1238
1105
1239
1106 def clean_parm_1_lower(self):
1240 def clean_parm_1_lower(self):
1107 parm_1_lower = self.cleaned_data['parm_1_lower']
1241 parm_1_lower = self.cleaned_data['parm_1_lower']
1108 if len(parm_1_lower) != 0:
1242 if len(parm_1_lower) != 0:
1109 try:
1243 try:
1110 parm_1_lower_value = float(parm_1_lower)
1244 parm_1_lower_value = float(parm_1_lower)
1111 except:
1245 except:
1112 raise django.forms.ValidationError('Invalid lower limit for parm 1: %(value)s cannot be converted to a float',
1246 raise django.forms.ValidationError('Invalid lower limit for parm 1: %(value)s cannot be converted to a float',
1113 code='invalid',
1247 code='invalid',
1114 params={'value': parm_1_lower})
1248 params={'value': parm_1_lower})
1115 return(parm_1_lower)
1249 return(parm_1_lower)
1116
1250
1117
1251
1118 def clean_parm_1_upper(self):
1252 def clean_parm_1_upper(self):
1119 parm_1_upper = self.cleaned_data['parm_1_upper']
1253 parm_1_upper = self.cleaned_data['parm_1_upper']
1120 if len(parm_1_upper) != 0:
1254 if len(parm_1_upper) != 0:
1121 try:
1255 try:
1122 parm_1_upper_value = float(parm_1_upper)
1256 parm_1_upper_value = float(parm_1_upper)
1123 except:
1257 except:
1124 raise django.forms.ValidationError('Invalid upper limit for parm 1: %(value)s cannot be converted to a float',
1258 raise django.forms.ValidationError('Invalid upper limit for parm 1: %(value)s cannot be converted to a float',
1125 code='invalid',
1259 code='invalid',
1126 params={'value': parm_1_upper})
1260 params={'value': parm_1_upper})
1127 return(parm_1_upper)
1261 return(parm_1_upper)
1128
1262
1129
1263
1130 def clean_parm_2_lower(self):
1264 def clean_parm_2_lower(self):
1131 parm_2_lower = self.cleaned_data['parm_2_lower']
1265 parm_2_lower = self.cleaned_data['parm_2_lower']
1132 if len(parm_2_lower) != 0:
1266 if len(parm_2_lower) != 0:
1133 try:
1267 try:
1134 parm_2_lower_value = float(parm_2_lower)
1268 parm_2_lower_value = float(parm_2_lower)
1135 except:
1269 except:
1136 raise django.forms.ValidationError('Invalid lower limit for parm 2: %(value)s cannot be converted to a float',
1270 raise django.forms.ValidationError('Invalid lower limit for parm 2: %(value)s cannot be converted to a float',
1137 code='invalid',
1271 code='invalid',
1138 params={'value': parm_2_lower})
1272 params={'value': parm_2_lower})
1139 return(parm_2_lower)
1273 return(parm_2_lower)
1140
1274
1141
1275
1142 def clean_parm_2_upper(self):
1276 def clean_parm_2_upper(self):
1143 parm_2_upper = self.cleaned_data['parm_2_upper']
1277 parm_2_upper = self.cleaned_data['parm_2_upper']
1144 if len(parm_2_upper) != 0:
1278 if len(parm_2_upper) != 0:
1145 try:
1279 try:
1146 parm_2_upper_value = float(parm_2_upper)
1280 parm_2_upper_value = float(parm_2_upper)
1147 except:
1281 except:
1148 raise django.forms.ValidationError('Invalid upper limit for parm 2: %(value)s cannot be converted to a float',
1282 raise django.forms.ValidationError('Invalid upper limit for parm 2: %(value)s cannot be converted to a float',
1149 code='invalid',
1283 code='invalid',
1150 params={'value': parm_2_upper})
1284 params={'value': parm_2_upper})
1151 return(parm_2_upper)
1285 return(parm_2_upper)
1152
1286
1153
1287
1154 def clean_parm_3_lower(self):
1288 def clean_parm_3_lower(self):
1155 parm_3_lower = self.cleaned_data['parm_3_lower']
1289 parm_3_lower = self.cleaned_data['parm_3_lower']
1156 if len(parm_3_lower) != 0:
1290 if len(parm_3_lower) != 0:
1157 try:
1291 try:
1158 parm_3_lower_value = float(parm_3_lower)
1292 parm_3_lower_value = float(parm_3_lower)
1159 except:
1293 except:
1160 raise django.forms.ValidationError('Invalid lower limit for parm 3: %(value)s cannot be converted to a float',
1294 raise django.forms.ValidationError('Invalid lower limit for parm 3: %(value)s cannot be converted to a float',
1161 code='invalid',
1295 code='invalid',
1162 params={'value': parm_3_lower})
1296 params={'value': parm_3_lower})
1163 return(parm_3_lower)
1297 return(parm_3_lower)
1164
1298
1165
1299
1166 def clean_parm_3_upper(self):
1300 def clean_parm_3_upper(self):
1167 parm_3_upper = self.cleaned_data['parm_3_upper']
1301 parm_3_upper = self.cleaned_data['parm_3_upper']
1168 if len(parm_3_upper) != 0:
1302 if len(parm_3_upper) != 0:
1169 try:
1303 try:
1170 parm_3_upper_value = float(parm_3_upper)
1304 parm_3_upper_value = float(parm_3_upper)
1171 except:
1305 except:
1172 raise django.forms.ValidationError('Invalid upper limit for parm 3: %(value)s cannot be converted to a float',
1306 raise django.forms.ValidationError('Invalid upper limit for parm 3: %(value)s cannot be converted to a float',
1173 code='invalid',
1307 code='invalid',
1174 params={'value': parm_3_upper})
1308 params={'value': parm_3_upper})
1175 return(parm_3_upper)
1309 return(parm_3_upper)
1176
1310
1177
1311
1178
1312
1179
1313
1180 def clean(self):
1314 def clean(self):
1181 """clean in the Django method to validate things in a form that require looking at multiple fields
1315 """clean in the Django method to validate things in a form that require looking at multiple fields
1182 """
1316 """
1183 # rule 1 - start_date < end_date
1317 # rule 1 - start_date < end_date
1184 if self.cleaned_data['start_date'] > self.cleaned_data['end_date']:
1318 if self.cleaned_data['start_date'] > self.cleaned_data['end_date']:
1185 raise django.forms.ValidationError('Error - start datetime greater than end datetime.')
1319 raise django.forms.ValidationError('Error - start datetime greater than end datetime.')
1186
1320
1187 # rule 2 - min_alt <= max_alt
1321 # rule 2 - min_alt <= max_alt
1188 try:
1322 try:
1189 min_alt = float(self.cleaned_data['min_alt'])
1323 min_alt = float(self.cleaned_data['min_alt'])
1190 max_alt = float(self.cleaned_data['max_alt'])
1324 max_alt = float(self.cleaned_data['max_alt'])
1191 except:
1325 except:
1192 min_alt = 0.0
1326 min_alt = 0.0
1193 max_alt = 1.0
1327 max_alt = 1.0
1194 if min_alt > max_alt:
1328 if min_alt > max_alt:
1195 raise django.forms.ValidationError('Error - Minimum altitude greater than maximum altitude.')
1329 raise django.forms.ValidationError('Error - Minimum altitude greater than maximum altitude.')
1196
1330
1197 # rule 3 - min_az <= max_az
1331 # rule 3 - min_az <= max_az
1198 try:
1332 try:
1199 min_az = float(self.cleaned_data['min_az'])
1333 min_az = float(self.cleaned_data['min_az'])
1200 max_az = float(self.cleaned_data['max_az'])
1334 max_az = float(self.cleaned_data['max_az'])
1201 except:
1335 except:
1202 min_az = 0.0
1336 min_az = 0.0
1203 max_az = 1.0
1337 max_az = 1.0
1204 if min_az > max_az:
1338 if min_az > max_az:
1205 raise django.forms.ValidationError('Error - Minimum azimuth greater than maximum azimuth.')
1339 raise django.forms.ValidationError('Error - Minimum azimuth greater than maximum azimuth.')
1206
1340
1207 # rule 4 - min_el <= max_el
1341 # rule 4 - min_el <= max_el
1208 try:
1342 try:
1209 min_el = float(self.cleaned_data['min_el'])
1343 min_el = float(self.cleaned_data['min_el'])
1210 max_el = float(self.cleaned_data['max_el'])
1344 max_el = float(self.cleaned_data['max_el'])
1211 except:
1345 except:
1212 min_el = 0.0
1346 min_el = 0.0
1213 max_el = 1.0
1347 max_el = 1.0
1214 if min_el > max_el:
1348 if min_el > max_el:
1215 raise django.forms.ValidationError('Error - Minimum elevation greater than maximum elevation.')
1349 raise django.forms.ValidationError('Error - Minimum elevation greater than maximum elevation.')
1216
1350
1217 # rule 5 - min_az2 <= max_az2
1351 # rule 5 - min_az2 <= max_az2
1218 try:
1352 try:
1219 min_az2 = float(self.cleaned_data['min_az2'])
1353 min_az2 = float(self.cleaned_data['min_az2'])
1220 max_az2 = float(self.cleaned_data['max_az2'])
1354 max_az2 = float(self.cleaned_data['max_az2'])
1221 except:
1355 except:
1222 min_az2 = 0.0
1356 min_az2 = 0.0
1223 max_az2 = 1.0
1357 max_az2 = 1.0
1224 if min_az2 > max_az2:
1358 if min_az2 > max_az2:
1225 raise django.forms.ValidationError('Error - Minimum azimuth 2 greater than maximum azimuth 2.')
1359 raise django.forms.ValidationError('Error - Minimum azimuth 2 greater than maximum azimuth 2.')
1226
1360
1227 # rule 6 - min_el2 <= max_el2
1361 # rule 6 - min_el2 <= max_el2
1228 try:
1362 try:
1229 min_el2 = float(self.cleaned_data['min_el2'])
1363 min_el2 = float(self.cleaned_data['min_el2'])
1230 max_el2 = float(self.cleaned_data['max_el2'])
1364 max_el2 = float(self.cleaned_data['max_el2'])
1231 except:
1365 except:
1232 min_el2 = 0.0
1366 min_el2 = 0.0
1233 max_el2 = 1.0
1367 max_el2 = 1.0
1234 if min_el2 > max_el2:
1368 if min_el2 > max_el2:
1235 raise django.forms.ValidationError('Error - Minimum elevation 2 greater than maximum elevation 2.')
1369 raise django.forms.ValidationError('Error - Minimum elevation 2 greater than maximum elevation 2.')
1236
1370
1237 # rule 7 - min_pl <= max_pl
1371 # rule 7 - min_pl <= max_pl
1238 try:
1372 try:
1239 min_pl = float(self.cleaned_data['min_pl'])
1373 min_pl = float(self.cleaned_data['min_pl'])
1240 max_pl = float(self.cleaned_data['max_pl'])
1374 max_pl = float(self.cleaned_data['max_pl'])
1241 except:
1375 except:
1242 min_pl = 0.0
1376 min_pl = 0.0
1243 max_pl = 1.0
1377 max_pl = 1.0
1244 if min_pl > max_pl:
1378 if min_pl > max_pl:
1245 raise django.forms.ValidationError('Error - Minimum pulse length greater than maximum pulse length.')
1379 raise django.forms.ValidationError('Error - Minimum pulse length greater than maximum pulse length.')
1246
1380
1247 # rule 8 - parm_1_lower <= parm_1_upper
1381 # rule 8 - parm_1_lower <= parm_1_upper
1248 try:
1382 try:
1249 parm_1_lower = float(self.cleaned_data['parm_1_lower'])
1383 parm_1_lower = float(self.cleaned_data['parm_1_lower'])
1250 parm_1_upper = float(self.cleaned_data['parm_1_upper'])
1384 parm_1_upper = float(self.cleaned_data['parm_1_upper'])
1251 except:
1385 except:
1252 parm_1_lower = 0.0
1386 parm_1_lower = 0.0
1253 parm_1_upper = 1.0
1387 parm_1_upper = 1.0
1254 if parm_1_lower > parm_1_upper:
1388 if parm_1_lower > parm_1_upper:
1255 raise django.forms.ValidationError('Error - parm 1 lower limit greater than upper limit.')
1389 raise django.forms.ValidationError('Error - parm 1 lower limit greater than upper limit.')
1256
1390
1257 # rule 9 - parm_2_lower <= parm_2_upper
1391 # rule 9 - parm_2_lower <= parm_2_upper
1258 try:
1392 try:
1259 parm_2_lower = float(self.cleaned_data['parm_2_lower'])
1393 parm_2_lower = float(self.cleaned_data['parm_2_lower'])
1260 parm_2_upper = float(self.cleaned_data['parm_2_upper'])
1394 parm_2_upper = float(self.cleaned_data['parm_2_upper'])
1261 except:
1395 except:
1262 parm_2_lower = 0.0
1396 parm_2_lower = 0.0
1263 parm_2_upper = 1.0
1397 parm_2_upper = 1.0
1264 if parm_2_lower > parm_2_upper:
1398 if parm_2_lower > parm_2_upper:
1265 raise django.forms.ValidationError('Error - parm 2 lower limit greater than upper limit.')
1399 raise django.forms.ValidationError('Error - parm 2 lower limit greater than upper limit.')
1266
1400
1267 # rule 10 - parm_3_lower <= parm_3_upper
1401 # rule 10 - parm_3_lower <= parm_3_upper
1268 try:
1402 try:
1269 parm_3_lower = float(self.cleaned_data['parm_3_lower'])
1403 parm_3_lower = float(self.cleaned_data['parm_3_lower'])
1270 parm_3_upper = float(self.cleaned_data['parm_3_upper'])
1404 parm_3_upper = float(self.cleaned_data['parm_3_upper'])
1271 except:
1405 except:
1272 parm_3_lower = 0.0
1406 parm_3_lower = 0.0
1273 parm_3_upper = 1.0
1407 parm_3_upper = 1.0
1274 if parm_3_lower > parm_3_upper:
1408 if parm_3_lower > parm_3_upper:
1275 raise django.forms.ValidationError('Error - parm 3 lower limit greater than upper limit.')
1409 raise django.forms.ValidationError('Error - parm 3 lower limit greater than upper limit.')
1276
1410
1277
1411
1278 class ListExpForm(django.forms.Form):
1412 class ListExpForm(django.forms.Form):
1279 """ListExpForm is a Form class for the default fields in the List Experiment interface
1413 """ListExpForm is a Form class for the default fields in the List Experiment interface
1280 """
1414 """
1281 def __init__(self, *args, **kwargs):
1415 def __init__(self, *args, **kwargs):
1282 super(ListExpForm, self).__init__(*args, **kwargs)
1416 super(ListExpForm, self).__init__(*args, **kwargs)
1283 madDB = madrigal.metadata.MadrigalDB()
1417 madDB = madrigal.metadata.MadrigalDB()
1284 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1418 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1285 isGlobal = True # default load
1419 isGlobal = True # default load
1286 now = datetime.datetime.now()
1420 now = datetime.datetime.now()
1287 endDateTime = datetime.datetime(now.year, 12, 31, 23, 59, 59)
1421 endDateTime = datetime.datetime(now.year, 12, 31, 23, 59, 59)
1288 self.fields['isGlobal'] = django.forms.BooleanField(widget = django.forms.CheckboxInput(attrs={"onChange":'changeGlobal(this.form)'}),
1422 self.fields['isGlobal'] = django.forms.BooleanField(widget = django.forms.CheckboxInput(attrs={"onChange":'changeGlobal(this.form)'}),
1289 required=False, label='Use all Madrigal sites: ',
1423 required=False, label='Use all Madrigal sites: ',
1290 initial=isGlobal)
1424 initial=isGlobal)
1291
1425
1292
1426
1293 categoriesSelection = '0'
1427 categoriesSelection = '0'
1294 self.fields['categories'] = django.forms.MultipleChoiceField(widget=django.forms.SelectMultiple(attrs={"onChange":"updateInstruments(this.form)"}),
1428 self.fields['categories'] = django.forms.MultipleChoiceField(widget=django.forms.SelectMultiple(attrs={"onChange":"updateInstruments(this.form)"}),
1295 choices=getCategoryList(args, kwargs, madInstData, True),
1429 choices=getCategoryList(args, kwargs, madInstData, True),
1296 initial='0',
1430 initial='0',
1297 label='Choose instrument category(s):')
1431 label='Choose instrument category(s):')
1298
1432
1299 self.fields['instruments'] = django.forms.MultipleChoiceField(widget = django.forms.SelectMultiple(),
1433 self.fields['instruments'] = django.forms.MultipleChoiceField(widget = django.forms.SelectMultiple(),
1300 choices=getInstrumentList(args, kwargs, madInstData, 'All instruments', local=False, includeYears=True),
1434 choices=getInstrumentList(args, kwargs, madInstData, 'All instruments', local=False, includeYears=True),
1301 initial='0', label='Choose instrument(s)')
1435 initial='0', label='Choose instrument(s)')
1302
1436
1303 self.fields['showDefault'] = django.forms.BooleanField(widget = django.forms.CheckboxInput(),
1437 self.fields['showDefault'] = django.forms.BooleanField(widget = django.forms.CheckboxInput(),
1304 label='Show only default files: ',
1438 label='Show only default files: ',
1305 initial=True)
1439 initial=True)
1306
1440
1307 # time selection
1441 # time selection
1308 self.fields['start_date'] = django.forms.SplitDateTimeField(input_date_formats=['%Y-%m-%d'], input_time_formats=['%H:%M:%S'],
1442 self.fields['start_date'] = django.forms.SplitDateTimeField(input_date_formats=['%Y-%m-%d'], input_time_formats=['%H:%M:%S'],
1309 label='Start date',
1443 label='Start date',
1310 help_text='Modify this field to select experiments after this start time.',
1444 help_text='Modify this field to select experiments after this start time.',
1311 initial=datetime.datetime(1950,1,1))
1445 initial=datetime.datetime(1950,1,1))
1312
1446
1313 self.fields['end_date'] = django.forms.SplitDateTimeField(input_date_formats=['%Y-%m-%d'], input_time_formats=['%H:%M:%S'],
1447 self.fields['end_date'] = django.forms.SplitDateTimeField(input_date_formats=['%Y-%m-%d'], input_time_formats=['%H:%M:%S'],
1314 label='End date',
1448 label='End date',
1315 help_text='Modify this field to select experiments before this end time.',
1449 help_text='Modify this field to select experiments before this end time.',
1316 initial=endDateTime)
1450 initial=endDateTime)
1317
1451
1318
1452
1319
1453
1320 # attributes to support javascript
1454 # attributes to support javascript
1321 local_categories = madInstData.getCategories(True)
1455 local_categories = madInstData.getCategories(True)
1322 global_categories = madInstData.getCategories(False)
1456 global_categories = madInstData.getCategories(False)
1323 local_category_ids = [cat[0] for cat in local_categories]
1457 local_category_ids = [cat[0] for cat in local_categories]
1324 self.categories = [] # each item a tuple of (category description, category id, global only js bool)
1458 self.categories = [] # each item a tuple of (category description, category id, global only js bool)
1325 self.instruments = [] # each item a tiple of (instrument desc, category id, kinst, local start year, local end year, global sy, global ey)
1459 self.instruments = [] # each item a tiple of (instrument desc, category id, kinst, local start year, local end year, global sy, global ey)
1326 for id, desc in global_categories:
1460 for id, desc in global_categories:
1327 if id in local_category_ids:
1461 if id in local_category_ids:
1328 localBool = 'false'
1462 localBool = 'false'
1329 else:
1463 else:
1330 localBool = 'true'
1464 localBool = 'true'
1331 self.categories.append((desc, id, localBool))
1465 self.categories.append((desc, id, localBool))
1332 for kinst, instDesc, siteId in madInstData.getInstruments(id):
1466 for kinst, instDesc, siteId in madInstData.getInstruments(id):
1333 if siteId == madDB.getSiteID():
1467 if siteId == madDB.getSiteID():
1334 localInst = True
1468 localInst = True
1335 else:
1469 else:
1336 localInst = False
1470 localInst = False
1337 yearList = madInstData.getInstrumentYears(kinst)
1471 yearList = madInstData.getInstrumentYears(kinst)
1338 if localInst:
1472 if localInst:
1339 self.instruments.append((instDesc, id, kinst, yearList[0], yearList[-1], yearList[0], yearList[-1]))
1473 self.instruments.append((instDesc, id, kinst, yearList[0], yearList[-1], yearList[0], yearList[-1]))
1340 else:
1474 else:
1341 self.instruments.append((instDesc, id, kinst, 0, 0, yearList[0], yearList[-1]))
1475 self.instruments.append((instDesc, id, kinst, 0, 0, yearList[0], yearList[-1]))
1342
1476
1343
1477
1344 def clean(self):
1478 def clean(self):
1345 """clean in the Django method to validate things in a form that require looking at multiple fields
1479 """clean in the Django method to validate things in a form that require looking at multiple fields
1346 """
1480 """
1347 # rule 1 - start_date < end_date
1481 # rule 1 - start_date < end_date
1348 if self.cleaned_data['start_date'] > self.cleaned_data['end_date']:
1482 if self.cleaned_data['start_date'] > self.cleaned_data['end_date']:
1349 raise django.forms.ValidationError('Error - start datetime greater than end datetime.')
1483 raise django.forms.ValidationError('Error - start datetime greater than end datetime.')
1350
1484
1351
1485
1352 class DownloadAsIsScriptForm(django.forms.Form):
1486 class DownloadAsIsScriptForm(django.forms.Form):
1353 """DownloadAsIsScriptForm is a Form class for the default fields in the download files as is script generator interface
1487 """DownloadAsIsScriptForm is a Form class for the default fields in the download files as is script generator interface
1354 """
1488 """
1355 def __init__(self, *args, **kwargs):
1489 def __init__(self, *args, **kwargs):
1356 super(DownloadAsIsScriptForm, self).__init__(*args, **kwargs)
1490 super(DownloadAsIsScriptForm, self).__init__(*args, **kwargs)
1357 madDB = madrigal.metadata.MadrigalDB()
1491 madDB = madrigal.metadata.MadrigalDB()
1358 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1492 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1359 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1493 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1360 madInstKindatObj = madrigal.metadata.MadrigalInstrumentKindats(madDB)
1494 madInstKindatObj = madrigal.metadata.MadrigalInstrumentKindats(madDB)
1361 now = datetime.datetime.now()
1495 now = datetime.datetime.now()
1362 endDateTime = datetime.datetime(now.year, 12, 31, 23, 59, 59)
1496 endDateTime = datetime.datetime(now.year, 12, 31, 23, 59, 59)
1363 kwargs['isGlobal'] = '0'
1497 kwargs['isGlobal'] = '0'
1364 formatChoices = (('hdf5', 'Hdf5'), ('ascii', 'Space-delimited ascii'), ('netCDF4', 'netCDF4'))
1498 formatChoices = (('hdf5', 'Hdf5'), ('ascii', 'Space-delimited ascii'), ('netCDF4', 'netCDF4'))
1365 languageChoices = (('python', 'python'), ('Matlab', 'Matlab'), ('IDL', 'IDL'))
1499 languageChoices = (('python', 'python'), ('Matlab', 'Matlab'), ('IDL', 'IDL'))
1366
1500
1367 categoriesSelection = '0'
1501 categoriesSelection = '0'
1368 self.fields['categories'] = django.forms.ChoiceField(widget=django.forms.Select(attrs={"onChange":"updateInstruments(this.form)"}),
1502 self.fields['categories'] = django.forms.ChoiceField(widget=django.forms.Select(attrs={"onChange":"updateInstruments(this.form)"}),
1369 choices=getCategoryList(args, kwargs, madInstData),
1503 choices=getCategoryList(args, kwargs, madInstData),
1370 initial='0',
1504 initial='0',
1371 label='Choose an instrument category if desired:')
1505 label='Choose an instrument category if desired:')
1372
1506
1373 self.fields['instruments'] = django.forms.ChoiceField(widget=django.forms.Select(attrs={"onChange":"updateKindats(this.form)"}),
1507 self.fields['instruments'] = django.forms.ChoiceField(widget=django.forms.Select(attrs={"onChange":"updateKindats(this.form)"}),
1374 choices=getInstrumentList(args, kwargs, madInstData, local=True, includeYears=True),
1508 choices=getInstrumentList(args, kwargs, madInstData, local=True, includeYears=True),
1375 initial='0', label='Choose one instrument')
1509 initial='0', label='Choose one instrument')
1376
1510
1377 # time selection
1511 # time selection
1378 self.fields['start_date'] = django.forms.DateField(input_formats=['%Y-%m-%d'],
1512 self.fields['start_date'] = django.forms.DateField(input_formats=['%Y-%m-%d'],
1379 label='Start date',
1513 label='Start date',
1380 help_text='Modify this field to select experiments after this start time.',
1514 help_text='Modify this field to select experiments after this start time.',
1381 initial=datetime.datetime(1950,1,1))
1515 initial=datetime.datetime(1950,1,1))
1382
1516
1383
1517
1384 self.fields['end_date'] = django.forms.DateField(input_formats=['%Y-%m-%d'],
1518 self.fields['end_date'] = django.forms.DateField(input_formats=['%Y-%m-%d'],
1385 label='End date',
1519 label='End date',
1386 help_text='Modify this field to select experiments before this end time.',
1520 help_text='Modify this field to select experiments before this end time.',
1387 initial=endDateTime)
1521 initial=endDateTime)
1388
1522
1389 self.fields['format_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(),
1523 self.fields['format_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(),
1390 choices=formatChoices,
1524 choices=formatChoices,
1391 initial=formatChoices[0][0],
1525 initial=formatChoices[0][0],
1392 label='File format to download:')
1526 label='File format to download:')
1393
1527
1394 self.fields['language_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(),
1528 self.fields['language_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(),
1395 choices=languageChoices,
1529 choices=languageChoices,
1396 initial=languageChoices[0][0],
1530 initial=languageChoices[0][0],
1397 label='Choose scripting language:')
1531 label='Choose scripting language:')
1398
1532
1399 choices=(('0', 'Select an instrument first to see list'),)
1533 choices=(('0', 'Select an instrument first to see list'),)
1400 if len(args) > 0:
1534 if len(args) > 0:
1401 if 'kindat_select' in args[0]:
1535 if 'kindat_select' in args[0]:
1402 choices = [(kindat, kindat) for kindat in args[0].getlist('kindat_select')]
1536 choices = [(kindat, kindat) for kindat in args[0].getlist('kindat_select')]
1403 self.fields['kindat_select'] = django.forms.MultipleChoiceField(choices=choices,
1537 self.fields['kindat_select'] = django.forms.MultipleChoiceField(choices=choices,
1404 initial='0',
1538 initial='0',
1405 label='Choose one or more kinds of data:',
1539 label='Choose one or more kinds of data:',
1406 required=False)
1540 required=False)
1407 self.fields['kindat_select'].widget.attrs['style']="max-width:100%;"
1541 self.fields['kindat_select'].widget.attrs['style']="max-width:100%;"
1408
1542
1409 self.fields['expName'] = django.forms.CharField(max_length=256, required=False)
1543 self.fields['expName'] = django.forms.CharField(max_length=256, required=False)
1410
1544
1411 self.fields['fileDesc'] = django.forms.CharField(max_length=256, required=False)
1545 self.fields['fileDesc'] = django.forms.CharField(max_length=256, required=False)
1412
1546
1413
1547
1414
1548
1415 # attributes to support javascript
1549 # attributes to support javascript
1416 local_categories = madInstData.getCategories(True)
1550 local_categories = madInstData.getCategories(True)
1417 local_category_ids = [cat[0] for cat in local_categories]
1551 local_category_ids = [cat[0] for cat in local_categories]
1418 self.categories = [] # each item a tuple of (category description, category id, global only js bool)
1552 self.categories = [] # each item a tuple of (category description, category id, global only js bool)
1419 self.instruments = [] # each item a tiple of (instrument desc, category id, kinst, local start year, local end year)
1553 self.instruments = [] # each item a tiple of (instrument desc, category id, kinst, local start year, local end year)
1420 self.kindats = [] # each item is a tuple of (kindat, kindatDesc, kinst)
1554 self.kindats = [] # each item is a tuple of (kindat, kindatDesc, kinst)
1421 for id, desc in local_categories:
1555 for id, desc in local_categories:
1422 self.categories.append((desc, id))
1556 self.categories.append((desc, id))
1423 for kinst, instDesc, siteId in madInstData.getInstruments(id):
1557 for kinst, instDesc, siteId in madInstData.getInstruments(id):
1424 if siteId != madDB.getSiteID():
1558 if siteId != madDB.getSiteID():
1425 continue
1559 continue
1426 yearList = madInstData.getInstrumentYears(kinst)
1560 yearList = madInstData.getInstrumentYears(kinst)
1427 self.instruments.append((instDesc, id, kinst, yearList[0], yearList[-1]))
1561 self.instruments.append((instDesc, id, kinst, yearList[0], yearList[-1]))
1428 kindatList = madInstKindatObj.getKindatListForInstruments([kinst])
1562 kindatList = madInstKindatObj.getKindatListForInstruments([kinst])
1429 for kindat in kindatList:
1563 for kindat in kindatList:
1430 self.kindats.append((kindat, madKindatObj.getKindatDescription(kindat, kinst),
1564 self.kindats.append((kindat, madKindatObj.getKindatDescription(kindat, kinst),
1431 kinst))
1565 kinst))
1432
1566
1433
1567
1434 def clean(self):
1568 def clean(self):
1435 """clean is the Django method to validate things in a form that require looking at multiple fields
1569 """clean is the Django method to validate things in a form that require looking at multiple fields
1436 """
1570 """
1437 # rule 1 - start_date < end_date
1571 # rule 1 - start_date < end_date
1438 if self.cleaned_data['start_date'] > self.cleaned_data['end_date']:
1572 if self.cleaned_data['start_date'] > self.cleaned_data['end_date']:
1439 raise django.forms.ValidationError('Error - start datetime greater than end datetime.')
1573 raise django.forms.ValidationError('Error - start datetime greater than end datetime.')
1440
1574
1441
1575
1442 class DownloadAdvancedScriptForm(django.forms.Form):
1576 class DownloadAdvancedScriptForm(django.forms.Form):
1443 """DownloadAdvancedScriptForm is a Form class for the default fields in the download advanced script generator interface
1577 """DownloadAdvancedScriptForm is a Form class for the default fields in the download advanced script generator interface
1444 """
1578 """
1445 def __init__(self, *args, **kwargs):
1579 def __init__(self, *args, **kwargs):
1446 super(DownloadAdvancedScriptForm, self).__init__(*args, **kwargs)
1580 super(DownloadAdvancedScriptForm, self).__init__(*args, **kwargs)
1447 madDB = madrigal.metadata.MadrigalDB()
1581 madDB = madrigal.metadata.MadrigalDB()
1448 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1582 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1449 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1583 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1450 madInstKindatObj = madrigal.metadata.MadrigalInstrumentKindats(madDB)
1584 madInstKindatObj = madrigal.metadata.MadrigalInstrumentKindats(madDB)
1451 now = datetime.datetime.now()
1585 now = datetime.datetime.now()
1452 endDateTime = datetime.datetime(now.year, 12, 31, 23, 59, 59)
1586 endDateTime = datetime.datetime(now.year, 12, 31, 23, 59, 59)
1453 kwargs['isGlobal'] = '0'
1587 kwargs['isGlobal'] = '0'
1454 formatChoices = (('hdf5', 'Hdf5'), ('ascii', 'Space-delimited ascii'), ('netCDF4', 'netCDF4'))
1588 formatChoices = (('hdf5', 'Hdf5'), ('ascii', 'Space-delimited ascii'), ('netCDF4', 'netCDF4'))
1455 directoryChoices = (('Directory', 'Directory'), ('File', 'File'))
1589 directoryChoices = (('Directory', 'Directory'), ('File', 'File'))
1456 languageChoices = (('python', 'python'), ('Matlab', 'Matlab'), ('IDL', 'IDL'))
1590 languageChoices = (('python', 'python'), ('Matlab', 'Matlab'), ('IDL', 'IDL'))
1457
1591
1458 categoriesSelection = '0'
1592 categoriesSelection = '0'
1459 self.fields['categories'] = django.forms.ChoiceField(widget=django.forms.Select(attrs={"onChange":"updateInstruments(this.form)"}),
1593 self.fields['categories'] = django.forms.ChoiceField(widget=django.forms.Select(attrs={"onChange":"updateInstruments(this.form)"}),
1460 choices=getCategoryList(args, kwargs, madInstData),
1594 choices=getCategoryList(args, kwargs, madInstData),
1461 initial='0',
1595 initial='0',
1462 label='Choose an instrument category if desired:')
1596 label='Choose an instrument category if desired:')
1463
1597
1464 self.fields['instruments'] = django.forms.ChoiceField(widget=django.forms.Select(attrs={"onChange":"updateParmsKindats(this.form)"}),
1598 self.fields['instruments'] = django.forms.ChoiceField(widget=django.forms.Select(attrs={"onChange":"updateParmsKindats(this.form)"}),
1465 choices=getInstrumentList(args, kwargs, madInstData, local=True, includeYears=True),
1599 choices=getInstrumentList(args, kwargs, madInstData, local=True, includeYears=True),
1466 initial='0', label='Choose one instrument')
1600 initial='0', label='Choose one instrument')
1467
1601
1468 # time selection
1602 # time selection
1469 self.fields['start_date'] = django.forms.DateField(input_formats=['%Y-%m-%d'],
1603 self.fields['start_date'] = django.forms.DateField(input_formats=['%Y-%m-%d'],
1470 label='Start date',
1604 label='Start date',
1471 help_text='Modify this field to select experiments after this start time.',
1605 help_text='Modify this field to select experiments after this start time.',
1472 initial=datetime.datetime(1950,1,1))
1606 initial=datetime.datetime(1950,1,1))
1473
1607
1474 self.fields['end_date'] = django.forms.DateField(input_formats=['%Y-%m-%d'],
1608 self.fields['end_date'] = django.forms.DateField(input_formats=['%Y-%m-%d'],
1475 label='End date',
1609 label='End date',
1476 help_text='Modify this field to select experiments before this end time.',
1610 help_text='Modify this field to select experiments before this end time.',
1477 initial=endDateTime)
1611 initial=endDateTime)
1478
1612
1479 self.fields['format_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(attrs={"onChange":'changeFormat(this)'}),
1613 self.fields['format_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(attrs={"onChange":'changeFormat(this)'}),
1480 choices=formatChoices,
1614 choices=formatChoices,
1481 initial=formatChoices[0][0],
1615 initial=formatChoices[0][0],
1482 label='File format to download:')
1616 label='File format to download:')
1483
1617
1484 self.fields['directory_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(),
1618 self.fields['directory_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(),
1485 choices=directoryChoices,
1619 choices=directoryChoices,
1486 initial=directoryChoices[0][0],
1620 initial=directoryChoices[0][0],
1487 label='If ascii, download result to:')
1621 label='If ascii, download result to:')
1488
1622
1489 self.fields['language_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(),
1623 self.fields['language_select'] = django.forms.ChoiceField(widget = HorizontalRadioSelect(),
1490 choices=languageChoices,
1624 choices=languageChoices,
1491 initial=languageChoices[0][0],
1625 initial=languageChoices[0][0],
1492 label='Choose scripting language:')
1626 label='Choose scripting language:')
1493
1627
1494 choices=(('0', 'Select an instrument first to see list'),)
1628 choices=(('0', 'Select an instrument first to see list'),)
1495 if len(args) > 0:
1629 if len(args) > 0:
1496 if 'kindat_select' in args[0]:
1630 if 'kindat_select' in args[0]:
1497 choices = [(kindat, kindat) for kindat in args[0].getlist('kindat_select')]
1631 choices = [(kindat, kindat) for kindat in args[0].getlist('kindat_select')]
1498 self.fields['kindat_select'] = django.forms.MultipleChoiceField(choices=choices,
1632 self.fields['kindat_select'] = django.forms.MultipleChoiceField(choices=choices,
1499 initial='0',
1633 initial='0',
1500 label='Choose one or more kinds of data:',
1634 label='Choose one or more kinds of data:',
1501 required=False)
1635 required=False)
1502 self.fields['kindat_select'].widget.attrs['style']="max-width:100%;"
1636 self.fields['kindat_select'].widget.attrs['style']="max-width:100%;"
1503
1637
1504 self.fields['expName'] = django.forms.CharField(max_length=256, required=False)
1638 self.fields['expName'] = django.forms.CharField(max_length=256, required=False)
1505
1639
1506 self.fields['fileDesc'] = django.forms.CharField(max_length=256, required=False)
1640 self.fields['fileDesc'] = django.forms.CharField(max_length=256, required=False)
1507
1641
1508 self.fields['seasonalStartDay'] = django.forms.IntegerField(min_value=1, max_value=31, initial=1)
1642 self.fields['seasonalStartDay'] = django.forms.IntegerField(min_value=1, max_value=31, initial=1)
1509 self.fields['seasonalStartMonth'] = django.forms.IntegerField(min_value=1, max_value=12, initial=1)
1643 self.fields['seasonalStartMonth'] = django.forms.IntegerField(min_value=1, max_value=12, initial=1)
1510 self.fields['seasonalEndDay'] = django.forms.IntegerField(min_value=1, max_value=31, initial=31)
1644 self.fields['seasonalEndDay'] = django.forms.IntegerField(min_value=1, max_value=31, initial=31)
1511 self.fields['seasonalEndMonth'] = django.forms.IntegerField(min_value=1, max_value=12, initial=12)
1645 self.fields['seasonalEndMonth'] = django.forms.IntegerField(min_value=1, max_value=12, initial=12)
1512
1646
1513
1647
1514 # attributes to support javascript
1648 # attributes to support javascript
1515 local_categories = madInstData.getCategories(True)
1649 local_categories = madInstData.getCategories(True)
1516 local_category_ids = [cat[0] for cat in local_categories]
1650 local_category_ids = [cat[0] for cat in local_categories]
1517 self.categories = [] # each item a tuple of (category description, category id, global only js bool)
1651 self.categories = [] # each item a tuple of (category description, category id, global only js bool)
1518 self.instruments = [] # each item a tiple of (instrument desc, category id, kinst, local start year, local end year)
1652 self.instruments = [] # each item a tiple of (instrument desc, category id, kinst, local start year, local end year)
1519 self.kindats = [] # each item is a tuple of (kindat, kindatDesc, kinst)
1653 self.kindats = [] # each item is a tuple of (kindat, kindatDesc, kinst)
1520 for id, desc in local_categories:
1654 for id, desc in local_categories:
1521 self.categories.append((desc, id))
1655 self.categories.append((desc, id))
1522 for kinst, instDesc, siteId in madInstData.getInstruments(id):
1656 for kinst, instDesc, siteId in madInstData.getInstruments(id):
1523 if siteId != madDB.getSiteID():
1657 if siteId != madDB.getSiteID():
1524 continue
1658 continue
1525 yearList = madInstData.getInstrumentYears(kinst)
1659 yearList = madInstData.getInstrumentYears(kinst)
1526 self.instruments.append((instDesc, id, kinst, yearList[0], yearList[-1]))
1660 self.instruments.append((instDesc, id, kinst, yearList[0], yearList[-1]))
1527 kindatList = madInstKindatObj.getKindatListForInstruments([kinst])
1661 kindatList = madInstKindatObj.getKindatListForInstruments([kinst])
1528 for kindat in kindatList:
1662 for kindat in kindatList:
1529 self.kindats.append((kindat, madKindatObj.getKindatDescription(kindat, kinst),
1663 self.kindats.append((kindat, madKindatObj.getKindatDescription(kindat, kinst),
1530 kinst))
1664 kinst))
1531
1665
1532
1666
1533 def clean(self):
1667 def clean(self):
1534 """clean is the Django method to validate things in a form that require looking at multiple fields
1668 """clean is the Django method to validate things in a form that require looking at multiple fields
1535 """
1669 """
1536 # rule 1 - start_date < end_date
1670 # rule 1 - start_date < end_date
1537 if self.cleaned_data['start_date'] > self.cleaned_data['end_date']:
1671 if self.cleaned_data['start_date'] > self.cleaned_data['end_date']:
1538 raise django.forms.ValidationError('Error - start datetime greater than end datetime.')
1672 raise django.forms.ValidationError('Error - start datetime greater than end datetime.')
1539
1673
1540 # rule 2 - seasonal start must be before seasonal end
1674 # rule 2 - seasonal start must be before seasonal end
1541 if ((self.cleaned_data['seasonalStartDay'] + 31*self.cleaned_data['seasonalStartMonth']) > \
1675 if ((self.cleaned_data['seasonalStartDay'] + 31*self.cleaned_data['seasonalStartMonth']) > \
1542 (self.cleaned_data['seasonalEndDay'] + 31*self.cleaned_data['seasonalEndMonth'])):
1676 (self.cleaned_data['seasonalEndDay'] + 31*self.cleaned_data['seasonalEndMonth'])):
1543 raise django.forms.ValidationError('Error - seasonal start after seasonal end.')
1677 raise django.forms.ValidationError('Error - seasonal start after seasonal end.')
1544
1678
1545
1679
1546
1680
1547 class AdvScriptParmsForm(django.forms.Form):
1681 class AdvScriptParmsForm(django.forms.Form):
1548 """AdvScriptParmsForm is the form for the parameters
1682 """AdvScriptParmsForm is the form for the parameters
1549 """
1683 """
1550 def __init__(self, *args, **kwargs):
1684 def __init__(self, *args, **kwargs):
1551
1685
1552 kinst = int(getSelection('instruments', args, kwargs))
1686 kinst = int(getSelection('instruments', args, kwargs))
1553 if kinst == 0:
1687 if kinst == 0:
1554 raise ValueError('kinst should never be zero')
1688 raise ValueError('kinst should never be zero')
1555 madDB = madrigal.metadata.MadrigalDB()
1689 madDB = madrigal.metadata.MadrigalDB()
1556 madParmObj = madrigal.data.MadrigalParameters(madDB)
1690 madParmObj = madrigal.data.MadrigalParameters(madDB)
1557 parmList = madParmObj.getParametersForInstruments([kinst])
1691 parmList = madParmObj.getParametersForInstruments([kinst])
1558 self.parmList = []
1692 self.parmList = []
1559 for parm in parmList:
1693 for parm in parmList:
1560 self.parmList.append((parm, madParmObj.getSimpleParmDescription(parm)))
1694 self.parmList.append((parm, madParmObj.getSimpleParmDescription(parm)))
1561
1695
1562 madCatObj = madrigal.metadata.MadrigalParmCategory(madDB)
1696 madCatObj = madrigal.metadata.MadrigalParmCategory(madDB)
1563
1697
1564 catList = madCatObj.getCategoryList()
1698 catList = madCatObj.getCategoryList()
1565 catDict = madParmObj.getCategoryDict(parmList)
1699 catDict = madParmObj.getCategoryDict(parmList)
1566
1700
1567 choices = []
1701 choices = []
1568 isDerivedDict = {}
1702 isDerivedDict = {}
1569 parmDescDict = {}
1703 parmDescDict = {}
1570 for catDesc, catID in catList:
1704 for catDesc, catID in catList:
1571 if catID not in list(catDict.keys()):
1705 if catID not in list(catDict.keys()):
1572 continue
1706 continue
1573 theseParms = []
1707 theseParms = []
1574 for parm in catDict[catID][1]:
1708 for parm in catDict[catID][1]:
1575 theseParms.append((parm, parm))
1709 theseParms.append((parm, parm))
1576 isDerivedDict[parm] = False
1710 isDerivedDict[parm] = False
1577 parmDescDict[parm] = madParmObj.getParmDescription(parm)
1711 parmDescDict[parm] = madParmObj.getParmDescription(parm)
1578 choices.append((catDesc, theseParms))
1712 choices.append((catDesc, theseParms))
1579
1713
1580 super(AdvScriptParmsForm, self).__init__(*args, **kwargs)
1714 super(AdvScriptParmsForm, self).__init__(*args, **kwargs)
1581
1715
1582 self.fields['parameters'] = IsprintChoiceField(choices=choices,
1716 self.fields['parameters'] = IsprintChoiceField(choices=choices,
1583 initial=['YEAR', 'MIN'],
1717 initial=['YEAR', 'MIN'],
1584 required=False,
1718 required=False,
1585 isDerivedDict=isDerivedDict,
1719 isDerivedDict=isDerivedDict,
1586 parmDescDict=parmDescDict,
1720 parmDescDict=parmDescDict,
1587 separateProlog=False,
1721 separateProlog=False,
1588 label = "")
1722 label = "")
1589
1723
1590
1724
1591 class AdvScriptParmsFiltersForm(django.forms.Form):
1725 class AdvScriptParmsFiltersForm(django.forms.Form):
1592 """AdvScriptParmsFiltersForm is the form for the parameter filters in the scrip generator
1726 """AdvScriptParmsFiltersForm is the form for the parameter filters in the scrip generator
1593 """
1727 """
1594 def __init__(self, *args, **kwargs):
1728 def __init__(self, *args, **kwargs):
1595
1729
1596 kinst = int(getSelection('instruments', args, kwargs))
1730 kinst = int(getSelection('instruments', args, kwargs))
1597 if kinst == 0:
1731 if kinst == 0:
1598 raise ValueError('kinst should never be zero')
1732 raise ValueError('kinst should never be zero')
1599 madDB = madrigal.metadata.MadrigalDB()
1733 madDB = madrigal.metadata.MadrigalDB()
1600 madParmObj = madrigal.data.MadrigalParameters(madDB)
1734 madParmObj = madrigal.data.MadrigalParameters(madDB)
1601 parmList = madParmObj.getParametersForInstruments([kinst])
1735 parmList = madParmObj.getParametersForInstruments([kinst])
1602 self.parmList = []
1736 self.parmList = []
1603 for parm in parmList:
1737 for parm in parmList:
1604 self.parmList.append((parm, madParmObj.getSimpleParmDescription(parm)))
1738 self.parmList.append((parm, madParmObj.getSimpleParmDescription(parm)))
1605
1739
1606 super(AdvScriptParmsFiltersForm, self).__init__(*args, **kwargs)
1740 super(AdvScriptParmsFiltersForm, self).__init__(*args, **kwargs)
1607
1741
1608 choices = [(parm, parm) for parm in parmList]
1742 choices = [(parm, parm) for parm in parmList]
1609 choices_with_null = [('None', 'None')] + choices
1743 choices_with_null = [('None', 'None')] + choices
1610
1744
1611 self.fields['parm_1'] = django.forms.ChoiceField(required=False,
1745 self.fields['parm_1'] = django.forms.ChoiceField(required=False,
1612 choices=choices_with_null)
1746 choices=choices_with_null)
1613 self.fields['parm_1_lower'] = django.forms.CharField(required=False, initial='')
1747 self.fields['parm_1_lower'] = django.forms.CharField(required=False, initial='')
1614 self.fields['parm_1_upper'] = django.forms.CharField(required=False, initial='')
1748 self.fields['parm_1_upper'] = django.forms.CharField(required=False, initial='')
1615
1749
1616 self.fields['parm_2'] = django.forms.ChoiceField(required=False,
1750 self.fields['parm_2'] = django.forms.ChoiceField(required=False,
1617 choices=choices_with_null)
1751 choices=choices_with_null)
1618 self.fields['parm_2_lower'] = django.forms.CharField(required=False, initial='')
1752 self.fields['parm_2_lower'] = django.forms.CharField(required=False, initial='')
1619 self.fields['parm_2_upper'] = django.forms.CharField(required=False, initial='')
1753 self.fields['parm_2_upper'] = django.forms.CharField(required=False, initial='')
1620
1754
1621 self.fields['parm_3'] = django.forms.ChoiceField(required=False,
1755 self.fields['parm_3'] = django.forms.ChoiceField(required=False,
1622 choices=choices_with_null)
1756 choices=choices_with_null)
1623 self.fields['parm_3_lower'] = django.forms.CharField(required=False, initial='')
1757 self.fields['parm_3_lower'] = django.forms.CharField(required=False, initial='')
1624 self.fields['parm_3_upper'] = django.forms.CharField(required=False, initial='')
1758 self.fields['parm_3_upper'] = django.forms.CharField(required=False, initial='')
1625
1759
1626
1760
1627
1761
1628 class MadCalculatorForm(django.forms.Form):
1762 class MadCalculatorForm(django.forms.Form):
1629 """MadCalculatorForm is the form for the madCalculator page
1763 """MadCalculatorForm is the form for the madCalculator page
1630 """
1764 """
1631 def __init__(self, *args, **kwargs):
1765 def __init__(self, *args, **kwargs):
1632 """
1766 """
1633 """
1767 """
1634 madDB = madrigal.metadata.MadrigalDB()
1768 madDB = madrigal.metadata.MadrigalDB()
1635 madParmObj = madrigal.data.MadrigalParameters(madDB)
1769 madParmObj = madrigal.data.MadrigalParameters(madDB)
1636 super(MadCalculatorForm, self).__init__(*args, **kwargs)
1770 super(MadCalculatorForm, self).__init__(*args, **kwargs)
1637 fullDerivedParmList = madrigal.derivation.getDerivableParms(['gdalt', 'gdlat', 'glon'])
1771 fullDerivedParmList = madrigal.derivation.getDerivableParms(['gdalt', 'gdlat', 'glon'])
1638
1772
1639 # removed unwanted time and prolog parameters
1773 # removed unwanted time and prolog parameters
1640 rejectedCats = ('Time Related Parameter', 'Prolog Parameters', 'Radar Instrument Operation Parameter',
1774 rejectedCats = ('Time Related Parameter', 'Prolog Parameters', 'Radar Instrument Operation Parameter',
1641 'Madrigal Hdf5 Prolog Parameters')
1775 'Madrigal Hdf5 Prolog Parameters')
1642 # define time parameters that do make sense to calculate
1776 # define time parameters that do make sense to calculate
1643 neededTimeParms = ('APLT', 'CONJ_SUNRISE_H', 'CONJ_SUNSET_H',
1777 neededTimeParms = ('APLT', 'CONJ_SUNRISE_H', 'CONJ_SUNSET_H',
1644 'SUNRISE_H', 'SUNSET_H', 'MLT')
1778 'SUNRISE_H', 'SUNSET_H', 'MLT')
1645
1779
1646 # skip parms related to inst location
1780 # skip parms related to inst location
1647 instLocationParms = ('AZM','ELM','GALTR','GDLONR','GDLATR','RANGE', 'ASPECT',
1781 instLocationParms = ('AZM','ELM','GALTR','GDLONR','GDLATR','RANGE', 'ASPECT',
1648 'GDALT', 'GDLAT', 'GLON', 'CXR', 'CYR', 'CZR')
1782 'GDALT', 'GDLAT', 'GLON', 'CXR', 'CYR', 'CZR')
1649
1783
1650 madCatObj = madrigal.metadata.MadrigalParmCategory(madDB)
1784 madCatObj = madrigal.metadata.MadrigalParmCategory(madDB)
1651
1785
1652 catList = madCatObj.getCategoryList()
1786 catList = madCatObj.getCategoryList()
1653 catDict = madParmObj.getCategoryDict(fullDerivedParmList)
1787 catDict = madParmObj.getCategoryDict(fullDerivedParmList)
1654 choices = []
1788 choices = []
1655 isDerivedDict = {}
1789 isDerivedDict = {}
1656 self.parmDescDict = {}
1790 self.parmDescDict = {}
1657 for catDesc, catID in catList:
1791 for catDesc, catID in catList:
1658 if catDesc in rejectedCats[1:]:
1792 if catDesc in rejectedCats[1:]:
1659 continue
1793 continue
1660 if catID not in list(catDict.keys()):
1794 if catID not in list(catDict.keys()):
1661 continue
1795 continue
1662 theseParms = []
1796 theseParms = []
1663 for parm in catDict[catID][1]:
1797 for parm in catDict[catID][1]:
1664 if parm in instLocationParms:
1798 if parm in instLocationParms:
1665 continue
1799 continue
1666 if catDesc in rejectedCats and parm not in neededTimeParms:
1800 if catDesc in rejectedCats and parm not in neededTimeParms:
1667 continue
1801 continue
1668 if not parm in fullDerivedParmList:
1802 if not parm in fullDerivedParmList:
1669 continue
1803 continue
1670 theseParms.append((parm, parm))
1804 theseParms.append((parm, parm))
1671 isDerivedDict[parm] = True
1805 isDerivedDict[parm] = True
1672 self.parmDescDict[parm] = madParmObj.getParmDescription(parm)
1806 self.parmDescDict[parm] = madParmObj.getParmDescription(parm)
1673 choices.append((catDesc, theseParms))
1807 choices.append((catDesc, theseParms))
1674
1808
1675
1809
1676
1810
1677 # form fields
1811 # form fields
1678 self.fields['min_latitude'] = django.forms.FloatField(initial=-90.0, min_value=-90.0,
1812 self.fields['min_latitude'] = django.forms.FloatField(initial=-90.0, min_value=-90.0,
1679 max_value=90.0)
1813 max_value=90.0)
1680 self.fields['max_latitude'] = django.forms.FloatField(initial=90.0, min_value=-90.0,
1814 self.fields['max_latitude'] = django.forms.FloatField(initial=90.0, min_value=-90.0,
1681 max_value=90.0)
1815 max_value=90.0)
1682 self.fields['delta_latitude'] = django.forms.FloatField(initial=45, min_value=1.0E-6)
1816 self.fields['delta_latitude'] = django.forms.FloatField(initial=45, min_value=1.0E-6)
1683
1817
1684 self.fields['min_longitude'] = django.forms.FloatField(initial=-180.0, min_value=-180.0,
1818 self.fields['min_longitude'] = django.forms.FloatField(initial=-180.0, min_value=-180.0,
1685 max_value=180.0)
1819 max_value=180.0)
1686 self.fields['max_longitude'] = django.forms.FloatField(initial=180.0, min_value=-180.0,
1820 self.fields['max_longitude'] = django.forms.FloatField(initial=180.0, min_value=-180.0,
1687 max_value=180.0)
1821 max_value=180.0)
1688 self.fields['delta_longitude'] = django.forms.FloatField(initial=90, min_value=1.0E-6)
1822 self.fields['delta_longitude'] = django.forms.FloatField(initial=90, min_value=1.0E-6)
1689
1823
1690 self.fields['min_altitude'] = django.forms.FloatField(initial=0.0, min_value=0.0)
1824 self.fields['min_altitude'] = django.forms.FloatField(initial=0.0, min_value=0.0)
1691 self.fields['max_altitude'] = django.forms.FloatField(initial=600.0, min_value=0.0)
1825 self.fields['max_altitude'] = django.forms.FloatField(initial=600.0, min_value=0.0)
1692 self.fields['delta_altitude'] = django.forms.FloatField(initial=200, min_value=1.0E-6)
1826 self.fields['delta_altitude'] = django.forms.FloatField(initial=200, min_value=1.0E-6)
1693
1827
1694 # time selection
1828 # time selection
1695 now = datetime.datetime.utcnow()
1829 now = datetime.datetime.utcnow()
1696 self.fields['datetime'] = django.forms.SplitDateTimeField(input_date_formats=['%Y-%m-%d'], input_time_formats=['%H:%M:%S'],
1830 self.fields['datetime'] = django.forms.SplitDateTimeField(input_date_formats=['%Y-%m-%d'], input_time_formats=['%H:%M:%S'],
1697 label='Select UT datetime',
1831 label='Select UT datetime',
1698 help_text='Select the UT time at which to run this calcuation',
1832 help_text='Select the UT time at which to run this calcuation',
1699 initial=datetime.datetime(now.year,1,1))
1833 initial=datetime.datetime(now.year,1,1))
1700
1834
1701 self.fields['parameters'] = IsprintChoiceField(choices=choices,
1835 self.fields['parameters'] = IsprintChoiceField(choices=choices,
1702 required=False,
1836 required=False,
1703 isDerivedDict=isDerivedDict,
1837 isDerivedDict=isDerivedDict,
1704 parmDescDict=self.parmDescDict,
1838 parmDescDict=self.parmDescDict,
1705 separateProlog=False,
1839 separateProlog=False,
1706 label = "")
1840 label = "")
1707
1841
1708
1842
1709 def clean(self):
1843 def clean(self):
1710 """clean is the Django method to validate things in a form that require looking at multiple fields
1844 """clean is the Django method to validate things in a form that require looking at multiple fields
1711 """
1845 """
1712 max_len = 1.0E5
1846 max_len = 1.0E5
1713 try:
1847 try:
1714 a1 = numpy.arange(self.cleaned_data['min_latitude'], self.cleaned_data['max_latitude'], self.cleaned_data['delta_latitude'])
1848 a1 = numpy.arange(self.cleaned_data['min_latitude'], self.cleaned_data['max_latitude'], self.cleaned_data['delta_latitude'])
1715 if len(a1) > max_len:
1849 if len(a1) > max_len:
1716 raise django.forms.ValidationError('Too many latitudes: %i.' % (len(a1)))
1850 raise django.forms.ValidationError('Too many latitudes: %i.' % (len(a1)))
1717 except ZeroDivisionError:
1851 except ZeroDivisionError:
1718 raise django.forms.ValidationError('Infinite latitudes')
1852 raise django.forms.ValidationError('Infinite latitudes')
1719
1853
1720 try:
1854 try:
1721 a2 = numpy.arange(self.cleaned_data['min_longitude'], self.cleaned_data['max_longitude'], self.cleaned_data['delta_longitude'])
1855 a2 = numpy.arange(self.cleaned_data['min_longitude'], self.cleaned_data['max_longitude'], self.cleaned_data['delta_longitude'])
1722 if len(a1) > max_len:
1856 if len(a1) > max_len:
1723 raise django.forms.ValidationError('Too many longitudes: %i.' % (len(a1)))
1857 raise django.forms.ValidationError('Too many longitudes: %i.' % (len(a1)))
1724 except ZeroDivisionError:
1858 except ZeroDivisionError:
1725 raise django.forms.ValidationError('Infinite longitudes')
1859 raise django.forms.ValidationError('Infinite longitudes')
1726
1860
1727 try:
1861 try:
1728 a3 = numpy.arange(self.cleaned_data['min_altitude'], self.cleaned_data['max_altitude'], self.cleaned_data['delta_altitude'])
1862 a3 = numpy.arange(self.cleaned_data['min_altitude'], self.cleaned_data['max_altitude'], self.cleaned_data['delta_altitude'])
1729 if len(a1) > max_len:
1863 if len(a1) > max_len:
1730 raise django.forms.ValidationError('Too many altitudes: %i.' % (len(a1)))
1864 raise django.forms.ValidationError('Too many altitudes: %i.' % (len(a1)))
1731 except ZeroDivisionError:
1865 except ZeroDivisionError:
1732 raise django.forms.ValidationError('Infinite altitudes')
1866 raise django.forms.ValidationError('Infinite altitudes')
1733
1867
1734 total = len(a1) * len(a2) * len(a3)
1868 total = len(a1) * len(a2) * len(a3)
1735 if total > max_len:
1869 if total > max_len:
1736 raise django.forms.ValidationError('Too many calculations: %i' % (total))
1870 raise django.forms.ValidationError('Too many calculations: %i' % (total))
1737
1871
1738
1872
1739
1873
1740 class GetMetadataForm(django.forms.Form):
1874 class GetMetadataForm(django.forms.Form):
1741 """GetMetadataForm is the form for the getMetadata page
1875 """GetMetadataForm is the form for the getMetadata page
1742 """
1876 """
1743 def __init__(self, *args, **kwargs):
1877 def __init__(self, *args, **kwargs):
1744 """
1878 """
1745 """
1879 """
1746 super(GetMetadataForm, self).__init__(*args, **kwargs)
1880 super(GetMetadataForm, self).__init__(*args, **kwargs)
1747
1881
1748 fileTypeChoices = (("0", "Experiment Table"),
1882 fileTypeChoices = (("0", "Experiment Table"),
1749 ("1", "File Table"),
1883 ("1", "File Table"),
1750 ("3", "Instrument Table"),
1884 ("3", "Instrument Table"),
1751 ("4", "Parameter Table"),
1885 ("4", "Parameter Table"),
1752 ("5", "Site Table"),
1886 ("5", "Site Table"),
1753 ("6", "Type Table"),
1887 ("6", "Type Table"),
1754 ("7", "Instrument Kindat Table"),
1888 ("7", "Instrument Kindat Table"),
1755 ("8", "Instrument Parameter Table"),
1889 ("8", "Instrument Parameter Table"),
1756 ("9", "Madrigal categories table"),
1890 ("9", "Madrigal categories table"),
1757 ("10", "Instrument categories table"),)
1891 ("10", "Instrument categories table"),)
1758
1892
1759 self.fields['fileType'] = django.forms.ChoiceField(widget = django.forms.RadioSelect,
1893 self.fields['fileType'] = django.forms.ChoiceField(widget = django.forms.RadioSelect,
1760 choices=fileTypeChoices,
1894 choices=fileTypeChoices,
1761 initial="0",
1895 initial="0",
1762 label="Choose the metadata file type to download")
1896 label="Choose the metadata file type to download")
1763
1897
1764
1898
1765 class LookerSelectForm(django.forms.Form):
1899 class LookerSelectForm(django.forms.Form):
1766 """LookerSelectForm is the form for the looker_form page
1900 """LookerSelectForm is the form for the looker_form page
1767 """
1901 """
1768 def __init__(self, *args, **kwargs):
1902 def __init__(self, *args, **kwargs):
1769 """
1903 """
1770 """
1904 """
1771 super(LookerSelectForm, self).__init__(*args, **kwargs)
1905 super(LookerSelectForm, self).__init__(*args, **kwargs)
1772
1906
1773 lookerOptionChoices = (("1", "Geodetic latitude, longitude and altitude of the points"),
1907 lookerOptionChoices = (("1", "Geodetic latitude, longitude and altitude of the points"),
1774 ("2", "Apex latitude, longitude and altitude of the points"),
1908 ("2", "Apex latitude, longitude and altitude of the points"),
1775 ("3", "Geodetic latitude, longitude and altitude of the points"),
1909 ("3", "Geodetic latitude, longitude and altitude of the points"),
1776 ("4", "Azimuth, elevation and range of the points from a specified instrument (output includes aspect angle)"),
1910 ("4", "Azimuth, elevation and range of the points from a specified instrument (output includes aspect angle)"),
1777 ("5", "Azimuth, elevation, range from specified instrument"),
1911 ("5", "Azimuth, elevation, range from specified instrument"),
1778 ("6", "Geodetic latitude, longitude, altitude of a point on the field line"),
1912 ("6", "Geodetic latitude, longitude, altitude of a point on the field line"),
1779 ("7", "Apex latitude, longitude of the field line"),
1913 ("7", "Apex latitude, longitude of the field line"),
1780 ("8", "Geodetic latitude, longitude and altitude of the points"))
1914 ("8", "Geodetic latitude, longitude and altitude of the points"))
1781
1915
1782 self.fields['looker_options'] = django.forms.ChoiceField(widget = django.forms.RadioSelect,
1916 self.fields['looker_options'] = django.forms.ChoiceField(widget = django.forms.RadioSelect,
1783 choices=lookerOptionChoices,
1917 choices=lookerOptionChoices,
1784 initial="1")
1918 initial="1")
1785
1919
1786
1920
1787 class LookerGeodeticRadar(django.forms.Form):
1921 class LookerGeodeticRadar(django.forms.Form):
1788 """LookerGeodeticRadar is the form for the geodetic to radar page
1922 """LookerGeodeticRadar is the form for the geodetic to radar page
1789 """
1923 """
1790 def __init__(self, *args, **kwargs):
1924 def __init__(self, *args, **kwargs):
1791 """
1925 """
1792 """
1926 """
1793 super(LookerGeodeticRadar, self).__init__(*args, **kwargs)
1927 super(LookerGeodeticRadar, self).__init__(*args, **kwargs)
1794 madDB = madrigal.metadata.MadrigalDB()
1928 madDB = madrigal.metadata.MadrigalDB()
1795 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1929 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1796 dict1 = {'isGlobal': True, 'categories': "0"}
1930 dict1 = {'isGlobal': True, 'categories': "0"}
1797
1931
1798 self.fields['looker_options'] = django.forms.CharField(initial="1",
1932 self.fields['looker_options'] = django.forms.CharField(initial="1",
1799 widget=django.forms.HiddenInput(attrs={'value': "1"}))
1933 widget=django.forms.HiddenInput(attrs={'value': "1"}))
1800
1934
1801 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
1935 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
1802 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
1936 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
1803 required=False, label='Instrument: ')
1937 required=False, label='Instrument: ')
1804
1938
1805 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
1939 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
1806 widget=django.forms.TextInput(attrs={'size':5}))
1940 widget=django.forms.TextInput(attrs={'size':5}))
1807 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
1941 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
1808 widget=django.forms.TextInput(attrs={'size':5}))
1942 widget=django.forms.TextInput(attrs={'size':5}))
1809 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
1943 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
1810 widget=django.forms.TextInput(attrs={'size':5}))
1944 widget=django.forms.TextInput(attrs={'size':5}))
1811 self.fields['start_lat'] = django.forms.FloatField(initial=30.0, min_value=-90.0, max_value=90.0,
1945 self.fields['start_lat'] = django.forms.FloatField(initial=30.0, min_value=-90.0, max_value=90.0,
1812 widget=django.forms.TextInput(attrs={'size':5}))
1946 widget=django.forms.TextInput(attrs={'size':5}))
1813 self.fields['stop_lat'] = django.forms.FloatField(initial=50.0, min_value=-90.0, max_value=90.0,
1947 self.fields['stop_lat'] = django.forms.FloatField(initial=50.0, min_value=-90.0, max_value=90.0,
1814 widget=django.forms.TextInput(attrs={'size':5}))
1948 widget=django.forms.TextInput(attrs={'size':5}))
1815 self.fields['step_lat'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1949 self.fields['step_lat'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1816 widget=django.forms.TextInput(attrs={'size':5}))
1950 widget=django.forms.TextInput(attrs={'size':5}))
1817 self.fields['start_lon'] = django.forms.FloatField(initial=-100.0, min_value=-180.0, max_value=180.0,
1951 self.fields['start_lon'] = django.forms.FloatField(initial=-100.0, min_value=-180.0, max_value=180.0,
1818 widget=django.forms.TextInput(attrs={'size':5}))
1952 widget=django.forms.TextInput(attrs={'size':5}))
1819 self.fields['stop_lon'] = django.forms.FloatField(initial=-80.0, min_value=-180.0, max_value=180.0,
1953 self.fields['stop_lon'] = django.forms.FloatField(initial=-80.0, min_value=-180.0, max_value=180.0,
1820 widget=django.forms.TextInput(attrs={'size':5}))
1954 widget=django.forms.TextInput(attrs={'size':5}))
1821 self.fields['step_lon'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1955 self.fields['step_lon'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1822 widget=django.forms.TextInput(attrs={'size':5}))
1956 widget=django.forms.TextInput(attrs={'size':5}))
1823 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
1957 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
1824 widget=django.forms.TextInput(attrs={'size':5}))
1958 widget=django.forms.TextInput(attrs={'size':5}))
1825 self.fields['stop_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
1959 self.fields['stop_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
1826 widget=django.forms.TextInput(attrs={'size':5}))
1960 widget=django.forms.TextInput(attrs={'size':5}))
1827 self.fields['step_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
1961 self.fields['step_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
1828 widget=django.forms.TextInput(attrs={'size':5}))
1962 widget=django.forms.TextInput(attrs={'size':5}))
1829
1963
1830
1964
1831 class LookerGeomagRadar(django.forms.Form):
1965 class LookerGeomagRadar(django.forms.Form):
1832 """LookerGeomagRadar is the form for the geomagnetic to radar page
1966 """LookerGeomagRadar is the form for the geomagnetic to radar page
1833 """
1967 """
1834 def __init__(self, *args, **kwargs):
1968 def __init__(self, *args, **kwargs):
1835 """
1969 """
1836 """
1970 """
1837 super(LookerGeomagRadar, self).__init__(*args, **kwargs)
1971 super(LookerGeomagRadar, self).__init__(*args, **kwargs)
1838 madDB = madrigal.metadata.MadrigalDB()
1972 madDB = madrigal.metadata.MadrigalDB()
1839 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1973 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1840 dict1 = {'isGlobal': True, 'categories': "0"}
1974 dict1 = {'isGlobal': True, 'categories': "0"}
1841
1975
1842 self.fields['looker_options'] = django.forms.CharField(initial="2",
1976 self.fields['looker_options'] = django.forms.CharField(initial="2",
1843 widget=django.forms.HiddenInput(attrs={'value': "2"}))
1977 widget=django.forms.HiddenInput(attrs={'value': "2"}))
1844
1978
1845 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
1979 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
1846 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
1980 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
1847 required=False, label='Instrument: ')
1981 required=False, label='Instrument: ')
1848
1982
1849 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
1983 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
1850 widget=django.forms.TextInput(attrs={'size':5}))
1984 widget=django.forms.TextInput(attrs={'size':5}))
1851 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
1985 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
1852 widget=django.forms.TextInput(attrs={'size':5}))
1986 widget=django.forms.TextInput(attrs={'size':5}))
1853 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
1987 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
1854 widget=django.forms.TextInput(attrs={'size':5}))
1988 widget=django.forms.TextInput(attrs={'size':5}))
1855 self.fields['start_lat'] = django.forms.FloatField(initial=30.0, min_value=-90.0, max_value=90.0,
1989 self.fields['start_lat'] = django.forms.FloatField(initial=30.0, min_value=-90.0, max_value=90.0,
1856 widget=django.forms.TextInput(attrs={'size':5}))
1990 widget=django.forms.TextInput(attrs={'size':5}))
1857 self.fields['stop_lat'] = django.forms.FloatField(initial=50.0, min_value=-90.0, max_value=90.0,
1991 self.fields['stop_lat'] = django.forms.FloatField(initial=50.0, min_value=-90.0, max_value=90.0,
1858 widget=django.forms.TextInput(attrs={'size':5}))
1992 widget=django.forms.TextInput(attrs={'size':5}))
1859 self.fields['step_lat'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1993 self.fields['step_lat'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1860 widget=django.forms.TextInput(attrs={'size':5}))
1994 widget=django.forms.TextInput(attrs={'size':5}))
1861 self.fields['start_lon'] = django.forms.FloatField(initial=-100.0, min_value=-180.0, max_value=180.0,
1995 self.fields['start_lon'] = django.forms.FloatField(initial=-100.0, min_value=-180.0, max_value=180.0,
1862 widget=django.forms.TextInput(attrs={'size':5}))
1996 widget=django.forms.TextInput(attrs={'size':5}))
1863 self.fields['stop_lon'] = django.forms.FloatField(initial=-80.0, min_value=-180.0, max_value=180.0,
1997 self.fields['stop_lon'] = django.forms.FloatField(initial=-80.0, min_value=-180.0, max_value=180.0,
1864 widget=django.forms.TextInput(attrs={'size':5}))
1998 widget=django.forms.TextInput(attrs={'size':5}))
1865 self.fields['step_lon'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1999 self.fields['step_lon'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1866 widget=django.forms.TextInput(attrs={'size':5}))
2000 widget=django.forms.TextInput(attrs={'size':5}))
1867 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2001 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
1868 widget=django.forms.TextInput(attrs={'size':5}))
2002 widget=django.forms.TextInput(attrs={'size':5}))
1869 self.fields['stop_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
2003 self.fields['stop_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
1870 widget=django.forms.TextInput(attrs={'size':5}))
2004 widget=django.forms.TextInput(attrs={'size':5}))
1871 self.fields['step_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
2005 self.fields['step_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
1872 widget=django.forms.TextInput(attrs={'size':5}))
2006 widget=django.forms.TextInput(attrs={'size':5}))
1873 now = datetime.datetime.utcnow()
2007 now = datetime.datetime.utcnow()
1874 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
2008 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
1875 widget=django.forms.TextInput(attrs={'size':5}))
2009 widget=django.forms.TextInput(attrs={'size':5}))
1876
2010
1877 class LookerGeomagFromGeodetic(django.forms.Form):
2011 class LookerGeomagFromGeodetic(django.forms.Form):
1878 """LookerGeomagFromGeodetic is the form for the geomagnetic from geodetic page
2012 """LookerGeomagFromGeodetic is the form for the geomagnetic from geodetic page
1879 """
2013 """
1880 def __init__(self, *args, **kwargs):
2014 def __init__(self, *args, **kwargs):
1881 """
2015 """
1882 """
2016 """
1883 super(LookerGeomagFromGeodetic, self).__init__(*args, **kwargs)
2017 super(LookerGeomagFromGeodetic, self).__init__(*args, **kwargs)
1884
2018
1885 self.fields['looker_options'] = django.forms.CharField(initial="3",
2019 self.fields['looker_options'] = django.forms.CharField(initial="3",
1886 widget=django.forms.HiddenInput(attrs={'value': "3"}))
2020 widget=django.forms.HiddenInput(attrs={'value': "3"}))
1887
2021
1888 self.fields['start_lat'] = django.forms.FloatField(initial=30.0, min_value=-90.0, max_value=90.0,
2022 self.fields['start_lat'] = django.forms.FloatField(initial=30.0, min_value=-90.0, max_value=90.0,
1889 widget=django.forms.TextInput(attrs={'size':5}))
2023 widget=django.forms.TextInput(attrs={'size':5}))
1890 self.fields['stop_lat'] = django.forms.FloatField(initial=50.0, min_value=-90.0, max_value=90.0,
2024 self.fields['stop_lat'] = django.forms.FloatField(initial=50.0, min_value=-90.0, max_value=90.0,
1891 widget=django.forms.TextInput(attrs={'size':5}))
2025 widget=django.forms.TextInput(attrs={'size':5}))
1892 self.fields['step_lat'] = django.forms.FloatField(initial=10.0, min_value=0.0,
2026 self.fields['step_lat'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1893 widget=django.forms.TextInput(attrs={'size':5}))
2027 widget=django.forms.TextInput(attrs={'size':5}))
1894 self.fields['start_lon'] = django.forms.FloatField(initial=-100.0, min_value=-180.0, max_value=180.0,
2028 self.fields['start_lon'] = django.forms.FloatField(initial=-100.0, min_value=-180.0, max_value=180.0,
1895 widget=django.forms.TextInput(attrs={'size':5}))
2029 widget=django.forms.TextInput(attrs={'size':5}))
1896 self.fields['stop_lon'] = django.forms.FloatField(initial=-80.0, min_value=-180.0, max_value=180.0,
2030 self.fields['stop_lon'] = django.forms.FloatField(initial=-80.0, min_value=-180.0, max_value=180.0,
1897 widget=django.forms.TextInput(attrs={'size':5}))
2031 widget=django.forms.TextInput(attrs={'size':5}))
1898 self.fields['step_lon'] = django.forms.FloatField(initial=10.0, min_value=0.0,
2032 self.fields['step_lon'] = django.forms.FloatField(initial=10.0, min_value=0.0,
1899 widget=django.forms.TextInput(attrs={'size':5}))
2033 widget=django.forms.TextInput(attrs={'size':5}))
1900 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2034 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
1901 widget=django.forms.TextInput(attrs={'size':5}))
2035 widget=django.forms.TextInput(attrs={'size':5}))
1902 self.fields['stop_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
2036 self.fields['stop_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
1903 widget=django.forms.TextInput(attrs={'size':5}))
2037 widget=django.forms.TextInput(attrs={'size':5}))
1904 self.fields['step_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
2038 self.fields['step_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
1905 widget=django.forms.TextInput(attrs={'size':5}))
2039 widget=django.forms.TextInput(attrs={'size':5}))
1906 now = datetime.datetime.utcnow()
2040 now = datetime.datetime.utcnow()
1907 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
2041 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
1908 widget=django.forms.TextInput(attrs={'size':5}))
2042 widget=django.forms.TextInput(attrs={'size':5}))
1909
2043
1910 class LookerGeomagFromRadar(django.forms.Form):
2044 class LookerGeomagFromRadar(django.forms.Form):
1911 """LookerGeomagFromRadar is the form for the geomagnetic from radar page
2045 """LookerGeomagFromRadar is the form for the geomagnetic from radar page
1912 """
2046 """
1913 def __init__(self, *args, **kwargs):
2047 def __init__(self, *args, **kwargs):
1914 """
2048 """
1915 """
2049 """
1916 super(LookerGeomagFromRadar, self).__init__(*args, **kwargs)
2050 super(LookerGeomagFromRadar, self).__init__(*args, **kwargs)
1917 madDB = madrigal.metadata.MadrigalDB()
2051 madDB = madrigal.metadata.MadrigalDB()
1918 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
2052 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1919 dict1 = {'isGlobal': True, 'categories': "0"}
2053 dict1 = {'isGlobal': True, 'categories': "0"}
1920
2054
1921 self.fields['looker_options'] = django.forms.CharField(initial="4",
2055 self.fields['looker_options'] = django.forms.CharField(initial="4",
1922 widget=django.forms.HiddenInput(attrs={'value': "4"}))
2056 widget=django.forms.HiddenInput(attrs={'value': "4"}))
1923
2057
1924 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
2058 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
1925 choices=getInstrumentList([], dict1, madInstData, local=False)[1:],
2059 choices=getInstrumentList([], dict1, madInstData, local=False)[1:],
1926 required=False, label='Instrument: ')
2060 required=False, label='Instrument: ')
1927
2061
1928 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
2062 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
1929 widget=django.forms.TextInput(attrs={'size':5}))
2063 widget=django.forms.TextInput(attrs={'size':5}))
1930 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
2064 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
1931 widget=django.forms.TextInput(attrs={'size':5}))
2065 widget=django.forms.TextInput(attrs={'size':5}))
1932 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2066 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
1933 widget=django.forms.TextInput(attrs={'size':5}))
2067 widget=django.forms.TextInput(attrs={'size':5}))
1934 self.fields['start_az'] = django.forms.FloatField(initial=-180.0, min_value=-180.0, max_value=180.0,
2068 self.fields['start_az'] = django.forms.FloatField(initial=-180.0, min_value=-180.0, max_value=180.0,
1935 widget=django.forms.TextInput(attrs={'size':5}))
2069 widget=django.forms.TextInput(attrs={'size':5}))
1936 self.fields['stop_az'] = django.forms.FloatField(initial=180.0, min_value=-180.0, max_value=180.0,
2070 self.fields['stop_az'] = django.forms.FloatField(initial=180.0, min_value=-180.0, max_value=180.0,
1937 widget=django.forms.TextInput(attrs={'size':5}))
2071 widget=django.forms.TextInput(attrs={'size':5}))
1938 self.fields['step_az'] = django.forms.FloatField(initial=45.0, min_value=0.0,
2072 self.fields['step_az'] = django.forms.FloatField(initial=45.0, min_value=0.0,
1939 widget=django.forms.TextInput(attrs={'size':5}))
2073 widget=django.forms.TextInput(attrs={'size':5}))
1940 self.fields['start_el'] = django.forms.FloatField(initial=0.0, min_value=0.0, max_value=90.0,
2074 self.fields['start_el'] = django.forms.FloatField(initial=0.0, min_value=0.0, max_value=90.0,
1941 widget=django.forms.TextInput(attrs={'size':5}))
2075 widget=django.forms.TextInput(attrs={'size':5}))
1942 self.fields['stop_el'] = django.forms.FloatField(initial=90.0, min_value=0.0, max_value=90.0,
2076 self.fields['stop_el'] = django.forms.FloatField(initial=90.0, min_value=0.0, max_value=90.0,
1943 widget=django.forms.TextInput(attrs={'size':5}))
2077 widget=django.forms.TextInput(attrs={'size':5}))
1944 self.fields['step_el'] = django.forms.FloatField(initial=30.0, min_value=0.0,
2078 self.fields['step_el'] = django.forms.FloatField(initial=30.0, min_value=0.0,
1945 widget=django.forms.TextInput(attrs={'size':5}))
2079 widget=django.forms.TextInput(attrs={'size':5}))
1946 self.fields['start_range'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2080 self.fields['start_range'] = django.forms.FloatField(initial=0.0, min_value=0.0,
1947 widget=django.forms.TextInput(attrs={'size':5}))
2081 widget=django.forms.TextInput(attrs={'size':5}))
1948 self.fields['stop_range'] = django.forms.FloatField(initial=600.0, min_value=0.0,
2082 self.fields['stop_range'] = django.forms.FloatField(initial=600.0, min_value=0.0,
1949 widget=django.forms.TextInput(attrs={'size':5}))
2083 widget=django.forms.TextInput(attrs={'size':5}))
1950 self.fields['step_range'] = django.forms.FloatField(initial=200.0, min_value=0.0,
2084 self.fields['step_range'] = django.forms.FloatField(initial=200.0, min_value=0.0,
1951 widget=django.forms.TextInput(attrs={'size':5}))
2085 widget=django.forms.TextInput(attrs={'size':5}))
1952 now = datetime.datetime.utcnow()
2086 now = datetime.datetime.utcnow()
1953 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
2087 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
1954 widget=django.forms.TextInput(attrs={'size':5}))
2088 widget=django.forms.TextInput(attrs={'size':5}))
1955
2089
1956
2090
1957 class LookerFieldLineFromRadar(django.forms.Form):
2091 class LookerFieldLineFromRadar(django.forms.Form):
1958 """LookerFieldLineFromRadar is the form for the field line from radar page
2092 """LookerFieldLineFromRadar is the form for the field line from radar page
1959 """
2093 """
1960 def __init__(self, *args, **kwargs):
2094 def __init__(self, *args, **kwargs):
1961 """
2095 """
1962 """
2096 """
1963 super(LookerFieldLineFromRadar, self).__init__(*args, **kwargs)
2097 super(LookerFieldLineFromRadar, self).__init__(*args, **kwargs)
1964 madDB = madrigal.metadata.MadrigalDB()
2098 madDB = madrigal.metadata.MadrigalDB()
1965 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
2099 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
1966 dict1 = {'isGlobal': True, 'categories': "0"}
2100 dict1 = {'isGlobal': True, 'categories': "0"}
1967
2101
1968 self.fields['looker_options'] = django.forms.CharField(initial="5",
2102 self.fields['looker_options'] = django.forms.CharField(initial="5",
1969 widget=django.forms.HiddenInput(attrs={'value': "5"}))
2103 widget=django.forms.HiddenInput(attrs={'value': "5"}))
1970
2104
1971 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
2105 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
1972 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
2106 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
1973 required=False, label='Instrument: ')
2107 required=False, label='Instrument: ')
1974
2108
1975 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
2109 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
1976 widget=django.forms.TextInput(attrs={'size':5}))
2110 widget=django.forms.TextInput(attrs={'size':5}))
1977 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
2111 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
1978 widget=django.forms.TextInput(attrs={'size':5}))
2112 widget=django.forms.TextInput(attrs={'size':5}))
1979 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2113 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
1980 widget=django.forms.TextInput(attrs={'size':5}))
2114 widget=django.forms.TextInput(attrs={'size':5}))
1981 self.fields['fl_az'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
2115 self.fields['fl_az'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
1982 widget=django.forms.TextInput(attrs={'size':5}))
2116 widget=django.forms.TextInput(attrs={'size':5}))
1983 self.fields['fl_el'] = django.forms.FloatField(initial=45.0, min_value=0.0, max_value=90.0,
2117 self.fields['fl_el'] = django.forms.FloatField(initial=45.0, min_value=0.0, max_value=90.0,
1984 widget=django.forms.TextInput(attrs={'size':5}))
2118 widget=django.forms.TextInput(attrs={'size':5}))
1985 self.fields['fl_range'] = django.forms.FloatField(initial=1000.0, min_value=0.0,
2119 self.fields['fl_range'] = django.forms.FloatField(initial=1000.0, min_value=0.0,
1986 widget=django.forms.TextInput(attrs={'size':5}))
2120 widget=django.forms.TextInput(attrs={'size':5}))
1987
2121
1988 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2122 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
1989 widget=django.forms.TextInput(attrs={'size':5}))
2123 widget=django.forms.TextInput(attrs={'size':5}))
1990 self.fields['stop_alt'] = django.forms.FloatField(initial=1000.0, min_value=0.0,
2124 self.fields['stop_alt'] = django.forms.FloatField(initial=1000.0, min_value=0.0,
1991 widget=django.forms.TextInput(attrs={'size':5}))
2125 widget=django.forms.TextInput(attrs={'size':5}))
1992 self.fields['step_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2126 self.fields['step_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
1993 widget=django.forms.TextInput(attrs={'size':5}))
2127 widget=django.forms.TextInput(attrs={'size':5}))
1994 now = datetime.datetime.utcnow()
2128 now = datetime.datetime.utcnow()
1995 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
2129 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
1996 widget=django.forms.TextInput(attrs={'size':5}))
2130 widget=django.forms.TextInput(attrs={'size':5}))
1997
2131
1998
2132
1999
2133
2000 class LookerFieldLineFromGeodetic(django.forms.Form):
2134 class LookerFieldLineFromGeodetic(django.forms.Form):
2001 """LookerFieldLineFromGeodetic is the form for the field line from geodetic page
2135 """LookerFieldLineFromGeodetic is the form for the field line from geodetic page
2002 """
2136 """
2003 def __init__(self, *args, **kwargs):
2137 def __init__(self, *args, **kwargs):
2004 """
2138 """
2005 """
2139 """
2006 super(LookerFieldLineFromGeodetic, self).__init__(*args, **kwargs)
2140 super(LookerFieldLineFromGeodetic, self).__init__(*args, **kwargs)
2007 madDB = madrigal.metadata.MadrigalDB()
2141 madDB = madrigal.metadata.MadrigalDB()
2008 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
2142 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
2009 dict1 = {'isGlobal': True, 'categories': "0"}
2143 dict1 = {'isGlobal': True, 'categories': "0"}
2010
2144
2011 self.fields['looker_options'] = django.forms.CharField(initial="6",
2145 self.fields['looker_options'] = django.forms.CharField(initial="6",
2012 widget=django.forms.HiddenInput(attrs={'value': "6"}))
2146 widget=django.forms.HiddenInput(attrs={'value': "6"}))
2013
2147
2014 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
2148 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
2015 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
2149 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
2016 required=False, label='Instrument: ')
2150 required=False, label='Instrument: ')
2017
2151
2018 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
2152 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
2019 widget=django.forms.TextInput(attrs={'size':5}))
2153 widget=django.forms.TextInput(attrs={'size':5}))
2020 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
2154 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
2021 widget=django.forms.TextInput(attrs={'size':5}))
2155 widget=django.forms.TextInput(attrs={'size':5}))
2022 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2156 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2023 widget=django.forms.TextInput(attrs={'size':5}))
2157 widget=django.forms.TextInput(attrs={'size':5}))
2024 self.fields['fl_lat'] = django.forms.FloatField(initial=45.0, min_value=-90.0, max_value=90.0,
2158 self.fields['fl_lat'] = django.forms.FloatField(initial=45.0, min_value=-90.0, max_value=90.0,
2025 widget=django.forms.TextInput(attrs={'size':5}))
2159 widget=django.forms.TextInput(attrs={'size':5}))
2026 self.fields['fl_lon'] = django.forms.FloatField(initial=-90.0, min_value=-180.0, max_value=180.0,
2160 self.fields['fl_lon'] = django.forms.FloatField(initial=-90.0, min_value=-180.0, max_value=180.0,
2027 widget=django.forms.TextInput(attrs={'size':5}))
2161 widget=django.forms.TextInput(attrs={'size':5}))
2028 self.fields['fl_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2162 self.fields['fl_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2029 widget=django.forms.TextInput(attrs={'size':5}))
2163 widget=django.forms.TextInput(attrs={'size':5}))
2030
2164
2031 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2165 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2032 widget=django.forms.TextInput(attrs={'size':5}))
2166 widget=django.forms.TextInput(attrs={'size':5}))
2033 self.fields['stop_alt'] = django.forms.FloatField(initial=1000.0, min_value=0.0,
2167 self.fields['stop_alt'] = django.forms.FloatField(initial=1000.0, min_value=0.0,
2034 widget=django.forms.TextInput(attrs={'size':5}))
2168 widget=django.forms.TextInput(attrs={'size':5}))
2035 self.fields['step_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2169 self.fields['step_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2036 widget=django.forms.TextInput(attrs={'size':5}))
2170 widget=django.forms.TextInput(attrs={'size':5}))
2037 now = datetime.datetime.utcnow()
2171 now = datetime.datetime.utcnow()
2038 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
2172 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
2039 widget=django.forms.TextInput(attrs={'size':5}))
2173 widget=django.forms.TextInput(attrs={'size':5}))
2040
2174
2041
2175
2042 class LookerFieldLineFromApex(django.forms.Form):
2176 class LookerFieldLineFromApex(django.forms.Form):
2043 """LookerFieldLineFromApex is the form for the field line from apex coordinates page
2177 """LookerFieldLineFromApex is the form for the field line from apex coordinates page
2044 """
2178 """
2045 def __init__(self, *args, **kwargs):
2179 def __init__(self, *args, **kwargs):
2046 """
2180 """
2047 """
2181 """
2048 super(LookerFieldLineFromApex, self).__init__(*args, **kwargs)
2182 super(LookerFieldLineFromApex, self).__init__(*args, **kwargs)
2049 madDB = madrigal.metadata.MadrigalDB()
2183 madDB = madrigal.metadata.MadrigalDB()
2050 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
2184 madInstData = madrigal.metadata.MadrigalInstrumentData(madDB)
2051 dict1 = {'isGlobal': True, 'categories': "0"}
2185 dict1 = {'isGlobal': True, 'categories': "0"}
2052
2186
2053 self.fields['looker_options'] = django.forms.CharField(initial="7",
2187 self.fields['looker_options'] = django.forms.CharField(initial="7",
2054 widget=django.forms.HiddenInput(attrs={'value': "7"}))
2188 widget=django.forms.HiddenInput(attrs={'value': "7"}))
2055
2189
2056 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
2190 self.fields['instruments'] = django.forms.ChoiceField(widget = django.forms.Select(attrs={'size':'3'}),
2057 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
2191 choices=getInstrumentList([], dict1, madInstData, 'Set location manually', local=False),
2058 required=False, label='Instrument: ')
2192 required=False, label='Instrument: ')
2059
2193
2060 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
2194 self.fields['inst_lat'] = django.forms.FloatField(initial=0.0, min_value=-90.0, max_value=90.0,
2061 widget=django.forms.TextInput(attrs={'size':5}))
2195 widget=django.forms.TextInput(attrs={'size':5}))
2062 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
2196 self.fields['inst_lon'] = django.forms.FloatField(initial=0.0, min_value=-180.0, max_value=180.0,
2063 widget=django.forms.TextInput(attrs={'size':5}))
2197 widget=django.forms.TextInput(attrs={'size':5}))
2064 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2198 self.fields['inst_alt'] = django.forms.FloatField(initial=0.0, min_value=0.0,
2065 widget=django.forms.TextInput(attrs={'size':5}))
2199 widget=django.forms.TextInput(attrs={'size':5}))
2066 self.fields['fl_apex_lat'] = django.forms.FloatField(initial=65.0, min_value=-00.0, max_value=90.0,
2200 self.fields['fl_apex_lat'] = django.forms.FloatField(initial=65.0, min_value=-00.0, max_value=90.0,
2067 widget=django.forms.TextInput(attrs={'size':5}))
2201 widget=django.forms.TextInput(attrs={'size':5}))
2068 self.fields['fl_apex_lon'] = django.forms.FloatField(initial=-90.0, min_value=-180.0, max_value=180.0,
2202 self.fields['fl_apex_lon'] = django.forms.FloatField(initial=-90.0, min_value=-180.0, max_value=180.0,
2069 widget=django.forms.TextInput(attrs={'size':5}))
2203 widget=django.forms.TextInput(attrs={'size':5}))
2070
2204
2071 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2205 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2072 widget=django.forms.TextInput(attrs={'size':5}))
2206 widget=django.forms.TextInput(attrs={'size':5}))
2073 self.fields['stop_alt'] = django.forms.FloatField(initial=1000.0, min_value=0.0,
2207 self.fields['stop_alt'] = django.forms.FloatField(initial=1000.0, min_value=0.0,
2074 widget=django.forms.TextInput(attrs={'size':5}))
2208 widget=django.forms.TextInput(attrs={'size':5}))
2075 self.fields['step_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2209 self.fields['step_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2076 widget=django.forms.TextInput(attrs={'size':5}))
2210 widget=django.forms.TextInput(attrs={'size':5}))
2077 now = datetime.datetime.utcnow()
2211 now = datetime.datetime.utcnow()
2078 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
2212 self.fields['year'] = django.forms.FloatField(initial=float(now.year), min_value=1950.0,
2079 widget=django.forms.TextInput(attrs={'size':5}))
2213 widget=django.forms.TextInput(attrs={'size':5}))
2080
2214
2081
2215
2082 class LookerConjugateFromGeodetic(django.forms.Form):
2216 class LookerConjugateFromGeodetic(django.forms.Form):
2083 """LookerConjugateFromGeodetic is the form for the geomagnetic/conjugate from geodetic page
2217 """LookerConjugateFromGeodetic is the form for the geomagnetic/conjugate from geodetic page
2084 """
2218 """
2085 def __init__(self, *args, **kwargs):
2219 def __init__(self, *args, **kwargs):
2086 """
2220 """
2087 """
2221 """
2088 super(LookerConjugateFromGeodetic, self).__init__(*args, **kwargs)
2222 super(LookerConjugateFromGeodetic, self).__init__(*args, **kwargs)
2089
2223
2090 parmChoices = [("MAGCONJLAT", 'Magnetic conjugate latitude'),
2224 parmChoices = [("MAGCONJLAT", 'Magnetic conjugate latitude'),
2091 ("MAGCONJLON", 'Magnetic conjugate longitude'),
2225 ("MAGCONJLON", 'Magnetic conjugate longitude'),
2092 ("SZEN", 'Solar zenith angle'),
2226 ("SZEN", 'Solar zenith angle'),
2093 ("SZENC", 'Magnetic conjugate solar zenith angle'),
2227 ("SZENC", 'Magnetic conjugate solar zenith angle'),
2094 ("SDWHT", 'Shadow height (km)'),
2228 ("SDWHT", 'Shadow height (km)'),
2095 ("MAGCONJSDWHT", 'Magnetic conjugate shadow height (km)')]
2229 ("MAGCONJSDWHT", 'Magnetic conjugate shadow height (km)')]
2096 parmInitial = [key for key, value in parmChoices]
2230 parmInitial = [key for key, value in parmChoices]
2097
2231
2098 self.fields['looker_options'] = django.forms.CharField(initial="8",
2232 self.fields['looker_options'] = django.forms.CharField(initial="8",
2099 widget=django.forms.HiddenInput(attrs={'value': "8"}))
2233 widget=django.forms.HiddenInput(attrs={'value': "8"}))
2100
2234
2101 self.fields['start_lat'] = django.forms.FloatField(initial=30.0, min_value=-90.0, max_value=90.0,
2235 self.fields['start_lat'] = django.forms.FloatField(initial=30.0, min_value=-90.0, max_value=90.0,
2102 widget=django.forms.TextInput(attrs={'size':5}))
2236 widget=django.forms.TextInput(attrs={'size':5}))
2103 self.fields['stop_lat'] = django.forms.FloatField(initial=50.0, min_value=-90.0, max_value=90.0,
2237 self.fields['stop_lat'] = django.forms.FloatField(initial=50.0, min_value=-90.0, max_value=90.0,
2104 widget=django.forms.TextInput(attrs={'size':5}))
2238 widget=django.forms.TextInput(attrs={'size':5}))
2105 self.fields['step_lat'] = django.forms.FloatField(initial=10.0, min_value=0.0,
2239 self.fields['step_lat'] = django.forms.FloatField(initial=10.0, min_value=0.0,
2106 widget=django.forms.TextInput(attrs={'size':5}))
2240 widget=django.forms.TextInput(attrs={'size':5}))
2107 self.fields['start_lon'] = django.forms.FloatField(initial=-100.0, min_value=-180.0, max_value=180.0,
2241 self.fields['start_lon'] = django.forms.FloatField(initial=-100.0, min_value=-180.0, max_value=180.0,
2108 widget=django.forms.TextInput(attrs={'size':5}))
2242 widget=django.forms.TextInput(attrs={'size':5}))
2109 self.fields['stop_lon'] = django.forms.FloatField(initial=-80.0, min_value=-180.0, max_value=180.0,
2243 self.fields['stop_lon'] = django.forms.FloatField(initial=-80.0, min_value=-180.0, max_value=180.0,
2110 widget=django.forms.TextInput(attrs={'size':5}))
2244 widget=django.forms.TextInput(attrs={'size':5}))
2111 self.fields['step_lon'] = django.forms.FloatField(initial=10.0, min_value=0.0,
2245 self.fields['step_lon'] = django.forms.FloatField(initial=10.0, min_value=0.0,
2112 widget=django.forms.TextInput(attrs={'size':5}))
2246 widget=django.forms.TextInput(attrs={'size':5}))
2113 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2247 self.fields['start_alt'] = django.forms.FloatField(initial=100.0, min_value=0.0,
2114 widget=django.forms.TextInput(attrs={'size':5}))
2248 widget=django.forms.TextInput(attrs={'size':5}))
2115 self.fields['stop_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
2249 self.fields['stop_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
2116 widget=django.forms.TextInput(attrs={'size':5}))
2250 widget=django.forms.TextInput(attrs={'size':5}))
2117 self.fields['step_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
2251 self.fields['step_alt'] = django.forms.FloatField(initial=500.0, min_value=0.0,
2118 widget=django.forms.TextInput(attrs={'size':5}))
2252 widget=django.forms.TextInput(attrs={'size':5}))
2119
2253
2120 # time selection
2254 # time selection
2121 now = datetime.datetime.utcnow()
2255 now = datetime.datetime.utcnow()
2122 self.fields['datetime'] = django.forms.SplitDateTimeField(input_date_formats=['%Y-%m-%d'], input_time_formats=['%H:%M:%S'],
2256 self.fields['datetime'] = django.forms.SplitDateTimeField(input_date_formats=['%Y-%m-%d'], input_time_formats=['%H:%M:%S'],
2123 label='Select UT datetime',
2257 label='Select UT datetime',
2124 help_text='Select the UT time at which to run this calcuation',
2258 help_text='Select the UT time at which to run this calcuation',
2125 initial=datetime.datetime(now.year,1,1))
2259 initial=datetime.datetime(now.year,1,1))
2126
2260
2127 self.fields['pList'] = django.forms.MultipleChoiceField(widget=django.forms.CheckboxSelectMultiple(),
2261 self.fields['pList'] = django.forms.MultipleChoiceField(widget=django.forms.CheckboxSelectMultiple(),
2128 choices=parmChoices, initial=parmInitial)
2262 choices=parmChoices, initial=parmInitial)
2129
2263
@@ -1,59 +1,67
1 {% extends "base.html" %}
1 {% extends "base.html" %}
2
2
3 {% comment %}
3 {% comment %}
4 Written by Bill Rideout brideout@haystack.mit.edu
4 Written by Bill Rideout brideout@haystack.mit.edu
5
5
6 Base template for Madrigal show experiment web interface
6 Base template for Madrigal show experiment web interface
7
7
8 $Id: show_experiment.html 7310 2021-03-02 14:31:06Z brideout $
8 $Id: show_experiment.html 7310 2021-03-02 14:31:06Z brideout $
9 {% endcomment %}
9 {% endcomment %}
10
10
11 {% block title %}Show Madrigal experiment{% endblock %}
11 {% block title %}Show Madrigal experiment{% endblock %}
12
12
13 {% block extra_head %}
13 {% block extra_head %}
14 <script>
14 <script>
15
15
16 function changeFile (select) {
16 function changeFile (select) {
17 var basename = select.options[select.selectedIndex].value;
17 var basename = select.options[select.selectedIndex].value;
18 {% if form.exp_id %}
18 {% if form.exp_id %}
19 var url = '{% url 'change_files' %}' + '?experiment_list={{ form.exp_id.label }}&file_list=' + basename;
19 var url = '{% url 'change_files' %}' + '?experiment_list={{ form.exp_id.label }}&file_list=' + basename;
20 {% else %}
20 {% else %}
21 var exp_id = $("#id_experiment_list")[0].options[$("#id_experiment_list")[0].selectedIndex].value;
21 var exp_id = $("#id_experiment_list")[0].options[$("#id_experiment_list")[0].selectedIndex].value;
22 var url = '{% url 'change_files' %}' + '?experiment_list=' + exp_id + '&file_list=' + basename;
22 var url = '{% url 'change_files' %}' + '?experiment_list=' + exp_id + '&file_list=' + basename;
23 {% endif %}
23 {% endif %}
24 // first delete all forms that are now out of date
24 // first delete all forms that are now out of date
25 divIndex = $(".single_form").index($( "#file_buttons" ))
25 divIndex = $(".single_form").index($( "#file_buttons" ))
26 $(".single_form").slice(divIndex).empty()
26 $(".single_form").slice(divIndex).empty()
27 // second populate the file_list html if '0' not selected
27 // second populate the file_list html if '0' not selected
28 if (basename != '0') {
28 if (basename != '0') {
29 $(".single_form").slice(divIndex,divIndex+1).load(url);
29 $(".single_form").slice(divIndex,divIndex+1).load(url);
30 }
30 }
31 }
31 }
32
32
33 {% include "madweb/fileDownload.js" %}
33 {% include "madweb/fileDownload.js" %}
34
34
35 </script>
35 </script>
36 {% endblock %}
36 {% endblock %}
37
37
38 {% block content %}
38 {% block content %}
39 <center><h4> {{ form.exp_desc.label }} </h4></center>
39 <center><h4> {{ form.exp_desc.label }} </h4></center>
40
40
41 {% include "madweb/file_list.html" %}
41 {% include "madweb/file_list.html" %}
42
42
43 <!-- file select div -->
43 <!-- file select div -->
44 <div class="col-md-12 single_form" id="file_buttons">
44 <div class="col-md-12 single_form" id="file_buttons">
45 {% if form.file_buttons %}
45 {% if form.file_buttons %}
46 {% include "madweb/file_buttons.html" %}
46 {% include "madweb/file_buttons.html" %}
47 {% endif %}
47 {% endif %}
48 </div> <!-- end subdivide -->
48 </div> <!-- end subdivide -->
49 <div>&nbsp;</div>
49 <div>&nbsp;</div>
50
50
51 <!-- file select div -->
51 <!-- file select div -->
52 <div class="col-md-12 single_form" id="file_data">
52 <div class="col-md-12 single_form" id="file_data">
53 {% if form.show_plots %}
53 {% if form.show_plots %}
54 {% include "madweb/show_plots.html" %}
54 {% include "madweb/show_plots.html" %}
55 {% elif form.plot_list %}
55 {% elif form.plot_list %}
56 {% include "madweb/show_plots.html" %}
56 {% include "madweb/show_plots.html" %}
57 {% endif %}
57 {% endif %}
58 </div> <!-- end subdivide -->
58 </div> <!-- end subdivide -->
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
59 {% endblock %} No newline at end of file
67 {% endblock %}
@@ -1,259 +1,268
1 {% extends "base_single.html" %}
1 {% extends "base_single.html" %}
2
2
3 {% comment %}
3 {% comment %}
4 Written by Bill Rideout brideout@haystack.mit.edu
4 Written by Bill Rideout brideout@haystack.mit.edu
5
5
6 Final template for Madrigal single experiment web interface
6 Final template for Madrigal single experiment web interface
7
7
8 $Id: single.html 7290 2021-01-13 21:07:21Z brideout $
8 $Id: single.html 7290 2021-01-13 21:07:21Z brideout $
9 {% endcomment %}
9 {% endcomment %}
10
10
11
11
12 {% block ajax_js %}
12 {% block ajax_js %}
13 <script type="text/javascript">
13 <script type="text/javascript">
14
14
15
15
16 {% if years %}
16 {% if years %}
17 $( document ).ready(function() {
17 $( document ).ready(function() {
18 createCalendar();
18 createCalendar();
19 });
19 });
20 {% endif %}
20 {% endif %}
21
21
22 var redirectLookup = {
22 var redirectLookup = {
23 "0": function() { return ""; },
23 "0": function() { return ""; },
24 {% for redirect in redirect_list %}
24 {% for redirect in redirect_list %}
25 "{{ redirect.0 }}": function() { return "{{ redirect.1|safe }}"; },
25 "{{ redirect.0 }}": function() { return "{{ redirect.1|safe }}"; },
26 {% endfor %}
26 {% endfor %}
27 };
27 };
28
28
29 function populateCat (checkbox) {
29 function populateCat (checkbox) {
30 var is_global = 0;
30 var is_global = 0;
31 if (checkbox.checked) {
31 if (checkbox.checked) {
32 is_global = 1;
32 is_global = 1;
33 }
33 }
34 var url = '{% url 'get_categories' %}' + '?isGlobal=' + is_global;
34 var url = '{% url 'get_categories' %}' + '?isGlobal=' + is_global;
35 // first delete all forms that are now out of date
35 // first delete all forms that are now out of date
36 divIndex = $(".single_form").index($( "#categories" ))
36 divIndex = $(".single_form").index($( "#categories" ))
37 $(".single_form").slice(divIndex).empty()
37 $(".single_form").slice(divIndex).empty()
38 // second populate the categories html
38 // second populate the categories html
39 $(".single_form").slice(divIndex,divIndex+1).load(url);
39 $(".single_form").slice(divIndex,divIndex+1).load(url);
40 }
40 }
41
41
42 function populateInst (select) {
42 function populateInst (select) {
43 var is_global = 0;
43 var is_global = 0;
44 if ($("#id_isGlobal")[0].checked) {
44 if ($("#id_isGlobal")[0].checked) {
45 is_global = 1;
45 is_global = 1;
46 }
46 }
47 var category = select.options[select.selectedIndex].value;
47 var category = select.options[select.selectedIndex].value;
48 var url = '{% url 'get_instruments' %}' + '?isGlobal=' + is_global + '&categories=' + category;
48 var url = '{% url 'get_instruments' %}' + '?isGlobal=' + is_global + '&categories=' + category;
49 // first delete all forms that are now out of date
49 // first delete all forms that are now out of date
50 divIndex = $(".single_form").index($( "#instruments" ))
50 divIndex = $(".single_form").index($( "#instruments" ))
51 $(".single_form").slice(divIndex).empty()
51 $(".single_form").slice(divIndex).empty()
52 // second populate the instruments html if '0' not selected
52 // second populate the instruments html if '0' not selected
53 if (category != '0') {
53 if (category != '0') {
54 $(".single_form").slice(divIndex,divIndex+1).load(url);
54 $(".single_form").slice(divIndex,divIndex+1).load(url);
55 }
55 }
56 }
56 }
57
57
58 function populateYear (select) {
58 function populateYear (select) {
59 var is_global = 0;
59 var is_global = 0;
60 if ($("#id_isGlobal")[0].checked) {
60 if ($("#id_isGlobal")[0].checked) {
61 is_global = 1;
61 is_global = 1;
62 }
62 }
63 // this method may redirect if instrument is not local
63 // this method may redirect if instrument is not local
64 var kinst = select.options[select.selectedIndex].value;
64 var kinst = select.options[select.selectedIndex].value;
65 var redirectUrl = redirectLookup[kinst]();
65 var redirectUrl = redirectLookup[kinst]();
66 if (redirectUrl.length > 0) {
66 if (redirectUrl.length > 0) {
67 // redirect
67 // redirect
68 alert('Because this data is not local, you will be redirected to ' + redirectUrl);
68 alert('Because this data is not local, you will be redirected to ' + redirectUrl);
69 window.location.href = redirectUrl;
69 window.location.href = redirectUrl;
70 } else {
70 } else {
71 var url = '{% url 'get_years' %}' + '?isGlobal=' + is_global + '&instruments=' + kinst;
71 var url = '{% url 'get_years' %}' + '?isGlobal=' + is_global + '&instruments=' + kinst;
72 // first delete all forms that are now out of date
72 // first delete all forms that are now out of date
73 divIndex = $(".single_form").index($( "#years" ))
73 divIndex = $(".single_form").index($( "#years" ))
74 $(".single_form").slice(divIndex).empty()
74 $(".single_form").slice(divIndex).empty()
75 // second populate the years html if '0' not selected
75 // second populate the years html if '0' not selected
76 if (kinst != '0') {
76 if (kinst != '0') {
77 $(".single_form").slice(divIndex,divIndex+1).load(url);
77 $(".single_form").slice(divIndex,divIndex+1).load(url);
78 }
78 }
79 }
79 }
80 }
80 }
81
81
82 function populateMonth (select) {
82 function populateMonth (select) {
83 var year = select.options[select.selectedIndex].value;
83 var year = select.options[select.selectedIndex].value;
84 var kinst = $("#id_instruments")[0].options[$("#id_instruments")[0].selectedIndex].value;
84 var kinst = $("#id_instruments")[0].options[$("#id_instruments")[0].selectedIndex].value;
85 var is_global = 0;
85 var is_global = 0;
86 if ($("#id_isGlobal")[0].checked) {
86 if ($("#id_isGlobal")[0].checked) {
87 is_global = 1;
87 is_global = 1;
88 }
88 }
89
89
90 var url = '{% url 'get_months' %}' + '?isGlobal=' + is_global + '&instruments=' + kinst + '&years=' + year;
90 var url = '{% url 'get_months' %}' + '?isGlobal=' + is_global + '&instruments=' + kinst + '&years=' + year;
91 // first delete all forms that are now out of date
91 // first delete all forms that are now out of date
92 divIndex = $(".single_form").index($( "#months" ))
92 divIndex = $(".single_form").index($( "#months" ))
93 $(".single_form").slice(divIndex).empty()
93 $(".single_form").slice(divIndex).empty()
94 // second populate the years html if '0' not selected
94 // second populate the years html if '0' not selected
95 if (kinst != '0') {
95 if (kinst != '0') {
96 $(".single_form").slice(divIndex,divIndex+1).load(url);
96 $(".single_form").slice(divIndex,divIndex+1).load(url);
97 }
97 }
98 }
98 }
99
99
100 function populateCalendar (select) {
100 function populateCalendar (select) {
101 var year = $("#id_years")[0].options[$("#id_years")[0].selectedIndex].value;
101 var year = $("#id_years")[0].options[$("#id_years")[0].selectedIndex].value;
102 var month = select.options[select.selectedIndex].value;
102 var month = select.options[select.selectedIndex].value;
103 var kinst = $("#id_instruments")[0].options[$("#id_instruments")[0].selectedIndex].value;
103 var kinst = $("#id_instruments")[0].options[$("#id_instruments")[0].selectedIndex].value;
104 var is_global = 0;
104 var is_global = 0;
105 if ($("#id_isGlobal")[0].checked) {
105 if ($("#id_isGlobal")[0].checked) {
106 is_global = 1;
106 is_global = 1;
107 }
107 }
108 var url = '{% url 'get_calendar' %}' + '?isGlobal=' + is_global + '&instruments=' + kinst + '&years=' + year + '&months=' + month;
108 var url = '{% url 'get_calendar' %}' + '?isGlobal=' + is_global + '&instruments=' + kinst + '&years=' + year + '&months=' + month;
109 // first delete all forms that are now out of date
109 // first delete all forms that are now out of date
110 divIndex = $(".single_form").index($( "#calendar" ))
110 divIndex = $(".single_form").index($( "#calendar" ))
111 $(".single_form").slice(divIndex).empty()
111 $(".single_form").slice(divIndex).empty()
112 // second populate the calendar html if '0' not selected
112 // second populate the calendar html if '0' not selected
113 if (year != '0') {
113 if (year != '0') {
114 $(".single_form").slice(divIndex,divIndex+1).load(url, function() {
114 $(".single_form").slice(divIndex,divIndex+1).load(url, function() {
115 createCalendar();
115 createCalendar();
116 });
116 });
117 }
117 }
118 }
118 }
119
119
120 function populateFile (select) {
120 function populateFile (select) {
121 var expId = select.options[select.selectedIndex].value;
121 var expId = select.options[select.selectedIndex].value;
122 var url = '{% url 'get_files' %}' + '?experiment_list=' + expId;
122 var url = '{% url 'get_files' %}' + '?experiment_list=' + expId;
123 // first delete all forms that are now out of date
123 // first delete all forms that are now out of date
124 divIndex = $(".single_form").index($( "#file_select" ))
124 divIndex = $(".single_form").index($( "#file_select" ))
125 $(".single_form").slice(divIndex).empty()
125 $(".single_form").slice(divIndex).empty()
126 // second populate the file_list html if '0' not selected
126 // second populate the file_list html if '0' not selected
127 if (expId != '0') {
127 if (expId != '0') {
128 $(".single_form").slice(divIndex,divIndex+1).load(url);
128 $(".single_form").slice(divIndex,divIndex+1).load(url);
129 }
129 }
130 }
130 }
131
131
132 function changeFile (select) {
132 function changeFile (select) {
133 var basename = select.options[select.selectedIndex].value;
133 var basename = select.options[select.selectedIndex].value;
134 {% if form.exp_id %}
134 {% if form.exp_id %}
135 var url = '{% url 'change_files' %}' + '?experiment_list={{ form.exp_id.label }}&file_list=' + basename;
135 var url = '{% url 'change_files' %}' + '?experiment_list={{ form.exp_id.label }}&file_list=' + basename;
136 {% else %}
136 {% else %}
137 var exp_id = $("#id_experiment_list")[0].options[$("#id_experiment_list")[0].selectedIndex].value;
137 var exp_id = $("#id_experiment_list")[0].options[$("#id_experiment_list")[0].selectedIndex].value;
138 var url = '{% url 'change_files' %}' + '?experiment_list=' + exp_id + '&file_list=' + basename;
138 var url = '{% url 'change_files' %}' + '?experiment_list=' + exp_id + '&file_list=' + basename;
139 {% endif %}
139 {% endif %}
140 // first delete all forms that are now out of date
140 // first delete all forms that are now out of date
141 divIndex = $(".single_form").index($( "#file_buttons" ))
141 divIndex = $(".single_form").index($( "#file_buttons" ))
142 $(".single_form").slice(divIndex).empty()
142 $(".single_form").slice(divIndex).empty()
143 // second populate the file_list html if '0' not selected
143 // second populate the file_list html if '0' not selected
144 if (basename != '0') {
144 if (basename != '0') {
145 $(".single_form").slice(divIndex,divIndex+1).load(url);
145 $(".single_form").slice(divIndex,divIndex+1).load(url);
146 }
146 }
147 }
147 }
148
148
149 {% include "madweb/fileDownload.js" %}
149 {% include "madweb/fileDownload.js" %}
150
150
151 </script>
151 </script>
152 {% endblock %}
152 {% endblock %}
153
153
154
154
155 {% block isGlobal %}
155 {% block isGlobal %}
156 <div class="col-md-12 single_form" id="isGlobal">
156 <div class="col-md-12 single_form" id="isGlobal">
157 {{ form.isGlobal.label }} {{ form.isGlobal }}
157 {{ form.isGlobal.label }} {{ form.isGlobal }}
158 </div> <!-- end subdivide -->
158 </div> <!-- end subdivide -->
159 {% endblock %}
159 {% endblock %}
160
160
161 {% block categories %}
161 {% block categories %}
162 <!-- subdivide selection column for categories to be possibly filled in by ajax - single_form 0 -->
162 <!-- subdivide selection column for categories to be possibly filled in by ajax - single_form 0 -->
163 <div class="col-md-12 single_form" id="categories">
163 <div class="col-md-12 single_form" id="categories">
164
164
165 {% if form.categories %}
165 {% if form.categories %}
166 {% include "madweb/categories.html" %}
166 {% include "madweb/categories.html" %}
167 {% endif %}
167 {% endif %}
168
168
169 </div> <!-- end subdivide -->
169 </div> <!-- end subdivide -->
170 {% endblock %}
170 {% endblock %}
171
171
172
172
173 {% block instruments %}
173 {% block instruments %}
174 <!-- subdivide selection column for instruments to be possibly filled in by ajax - single_form 0 -->
174 <!-- subdivide selection column for instruments to be possibly filled in by ajax - single_form 0 -->
175 <div class="col-md-12 single_form" id="instruments">
175 <div class="col-md-12 single_form" id="instruments">
176
176
177 {% if form.instruments %}
177 {% if form.instruments %}
178 {% include "madweb/instruments.html" %}
178 {% include "madweb/instruments.html" %}
179 {% endif %}
179 {% endif %}
180
180
181 </div> <!-- end subdivide -->
181 </div> <!-- end subdivide -->
182 {% endblock %}
182 {% endblock %}
183
183
184
184
185 {% block years %}
185 {% block years %}
186 <!-- subdivide selection column for year to be possibly filled in by ajax - single_form 1 -->
186 <!-- subdivide selection column for year to be possibly filled in by ajax - single_form 1 -->
187 <div class="col-md-12 single_form" id="years">
187 <div class="col-md-12 single_form" id="years">
188
188
189 {% if form.years %}
189 {% if form.years %}
190 {% include "madweb/years.html" %}
190 {% include "madweb/years.html" %}
191 {% endif %}
191 {% endif %}
192
192
193 </div> <!-- end subdivide -->
193 </div> <!-- end subdivide -->
194 {% endblock %}
194 {% endblock %}
195
195
196
196
197 {% block months %}
197 {% block months %}
198 <!-- subdivide selection column for month to be possibly filled in by ajax - single_form 1 -->
198 <!-- subdivide selection column for month to be possibly filled in by ajax - single_form 1 -->
199 <div class="col-md-12 single_form" id="months">
199 <div class="col-md-12 single_form" id="months">
200
200
201 {% if form.months %}
201 {% if form.months %}
202 {% include "madweb/months.html" %}
202 {% include "madweb/months.html" %}
203 {% endif %}
203 {% endif %}
204
204
205 </div> <!-- end subdivide -->
205 </div> <!-- end subdivide -->
206 {% endblock %}
206 {% endblock %}
207
207
208
208
209 {% block calendar %}
209 {% block calendar %}
210 <!-- subdivide selection column for calendar to be possibly filled in by ajax - single_form 2 -->
210 <!-- subdivide selection column for calendar to be possibly filled in by ajax - single_form 2 -->
211 <div class="col-md-12 single_form" id="calendar">
211 <div class="col-md-12 single_form" id="calendar">
212
212
213 {% if form.days %}
213 {% if form.days %}
214 {% include "madweb/calendar.html" %}
214 {% include "madweb/calendar.html" %}
215 {% endif %}
215 {% endif %}
216
216
217 </div> <!-- end subdivide -->
217 </div> <!-- end subdivide -->
218 {% endblock %}
218 {% endblock %}
219
219
220 {% block experiment_select %}
220 {% block experiment_select %}
221 <!-- this select only appears if there are multiple experiments in the day -->
221 <!-- this select only appears if there are multiple experiments in the day -->
222 <div class="col-md-12 single_form" id="experiment_select">
222 <div class="col-md-12 single_form" id="experiment_select">
223 {% if form.experiment_list %}
223 {% if form.experiment_list %}
224 {% include "madweb/exp_list.html" %}
224 {% include "madweb/exp_list.html" %}
225 {% endif %}
225 {% endif %}
226 </div> <!-- end subdivide -->
226 </div> <!-- end subdivide -->
227 {% endblock %}
227 {% endblock %}
228
228
229 {% block file_select %}
229 {% block file_select %}
230 <!-- file select div -->
230 <!-- file select div -->
231 <div class="col-md-12 single_form" id="file_select">
231 <div class="col-md-12 single_form" id="file_select">
232 {% if form.file_list|length > 1 %}
232 {% if form.file_list|length > 1 %}
233 {% include "madweb/file_list.html" %}
233 {% include "madweb/file_list.html" %}
234 {% elif form.days and not form.experiment_list %}
234 {% elif form.days and not form.experiment_list %}
235 <center><p> This experiment has no Madrigal CEDAR format Hdf5 files. Showing only plots and auxillary files instead.</p></center>
235 <center><p> This experiment has no Madrigal CEDAR format Hdf5 files. Showing only plots and auxillary files instead.</p></center>
236 {% include "madweb/show_plots.html" %}
236 {% include "madweb/show_plots.html" %}
237 {% endif %}
237 {% endif %}
238 </div> <!-- end subdivide -->
238 </div> <!-- end subdivide -->
239 {% endblock %}
239 {% endblock %}
240
240
241 {% block file_buttons %}
241 {% block file_buttons %}
242 <!-- file select div -->
242 <!-- file select div -->
243 <div class="col-md-12 single_form" id="file_buttons">
243 <div class="col-md-12 single_form" id="file_buttons">
244 {% if form.file_buttons %}
244 {% if form.file_buttons %}
245 {% include "madweb/file_buttons.html" %}
245 {% include "madweb/file_buttons.html" %}
246 {% endif %}
246 {% endif %}
247 </div> <!-- end subdivide -->
247 </div> <!-- end subdivide -->
248 <div>&nbsp;</div>
248 <div>&nbsp;</div>
249 {% endblock %}
249 {% endblock %}
250
250
251 {% block file_data %}
251 {% block file_data %}
252 <!-- file select div -->
252 <!-- file select div -->
253 <div class="col-md-12 single_form" id="file_data">
253 <div class="col-md-12 single_form" id="file_data">
254 {% if form.show_plots %}
254 {% if form.show_plots %}
255 {% include "madweb/show_plots.html" %}
255 {% include "madweb/show_plots.html" %}
256 {% endif %}
256 {% endif %}
257 </div> <!-- end subdivide -->
257 </div> <!-- end subdivide -->
258 {% endblock %}
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
@@ -1,239 +1,242
1 '''
1 '''
2 Created on Jul 16, 2013
2 Created on Jul 16, 2013
3
3
4 @author: Jose Antonio Sal y Rosas Celi
4 @author: Jose Antonio Sal y Rosas Celi
5 @contact: arturo.jasyrc@gmail.com
5 @contact: arturo.jasyrc@gmail.com
6
6
7 As imported and slightly modified by Bill Rideout Jan 20, 2015
7 As imported and slightly modified by Bill Rideout Jan 20, 2015
8
8
9 $Id: urls.py 7246 2020-10-12 14:54:26Z brideout $
9 $Id: urls.py 7246 2020-10-12 14:54:26Z brideout $
10 '''
10 '''
11
11
12 from django.conf.urls import url
12 from django.conf.urls import url
13 from . import views
13 from . import views
14
14
15 urlpatterns = [ url(r'^$',
15 urlpatterns = [ url(r'^$',
16 views.index,
16 views.index,
17 name='index'),
17 name='index'),
18 url(r'^index.html/?$',
18 url(r'^index.html/?$',
19 views.index,
19 views.index,
20 name='index'),
20 name='index'),
21 url(r'^single/?$',
21 url(r'^single/?$',
22 views.check_registration(views.view_single),
22 views.check_registration(views.view_single),
23 name='view_single'),
23 name='view_single'),
24 url(r'^register/?$',
24 url(r'^register/?$',
25 views.view_registration,
25 views.view_registration,
26 name='view_registration'),
26 name='view_registration'),
27 url(r'^getCategories/?$',
27 url(r'^getCategories/?$',
28 views.get_categories,
28 views.get_categories,
29 name='get_categories'),
29 name='get_categories'),
30 url(r'^getInstruments/?$',
30 url(r'^getInstruments/?$',
31 views.get_instruments,
31 views.get_instruments,
32 name='get_instruments'),
32 name='get_instruments'),
33 url(r'^getYears/?$',
33 url(r'^getYears/?$',
34 views.get_years,
34 views.get_years,
35 name='get_years'),
35 name='get_years'),
36 url(r'^getMonths/?$',
36 url(r'^getMonths/?$',
37 views.get_months,
37 views.get_months,
38 name='get_months'),
38 name='get_months'),
39 url(r'^getCalendar/?$',
39 url(r'^getCalendar/?$',
40 views.get_calendar,
40 views.get_calendar,
41 name='get_calendar'),
41 name='get_calendar'),
42 url(r'^populateCalendarExperiment/?$',
42 url(r'^populateCalendarExperiment/?$',
43 views.populate_calendar_experiment,
43 views.populate_calendar_experiment,
44 name='populate_calendar_experiment'),
44 name='populate_calendar_experiment'),
45 url(r'^getFiles/?$',
45 url(r'^getFiles/?$',
46 views.get_files,
46 views.get_files,
47 name='get_files'),
47 name='get_files'),
48 url(r'^changeFiles/?$',
48 url(r'^changeFiles/?$',
49 views.change_files,
49 views.change_files,
50 name='change_files'),
50 name='change_files'),
51 url(r'^showPlots/?$',
51 url(r'^showPlots/?$',
52 views.show_plots,
52 views.show_plots,
53 name='show_plots'),
53 name='show_plots'),
54 url(r'^view_plot/?$',
55 views.view_plot,
56 name='plot'),
54 url(r'^downloadAsIs/?$',
57 url(r'^downloadAsIs/?$',
55 views.download_as_is,
58 views.download_as_is,
56 name='download_as_is'),
59 name='download_as_is'),
57 url(r'^downloadFileAsIs/?$',
60 url(r'^downloadFileAsIs/?$',
58 views.download_file_as_is,
61 views.download_file_as_is,
59 name='download_file_as_is'),
62 name='download_file_as_is'),
60 url(r'^printAsIs/?$',
63 url(r'^printAsIs/?$',
61 views.print_as_is,
64 views.print_as_is,
62 name='print_as_is'),
65 name='print_as_is'),
63 url(r'^listRecords/?$',
66 url(r'^listRecords/?$',
64 views.list_records,
67 views.list_records,
65 name='list_records'),
68 name='list_records'),
66 url(r'^showInfo/?$',
69 url(r'^showInfo/?$',
67 views.show_info,
70 views.show_info,
68 name='show_info'),
71 name='show_info'),
69 url(r'^showDoi/?$',
72 url(r'^showDoi/?$',
70 views.show_doi,
73 views.show_doi,
71 name='show_doi'),
74 name='show_doi'),
72 url(r'^getAdvanced/?$',
75 url(r'^getAdvanced/?$',
73 views.get_advanced,
76 views.get_advanced,
74 name='get_advanced'),
77 name='get_advanced'),
75 url(r'^advancedDownload/?$',
78 url(r'^advancedDownload/?$',
76 views.advanced_download,
79 views.advanced_download,
77 name='advanced_download'),
80 name='advanced_download'),
78 url(r'^advancedPrint/?$',
81 url(r'^advancedPrint/?$',
79 views.advanced_print,
82 views.advanced_print,
80 name='advanced_print'),
83 name='advanced_print'),
81 url(r'^list/?$',
84 url(r'^list/?$',
82 views.check_registration(views.view_list),
85 views.check_registration(views.view_list),
83 name='view_list'),
86 name='view_list'),
84 url(r'^downloadAsIsScript/?$',
87 url(r'^downloadAsIsScript/?$',
85 views.download_as_is_script,
88 views.download_as_is_script,
86 name='download_as_is_script'),
89 name='download_as_is_script'),
87 url(r'^generateDownloadFilesScript/?$',
90 url(r'^generateDownloadFilesScript/?$',
88 views.generate_download_files_script,
91 views.generate_download_files_script,
89 name='generate_download_files_script'),
92 name='generate_download_files_script'),
90 url(r'^downloadAdvancedScript/?$',
93 url(r'^downloadAdvancedScript/?$',
91 views.download_advanced_script,
94 views.download_advanced_script,
92 name='download_advanced_script'),
95 name='download_advanced_script'),
93 url(r'^generateDownloadAdvancedScript/?$',
96 url(r'^generateDownloadAdvancedScript/?$',
94 views.generate_download_advanced_script,
97 views.generate_download_advanced_script,
95 name='generate_download_advanced_script'),
98 name='generate_download_advanced_script'),
96 url(r'^generateParmsScript/?$',
99 url(r'^generateParmsScript/?$',
97 views.generate_parms_script,
100 views.generate_parms_script,
98 name='generate_parms_script'),
101 name='generate_parms_script'),
99 url(r'^generateParmsFiltersScript/?$',
102 url(r'^generateParmsFiltersScript/?$',
100 views.generate_parms_filters_script,
103 views.generate_parms_filters_script,
101 name='generate_parms_filters_script'),
104 name='generate_parms_filters_script'),
102 url(r'^listExperiments/?$',
105 url(r'^listExperiments/?$',
103 views.list_experiments,
106 views.list_experiments,
104 name='list_experiments'),
107 name='list_experiments'),
105 url(r'^viewRecordPlot/?$',
108 url(r'^viewRecordPlot/?$',
106 views.view_record_plot,
109 views.view_record_plot,
107 name='view_record_plot'),
110 name='view_record_plot'),
108 url(r'^viewRecordImage/?$',
111 url(r'^viewRecordImage/?$',
109 views.view_record_image,
112 views.view_record_image,
110 name='view_record_image'),
113 name='view_record_image'),
111 url(r'^showExperiment/?$',
114 url(r'^showExperiment/?$',
112 views.check_registration(views.show_experiment),
115 views.check_registration(views.show_experiment),
113 name='show_experiment'),
116 name='show_experiment'),
114 url(r'^madExperiment.cgi/*$',
117 url(r'^madExperiment.cgi/*$',
115 views.check_registration(views.show_experiment_v2),
118 views.check_registration(views.show_experiment_v2),
116 name='show_experiment_v2'),
119 name='show_experiment_v2'),
117 url(r'^chooseScript/?$',
120 url(r'^chooseScript/?$',
118 views.check_registration(views.choose_script),
121 views.check_registration(views.choose_script),
119 name='choose_script'),
122 name='choose_script'),
120 url(r'^ftp/$',
123 url(r'^ftp/$',
121 views.check_registration(views.ftp),
124 views.check_registration(views.ftp),
122 name='ftp'),
125 name='ftp'),
123 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/$',
126 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/$',
124 views.ftp_instrument,
127 views.ftp_instrument,
125 name='ftp_instrument'),
128 name='ftp_instrument'),
126 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/year/(\d+)/$',
129 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/year/(\d+)/$',
127 views.ftp_year,
130 views.ftp_year,
128 name='ftp_year'),
131 name='ftp_year'),
129 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/year/(\d+)/kindat/(\d+)/$',
132 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/year/(\d+)/kindat/(\d+)/$',
130 views.ftp_kindat,
133 views.ftp_kindat,
131 name='ftp_kindat'),
134 name='ftp_kindat'),
132 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/year/(\d+)/kindat/(\d+)/format/([^/]+)/$',
135 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/year/(\d+)/kindat/(\d+)/format/([^/]+)/$',
133 views.ftp_files,
136 views.ftp_files,
134 name='ftp_files'),
137 name='ftp_files'),
135 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/year/(\d+)/kindat/(\d+)/format/([^/]+)/fullFilename/([^/]+)/$',
138 url(r'^ftp/fullname/([^/]+)/email/([^/]+)/affiliation/([^/]+)/kinst/(\d+)/year/(\d+)/kindat/(\d+)/format/([^/]+)/fullFilename/([^/]+)/$',
136 views.ftp_download,
139 views.ftp_download,
137 name='ftp_download'),
140 name='ftp_download'),
138 url(r'ftpMultipleDownload/$',
141 url(r'ftpMultipleDownload/$',
139 views.ftp_multiple_download,
142 views.ftp_multiple_download,
140 name='ftp_multiple_download'),
143 name='ftp_multiple_download'),
141 url(r'^instMetadata/?$',
144 url(r'^instMetadata/?$',
142 views.instrument_metadata,
145 views.instrument_metadata,
143 name='instrument_metadata'),
146 name='instrument_metadata'),
144 url(r'^siteMetadata/?$',
147 url(r'^siteMetadata/?$',
145 views.site_metadata,
148 views.site_metadata,
146 name='site_metadata'),
149 name='site_metadata'),
147 url(r'^parameterMetadata/?$',
150 url(r'^parameterMetadata/?$',
148 views.parameter_metadata,
151 views.parameter_metadata,
149 name='parameter_metadata'),
152 name='parameter_metadata'),
150 url(r'^kindatMetadata/?$',
153 url(r'^kindatMetadata/?$',
151 views.kindat_metadata,
154 views.kindat_metadata,
152 name='kindat_metadata'),
155 name='kindat_metadata'),
153 url(r'^madCalculator/?$',
156 url(r'^madCalculator/?$',
154 views.madrigal_calculator,
157 views.madrigal_calculator,
155 name='madrigal_calculator'),
158 name='madrigal_calculator'),
156 url(r'^madCalculatorOutput/?$',
159 url(r'^madCalculatorOutput/?$',
157 views.madrigal_calculator_output,
160 views.madrigal_calculator_output,
158 name='madrigal_calculator_output'),
161 name='madrigal_calculator_output'),
159 url(r'^getMetadata/*$',
162 url(r'^getMetadata/*$',
160 views.get_metadata,
163 views.get_metadata,
161 name='get_metadata'),
164 name='get_metadata'),
162 url(r'^looker/?$',
165 url(r'^looker/?$',
163 views.looker_main,
166 views.looker_main,
164 name='looker_main'),
167 name='looker_main'),
165 url(r'^lookerForm/?$',
168 url(r'^lookerForm/?$',
166 views.looker_form,
169 views.looker_form,
167 name='looker_form'),
170 name='looker_form'),
168 url(r'^lookerOutput/?$',
171 url(r'^lookerOutput/?$',
169 views.looker_output,
172 views.looker_output,
170 name='looker_output'),
173 name='looker_output'),
171 url(r'^getVersionService.py/*$',
174 url(r'^getVersionService.py/*$',
172 views.get_version_service,
175 views.get_version_service,
173 name='get_version_service'),
176 name='get_version_service'),
174 url(r'^getInstrumentsService.py/*$',
177 url(r'^getInstrumentsService.py/*$',
175 views.get_instruments_service,
178 views.get_instruments_service,
176 name='get_instruments_service'),
179 name='get_instruments_service'),
177 url(r'^getExperimentsService.py/*$',
180 url(r'^getExperimentsService.py/*$',
178 views.get_experiments_service,
181 views.get_experiments_service,
179 name='get_experiments_service'),
182 name='get_experiments_service'),
180 url(r'^getExperimentFilesService.py/*$',
183 url(r'^getExperimentFilesService.py/*$',
181 views.get_experiment_files_service,
184 views.get_experiment_files_service,
182 name='get_experiment_files_service'),
185 name='get_experiment_files_service'),
183 url(r'^getParametersService.py/*$',
186 url(r'^getParametersService.py/*$',
184 views.get_parameters_service,
187 views.get_parameters_service,
185 name='get_parameters_service'),
188 name='get_parameters_service'),
186 url(r'^isprintService.py/*$',
189 url(r'^isprintService.py/*$',
187 views.isprint_service,
190 views.isprint_service,
188 name='isprint_service'),
191 name='isprint_service'),
189 url(r'^getMadfile.cgi/*$',
192 url(r'^getMadfile.cgi/*$',
190 views.get_madfile_service,
193 views.get_madfile_service,
191 name='get_madfile_service'),
194 name='get_madfile_service'),
192 url(r'^madCalculatorService.py/*$',
195 url(r'^madCalculatorService.py/*$',
193 views.mad_calculator_service,
196 views.mad_calculator_service,
194 name='mad_calculator_service'),
197 name='mad_calculator_service'),
195 url(r'^madTimeCalculatorService.py/*$',
198 url(r'^madTimeCalculatorService.py/*$',
196 views.mad_time_calculator_service,
199 views.mad_time_calculator_service,
197 name='mad_time_calculator_service'),
200 name='mad_time_calculator_service'),
198 url(r'^madCalculator2Service.py/*$',
201 url(r'^madCalculator2Service.py/*$',
199 views.mad_calculator2_service,
202 views.mad_calculator2_service,
200 name='mad_calculator2_service'),
203 name='mad_calculator2_service'),
201 url(r'^madCalculator2Service.py',
204 url(r'^madCalculator2Service.py',
202 views.mad_calculator2_service,
205 views.mad_calculator2_service,
203 name='mad_calculator2_service'),
206 name='mad_calculator2_service'),
204 url(r'^madCalculator3Service.py/*$',
207 url(r'^madCalculator3Service.py/*$',
205 views.mad_calculator3_service,
208 views.mad_calculator3_service,
206 name='mad_calculator3_service'),
209 name='mad_calculator3_service'),
207 url(r'^madCalculator3Service.py',
210 url(r'^madCalculator3Service.py',
208 views.mad_calculator3_service,
211 views.mad_calculator3_service,
209 name='mad_calculator3_service'),
212 name='mad_calculator3_service'),
210 url(r'^geodeticToRadarService.py',
213 url(r'^geodeticToRadarService.py',
211 views.geodetic_to_radar_service,
214 views.geodetic_to_radar_service,
212 name='geodetic_to_radar_service'),
215 name='geodetic_to_radar_service'),
213 url(r'^radarToGeodeticService.py',
216 url(r'^radarToGeodeticService.py',
214 views.radar_to_geodetic_service,
217 views.radar_to_geodetic_service,
215 name='radar_to_geodetic_service'),
218 name='radar_to_geodetic_service'),
216 url(r'^listFileTimesService.py',
219 url(r'^listFileTimesService.py',
217 views.list_file_times_service,
220 views.list_file_times_service,
218 name='list_file_times_service'),
221 name='list_file_times_service'),
219 url(r'^downloadWebFileService.py',
222 url(r'^downloadWebFileService.py',
220 views.download_web_file_service,
223 views.download_web_file_service,
221 name='download_web_file_service'),
224 name='download_web_file_service'),
222 url(r'^traceMagneticFieldService.py',
225 url(r'^traceMagneticFieldService.py',
223 views.trace_magnetic_field_service,
226 views.trace_magnetic_field_service,
224 name='trace_magnetic_field_service'),
227 name='trace_magnetic_field_service'),
225 url(r'^globalFileSearchService.py',
228 url(r'^globalFileSearchService.py',
226 views.global_file_search_service,
229 views.global_file_search_service,
227 name='global_file_search_service'),
230 name='global_file_search_service'),
228 url(r'^getUrlListFromGroupIdService.py',
231 url(r'^getUrlListFromGroupIdService.py',
229 views.get_url_list_from_group_id_service,
232 views.get_url_list_from_group_id_service,
230 name='get_url_list_from_group_id_service'),
233 name='get_url_list_from_group_id_service'),
231 url(r'^setGroupIdFromUrlListService.py',
234 url(r'^setGroupIdFromUrlListService.py',
232 views.set_group_id_from_url_list_service,
235 views.set_group_id_from_url_list_service,
233 name='set_group_id_from_url_list_service'),
236 name='set_group_id_from_url_list_service'),
234 url(r'docs/name/(.+)$',
237 url(r'docs/name/(.+)$',
235 views.docs,
238 views.docs,
236 name='docs'),
239 name='docs'),
237
240
238 ]
241 ]
239
242
@@ -1,3331 +1,3535
1 '''
1 '''
2
2
3 @author: Bill Rideout
3 @author: Bill Rideout
4 @contact: brideout@haystack.mit.edu
4 @contact: brideout@haystack.mit.edu
5
5
6 $Id: views.py 7345 2021-03-30 18:30:32Z brideout $
6 $Id: views.py 7345 2021-03-30 18:30:32Z brideout $
7 '''
7 '''
8 # standard python imports
8 # standard python imports
9 import os.path
9 import os.path
10 import urllib
10 import urllib
11 import os, sys
11 import os, sys
12 import json
12 import json
13 import datetime, time
13 import datetime, time
14 import glob
14 import glob
15 import re
15 import re
16 import subprocess
16 import subprocess
17 import io
17 import io
18 import collections
18 import collections
19 import shutil
19 import shutil
20 import mimetypes
20 import mimetypes
21 import tempfile
21 import tempfile
22 import random
22 import random
23
23
24 # django imports
24 # django imports
25 from django.shortcuts import render, redirect
25 from django.shortcuts import render, redirect
26 from django.views.decorators.csrf import csrf_exempt
26 from django.views.decorators.csrf import csrf_exempt
27 from django.template.context import RequestContext
27 from django.template.context import RequestContext
28 #from django.conf import settings
28 #from django.conf import settings
29 try:
29 try:
30 from django.urls import reverse
30 from django.urls import reverse
31 except ImportError:
31 except ImportError:
32 from django.core.urlresolvers import reverse
32 from django.core.urlresolvers import reverse
33 from django.http import HttpResponse, HttpResponseRedirect, StreamingHttpResponse
33 from django.http import HttpResponse, HttpResponseRedirect, StreamingHttpResponse
34 import django.utils.http
34 import django.utils.http
35 import django.core.files
35 import django.core.files
36 import django.utils.safestring
36 import django.utils.safestring
37 from wsgiref.util import FileWrapper
37 from wsgiref.util import FileWrapper
38
38
39 # third party imports
39 # third party imports
40 import numpy
40 import numpy
41 import plotly.offline as py
42 import plotly.graph_objs as go
43 import h5py
41
44
42
45
43 # madrigal imports
46 # madrigal imports
44 import madrigal._derive
47 import madrigal._derive
45 import madrigal.metadata
48 import madrigal.metadata
46 import madrigal.ui.web
49 import madrigal.ui.web
47 import madrigal.cedar
50 import madrigal.cedar
48 import madrigal.isprint
51 import madrigal.isprint
49 import madweb.forms
52 import madweb.forms
50
53
51
54
52 # temp only
55 # temp only
53 import logging
56 import logging
54
57
55
58
56 # constants
59 # constants
57 formatDict = collections.OrderedDict()
60 formatDict = collections.OrderedDict()
58 formatDict['hdf5'] = 'Hdf5'
61 formatDict['hdf5'] = 'Hdf5'
59 formatDict['netCDF4'] = 'netCDF4'
62 formatDict['netCDF4'] = 'netCDF4'
60 formatDict['ascii'] = 'Column-delimited ascii'
63 formatDict['ascii'] = 'Column-delimited ascii'
61 maxSize = 50000000 # 50 MB cutoff
64 maxSize = 50000000 # 50 MB cutoff
62
65
63
66
64
67
65
68
66 def index(request):
69 def index(request):
67 """index is the home page view
70 """index is the home page view
68 """
71 """
69 madDB = madrigal.metadata.MadrigalDB()
72 madDB = madrigal.metadata.MadrigalDB()
70 bg_color = madDB.getBackgroundColor()
73 bg_color = madDB.getBackgroundColor()
71 welcome = madDB.getIndexHead()
74 welcome = madDB.getIndexHead()
72 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
75 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
73 siteName, siteList = madWebObj.getSiteInfo()
76 siteName, siteList = madWebObj.getSiteInfo()
74 rulesRoadHtml = madDB.getLocalRulesOfRoad()
77 rulesRoadHtml = madDB.getLocalRulesOfRoad()
75 template_dict = {'home_active': 'class="active"', 'site_name': siteName, 'site_list': siteList,
78 template_dict = {'home_active': 'class="active"', 'site_name': siteName, 'site_list': siteList,
76 'rulesOfRoad':django.utils.safestring.mark_safe(rulesRoadHtml),
79 'rulesOfRoad':django.utils.safestring.mark_safe(rulesRoadHtml),
77 'bg_color': bg_color, 'welcome': welcome}
80 'bg_color': bg_color, 'welcome': welcome}
78 return render(request, 'madweb/index.html', template_dict)
81 return render(request, 'madweb/index.html', template_dict)
79
82
80 @csrf_exempt
83 @csrf_exempt
81 def check_registration(view):
84 def check_registration(view):
82 def check_cookies(request, *args, **kwargs):
85 def check_cookies(request, *args, **kwargs):
83 # this view checks if all the needed cookies are set
86 # this view checks if all the needed cookies are set
84 cookieDict = request.COOKIES
87 cookieDict = request.COOKIES
85 try:
88 try:
86 cookieDict['user_fullname']
89 cookieDict['user_fullname']
87 cookieDict['user_email']
90 cookieDict['user_email']
88 cookieDict['user_affiliation']
91 cookieDict['user_affiliation']
89 # no need to register
92 # no need to register
90 return(view(request, *args, **kwargs))
93 return(view(request, *args, **kwargs))
91 except KeyError:
94 except KeyError:
92 return(HttpResponseRedirect(reverse('view_registration') + '?redirect=%s' % (request.get_full_path())))
95 return(HttpResponseRedirect(reverse('view_registration') + '?redirect=%s' % (request.get_full_path())))
93
96
94 return(check_cookies)
97 return(check_cookies)
95
98
96
99
97 def view_registration(request):
100 def view_registration(request):
98 madDB = madrigal.metadata.MadrigalDB()
101 madDB = madrigal.metadata.MadrigalDB()
99 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
102 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
100 siteName, siteList = madWeb.getSiteInfo()
103 siteName, siteList = madWeb.getSiteInfo()
101 redirect = 'index' # default is to redirect to home page
104 redirect = 'index' # default is to redirect to home page
102 if request.method == 'GET':
105 if request.method == 'GET':
103 if 'redirect' in request.GET:
106 if 'redirect' in request.GET:
104 redirect = request.GET['redirect']
107 redirect = request.GET['redirect']
105 for key in request.GET:
108 for key in request.GET:
106 if key not in ('redirect', 'user_fullname', 'user_email', 'user_affiliation'):
109 if key not in ('redirect', 'user_fullname', 'user_email', 'user_affiliation'):
107 redirect += '&%s=%s' % (key, request.GET[key])
110 redirect += '&%s=%s' % (key, request.GET[key])
108 if len(list(request.GET.keys())) > 0 and 'user_fullname' in request.GET:
111 if len(list(request.GET.keys())) > 0 and 'user_fullname' in request.GET:
109 form = madweb.forms.RegisterForm(request.GET)
112 form = madweb.forms.RegisterForm(request.GET)
110 if form.is_valid():
113 if form.is_valid():
111 # write cookies and continue to main page
114 # write cookies and continue to main page
112 max_age = 3600*24*365 # one year
115 max_age = 3600*24*365 # one year
113 if redirect == 'index':
116 if redirect == 'index':
114 response = HttpResponseRedirect(reverse('index'))
117 response = HttpResponseRedirect(reverse('index'))
115 else:
118 else:
116 response = HttpResponseRedirect(redirect)
119 response = HttpResponseRedirect(redirect)
117 response.set_cookie('user_fullname', form.cleaned_data['user_fullname'], max_age=max_age, samesite='Strict')
120 response.set_cookie('user_fullname', form.cleaned_data['user_fullname'], max_age=max_age, samesite='Strict')
118 response.set_cookie('user_email', form.cleaned_data['user_email'], max_age=max_age, samesite='Strict')
121 response.set_cookie('user_email', form.cleaned_data['user_email'], max_age=max_age, samesite='Strict')
119 response.set_cookie('user_affiliation', form.cleaned_data['user_affiliation'], max_age=max_age, samesite='Strict')
122 response.set_cookie('user_affiliation', form.cleaned_data['user_affiliation'], max_age=max_age, samesite='Strict')
120 return(response)
123 return(response)
121 else:
124 else:
122 form = madweb.forms.RegisterForm()
125 form = madweb.forms.RegisterForm()
123
126
124 else:
127 else:
125 form = madweb.forms.RegisterForm()
128 form = madweb.forms.RegisterForm()
126 return render(request, 'madweb/register.html', {'form': form, 'home_active': 'class="active"',
129 return render(request, 'madweb/register.html', {'form': form, 'home_active': 'class="active"',
127 'site_name': siteName, 'site_list': siteList,
130 'site_name': siteName, 'site_list': siteList,
128 'redirect': redirect})
131 'redirect': redirect})
129
132
130
133
131
134
132
135
133
136
134
137
135 def view_single(request):
138 def view_single(request):
136 """view_single is the single experiment view. It is supplemented by ajax views to speed performamnce,
139 """view_single is the single experiment view. It is supplemented by ajax views to speed performamnce,
137 but this view can also create the entire page given a complete query string
140 but this view can also create the entire page given a complete query string
138 """
141 """
139 responseDict = {'single_active': 'class="active"'}
142 responseDict = {'single_active': 'class="active"'}
140 cookieDict = request.COOKIES
143 cookieDict = request.COOKIES
141 user_email = cookieDict['user_email']
144 user_email = cookieDict['user_email']
142 queryDict = request.GET.copy()
145 queryDict = request.GET.copy()
143 queryDict['user_email'] = user_email
146 queryDict['user_email'] = user_email
144 madDB = madrigal.metadata.MadrigalDB()
147 madDB = madrigal.metadata.MadrigalDB()
145 bg_color = madDB.getBackgroundColor()
148 bg_color = madDB.getBackgroundColor()
146 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
149 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
147 siteName, siteList = madWeb.getSiteInfo()
150 siteName, siteList = madWeb.getSiteInfo()
148 form = madweb.forms.SingleExpDefaultForm(queryDict)
151 form = madweb.forms.SingleExpDefaultForm(queryDict)
149 if not form.is_valid():
152 if not form.is_valid():
150 # new page
153 # new page
151 form = madweb.forms.SingleExpDefaultForm()
154 form = madweb.forms.SingleExpDefaultForm()
152 responseDict['form'] = form
155 responseDict['form'] = form
153 responseDict['site_name'] = siteName
156 responseDict['site_name'] = siteName
154 responseDict['site_list'] = siteList
157 responseDict['site_list'] = siteList
155 responseDict['redirect_list'] = madWeb.getSingleRedirectList()
158 responseDict['redirect_list'] = madWeb.getSingleRedirectList()
156 if 'instruments' in request.GET:
159 if 'instruments' in request.GET:
157 responseDict['instruments'] = request.GET['instruments']
160 responseDict['instruments'] = request.GET['instruments']
158 if 'years' in request.GET:
161 if 'years' in request.GET:
159 responseDict['years'] = request.GET['years']
162 responseDict['years'] = request.GET['years']
160 if 'months' in request.GET:
163 if 'months' in request.GET:
161 responseDict['months'] = request.GET['months']
164 responseDict['months'] = request.GET['months']
162 try:
165 try:
163 # add extra keys if choosing a file
166 # add extra keys if choosing a file
164 form.fields['file_list']
167 form.fields['file_list']
165 responseDict['loader'] = 'loadSingleForm'
168 responseDict['loader'] = 'loadSingleForm'
166 responseDict['redirect'] = reverse('get_files')
169 responseDict['redirect'] = reverse('get_files')
167 # handle the case with no files
170 # handle the case with no files
168 if len(form.fields['file_list'].choices) < 2:
171 if len(form.fields['file_list'].choices) < 2:
169 form2 = madweb.forms.SingleExpPlotsForm({'experiment_list':form['exp_id'].initial})
172 form2 = madweb.forms.SingleExpPlotsForm({'experiment_list':form['exp_id'].initial})
170 form.fields['plot_list'] = form2.fields['plot_list']
173 form.fields['plot_list'] = form2.fields['plot_list']
171 except:
174 except:
172 pass
175 pass
173 responseDict['bg_color'] = bg_color
176 responseDict['bg_color'] = bg_color
174 return render(request, 'madweb/single.html', responseDict)
177 return render(request, 'madweb/single.html', responseDict)
175
178
176
179
177 def get_categories(request):
180 def get_categories(request):
178 """get_categories is a Ajax call that returns the categories select html to support the
181 """get_categories is a Ajax call that returns the categories select html to support the
179 single experiment UI. Called when a user modifies the isGlobal checkbox.
182 single experiment UI. Called when a user modifies the isGlobal checkbox.
180
183
181 Inputs:
184 Inputs:
182 request
185 request
183 """
186 """
184 form = madweb.forms.SingleExpDefaultForm(request.GET)
187 form = madweb.forms.SingleExpDefaultForm(request.GET)
185
188
186 return render(request, 'madweb/categories.html', {'form': form})
189 return render(request, 'madweb/categories.html', {'form': form})
187
190
188
191
189 def get_instruments(request):
192 def get_instruments(request):
190 """get_instruments is a Ajax call that returns the instruments select html to support the
193 """get_instruments is a Ajax call that returns the instruments select html to support the
191 single experiment UI. Called when a user modifies the categories select field.
194 single experiment UI. Called when a user modifies the categories select field.
192
195
193 Inputs:
196 Inputs:
194 request
197 request
195 """
198 """
196 form = madweb.forms.SingleExpInstForm(request.GET)
199 form = madweb.forms.SingleExpInstForm(request.GET)
197
200
198 return render(request, 'madweb/instruments.html', {'form': form})
201 return render(request, 'madweb/instruments.html', {'form': form})
199
202
200
203
201 def get_years(request):
204 def get_years(request):
202 """get_years is a Ajax call that returns the years select html to support the
205 """get_years is a Ajax call that returns the years select html to support the
203 single experiment UI. Called when a user modifies the instruments select field.
206 single experiment UI. Called when a user modifies the instruments select field.
204
207
205 Inputs:
208 Inputs:
206 request
209 request
207 """
210 """
208 form = madweb.forms.SingleExpYearForm(request.GET)
211 form = madweb.forms.SingleExpYearForm(request.GET)
209
212
210 is_global = madweb.forms.getIsGlobal([], request.GET)
213 is_global = madweb.forms.getIsGlobal([], request.GET)
211
214
212 return render(request, 'madweb/years.html', {'isGlobal': is_global,
215 return render(request, 'madweb/years.html', {'isGlobal': is_global,
213 'form': form})
216 'form': form})
214
217
215
218
216 def get_months(request):
219 def get_months(request):
217 """get_months is a Ajax call that returns the months select html to support the
220 """get_months is a Ajax call that returns the months select html to support the
218 single experiment UI. Called when a user modifies the years select field.
221 single experiment UI. Called when a user modifies the years select field.
219
222
220 Inputs:
223 Inputs:
221 request
224 request
222 """
225 """
223 form = madweb.forms.SingleExpMonthForm(request.GET)
226 form = madweb.forms.SingleExpMonthForm(request.GET)
224
227
225 is_global = madweb.forms.getIsGlobal([], request.GET)
228 is_global = madweb.forms.getIsGlobal([], request.GET)
226 year = int(request.GET['years'])
229 year = int(request.GET['years'])
227 kinst =int(request.GET['instruments'])
230 kinst =int(request.GET['instruments'])
228
231
229 return render(request, 'madweb/months.html', {'isGlobal': is_global,
232 return render(request, 'madweb/months.html', {'isGlobal': is_global,
230 'years': year,
233 'years': year,
231 'form': form})
234 'form': form})
232
235
233
236
234 def get_calendar(request):
237 def get_calendar(request):
235 """get_calendar is a Ajax call that returns the calendar html to support the
238 """get_calendar is a Ajax call that returns the calendar html to support the
236 single experiment UI. Called when a user selects month field.
239 single experiment UI. Called when a user selects month field.
237
240
238 Inputs:
241 Inputs:
239 request
242 request
240 """
243 """
241 is_global = madweb.forms.getIsGlobal([], request.GET)
244 is_global = madweb.forms.getIsGlobal([], request.GET)
242 year = int(request.GET['years'])
245 year = int(request.GET['years'])
243 month = int(request.GET['months'])
246 month = int(request.GET['months'])
244 kinst =int(request.GET['instruments'])
247 kinst =int(request.GET['instruments'])
245
248
246 form = madweb.forms.SingleExpCalendarForm({'years': year,
249 form = madweb.forms.SingleExpCalendarForm({'years': year,
247 'months': month,
250 'months': month,
248 'instruments': kinst})
251 'instruments': kinst})
249
252
250 return render(request, 'madweb/calendar.html', {'isGlobal': is_global,
253 return render(request, 'madweb/calendar.html', {'isGlobal': is_global,
251 'years': year,
254 'years': year,
252 'months': month,
255 'months': month,
253 'instruments': kinst,
256 'instruments': kinst,
254 'form': form})
257 'form': form})
255
258
256
259
257 def populate_calendar_experiment(request):
260 def populate_calendar_experiment(request):
258 """populate_calendar_experiment is a ajax view that returns a json object used by the
261 """populate_calendar_experiment is a ajax view that returns a json object used by the
259 calender widget to populate itself.
262 calender widget to populate itself.
260
263
261 Inputs:
264 Inputs:
262 request
265 request
263 """
266 """
264 is_global = madweb.forms.getIsGlobal([], request.GET)
267 is_global = madweb.forms.getIsGlobal([], request.GET)
265 year = int(request.GET['years'])
268 year = int(request.GET['years'])
266 month = int(request.GET['months'])
269 month = int(request.GET['months'])
267 kinst =int(request.GET['instruments'])
270 kinst =int(request.GET['instruments'])
268 madDB = madrigal.metadata.MadrigalDB()
271 madDB = madrigal.metadata.MadrigalDB()
269 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
272 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
270 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
273 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
271 catId = madInstObj.getCategoryId(kinst)
274 catId = madInstObj.getCategoryId(kinst)
272
275
273 expDays = madWebObj.getDays(kinst, year, month)
276 expDays = madWebObj.getDays(kinst, year, month)
274
277
275 if len(expDays) == 0:
278 if len(expDays) == 0:
276 expDays = madWebObj.getDays(kinst, year, month, optimize=False)
279 expDays = madWebObj.getDays(kinst, year, month, optimize=False)
277
280
278 color = "#999"
281 color = "#999"
279 jsonListFinal = []
282 jsonListFinal = []
280 for expDay in expDays:
283 for expDay in expDays:
281 newdate = '%i/%i/%i' % (expDay.day, expDay.month, expDay.year)
284 newdate = '%i/%i/%i' % (expDay.day, expDay.month, expDay.year)
282 urlperDate = reverse('view_single')
285 urlperDate = reverse('view_single')
283 query_str = '?'
286 query_str = '?'
284 if is_global:
287 if is_global:
285 query_str += 'isGlobal=on&'
288 query_str += 'isGlobal=on&'
286 query_str += 'categories=%i&instruments=%i&years=%i&months=%i&days=%i' % (catId, kinst, year,
289 query_str += 'categories=%i&instruments=%i&years=%i&months=%i&days=%i' % (catId, kinst, year,
287 expDay.month, expDay.day)
290 expDay.month, expDay.day)
288 urlperDate += query_str
291 urlperDate += query_str
289 dayList = [newdate, "", urlperDate, color]
292 dayList = [newdate, "", urlperDate, color]
290 jsonListFinal.append(dayList)
293 jsonListFinal.append(dayList)
291
294
292 return HttpResponse(json.dumps(jsonListFinal), content_type='application/json')
295 return HttpResponse(json.dumps(jsonListFinal), content_type='application/json')
293
296
294
297
295 def get_files(request):
298 def get_files(request):
296 """get_files is a Ajax call that returns the files select html to support the
299 """get_files is a Ajax call that returns the files select html to support the
297 single experiment UI. Called when a user modifies the calendar or experiments fields.
300 single experiment UI. Called when a user modifies the calendar or experiments fields.
298
301
299 Inputs:
302 Inputs:
300 request
303 request
301 """
304 """
302 cookieDict = request.COOKIES
305 cookieDict = request.COOKIES
303 user_email = cookieDict['user_email']
306 user_email = cookieDict['user_email']
304 queryDict = request.GET.copy()
307 queryDict = request.GET.copy()
305 queryDict['user_email'] = user_email
308 queryDict['user_email'] = user_email
306 form = madweb.forms.SingleExpFileForm(queryDict)
309 form = madweb.forms.SingleExpFileForm(queryDict)
307
310
308 is_global = madweb.forms.getIsGlobal([], request.GET)
311 is_global = madweb.forms.getIsGlobal([], request.GET)
309
312
310 return render(request, 'madweb/file_list.html', {'isGlobal': is_global,
313 return render(request, 'madweb/file_list.html', {'isGlobal': is_global,
311 'form': form,
314 'form': form,
312 'loader': 'loadSingleForm',
315 'loader': 'loadSingleForm',
313 'redirect': reverse('get_files')})
316 'redirect': reverse('get_files')})
314
317
315
318
316 def change_files(request):
319 def change_files(request):
317 """change_files is a Ajax call that returns the files options html to support the
320 """change_files is a Ajax call that returns the files options html to support the
318 single experiment UI. Called when a user modifies the files select field.
321 single experiment UI. Called when a user modifies the files select field.
319
322
320 Inputs:
323 Inputs:
321 request
324 request
322 """
325 """
323 expID =int(request.GET['experiment_list'])
326 expID =int(request.GET['experiment_list'])
324 basename = request.GET['file_list']
327 basename = request.GET['file_list']
325 madDB = madrigal.metadata.MadrigalDB()
328 madDB = madrigal.metadata.MadrigalDB()
326 form = madweb.forms.SingleExpButtonsForm(request.GET)
329 form = madweb.forms.SingleExpButtonsForm(request.GET)
327
330
328 return render(request, 'madweb/file_buttons.html', {'form': form,
331 return render(request, 'madweb/file_buttons.html', {'form': form,
329 'plot_label': madDB.getPlotButtonLabel()})
332 'plot_label': madDB.getPlotButtonLabel()})
330
333
331
334
332 def show_plots(request):
335 def show_plots(request):
333 """show_plots is a Ajax call that returns the files data html with plots to support the
336 """show_plots is a Ajax call that returns the files data html with plots to support the
334 single experiment UI. Called when a user modifies the files select field.
337 single experiment UI. Called when a user modifies the files select field.
335
338
336 Inputs:
339 Inputs:
337 request
340 request
338 """
341 """
342 madDB = madrigal.metadata.MadrigalDB()
343 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
344 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
345
339 try:
346 try:
340 expID = int(request.GET['experiment_list'])
347 expID = int(request.GET['experiment_list'])
341 except ValueError:
348 except ValueError:
342 # convert expPath to expID
349 # convert expPath to expID
343 madDB = madrigal.metadata.MadrigalDB()
344 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
345 expID = madWebObj.getExpIDFromExpPath(request.GET['experiment_list'], True)
350 expID = madWebObj.getExpIDFromExpPath(request.GET['experiment_list'], True)
351 plotList = madExpObj.getExpLinksByExpId(expID)
352 if len(plotList) != 0:
346 form = madweb.forms.SingleExpPlotsForm(request.GET)
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 def download_as_is(request):
555 def download_as_is(request):
352 """download_as_is is a Ajax call that returns the download as is html to support the
556 """download_as_is is a Ajax call that returns the download as is html to support the
353 single experiment UI. Called when a user selects download/as is link.
557 single experiment UI. Called when a user selects download/as is link.
354
558
355 Inputs:
559 Inputs:
356 request
560 request
357 """
561 """
358 cookieDict = request.COOKIES
562 cookieDict = request.COOKIES
359 if not 'user_fullname' in cookieDict:
563 if not 'user_fullname' in cookieDict:
360 return(HttpResponse('<p>Cookie with user_fullname required for downloadAsIs</p>'))
564 return(HttpResponse('<p>Cookie with user_fullname required for downloadAsIs</p>'))
361 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
565 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
362 user_email = cookieDict['user_email']
566 user_email = cookieDict['user_email']
363 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
567 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
364 expID =int(request.GET['experiment_list'])
568 expID =int(request.GET['experiment_list'])
365 file_list = request.GET['file_list']
569 file_list = request.GET['file_list']
366 form = madweb.forms.SingleExpDownloadAsIsForm({'format_select':file_list,
570 form = madweb.forms.SingleExpDownloadAsIsForm({'format_select':file_list,
367 'expID': expID})
571 'expID': expID})
368
572
369 return render(request, 'madweb/download_as_is.html', {'form': form, 'exp_id':expID,
573 return render(request, 'madweb/download_as_is.html', {'form': form, 'exp_id':expID,
370 'user_fullname':user_fullname,
574 'user_fullname':user_fullname,
371 'user_email':user_email,
575 'user_email':user_email,
372 'user_affiliation': user_affiliation})
576 'user_affiliation': user_affiliation})
373
577
374
578
375 def download_file_as_is(request):
579 def download_file_as_is(request):
376 """download_file_as_is is a Ajax call that actually downloads a madrigal file.
580 """download_file_as_is is a Ajax call that actually downloads a madrigal file.
377
581
378 Inputs:
582 Inputs:
379 request
583 request
380 """
584 """
381 madDB = madrigal.metadata.MadrigalDB()
585 madDB = madrigal.metadata.MadrigalDB()
382 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
586 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
383 user_fullname = urllib.parse.unquote_plus(request.GET['user_fullname'])
587 user_fullname = urllib.parse.unquote_plus(request.GET['user_fullname'])
384 user_email = request.GET['user_email']
588 user_email = request.GET['user_email']
385 user_affiliation = urllib.parse.unquote_plus(request.GET['user_affiliation'])
589 user_affiliation = urllib.parse.unquote_plus(request.GET['user_affiliation'])
386 exp_id = request.GET['exp_id']
590 exp_id = request.GET['exp_id']
387 basename = request.GET['basename']
591 basename = request.GET['basename']
388 downloadFile = madWebObj.downloadFileAsIs(exp_id, basename, user_fullname, user_email, user_affiliation)
592 downloadFile = madWebObj.downloadFileAsIs(exp_id, basename, user_fullname, user_email, user_affiliation)
389 f = open(downloadFile, 'rb')
593 f = open(downloadFile, 'rb')
390 filename = os.path.basename(downloadFile)
594 filename = os.path.basename(downloadFile)
391 chunk_size = 8192
595 chunk_size = 8192
392 file_type = mimetypes.guess_type(downloadFile)[0]
596 file_type = mimetypes.guess_type(downloadFile)[0]
393 if file_type is None:
597 if file_type is None:
394 file_type = 'application/octet-stream'
598 file_type = 'application/octet-stream'
395 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
599 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
396 content_type=file_type)
600 content_type=file_type)
397 response['Content-Length'] = os.path.getsize(downloadFile)
601 response['Content-Length'] = os.path.getsize(downloadFile)
398 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
602 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
399 response.set_cookie('fileDownload', 'true', path='/', samesite='Strict')
603 response.set_cookie('fileDownload', 'true', path='/', samesite='Strict')
400 return(response)
604 return(response)
401
605
402
606
403 def print_as_is(request):
607 def print_as_is(request):
404 """print_as_is is a Ajax call that returns the text of the ascii file to support the
608 """print_as_is is a Ajax call that returns the text of the ascii file to support the
405 single experiment UI if request.GET has key "text", or the length of the file to be
609 single experiment UI if request.GET has key "text", or the length of the file to be
406 downloaded if not. Called when a user selects print/as is link.
610 downloaded if not. Called when a user selects print/as is link.
407
611
408 Inputs:
612 Inputs:
409 request
613 request
410 """
614 """
411 madDB = madrigal.metadata.MadrigalDB()
615 madDB = madrigal.metadata.MadrigalDB()
412 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
616 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
413 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
617 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
414 madParmObj = madrigal.data.MadrigalParameters(madDB)
618 madParmObj = madrigal.data.MadrigalParameters(madDB)
415
619
416 cookieDict = request.COOKIES
620 cookieDict = request.COOKIES
417 if not 'user_fullname' in cookieDict:
621 if not 'user_fullname' in cookieDict:
418 return(HttpResponse('<p>Cookie with user_fullname required for printAsIs</p>'))
622 return(HttpResponse('<p>Cookie with user_fullname required for printAsIs</p>'))
419 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
623 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
420 user_email = cookieDict['user_email']
624 user_email = cookieDict['user_email']
421 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
625 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
422 expID =int(request.GET['experiment_list'])
626 expID =int(request.GET['experiment_list'])
423 basename = request.GET['file_list']
627 basename = request.GET['file_list']
424 expDir = madExpObj.getExpDirByExpId(int(expID))
628 expDir = madExpObj.getExpDirByExpId(int(expID))
425 if expDir is None:
629 if expDir is None:
426 raise ValueError('No expDir found for exp_id %i' % (int(expID)))
630 raise ValueError('No expDir found for exp_id %i' % (int(expID)))
427 fullFilename = os.path.join(expDir, basename)
631 fullFilename = os.path.join(expDir, basename)
428
632
429 # determine if we need to return the full file text, or just the size and name
633 # determine if we need to return the full file text, or just the size and name
430 if 'text' in request.GET:
634 if 'text' in request.GET:
431 madFileObj = madrigal.data.MadrigalFile(fullFilename, madDB)
635 madFileObj = madrigal.data.MadrigalFile(fullFilename, madDB)
432 measParms = madFileObj.getMeasuredParmList()
636 measParms = madFileObj.getMeasuredParmList()
433 measParmMnemList = madParmObj.getParmMnemonicList(measParms) + madFileObj.getStandardParms(upper=True)
637 measParmMnemList = madParmObj.getParmMnemonicList(measParms) + madFileObj.getStandardParms(upper=True)
434 measParmDescList = madParmObj.getParmDescriptionList(measParmMnemList)
638 measParmDescList = madParmObj.getParmDescriptionList(measParmMnemList)
435 parmList = list(zip(measParmMnemList, measParmDescList))
639 parmList = list(zip(measParmMnemList, measParmDescList))
436 f = open(request.GET['text'])
640 f = open(request.GET['text'])
437 text = f.read()
641 text = f.read()
438 f.close()
642 f.close()
439
643
440 return render(request, 'madweb/print_as_is.html', {'text': text, 'parmList': parmList})
644 return render(request, 'madweb/print_as_is.html', {'text': text, 'parmList': parmList})
441
645
442 else:
646 else:
443 tmpFilename = madWebObj.printFileAsIs(fullFilename, user_fullname, user_email, user_affiliation)
647 tmpFilename = madWebObj.printFileAsIs(fullFilename, user_fullname, user_email, user_affiliation)
444 filesize = os.path.getsize(tmpFilename)
648 filesize = os.path.getsize(tmpFilename)
445 return(HttpResponse('%s:%s' % (filesize, tmpFilename)))
649 return(HttpResponse('%s:%s' % (filesize, tmpFilename)))
446
650
447
651
448 def list_records(request):
652 def list_records(request):
449 """list_records is a Ajax call that returns the list records text.
653 """list_records is a Ajax call that returns the list records text.
450
654
451 Inputs:
655 Inputs:
452 request
656 request
453 """
657 """
454 madDB = madrigal.metadata.MadrigalDB()
658 madDB = madrigal.metadata.MadrigalDB()
455 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
659 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
456 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
660 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
457
661
458 expID =int(request.GET['experiment_list'])
662 expID =int(request.GET['experiment_list'])
459 basename = request.GET['file_list']
663 basename = request.GET['file_list']
460 expDir = madExpObj.getExpDirByExpId(int(expID))
664 expDir = madExpObj.getExpDirByExpId(int(expID))
461 if expDir is None:
665 if expDir is None:
462 raise ValueError('No expDir found for exp_id %i' % (int(expID)))
666 raise ValueError('No expDir found for exp_id %i' % (int(expID)))
463 fullFilename = os.path.join(expDir, basename)
667 fullFilename = os.path.join(expDir, basename)
464
668
465 text = madWebObj.listRecords(fullFilename)
669 text = madWebObj.listRecords(fullFilename)
466
670
467 return render(request, 'madweb/list_records.html', {'expDir': expDir,
671 return render(request, 'madweb/list_records.html', {'expDir': expDir,
468 'basename': basename,
672 'basename': basename,
469 'text': text})
673 'text': text})
470
674
471
675
472 def view_record_plot(request):
676 def view_record_plot(request):
473 """view_record_plot returns the view individual record page.
677 """view_record_plot returns the view individual record page.
474
678
475 Inputs:
679 Inputs:
476 request
680 request
477 """
681 """
478 expDir = request.GET['expDir']
682 expDir = request.GET['expDir']
479 basename = request.GET['basename']
683 basename = request.GET['basename']
480 recno = int(request.GET['recno'])
684 recno = int(request.GET['recno'])
481
685
482 return render(request, 'madweb/view_record_plot.html', {'expDir': expDir,
686 return render(request, 'madweb/view_record_plot.html', {'expDir': expDir,
483 'basename': basename,
687 'basename': basename,
484 'recno': recno})
688 'recno': recno})
485
689
486
690
487 def view_record_image(request):
691 def view_record_image(request):
488 """view_record_plot is a Ajax call that returns the record plot.
692 """view_record_plot is a Ajax call that returns the record plot.
489
693
490 Inputs:
694 Inputs:
491 request
695 request
492 """
696 """
493 expDir = request.GET['expDir']
697 expDir = request.GET['expDir']
494 basename = request.GET['basename']
698 basename = request.GET['basename']
495 recno = int(request.GET['recno'])
699 recno = int(request.GET['recno'])
496 pngFiles = glob.glob(os.path.join(expDir, 'plots', basename, 'records/*%05i*.png' % (recno)))
700 pngFiles = glob.glob(os.path.join(expDir, 'plots', basename, 'records/*%05i*.png' % (recno)))
497
701
498 image_data = open(pngFiles[0], "rb").read()
702 image_data = open(pngFiles[0], "rb").read()
499 return HttpResponse(image_data, content_type="image/png")
703 return HttpResponse(image_data, content_type="image/png")
500
704
501
705
502
706
503
707
504 def show_info(request):
708 def show_info(request):
505 """show_info is a Ajax call that returns the text of the catalog/header text to support the
709 """show_info is a Ajax call that returns the text of the catalog/header text to support the
506 single experiment UI. Called when a user selects show info link.
710 single experiment UI. Called when a user selects show info link.
507
711
508 Inputs:
712 Inputs:
509 request
713 request
510 """
714 """
511 madDB = madrigal.metadata.MadrigalDB()
715 madDB = madrigal.metadata.MadrigalDB()
512 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
716 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
513
717
514 expID =int(request.GET['experiment_list'])
718 expID =int(request.GET['experiment_list'])
515 basename = request.GET['file_list']
719 basename = request.GET['file_list']
516 expDir = madExpObj.getExpDirByExpId(int(expID))
720 expDir = madExpObj.getExpDirByExpId(int(expID))
517 if expDir is None:
721 if expDir is None:
518 raise ValueError('No expDir found for exp_id %i' % (int(expID)))
722 raise ValueError('No expDir found for exp_id %i' % (int(expID)))
519 fullFilename = os.path.join(expDir, basename)
723 fullFilename = os.path.join(expDir, basename)
520
724
521 madFileObj = madrigal.data.MadrigalFile(fullFilename, madDB)
725 madFileObj = madrigal.data.MadrigalFile(fullFilename, madDB)
522 text = madFileObj.getCatalogHeaderStr()
726 text = madFileObj.getCatalogHeaderStr()
523
727
524 return render(request, 'madweb/show_info.html', {'text':text})
728 return render(request, 'madweb/show_info.html', {'text':text})
525
729
526
730
527 def show_doi(request):
731 def show_doi(request):
528 """show_doi is a Ajax call that returns the permanent url for references to support the
732 """show_doi is a Ajax call that returns the permanent url for references to support the
529 single experiment UI. Called when a user selects show doi link.
733 single experiment UI. Called when a user selects show doi link.
530
734
531 Inputs:
735 Inputs:
532 request
736 request
533 """
737 """
534 madDB = madrigal.metadata.MadrigalDB()
738 madDB = madrigal.metadata.MadrigalDB()
535 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
739 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
536 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
740 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
537
741
538 expID =request.GET['experiment_list']
742 expID =request.GET['experiment_list']
539 basename = request.GET['file_list']
743 basename = request.GET['file_list']
540 expDir = madExpObj.getExpDirByExpId(int(expID))
744 expDir = madExpObj.getExpDirByExpId(int(expID))
541 # get experiment PI and institution
745 # get experiment PI and institution
542 PI = madExpObj.getPIByExpId(int(expID))
746 PI = madExpObj.getPIByExpId(int(expID))
543 kinst = madExpObj.getKinstByExpId(int(expID))
747 kinst = madExpObj.getKinstByExpId(int(expID))
544 startDTList = madExpObj.getExpStartDateTimeByExpId(int(expID))
748 startDTList = madExpObj.getExpStartDateTimeByExpId(int(expID))
545 yearStr = str(startDTList[0])
749 yearStr = str(startDTList[0])
546 if PI is None:
750 if PI is None:
547 PI = madInstObj.getContactName(kinst)
751 PI = madInstObj.getContactName(kinst)
548 institution = madInstObj.getContactAddress1(kinst)
752 institution = madInstObj.getContactAddress1(kinst)
549
753
550 try:
754 try:
551 madFileObj = madrigal.metadata.MadrigalMetaFile(madDB, os.path.join(expDir, 'fileTab.txt'))
755 madFileObj = madrigal.metadata.MadrigalMetaFile(madDB, os.path.join(expDir, 'fileTab.txt'))
552 url = madFileObj.getFileDOIUrlByFilename(basename)
756 url = madFileObj.getFileDOIUrlByFilename(basename)
553 except:
757 except:
554 url = 'Unknown - please contact madrigal@haystack.mit.edu'
758 url = 'Unknown - please contact madrigal@haystack.mit.edu'
555
759
556 return render(request, 'madweb/show_doi.html', {'url':url, 'PI': PI, 'year': yearStr,
760 return render(request, 'madweb/show_doi.html', {'url':url, 'PI': PI, 'year': yearStr,
557 'institution': institution})
761 'institution': institution})
558
762
559
763
560 def get_advanced(request):
764 def get_advanced(request):
561 """get_advanced is a view that allows user to download/print files with selected parms
765 """get_advanced is a view that allows user to download/print files with selected parms
562 and filters.
766 and filters.
563
767
564 Inputs:
768 Inputs:
565 request
769 request
566 """
770 """
567 madDB = madrigal.metadata.MadrigalDB()
771 madDB = madrigal.metadata.MadrigalDB()
568 bg_color = madDB.getBackgroundColor()
772 bg_color = madDB.getBackgroundColor()
569 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
773 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
570 siteName, siteList = madWeb.getSiteInfo()
774 siteName, siteList = madWeb.getSiteInfo()
571 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
775 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
572 webFormatObj = madrigal.ui.web.MadrigalWebFormat()
776 webFormatObj = madrigal.ui.web.MadrigalWebFormat()
573 madParmObj = madrigal.data.MadrigalParameters(madDB)
777 madParmObj = madrigal.data.MadrigalParameters(madDB)
574 parmList = webFormatObj.getFormat('Comprehensive')
778 parmList = webFormatObj.getFormat('Comprehensive')
575 measParmList = []
779 measParmList = []
576 derivedParmList = []
780 derivedParmList = []
577 allParmList = []
781 allParmList = []
578 sureParmList = []
782 sureParmList = []
579
783
580 if 'experiment_list' in request.GET:
784 if 'experiment_list' in request.GET:
581 expID = int(request.GET['experiment_list'])
785 expID = int(request.GET['experiment_list'])
582 else:
786 else:
583 return(HttpResponse('<p>experiment_list required for getAdvanced</p>'))
787 return(HttpResponse('<p>experiment_list required for getAdvanced</p>'))
584 basename = request.GET['file_list']
788 basename = request.GET['file_list']
585 type = request.GET['type']
789 type = request.GET['type']
586 expDir = madExpObj.getExpDirByExpId(int(expID))
790 expDir = madExpObj.getExpDirByExpId(int(expID))
587 if expDir is None:
791 if expDir is None:
588 raise ValueError('No expDir found for exp_id %i' % (int(expID)))
792 raise ValueError('No expDir found for exp_id %i' % (int(expID)))
589 fullFilename = os.path.join(expDir, basename)
793 fullFilename = os.path.join(expDir, basename)
590 expName, kindatDesc = madWeb.getInfoFromFile(fullFilename)
794 expName, kindatDesc = madWeb.getInfoFromFile(fullFilename)
591 madFileObj = madrigal.data.MadrigalFile(fullFilename, madDB)
795 madFileObj = madrigal.data.MadrigalFile(fullFilename, madDB)
592 earliestTime = madFileObj.getEarliestTime()
796 earliestTime = madFileObj.getEarliestTime()
593 latestTime = madFileObj.getLatestTime()
797 latestTime = madFileObj.getLatestTime()
594 earliestDT = datetime.datetime(*earliestTime)
798 earliestDT = datetime.datetime(*earliestTime)
595 latestDT = datetime.datetime(*latestTime)
799 latestDT = datetime.datetime(*latestTime)
596 madFileObj.getMeasDervBothParmLists(parmList, measParmList, derivedParmList, allParmList, sureParmList)
800 madFileObj.getMeasDervBothParmLists(parmList, measParmList, derivedParmList, allParmList, sureParmList)
597 allParmDescList = madParmObj.getParmDescriptionList(allParmList)
801 allParmDescList = madParmObj.getParmDescriptionList(allParmList)
598
802
599 dataDict = {'type': type,
803 dataDict = {'type': type,
600 'fullFilename': fullFilename,
804 'fullFilename': fullFilename,
601 'madFileObj': madFileObj, 'parameters': [],
805 'madFileObj': madFileObj, 'parameters': [],
602 'measParmList': measParmList, 'derivedParmList': derivedParmList,
806 'measParmList': measParmList, 'derivedParmList': derivedParmList,
603 'allParmList': allParmList, 'allParmDescList': allParmDescList,
807 'allParmList': allParmList, 'allParmDescList': allParmDescList,
604 'madDB': madDB, 'madParmObj': madParmObj}
808 'madDB': madDB, 'madParmObj': madParmObj}
605
809
606 min_alt = madFileObj.getMinValidAltitude()
810 min_alt = madFileObj.getMinValidAltitude()
607 max_alt = madFileObj.getMaxValidAltitude()
811 max_alt = madFileObj.getMaxValidAltitude()
608 try:
812 try:
609 float(min_alt)
813 float(min_alt)
610 float(max_alt)
814 float(max_alt)
611 dataDict['min_alt'] = '%9.2f' % (min_alt)
815 dataDict['min_alt'] = '%9.2f' % (min_alt)
612 dataDict['max_alt'] = '%9.2f' % (max_alt)
816 dataDict['max_alt'] = '%9.2f' % (max_alt)
613 except:
817 except:
614 pass
818 pass
615
819
616 if 'AZM' in allParmList:
820 if 'AZM' in allParmList:
617 dataDict['min_az'] = '-180.0'
821 dataDict['min_az'] = '-180.0'
618 dataDict['max_az'] = '180.0'
822 dataDict['max_az'] = '180.0'
619 dataDict['min_az2'] = '0.0'
823 dataDict['min_az2'] = '0.0'
620 dataDict['max_az2'] = '0.0'
824 dataDict['max_az2'] = '0.0'
621
825
622 if 'ELM' in allParmList:
826 if 'ELM' in allParmList:
623 dataDict['min_el'] = '0.0'
827 dataDict['min_el'] = '0.0'
624 dataDict['max_el'] = '90.0'
828 dataDict['max_el'] = '90.0'
625 dataDict['min_el2'] = '0.0'
829 dataDict['min_el2'] = '0.0'
626 dataDict['max_el2'] = '0.0'
830 dataDict['max_el2'] = '0.0'
627
831
628 if 'PL' in allParmList:
832 if 'PL' in allParmList:
629 min_pl = madFileObj.getMinPulseLength()
833 min_pl = madFileObj.getMinPulseLength()
630 max_pl = madFileObj.getMaxPulseLength()
834 max_pl = madFileObj.getMaxPulseLength()
631 try:
835 try:
632 float(min_pl)
836 float(min_pl)
633 float(max_pl)
837 float(max_pl)
634 dataDict['min_pl'] = '%9.2f' % (min_pl)
838 dataDict['min_pl'] = '%9.2f' % (min_pl)
635 dataDict['max_pl'] = '%9.2f' % (max_pl)
839 dataDict['max_pl'] = '%9.2f' % (max_pl)
636 except:
840 except:
637 pass
841 pass
638
842
639 if type == 'download':
843 if type == 'download':
640 defaultFormat = 'Hdf5'
844 defaultFormat = 'Hdf5'
641 else:
845 else:
642 defaultFormat = 'ascii'
846 defaultFormat = 'ascii'
643 dataDict['formats'] = defaultFormat
847 dataDict['formats'] = defaultFormat
644 dataDict['missing'] = 'NaN'
848 dataDict['missing'] = 'NaN'
645 dataDict['start_date'] = earliestDT
849 dataDict['start_date'] = earliestDT
646 dataDict['end_date'] = latestDT
850 dataDict['end_date'] = latestDT
647
851
648
852
649 isprintForm = madweb.forms.IsprintForm(dataDict)
853 isprintForm = madweb.forms.IsprintForm(dataDict)
650
854
651 return render(request, 'madweb/get_advanced.html', {'form': isprintForm,
855 return render(request, 'madweb/get_advanced.html', {'form': isprintForm,
652 'parmList': isprintForm.parmList,
856 'parmList': isprintForm.parmList,
653 'measParmList': measParmList,
857 'measParmList': measParmList,
654 'site_name': siteName, 'site_list': siteList,
858 'site_name': siteName, 'site_list': siteList,
655 'expName': expName, 'kindatDesc': kindatDesc,
859 'expName': expName, 'kindatDesc': kindatDesc,
656 'basename': os.path.basename(fullFilename),
860 'basename': os.path.basename(fullFilename),
657 'type': type, 'bg_color': bg_color,
861 'type': type, 'bg_color': bg_color,
658 'datetime': True})
862 'datetime': True})
659
863
660 def advanced_download(request):
864 def advanced_download(request):
661 """advanced_download is a view that downloads a file with selected parms
865 """advanced_download is a view that downloads a file with selected parms
662 and filters.
866 and filters.
663
867
664 Inputs:
868 Inputs:
665 request
869 request
666 """
870 """
667 madDB = madrigal.metadata.MadrigalDB()
871 madDB = madrigal.metadata.MadrigalDB()
668 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
872 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
669 webFormatObj = madrigal.ui.web.MadrigalWebFormat()
873 webFormatObj = madrigal.ui.web.MadrigalWebFormat()
670 madParmObj = madrigal.data.MadrigalParameters(madDB)
874 madParmObj = madrigal.data.MadrigalParameters(madDB)
671
875
672 cookieDict = request.COOKIES
876 cookieDict = request.COOKIES
673 if not 'user_fullname' in cookieDict:
877 if not 'user_fullname' in cookieDict:
674 return(HttpResponse('<p>Cookie with user_fullname required for advancedDownload</p>'))
878 return(HttpResponse('<p>Cookie with user_fullname required for advancedDownload</p>'))
675 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
879 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
676 user_email = cookieDict['user_email']
880 user_email = cookieDict['user_email']
677 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
881 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
678
882
679 parmList = webFormatObj.getFormat('Comprehensive')
883 parmList = webFormatObj.getFormat('Comprehensive')
680 measParmList = []
884 measParmList = []
681 derivedParmList = []
885 derivedParmList = []
682 allParmList = []
886 allParmList = []
683 sureParmList = []
887 sureParmList = []
684 madFileObj = madrigal.data.MadrigalFile(request.GET['fullFilename'], madDB)
888 madFileObj = madrigal.data.MadrigalFile(request.GET['fullFilename'], madDB)
685 madFileObj.getMeasDervBothParmLists(parmList, measParmList, derivedParmList, allParmList, sureParmList)
889 madFileObj.getMeasDervBothParmLists(parmList, measParmList, derivedParmList, allParmList, sureParmList)
686 allParmDescList = madParmObj.getParmDescriptionList(allParmList)
890 allParmDescList = madParmObj.getParmDescriptionList(allParmList)
687
891
688 request.GET._mutable = True
892 request.GET._mutable = True
689 request.GET['madFileObj']=madFileObj
893 request.GET['madFileObj']=madFileObj
690 request.GET['measParmList']=measParmList
894 request.GET['measParmList']=measParmList
691 request.GET['derivedParmList']=derivedParmList
895 request.GET['derivedParmList']=derivedParmList
692 request.GET['allParmList']=allParmList
896 request.GET['allParmList']=allParmList
693 request.GET['allParmDescList']=allParmDescList
897 request.GET['allParmDescList']=allParmDescList
694 request.GET['start_date'] = request.GET['start_date'].strip()
898 request.GET['start_date'] = request.GET['start_date'].strip()
695 request.GET['end_date'] = request.GET['end_date'].strip()
899 request.GET['end_date'] = request.GET['end_date'].strip()
696 # convert dates to datetime
900 # convert dates to datetime
697 request.GET['start_date'] = datetime.datetime.strptime(request.GET['start_date'], '%Y-%m-%dT%H:%M:%S')
901 request.GET['start_date'] = datetime.datetime.strptime(request.GET['start_date'], '%Y-%m-%dT%H:%M:%S')
698 request.GET['end_date'] = datetime.datetime.strptime(request.GET['end_date'], '%Y-%m-%dT%H:%M:%S')
902 request.GET['end_date'] = datetime.datetime.strptime(request.GET['end_date'], '%Y-%m-%dT%H:%M:%S')
699 request.GET['madDB'] = madDB
903 request.GET['madDB'] = madDB
700 request.GET['madParmObj'] = madParmObj
904 request.GET['madParmObj'] = madParmObj
701
905
702
906
703 isprintForm = madweb.forms.IsprintForm(request.GET)
907 isprintForm = madweb.forms.IsprintForm(request.GET)
704
908
705
909
706 if not isprintForm.is_valid():
910 if not isprintForm.is_valid():
707 raise ValueError(str(isprintForm.errors))
911 raise ValueError(str(isprintForm.errors))
708
912
709 downloadFile = madWeb.downloadIsprintFileFromIsprintForm(isprintForm.cleaned_data, user_fullname, user_email, user_affiliation)
913 downloadFile = madWeb.downloadIsprintFileFromIsprintForm(isprintForm.cleaned_data, user_fullname, user_email, user_affiliation)
710
914
711
915
712 f = open(downloadFile, 'rb')
916 f = open(downloadFile, 'rb')
713 filename = os.path.basename(downloadFile)
917 filename = os.path.basename(downloadFile)
714 chunk_size = 8192
918 chunk_size = 8192
715 file_type = mimetypes.guess_type(downloadFile)[0]
919 file_type = mimetypes.guess_type(downloadFile)[0]
716 if file_type is None:
920 if file_type is None:
717 file_type = 'application/octet-stream'
921 file_type = 'application/octet-stream'
718 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
922 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
719 content_type=file_type)
923 content_type=file_type)
720 response['Content-Length'] = os.path.getsize(downloadFile)
924 response['Content-Length'] = os.path.getsize(downloadFile)
721 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
925 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
722 return(response)
926 return(response)
723
927
724
928
725 def advanced_print(request):
929 def advanced_print(request):
726 """advanced_download is a view that print a file with selected parms
930 """advanced_download is a view that print a file with selected parms
727 and filters.
931 and filters.
728
932
729 Inputs:
933 Inputs:
730 request
934 request
731 """
935 """
732 madDB = madrigal.metadata.MadrigalDB()
936 madDB = madrigal.metadata.MadrigalDB()
733 bg_color = madDB.getBackgroundColor()
937 bg_color = madDB.getBackgroundColor()
734 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
938 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
735 webFormatObj = madrigal.ui.web.MadrigalWebFormat()
939 webFormatObj = madrigal.ui.web.MadrigalWebFormat()
736 madParmObj = madrigal.data.MadrigalParameters(madDB)
940 madParmObj = madrigal.data.MadrigalParameters(madDB)
737
941
738 cookieDict = request.COOKIES
942 cookieDict = request.COOKIES
739 if not 'user_fullname' in cookieDict:
943 if not 'user_fullname' in cookieDict:
740 return(HttpResponse('<p>Cookie with user_fullname required for advancedPrint</p>'))
944 return(HttpResponse('<p>Cookie with user_fullname required for advancedPrint</p>'))
741 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
945 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
742 user_email = cookieDict['user_email']
946 user_email = cookieDict['user_email']
743 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
947 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
744
948
745 parmList = webFormatObj.getFormat('Comprehensive')
949 parmList = webFormatObj.getFormat('Comprehensive')
746 measParmList = []
950 measParmList = []
747 derivedParmList = []
951 derivedParmList = []
748 allParmList = []
952 allParmList = []
749 sureParmList = []
953 sureParmList = []
750 madFileObj = madrigal.data.MadrigalFile(request.GET['fullFilename'], madDB)
954 madFileObj = madrigal.data.MadrigalFile(request.GET['fullFilename'], madDB)
751 madFileObj.getMeasDervBothParmLists(parmList, measParmList, derivedParmList, allParmList, sureParmList)
955 madFileObj.getMeasDervBothParmLists(parmList, measParmList, derivedParmList, allParmList, sureParmList)
752 allParmDescList = madParmObj.getParmDescriptionList(allParmList)
956 allParmDescList = madParmObj.getParmDescriptionList(allParmList)
753 fullFilename = request.GET['fullFilename']
957 fullFilename = request.GET['fullFilename']
754 expName, kindatDesc = madWeb.getInfoFromFile(fullFilename)
958 expName, kindatDesc = madWeb.getInfoFromFile(fullFilename)
755
959
756 request.GET._mutable = True
960 request.GET._mutable = True
757 request.GET['madFileObj']=madFileObj
961 request.GET['madFileObj']=madFileObj
758 request.GET['measParmList']=measParmList
962 request.GET['measParmList']=measParmList
759 request.GET['derivedParmList']=derivedParmList
963 request.GET['derivedParmList']=derivedParmList
760 request.GET['allParmList']=allParmList
964 request.GET['allParmList']=allParmList
761 request.GET['allParmDescList']=allParmDescList
965 request.GET['allParmDescList']=allParmDescList
762 request.GET['start_date'] = request.GET['start_date'].strip()
966 request.GET['start_date'] = request.GET['start_date'].strip()
763 request.GET['end_date'] = request.GET['end_date'].strip()
967 request.GET['end_date'] = request.GET['end_date'].strip()
764 # convert dates to datetime
968 # convert dates to datetime
765 request.GET['start_date'] = datetime.datetime.strptime(request.GET['start_date'], '%Y-%m-%dT%H:%M:%S')
969 request.GET['start_date'] = datetime.datetime.strptime(request.GET['start_date'], '%Y-%m-%dT%H:%M:%S')
766 request.GET['end_date'] = datetime.datetime.strptime(request.GET['end_date'], '%Y-%m-%dT%H:%M:%S')
970 request.GET['end_date'] = datetime.datetime.strptime(request.GET['end_date'], '%Y-%m-%dT%H:%M:%S')
767 request.GET['madDB'] = madDB
971 request.GET['madDB'] = madDB
768 request.GET['madParmObj'] = madParmObj
972 request.GET['madParmObj'] = madParmObj
769
973
770 isprintForm = madweb.forms.IsprintForm(request.GET)
974 isprintForm = madweb.forms.IsprintForm(request.GET)
771
975
772
976
773 if not isprintForm.is_valid():
977 if not isprintForm.is_valid():
774 raise ValueError(str(isprintForm.errors))
978 raise ValueError(str(isprintForm.errors))
775
979
776 downloadFile = madWeb.downloadIsprintFileFromIsprintForm(isprintForm.cleaned_data, user_fullname, user_email, user_affiliation)
980 downloadFile = madWeb.downloadIsprintFileFromIsprintForm(isprintForm.cleaned_data, user_fullname, user_email, user_affiliation)
777
981
778 f = open(downloadFile, 'r')
982 f = open(downloadFile, 'r')
779 file_text = f.read()
983 file_text = f.read()
780 f.close()
984 f.close()
781 os.remove(downloadFile)
985 os.remove(downloadFile)
782 return render(request, 'madweb/advanced_print.html', {'expName': expName, 'kindatDesc': kindatDesc,
986 return render(request, 'madweb/advanced_print.html', {'expName': expName, 'kindatDesc': kindatDesc,
783 'basename': os.path.basename(fullFilename),
987 'basename': os.path.basename(fullFilename),
784 'file_text': file_text, 'bg_color': bg_color})
988 'file_text': file_text, 'bg_color': bg_color})
785
989
786
990
787 def view_list(request):
991 def view_list(request):
788 """view_list is the list experiment view.
992 """view_list is the list experiment view.
789 """
993 """
790 madDB = madrigal.metadata.MadrigalDB()
994 madDB = madrigal.metadata.MadrigalDB()
791 bg_color = madDB.getBackgroundColor()
995 bg_color = madDB.getBackgroundColor()
792 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
996 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
793 siteName, siteList = madWebObj.getSiteInfo()
997 siteName, siteList = madWebObj.getSiteInfo()
794 responseDict = {'list_active': 'class="active"'}
998 responseDict = {'list_active': 'class="active"'}
795 form = madweb.forms.ListExpForm()
999 form = madweb.forms.ListExpForm()
796 responseDict['form'] = form
1000 responseDict['form'] = form
797 responseDict['categoryList'] = form.categories
1001 responseDict['categoryList'] = form.categories
798 responseDict['instrumentList'] = form.instruments
1002 responseDict['instrumentList'] = form.instruments
799 responseDict['site_name'] = siteName
1003 responseDict['site_name'] = siteName
800 responseDict['site_list'] = siteList
1004 responseDict['site_list'] = siteList
801 responseDict['datetime'] = True
1005 responseDict['datetime'] = True
802 responseDict['bg_color'] = bg_color
1006 responseDict['bg_color'] = bg_color
803
1007
804 return render(request, 'madweb/list.html', responseDict)
1008 return render(request, 'madweb/list.html', responseDict)
805
1009
806
1010
807 def list_experiments(request):
1011 def list_experiments(request):
808 """list_experiments is a view that lists all selected experiments.
1012 """list_experiments is a view that lists all selected experiments.
809
1013
810 Inputs:
1014 Inputs:
811 request
1015 request
812 """
1016 """
813 madDB = madrigal.metadata.MadrigalDB()
1017 madDB = madrigal.metadata.MadrigalDB()
814 bg_color = madDB.getBackgroundColor()
1018 bg_color = madDB.getBackgroundColor()
815 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
1019 madWeb = madrigal.ui.web.MadrigalWeb(madDB)
816 siteName, siteList = madWeb.getSiteInfo()
1020 siteName, siteList = madWeb.getSiteInfo()
817
1021
818 listForm = madweb.forms.ListExpForm(request.GET)
1022 listForm = madweb.forms.ListExpForm(request.GET)
819 try:
1023 try:
820 if not listForm.is_valid():
1024 if not listForm.is_valid():
821 return(HttpResponse(str(listForm.errors)))
1025 return(HttpResponse(str(listForm.errors)))
822 except KeyError:
1026 except KeyError:
823 return(HttpResponse('<p>Missing arguments in list_experiments</p>'))
1027 return(HttpResponse('<p>Missing arguments in list_experiments</p>'))
824
1028
825 kinstList = [int(kinst) for kinst in listForm.cleaned_data['instruments']]
1029 kinstList = [int(kinst) for kinst in listForm.cleaned_data['instruments']]
826 startDate = listForm.cleaned_data['start_date']
1030 startDate = listForm.cleaned_data['start_date']
827 startDT = datetime.datetime(startDate.year, startDate.month, startDate.day, 0, 0, 0)
1031 startDT = datetime.datetime(startDate.year, startDate.month, startDate.day, 0, 0, 0)
828 endDate = listForm.cleaned_data['end_date']
1032 endDate = listForm.cleaned_data['end_date']
829 endDT = datetime.datetime(endDate.year, endDate.month, endDate.day, 23, 59, 59)
1033 endDT = datetime.datetime(endDate.year, endDate.month, endDate.day, 23, 59, 59)
830 localOnly = not listForm.cleaned_data['isGlobal']
1034 localOnly = not listForm.cleaned_data['isGlobal']
831 expList = madWeb.getExperimentList(kinstList, startDT, endDT, localOnly)
1035 expList = madWeb.getExperimentList(kinstList, startDT, endDT, localOnly)
832
1036
833 return render(request, 'madweb/list_experiments.html', {'expList':expList, 'localOnly':localOnly,
1037 return render(request, 'madweb/list_experiments.html', {'expList':expList, 'localOnly':localOnly,
834 'list_active': 'class="active"', 'site_name': siteName,
1038 'list_active': 'class="active"', 'site_name': siteName,
835 'site_list': siteList, 'bg_color': bg_color})
1039 'site_list': siteList, 'bg_color': bg_color})
836
1040
837
1041
838 def show_experiment(request):
1042 def show_experiment(request):
839 """show_experiment call that returns the experiment page to support the list experiments UI.
1043 """show_experiment call that returns the experiment page to support the list experiments UI.
840
1044
841 Inputs:
1045 Inputs:
842 request
1046 request
843 """
1047 """
844 madDB = madrigal.metadata.MadrigalDB()
1048 madDB = madrigal.metadata.MadrigalDB()
845 bg_color = madDB.getBackgroundColor()
1049 bg_color = madDB.getBackgroundColor()
846 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1050 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
847 siteName, siteList = madWebObj.getSiteInfo()
1051 siteName, siteList = madWebObj.getSiteInfo()
848 cookieDict = request.COOKIES
1052 cookieDict = request.COOKIES
849 user_email = cookieDict['user_email']
1053 user_email = cookieDict['user_email']
850 queryDict = request.GET.copy()
1054 queryDict = request.GET.copy()
851 queryDict['user_email'] = user_email
1055 queryDict['user_email'] = user_email
852 if 'show_plots' in queryDict:
1056 if 'show_plots' in queryDict:
853 plotsForm = madweb.forms.SingleExpPlotsForm(queryDict)
1057 plotsForm = madweb.forms.SingleExpPlotsForm(queryDict)
854 form = madweb.forms.SingleExpFileForm(queryDict)
1058 form = madweb.forms.SingleExpFileForm(queryDict)
855 if 'show_plots' in queryDict:
1059 if 'show_plots' in queryDict:
856 form.fields['plot_list'] = plotsForm.fields['plot_list']
1060 form.fields['plot_list'] = plotsForm.fields['plot_list']
857 if len(form.fields['file_list'].choices) > 1:
1061 if len(form.fields['file_list'].choices) > 1:
858 # this experiment has data files
1062 # this experiment has data files
859 return render(request, 'madweb/show_experiment.html', {'list_active': 'class="active"',
1063 return render(request, 'madweb/show_experiment.html', {'list_active': 'class="active"',
860 'form': form, 'site_name': siteName,
1064 'form': form, 'site_name': siteName,
861 'site_list': siteList,
1065 'site_list': siteList,
862 'loader': 'loadPage',
1066 'loader': 'loadPage',
863 'bg_color': bg_color,
1067 'bg_color': bg_color,
864 'redirect': reverse('show_experiment')})
1068 'redirect': reverse('show_experiment')})
865
1069
866 else:
1070 else:
867 # this experiment has no data files
1071 # this experiment has no data files
868 form2 = madweb.forms.SingleExpPlotsForm(request.GET)
1072 form2 = madweb.forms.SingleExpPlotsForm(request.GET)
869 exp_desc = form.fields['exp_desc'].label
1073 exp_desc = form.fields['exp_desc'].label
870 return render(request, 'madweb/show_exp_no_files.html', {'list_active': 'class="active"',
1074 return render(request, 'madweb/show_exp_no_files.html', {'list_active': 'class="active"',
871 'form': form2, 'exp_desc': exp_desc,
1075 'form': form2, 'exp_desc': exp_desc,
872 'site_name': siteName,
1076 'site_name': siteName,
873 'site_list': siteList,
1077 'site_list': siteList,
874 'loader': 'loadPage',
1078 'loader': 'loadPage',
875 'bg_color': bg_color,
1079 'bg_color': bg_color,
876 'redirect': reverse('show_experiment')})
1080 'redirect': reverse('show_experiment')})
877
1081
878
1082
879 def show_experiment_v2(request):
1083 def show_experiment_v2(request):
880 """show_experiment_v2 is a slight variant of show_experiment to accept old form
1084 """show_experiment_v2 is a slight variant of show_experiment to accept old form
881 calls from Madrigal2 sites.
1085 calls from Madrigal2 sites.
882
1086
883 Inputs:
1087 Inputs:
884 request
1088 request
885 """
1089 """
886 madDB = madrigal.metadata.MadrigalDB()
1090 madDB = madrigal.metadata.MadrigalDB()
887 bg_color = madDB.getBackgroundColor()
1091 bg_color = madDB.getBackgroundColor()
888 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1092 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
889 siteName, siteList = madWebObj.getSiteInfo()
1093 siteName, siteList = madWebObj.getSiteInfo()
890 cookieDict = request.COOKIES
1094 cookieDict = request.COOKIES
891 user_email = cookieDict['user_email']
1095 user_email = cookieDict['user_email']
892 queryDict = request.GET.copy()
1096 queryDict = request.GET.copy()
893 queryDict['user_email'] = user_email
1097 queryDict['user_email'] = user_email
894 queryDict['experiment_list'] = queryDict['exp']
1098 queryDict['experiment_list'] = queryDict['exp']
895 form = madweb.forms.SingleExpFileForm(queryDict)
1099 form = madweb.forms.SingleExpFileForm(queryDict)
896
1100
897 return render(request, 'madweb/show_experiment.html', {'list_active': 'class="active"',
1101 return render(request, 'madweb/show_experiment.html', {'list_active': 'class="active"',
898 'form': form, 'site_name': siteName,
1102 'form': form, 'site_name': siteName,
899 'site_list': siteList,
1103 'site_list': siteList,
900 'loader': 'loadPage',
1104 'loader': 'loadPage',
901 'bg_color': bg_color,
1105 'bg_color': bg_color,
902 'redirect': reverse('show_experiment')})
1106 'redirect': reverse('show_experiment')})
903
1107
904
1108
905 def choose_script(request):
1109 def choose_script(request):
906 """choose_script that returns the choose script page.
1110 """choose_script that returns the choose script page.
907
1111
908 Inputs:
1112 Inputs:
909 request
1113 request
910 """
1114 """
911 madDB = madrigal.metadata.MadrigalDB()
1115 madDB = madrigal.metadata.MadrigalDB()
912 bg_color = madDB.getBackgroundColor()
1116 bg_color = madDB.getBackgroundColor()
913 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1117 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
914 siteName, siteList = madWebObj.getSiteInfo()
1118 siteName, siteList = madWebObj.getSiteInfo()
915 return render(request, 'madweb/choose_script.html', {'script_active': 'class="active"', 'site_name': siteName,
1119 return render(request, 'madweb/choose_script.html', {'script_active': 'class="active"', 'site_name': siteName,
916 'site_list': siteList, 'bg_color': bg_color})
1120 'site_list': siteList, 'bg_color': bg_color})
917
1121
918
1122
919 def download_as_is_script(request):
1123 def download_as_is_script(request):
920 """download_as_is_script that returns the download_as_is_script script page.
1124 """download_as_is_script that returns the download_as_is_script script page.
921
1125
922 Inputs:
1126 Inputs:
923 request
1127 request
924 """
1128 """
925 madDB = madrigal.metadata.MadrigalDB()
1129 madDB = madrigal.metadata.MadrigalDB()
926 bg_color = madDB.getBackgroundColor()
1130 bg_color = madDB.getBackgroundColor()
927 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1131 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
928 siteName, siteList = madWebObj.getSiteInfo()
1132 siteName, siteList = madWebObj.getSiteInfo()
929 responseDict = {'script_active': 'class="active"'}
1133 responseDict = {'script_active': 'class="active"'}
930 form = madweb.forms.DownloadAsIsScriptForm()
1134 form = madweb.forms.DownloadAsIsScriptForm()
931 responseDict['form'] = form
1135 responseDict['form'] = form
932 responseDict['categoryList'] = form.categories
1136 responseDict['categoryList'] = form.categories
933 responseDict['instrumentList'] = form.instruments
1137 responseDict['instrumentList'] = form.instruments
934 responseDict['kindatList'] = form.kindats
1138 responseDict['kindatList'] = form.kindats
935 responseDict['site_name'] = siteName
1139 responseDict['site_name'] = siteName
936 responseDict['site_list'] = siteList
1140 responseDict['site_list'] = siteList
937 responseDict['datetime'] = True
1141 responseDict['datetime'] = True
938 responseDict['bg_color'] = bg_color
1142 responseDict['bg_color'] = bg_color
939
1143
940 return render(request, 'madweb/download_as_is_script.html', responseDict)
1144 return render(request, 'madweb/download_as_is_script.html', responseDict)
941
1145
942
1146
943 def generate_download_files_script(request):
1147 def generate_download_files_script(request):
944 """generate_download_files_script is a Ajax call that returns the generated file download script.
1148 """generate_download_files_script is a Ajax call that returns the generated file download script.
945
1149
946 Inputs:
1150 Inputs:
947 request
1151 request
948 """
1152 """
949 form = madweb.forms.DownloadAsIsScriptForm(request.GET)
1153 form = madweb.forms.DownloadAsIsScriptForm(request.GET)
950 if not form.is_valid():
1154 if not form.is_valid():
951 raise ValueError('Form error: %s' % (form.errors))
1155 raise ValueError('Form error: %s' % (form.errors))
952 cookieDict = request.COOKIES
1156 cookieDict = request.COOKIES
953 if not 'user_fullname' in cookieDict:
1157 if not 'user_fullname' in cookieDict:
954 return(HttpResponse('<p>Cookie with user_fullname required for generateDownloadFilesScript</p>'))
1158 return(HttpResponse('<p>Cookie with user_fullname required for generateDownloadFilesScript</p>'))
955 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
1159 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
956 user_email = cookieDict['user_email']
1160 user_email = cookieDict['user_email']
957 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
1161 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
958 madWebObj = madrigal.ui.web.MadrigalWeb()
1162 madWebObj = madrigal.ui.web.MadrigalWeb()
959 script_text = madWebObj.generateDownloadFileScriptFromForm(form.cleaned_data, user_fullname,
1163 script_text = madWebObj.generateDownloadFileScriptFromForm(form.cleaned_data, user_fullname,
960 user_email, user_affiliation)
1164 user_email, user_affiliation)
961 return render(request, 'madweb/download_files_script.html', {'script_text': script_text})
1165 return render(request, 'madweb/download_files_script.html', {'script_text': script_text})
962
1166
963
1167
964 def download_advanced_script(request):
1168 def download_advanced_script(request):
965 """download_advanced_script that returns the download_advanced_script script page.
1169 """download_advanced_script that returns the download_advanced_script script page.
966
1170
967 Inputs:
1171 Inputs:
968 request
1172 request
969 """
1173 """
970 madDB = madrigal.metadata.MadrigalDB()
1174 madDB = madrigal.metadata.MadrigalDB()
971 bg_color = madDB.getBackgroundColor()
1175 bg_color = madDB.getBackgroundColor()
972 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1176 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
973 siteName, siteList = madWebObj.getSiteInfo()
1177 siteName, siteList = madWebObj.getSiteInfo()
974 responseDict = {'script_active': 'class="active"'}
1178 responseDict = {'script_active': 'class="active"'}
975 form = madweb.forms.DownloadAdvancedScriptForm()
1179 form = madweb.forms.DownloadAdvancedScriptForm()
976 responseDict['form'] = form
1180 responseDict['form'] = form
977 responseDict['categoryList'] = form.categories
1181 responseDict['categoryList'] = form.categories
978 responseDict['instrumentList'] = form.instruments
1182 responseDict['instrumentList'] = form.instruments
979 responseDict['kindatList'] = form.kindats
1183 responseDict['kindatList'] = form.kindats
980 responseDict['site_name'] = siteName
1184 responseDict['site_name'] = siteName
981 responseDict['site_list'] = siteList
1185 responseDict['site_list'] = siteList
982 responseDict['datetime'] = True
1186 responseDict['datetime'] = True
983 responseDict['bg_color'] = bg_color
1187 responseDict['bg_color'] = bg_color
984
1188
985 return render(request, 'madweb/download_advanced_script.html', responseDict)
1189 return render(request, 'madweb/download_advanced_script.html', responseDict)
986
1190
987
1191
988 def generate_download_advanced_script(request):
1192 def generate_download_advanced_script(request):
989 """generate_download_advanced_script is a Ajax call that returns the generated advanced download script.
1193 """generate_download_advanced_script is a Ajax call that returns the generated advanced download script.
990
1194
991 Inputs:
1195 Inputs:
992 request
1196 request
993 """
1197 """
994 form1 = madweb.forms.DownloadAdvancedScriptForm(request.GET)
1198 form1 = madweb.forms.DownloadAdvancedScriptForm(request.GET)
995 if not form1.is_valid():
1199 if not form1.is_valid():
996 raise ValueError('Form error: %s' % (form1.errors))
1200 raise ValueError('Form error: %s' % (form1.errors))
997 form2 = madweb.forms.AdvScriptParmsForm(request.GET)
1201 form2 = madweb.forms.AdvScriptParmsForm(request.GET)
998 if not form2.is_valid():
1202 if not form2.is_valid():
999 raise ValueError('Form error: %s' % (form2.errors))
1203 raise ValueError('Form error: %s' % (form2.errors))
1000 form3 = madweb.forms.AdvScriptParmsFiltersForm(request.GET)
1204 form3 = madweb.forms.AdvScriptParmsFiltersForm(request.GET)
1001 if not form3.is_valid():
1205 if not form3.is_valid():
1002 raise ValueError('Form error: %s' % (form3.errors))
1206 raise ValueError('Form error: %s' % (form3.errors))
1003 cookieDict = request.COOKIES
1207 cookieDict = request.COOKIES
1004 if not 'user_fullname' in cookieDict:
1208 if not 'user_fullname' in cookieDict:
1005 return(HttpResponse('<p>Cookie with user_fullname required for generateAdvancedDownloadScript</p>'))
1209 return(HttpResponse('<p>Cookie with user_fullname required for generateAdvancedDownloadScript</p>'))
1006 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
1210 user_fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
1007 user_email = cookieDict['user_email']
1211 user_email = cookieDict['user_email']
1008 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
1212 user_affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
1009 madWebObj = madrigal.ui.web.MadrigalWeb()
1213 madWebObj = madrigal.ui.web.MadrigalWeb()
1010 script_text = madWebObj.generateGlobalIsprintScriptFromForm(form1.cleaned_data, form2.cleaned_data,
1214 script_text = madWebObj.generateGlobalIsprintScriptFromForm(form1.cleaned_data, form2.cleaned_data,
1011 form3.cleaned_data, user_fullname,
1215 form3.cleaned_data, user_fullname,
1012 user_email, user_affiliation)
1216 user_email, user_affiliation)
1013 return render(request, 'madweb/download_files_script.html', {'script_text': script_text})
1217 return render(request, 'madweb/download_files_script.html', {'script_text': script_text})
1014
1218
1015
1219
1016 def generate_parms_script(request):
1220 def generate_parms_script(request):
1017 """generate_parms_script is a Ajax call that returns the generated parameter script.
1221 """generate_parms_script is a Ajax call that returns the generated parameter script.
1018
1222
1019 Inputs:
1223 Inputs:
1020 request
1224 request
1021 """
1225 """
1022 form = madweb.forms.AdvScriptParmsForm(request.GET)
1226 form = madweb.forms.AdvScriptParmsForm(request.GET)
1023 return render(request, 'madweb/download_adv_parms_script.html', {'form': form,
1227 return render(request, 'madweb/download_adv_parms_script.html', {'form': form,
1024 'parmList': form.parmList})
1228 'parmList': form.parmList})
1025
1229
1026
1230
1027 def generate_parms_filters_script(request):
1231 def generate_parms_filters_script(request):
1028 """generate_parms_filters_script is a Ajax call that returns the generated parameter filters script.
1232 """generate_parms_filters_script is a Ajax call that returns the generated parameter filters script.
1029
1233
1030 Inputs:
1234 Inputs:
1031 request
1235 request
1032 """
1236 """
1033 form = madweb.forms.AdvScriptParmsFiltersForm(request.GET)
1237 form = madweb.forms.AdvScriptParmsFiltersForm(request.GET)
1034 return render(request, 'madweb/download_adv_parms_filters_script.html', {'form': form})
1238 return render(request, 'madweb/download_adv_parms_filters_script.html', {'form': form})
1035
1239
1036
1240
1037 def ftp(request):
1241 def ftp(request):
1038 """ftp creates the first ftp page listing instruments
1242 """ftp creates the first ftp page listing instruments
1039 """
1243 """
1040 madDB = madrigal.metadata.MadrigalDB()
1244 madDB = madrigal.metadata.MadrigalDB()
1041 bg_color = madDB.getBackgroundColor()
1245 bg_color = madDB.getBackgroundColor()
1042 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1246 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1043 siteName, siteList = madWebObj.getSiteInfo()
1247 siteName, siteList = madWebObj.getSiteInfo()
1044 cookieDict = request.COOKIES
1248 cookieDict = request.COOKIES
1045 if not 'user_fullname' in cookieDict:
1249 if not 'user_fullname' in cookieDict:
1046 return(HttpResponse('<p>Cookie with user_fullname required for ftp</p>'))
1250 return(HttpResponse('<p>Cookie with user_fullname required for ftp</p>'))
1047 fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
1251 fullname = django.utils.http.urlquote_plus(cookieDict['user_fullname'])
1048 email = cookieDict['user_email']
1252 email = cookieDict['user_email']
1049 affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
1253 affiliation = django.utils.http.urlquote_plus(cookieDict['user_affiliation'])
1050 # create instrument with data list with tuple (instrument_name, kinst)
1254 # create instrument with data list with tuple (instrument_name, kinst)
1051 madInstDataObj = madrigal.metadata.MadrigalInstrumentData(madDB)
1255 madInstDataObj = madrigal.metadata.MadrigalInstrumentData(madDB)
1052 madInstList = [(instrument_name, kinst) for kinst, instrument_name, site_id in madInstDataObj.getInstruments(local=True)]
1256 madInstList = [(instrument_name, kinst) for kinst, instrument_name, site_id in madInstDataObj.getInstruments(local=True)]
1053 return render(request, 'madweb/ftp_instruments.html', {'madInstList': madInstList, 'fullname': fullname,
1257 return render(request, 'madweb/ftp_instruments.html', {'madInstList': madInstList, 'fullname': fullname,
1054 'email': email, 'affiliation':affiliation, 'site_name': siteName,
1258 'email': email, 'affiliation':affiliation, 'site_name': siteName,
1055 'site_list': siteList, 'bg_color': bg_color})
1259 'site_list': siteList, 'bg_color': bg_color})
1056
1260
1057
1261
1058 def ftp_instrument(request, fullname, email, affiliation, kinst):
1262 def ftp_instrument(request, fullname, email, affiliation, kinst):
1059 """ftp_instrument creates the first ftp instrument page listing years
1263 """ftp_instrument creates the first ftp instrument page listing years
1060 Inputs: kinst selected
1264 Inputs: kinst selected
1061 """
1265 """
1062 kinst = int(kinst)
1266 kinst = int(kinst)
1063 madDB = madrigal.metadata.MadrigalDB()
1267 madDB = madrigal.metadata.MadrigalDB()
1064 bg_color = madDB.getBackgroundColor()
1268 bg_color = madDB.getBackgroundColor()
1065 madInstDataObj = madrigal.metadata.MadrigalInstrumentData(madDB)
1269 madInstDataObj = madrigal.metadata.MadrigalInstrumentData(madDB)
1066 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1270 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1067 inst_name = madInstObj.getInstrumentName(kinst)
1271 inst_name = madInstObj.getInstrumentName(kinst)
1068 yearList = madInstDataObj.getInstrumentYears(kinst)
1272 yearList = madInstDataObj.getInstrumentYears(kinst)
1069 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1273 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1070 siteName, siteList = madWebObj.getSiteInfo()
1274 siteName, siteList = madWebObj.getSiteInfo()
1071 return render(request, 'madweb/ftp_years.html',{'yearList':yearList, 'kinst':kinst,
1275 return render(request, 'madweb/ftp_years.html',{'yearList':yearList, 'kinst':kinst,
1072 'inst_name':inst_name, 'fullname': fullname,
1276 'inst_name':inst_name, 'fullname': fullname,
1073 'email': email, 'affiliation':affiliation,
1277 'email': email, 'affiliation':affiliation,
1074 'site_name': siteName, 'site_list': siteList,
1278 'site_name': siteName, 'site_list': siteList,
1075 'bg_color': bg_color })
1279 'bg_color': bg_color })
1076
1280
1077
1281
1078 def ftp_year(request, fullname, email, affiliation, kinst, year):
1282 def ftp_year(request, fullname, email, affiliation, kinst, year):
1079 """ftp_year creates the first ftp year page listing kindats
1283 """ftp_year creates the first ftp year page listing kindats
1080 Inputs: kinst selected, year selected
1284 Inputs: kinst selected, year selected
1081 """
1285 """
1082 kinst = int(kinst)
1286 kinst = int(kinst)
1083 year = int(year)
1287 year = int(year)
1084 madDB = madrigal.metadata.MadrigalDB()
1288 madDB = madrigal.metadata.MadrigalDB()
1085 bg_color = madDB.getBackgroundColor()
1289 bg_color = madDB.getBackgroundColor()
1086 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1290 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1087 inst_name = madInstObj.getInstrumentName(kinst)
1291 inst_name = madInstObj.getInstrumentName(kinst)
1088 madInstKindatObj = madrigal.metadata.MadrigalInstrumentKindats(madDB)
1292 madInstKindatObj = madrigal.metadata.MadrigalInstrumentKindats(madDB)
1089 kindatList = madInstKindatObj.getKindatListForInstrumentYear(kinst, year)
1293 kindatList = madInstKindatObj.getKindatListForInstrumentYear(kinst, year)
1090 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1294 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1091 # create kindatDescList, a list of tuples of (kindat_desc, kindat) for that kinst, year
1295 # create kindatDescList, a list of tuples of (kindat_desc, kindat) for that kinst, year
1092 kindatDescList = []
1296 kindatDescList = []
1093 for kindat in kindatList:
1297 for kindat in kindatList:
1094 kindatDescList.append((madKindatObj.getKindatDescription(kindat, kinst), kindat))
1298 kindatDescList.append((madKindatObj.getKindatDescription(kindat, kinst), kindat))
1095 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1299 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1096 siteName, siteList = madWebObj.getSiteInfo()
1300 siteName, siteList = madWebObj.getSiteInfo()
1097 return render(request, 'madweb/ftp_kindats.html', {'kindatDescList': kindatDescList, 'year': year,
1301 return render(request, 'madweb/ftp_kindats.html', {'kindatDescList': kindatDescList, 'year': year,
1098 'kinst': kinst, 'inst_name':inst_name, 'fullname': fullname,
1302 'kinst': kinst, 'inst_name':inst_name, 'fullname': fullname,
1099 'email': email, 'affiliation':affiliation,
1303 'email': email, 'affiliation':affiliation,
1100 'site_name': siteName, 'site_list': siteList,
1304 'site_name': siteName, 'site_list': siteList,
1101 'bg_color': bg_color })
1305 'bg_color': bg_color })
1102
1306
1103
1307
1104 def ftp_kindat(request, fullname, email, affiliation, kinst, year, kindat):
1308 def ftp_kindat(request, fullname, email, affiliation, kinst, year, kindat):
1105 """ftp_kindat creates the first ftp format page listing formats to choose from
1309 """ftp_kindat creates the first ftp format page listing formats to choose from
1106 Inputs: kinst selected, year selected, kindat selected
1310 Inputs: kinst selected, year selected, kindat selected
1107 """
1311 """
1108 kinst = int(kinst)
1312 kinst = int(kinst)
1109 kindat = int(kindat)
1313 kindat = int(kindat)
1110 madDB = madrigal.metadata.MadrigalDB()
1314 madDB = madrigal.metadata.MadrigalDB()
1111 bg_color = madDB.getBackgroundColor()
1315 bg_color = madDB.getBackgroundColor()
1112 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1316 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1113 kindat_desc = madKindatObj.getKindatDescription(kindat, kinst)
1317 kindat_desc = madKindatObj.getKindatDescription(kindat, kinst)
1114 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1318 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1115 inst_name = madInstObj.getInstrumentName(kinst)
1319 inst_name = madInstObj.getInstrumentName(kinst)
1116 formatDescList = [(formatDict[key], key) for key in list(formatDict.keys())]
1320 formatDescList = [(formatDict[key], key) for key in list(formatDict.keys())]
1117 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1321 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1118 siteName, siteList = madWebObj.getSiteInfo()
1322 siteName, siteList = madWebObj.getSiteInfo()
1119 return render(request, 'madweb/ftp_formats.html', {'formatDescList': formatDescList, 'year': year,
1323 return render(request, 'madweb/ftp_formats.html', {'formatDescList': formatDescList, 'year': year,
1120 'kinst': kinst, 'inst_name': inst_name, 'kindat': kindat,
1324 'kinst': kinst, 'inst_name': inst_name, 'kindat': kindat,
1121 'kindat_desc': kindat_desc, 'fullname': fullname,
1325 'kindat_desc': kindat_desc, 'fullname': fullname,
1122 'email': email, 'affiliation': affiliation,
1326 'email': email, 'affiliation': affiliation,
1123 'site_name': siteName, 'site_list': siteList,
1327 'site_name': siteName, 'site_list': siteList,
1124 'bg_color': bg_color } )
1328 'bg_color': bg_color } )
1125
1329
1126
1330
1127 def ftp_files(request, fullname, email, affiliation, kinst, year, kindat, format):
1331 def ftp_files(request, fullname, email, affiliation, kinst, year, kindat, format):
1128 """ftp_files creates the ftp files page listing individual files
1332 """ftp_files creates the ftp files page listing individual files
1129 Inputs: kinst selected, year selected, kindat selected
1333 Inputs: kinst selected, year selected, kindat selected
1130 """
1334 """
1131 kinst = int(kinst)
1335 kinst = int(kinst)
1132 year = int(year)
1336 year = int(year)
1133 dt = datetime.datetime(year,1,1) # speed up search
1337 dt = datetime.datetime(year,1,1) # speed up search
1134 kindat = int(kindat)
1338 kindat = int(kindat)
1135 if format not in ('hdf5', 'netCDF4', 'ascii'):
1339 if format not in ('hdf5', 'netCDF4', 'ascii'):
1136 raise ValueError('Unknown format %s' % (format))
1340 raise ValueError('Unknown format %s' % (format))
1137 if format == 'netCDF4':
1341 if format == 'netCDF4':
1138 thisExt = '.nc'
1342 thisExt = '.nc'
1139 elif format == 'ascii':
1343 elif format == 'ascii':
1140 thisExt = '.txt'
1344 thisExt = '.txt'
1141 format_desc = formatDict[format]
1345 format_desc = formatDict[format]
1142 # create a list of full names, where each item is a tuple of
1346 # create a list of full names, where each item is a tuple of
1143 # (fullFilename in Madrigal, output basename with correct extension, date string)
1347 # (fullFilename in Madrigal, output basename with correct extension, date string)
1144 fileList = []
1348 fileList = []
1145 madDB = madrigal.metadata.MadrigalDB()
1349 madDB = madrigal.metadata.MadrigalDB()
1146 bg_color = madDB.getBackgroundColor()
1350 bg_color = madDB.getBackgroundColor()
1147 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1351 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1148 kindat_desc = madKindatObj.getKindatDescription(kindat, kinst)
1352 kindat_desc = madKindatObj.getKindatDescription(kindat, kinst)
1149 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1353 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1150 inst_name = madInstObj.getInstrumentName(kinst)
1354 inst_name = madInstObj.getInstrumentName(kinst)
1151 pi = madInstObj.getContactName(kinst)
1355 pi = madInstObj.getContactName(kinst)
1152 pi_email = madInstObj.getContactEmail(kinst)
1356 pi_email = madInstObj.getContactEmail(kinst)
1153 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
1357 madExpObj = madrigal.metadata.MadrigalExperiment(madDB)
1154 startIndex = madExpObj.getStartPosition(dt) + 1
1358 startIndex = madExpObj.getStartPosition(dt) + 1
1155 for loop in (0,1):
1359 for loop in (0,1):
1156 # we normally only loop once, but sometimes multi-year experiments require a slow full search
1360 # we normally only loop once, but sometimes multi-year experiments require a slow full search
1157 if loop == 0:
1361 if loop == 0:
1158 thisStartIndex = startIndex
1362 thisStartIndex = startIndex
1159 else:
1363 else:
1160 thisStartIndex = 0 # should only get to this case for rare multi-year experiments
1364 thisStartIndex = 0 # should only get to this case for rare multi-year experiments
1161 for i in range(thisStartIndex, madExpObj.getExpCount()):
1365 for i in range(thisStartIndex, madExpObj.getExpCount()):
1162 if kinst != madExpObj.getKinstByPosition(i):
1366 if kinst != madExpObj.getKinstByPosition(i):
1163 continue
1367 continue
1164 stTuple = madExpObj.getExpStartDateTimeByPosition(i)[0:6]
1368 stTuple = madExpObj.getExpStartDateTimeByPosition(i)[0:6]
1165 etTuple = madExpObj.getExpEndDateTimeByPosition(i)[0:6]
1369 etTuple = madExpObj.getExpEndDateTimeByPosition(i)[0:6]
1166 expTitle = madExpObj.getExpNameByPosition(i)
1370 expTitle = madExpObj.getExpNameByPosition(i)
1167 sDT = datetime.datetime(*stTuple)
1371 sDT = datetime.datetime(*stTuple)
1168 eDT = datetime.datetime(*etTuple)
1372 eDT = datetime.datetime(*etTuple)
1169 if sDT.year > year:
1373 if sDT.year > year:
1170 break
1374 break
1171 if eDT.year < year:
1375 if eDT.year < year:
1172 continue
1376 continue
1173 dateStr = ' From %s to %s: %s' % (sDT.strftime('%Y-%m-%d %H:%M:%S'), eDT.strftime('%Y-%m-%d %H:%M:%S'), str(expTitle))
1377 dateStr = ' From %s to %s: %s' % (sDT.strftime('%Y-%m-%d %H:%M:%S'), eDT.strftime('%Y-%m-%d %H:%M:%S'), str(expTitle))
1174 expDir = madExpObj.getExpDirByPosition(i)
1378 expDir = madExpObj.getExpDirByPosition(i)
1175 # look at this exp for the right kindat
1379 # look at this exp for the right kindat
1176 try:
1380 try:
1177 madFileObj = madrigal.metadata.MadrigalMetaFile(madDB, os.path.join(expDir, 'fileTab.txt'))
1381 madFileObj = madrigal.metadata.MadrigalMetaFile(madDB, os.path.join(expDir, 'fileTab.txt'))
1178 except:
1382 except:
1179 pass
1383 pass
1180 for j in range(madFileObj.getFileCount()):
1384 for j in range(madFileObj.getFileCount()):
1181 if madFileObj.getCategoryByPosition(j) not in (0,1):
1385 if madFileObj.getCategoryByPosition(j) not in (0,1):
1182 # skip history and alternate files
1386 # skip history and alternate files
1183 continue
1387 continue
1184 if madFileObj.getKindatByPosition(j) != kindat:
1388 if madFileObj.getKindatByPosition(j) != kindat:
1185 continue
1389 continue
1186 statusStr = ' : %s' % (str(madFileObj.getStatusByPosition(j)))
1390 statusStr = ' : %s' % (str(madFileObj.getStatusByPosition(j)))
1187 fullFilename = os.path.join(expDir, madFileObj.getFilenameByPosition(j))
1391 fullFilename = os.path.join(expDir, madFileObj.getFilenameByPosition(j))
1188 fullBasename = os.path.basename(fullFilename)
1392 fullBasename = os.path.basename(fullFilename)
1189 if format != 'hdf5':
1393 if format != 'hdf5':
1190 base, file_extension = os.path.splitext(fullFilename)
1394 base, file_extension = os.path.splitext(fullFilename)
1191 basename = os.path.basename(base + thisExt)
1395 basename = os.path.basename(base + thisExt)
1192 else:
1396 else:
1193 basename = os.path.basename(fullFilename)
1397 basename = os.path.basename(fullFilename)
1194 # make sure this file isn't too big to create a cache
1398 # make sure this file isn't too big to create a cache
1195 file_size = os.path.getsize(fullFilename)
1399 file_size = os.path.getsize(fullFilename)
1196 if file_size > maxSize and format != 'hdf5':
1400 if file_size > maxSize and format != 'hdf5':
1197 # make sure cached file exists before adding
1401 # make sure cached file exists before adding
1198 if format == 'netCDF4':
1402 if format == 'netCDF4':
1199 cachedFile = os.path.join(expDir, 'overview', fullBasename + thisExt)
1403 cachedFile = os.path.join(expDir, 'overview', fullBasename + thisExt)
1200 else:
1404 else:
1201 cachedFile = os.path.join(expDir, 'overview', fullBasename + thisExt + '.gz')
1405 cachedFile = os.path.join(expDir, 'overview', fullBasename + thisExt + '.gz')
1202 if not os.path.exists(cachedFile):
1406 if not os.path.exists(cachedFile):
1203 continue
1407 continue
1204 fileList.append((urllib.parse.quote_plus(fullFilename), basename, dateStr + statusStr))
1408 fileList.append((urllib.parse.quote_plus(fullFilename), basename, dateStr + statusStr))
1205
1409
1206 if len(fileList) > 0:
1410 if len(fileList) > 0:
1207 break # usually we avoid the slow full loop
1411 break # usually we avoid the slow full loop
1208
1412
1209
1413
1210 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1414 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1211 siteName, siteList = madWebObj.getSiteInfo()
1415 siteName, siteList = madWebObj.getSiteInfo()
1212
1416
1213 return render(request, 'madweb/ftp_files.html', {'fullFilenames': fileList, 'year': year, 'kindat_desc': kindat_desc,
1417 return render(request, 'madweb/ftp_files.html', {'fullFilenames': fileList, 'year': year, 'kindat_desc': kindat_desc,
1214 'kinst': kinst, 'inst_name':inst_name, 'fullname': fullname,
1418 'kinst': kinst, 'inst_name':inst_name, 'fullname': fullname,
1215 'kindat': kindat, 'format': format, 'format_desc': format_desc,
1419 'kindat': kindat, 'format': format, 'format_desc': format_desc,
1216 'email': email, 'affiliation':affiliation,
1420 'email': email, 'affiliation':affiliation,
1217 'site_name': siteName, 'site_list': siteList,
1421 'site_name': siteName, 'site_list': siteList,
1218 'pi_email': pi_email, 'pi_name': pi,
1422 'pi_email': pi_email, 'pi_name': pi,
1219 'bg_color': bg_color})
1423 'bg_color': bg_color})
1220
1424
1221
1425
1222 def ftp_download(request, user_fullname, user_email, user_affiliation, kinst, year, kindat, format, fullHdf5Filename):
1426 def ftp_download(request, user_fullname, user_email, user_affiliation, kinst, year, kindat, format, fullHdf5Filename):
1223 """ftp_download creates the first ftp kindat page listing individual files
1427 """ftp_download creates the first ftp kindat page listing individual files
1224 Inputs: kinst selected, year selected, kindat selected
1428 Inputs: kinst selected, year selected, kindat selected
1225 """
1429 """
1226 madDB = madrigal.metadata.MadrigalDB()
1430 madDB = madrigal.metadata.MadrigalDB()
1227 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1431 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1228 user_fullname = urllib.parse.unquote_plus(user_fullname)
1432 user_fullname = urllib.parse.unquote_plus(user_fullname)
1229 user_affiliation = urllib.parse.unquote_plus(user_affiliation)
1433 user_affiliation = urllib.parse.unquote_plus(user_affiliation)
1230 fullHdf5Filename = urllib.parse.unquote_plus(fullHdf5Filename)
1434 fullHdf5Filename = urllib.parse.unquote_plus(fullHdf5Filename)
1231 fullFilename = madWebObj.downloadFullFileAsIs(fullHdf5Filename, format, user_fullname, user_email, user_affiliation)
1435 fullFilename = madWebObj.downloadFullFileAsIs(fullHdf5Filename, format, user_fullname, user_email, user_affiliation)
1232
1436
1233 f = open(fullFilename, 'rb')
1437 f = open(fullFilename, 'rb')
1234 filename = os.path.basename(fullFilename)
1438 filename = os.path.basename(fullFilename)
1235 chunk_size = 8192
1439 chunk_size = 8192
1236 file_type = mimetypes.guess_type(fullFilename)[0]
1440 file_type = mimetypes.guess_type(fullFilename)[0]
1237 if file_type is None:
1441 if file_type is None:
1238 file_type = 'application/octet-stream'
1442 file_type = 'application/octet-stream'
1239 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
1443 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
1240 content_type=file_type)
1444 content_type=file_type)
1241 response['Content-Length'] = os.path.getsize(fullFilename)
1445 response['Content-Length'] = os.path.getsize(fullFilename)
1242 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
1446 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
1243 return(response)
1447 return(response)
1244
1448
1245
1449
1246 @csrf_exempt
1450 @csrf_exempt
1247 def ftp_multiple_download(request):
1451 def ftp_multiple_download(request):
1248 """ftp_download creates the first ftp kindat page listing individual files
1452 """ftp_download creates the first ftp kindat page listing individual files
1249 Inputs: kinst selected, year selected, kindat selected
1453 Inputs: kinst selected, year selected, kindat selected
1250 """
1454 """
1251 if request.method == 'POST':
1455 if request.method == 'POST':
1252 reqDict = request.POST
1456 reqDict = request.POST
1253 else:
1457 else:
1254 reqDict = request.GET
1458 reqDict = request.GET
1255 madDB = madrigal.metadata.MadrigalDB()
1459 madDB = madrigal.metadata.MadrigalDB()
1256 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1460 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1257 user_fullname = urllib.parse.unquote_plus(reqDict.get('user_fullname'))
1461 user_fullname = urllib.parse.unquote_plus(reqDict.get('user_fullname'))
1258 user_email = reqDict.get('user_email')
1462 user_email = reqDict.get('user_email')
1259 user_affiliation = urllib.parse.unquote_plus(reqDict.get('user_affiliation'))
1463 user_affiliation = urllib.parse.unquote_plus(reqDict.get('user_affiliation'))
1260 format = reqDict.get('format')
1464 format = reqDict.get('format')
1261 fileList = reqDict.getlist('fullFilename')
1465 fileList = reqDict.getlist('fullFilename')
1262 fileList = [urllib.parse.unquote_plus(filename) for filename in fileList]
1466 fileList = [urllib.parse.unquote_plus(filename) for filename in fileList]
1263 if len(fileList) > 10:
1467 if len(fileList) > 10:
1264 # send user an email with warning
1468 # send user an email with warning
1265 tmpDir = os.path.join(madDB.getMadroot(), 'experiments/stage')
1469 tmpDir = os.path.join(madDB.getMadroot(), 'experiments/stage')
1266 fullFilename = os.path.join(tmpDir, 'result_error_%06i.txt' % (random.randint(0,999999)))
1470 fullFilename = os.path.join(tmpDir, 'result_error_%06i.txt' % (random.randint(0,999999)))
1267 f = open(fullFilename, 'w')
1471 f = open(fullFilename, 'w')
1268 f.write('Error - you requested %i files, maximum is 10\n' % (len(fileList)))
1472 f.write('Error - you requested %i files, maximum is 10\n' % (len(fileList)))
1269 f.close()
1473 f.close()
1270 else:
1474 else:
1271 fullFilename = madWebObj.downloadMultipleFiles(fileList, format, user_fullname, user_email, user_affiliation)
1475 fullFilename = madWebObj.downloadMultipleFiles(fileList, format, user_fullname, user_email, user_affiliation)
1272
1476
1273 f = open(fullFilename, 'rb')
1477 f = open(fullFilename, 'rb')
1274 filename = os.path.basename(fullFilename)
1478 filename = os.path.basename(fullFilename)
1275 chunk_size = 8192
1479 chunk_size = 8192
1276 file_type = mimetypes.guess_type(fullFilename)[0]
1480 file_type = mimetypes.guess_type(fullFilename)[0]
1277 if file_type is None:
1481 if file_type is None:
1278 file_type = 'application/octet-stream'
1482 file_type = 'application/octet-stream'
1279 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
1483 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
1280 content_type=file_type)
1484 content_type=file_type)
1281 response['Content-Length'] = os.path.getsize(fullFilename)
1485 response['Content-Length'] = os.path.getsize(fullFilename)
1282 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
1486 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
1283 return(response)
1487 return(response)
1284
1488
1285
1489
1286 def instrument_metadata(request):
1490 def instrument_metadata(request):
1287 """instrument_metadata returns the instrument_metadata page.
1491 """instrument_metadata returns the instrument_metadata page.
1288
1492
1289 Inputs:
1493 Inputs:
1290 request
1494 request
1291 """
1495 """
1292 # create a list of tuples of (kinst, name, category, latitude, longitude, altitude, pi, pi_email, mnemonic)
1496 # create a list of tuples of (kinst, name, category, latitude, longitude, altitude, pi, pi_email, mnemonic)
1293 madDB = madrigal.metadata.MadrigalDB()
1497 madDB = madrigal.metadata.MadrigalDB()
1294 bg_color = madDB.getBackgroundColor()
1498 bg_color = madDB.getBackgroundColor()
1295 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1499 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1296 siteName, siteList = madWebObj.getSiteInfo()
1500 siteName, siteList = madWebObj.getSiteInfo()
1297 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1501 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1298 instList = []
1502 instList = []
1299 for name, mnemonic, kinst, category, catID in madInstObj.getOrderedInstrumentList():
1503 for name, mnemonic, kinst, category, catID in madInstObj.getOrderedInstrumentList():
1300 latitude = madInstObj.getLatitude(kinst)
1504 latitude = madInstObj.getLatitude(kinst)
1301 longitude = madInstObj.getLongitude(kinst)
1505 longitude = madInstObj.getLongitude(kinst)
1302 altitude = madInstObj.getAltitude(kinst)
1506 altitude = madInstObj.getAltitude(kinst)
1303 pi = madInstObj.getContactName(kinst)
1507 pi = madInstObj.getContactName(kinst)
1304 pi_email = madInstObj.getContactEmail(kinst)
1508 pi_email = madInstObj.getContactEmail(kinst)
1305 instList.append((kinst, name, category, latitude, longitude, altitude, pi, pi_email, mnemonic))
1509 instList.append((kinst, name, category, latitude, longitude, altitude, pi, pi_email, mnemonic))
1306
1510
1307 responseDict = {'inst_active': 'class="active"', 'instList': instList,
1511 responseDict = {'inst_active': 'class="active"', 'instList': instList,
1308 'site_name': siteName, 'site_list': siteList, 'bg_color': bg_color}
1512 'site_name': siteName, 'site_list': siteList, 'bg_color': bg_color}
1309 return render(request, 'madweb/instrument_metadata.html', responseDict)
1513 return render(request, 'madweb/instrument_metadata.html', responseDict)
1310
1514
1311
1515
1312 def site_metadata(request):
1516 def site_metadata(request):
1313 """site_metadata returns the site_metadata page.
1517 """site_metadata returns the site_metadata page.
1314
1518
1315 Inputs:
1519 Inputs:
1316 request
1520 request
1317 """
1521 """
1318 # create a list of tuples of (siteId, name, url, contact, contact email, version)
1522 # create a list of tuples of (siteId, name, url, contact, contact email, version)
1319 madDB = madrigal.metadata.MadrigalDB()
1523 madDB = madrigal.metadata.MadrigalDB()
1320 bg_color = madDB.getBackgroundColor()
1524 bg_color = madDB.getBackgroundColor()
1321 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1525 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1322 siteName, otherSiteList = madWebObj.getSiteInfo()
1526 siteName, otherSiteList = madWebObj.getSiteInfo()
1323 madSiteObj = madrigal.metadata.MadrigalSite(madDB)
1527 madSiteObj = madrigal.metadata.MadrigalSite(madDB)
1324 siteList = []
1528 siteList = []
1325 for siteId, siteName in madSiteObj.getSiteList():
1529 for siteId, siteName in madSiteObj.getSiteList():
1326 if madSiteObj.getSiteServer(siteId).find('http') == -1:
1530 if madSiteObj.getSiteServer(siteId).find('http') == -1:
1327 url = 'http://' + os.path.join(madSiteObj.getSiteServer(siteId),
1531 url = 'http://' + os.path.join(madSiteObj.getSiteServer(siteId),
1328 madSiteObj.getSiteDocRoot(siteId))
1532 madSiteObj.getSiteDocRoot(siteId))
1329 else:
1533 else:
1330 url = os.path.join(madSiteObj.getSiteServer(siteId),
1534 url = os.path.join(madSiteObj.getSiteServer(siteId),
1331 madSiteObj.getSiteDocRoot(siteId))
1535 madSiteObj.getSiteDocRoot(siteId))
1332 contact = madSiteObj.getSiteContactName(siteId)
1536 contact = madSiteObj.getSiteContactName(siteId)
1333 contact_email = madSiteObj.getSiteEmail(siteId)
1537 contact_email = madSiteObj.getSiteEmail(siteId)
1334 version = madSiteObj.getSiteVersion(siteId)
1538 version = madSiteObj.getSiteVersion(siteId)
1335 siteList.append((siteId, siteName, url, contact, contact_email, version))
1539 siteList.append((siteId, siteName, url, contact, contact_email, version))
1336
1540
1337 responseDict = {'site_active': 'class="active"', 'siteList': siteList,
1541 responseDict = {'site_active': 'class="active"', 'siteList': siteList,
1338 'site_name': siteName, 'site_list': otherSiteList, 'bg_color': bg_color}
1542 'site_name': siteName, 'site_list': otherSiteList, 'bg_color': bg_color}
1339 return render(request, 'madweb/site_metadata.html', responseDict)
1543 return render(request, 'madweb/site_metadata.html', responseDict)
1340
1544
1341
1545
1342 def parameter_metadata(request):
1546 def parameter_metadata(request):
1343 """parameter_metadata returns the site_metadata page.
1547 """parameter_metadata returns the site_metadata page.
1344
1548
1345 Inputs:
1549 Inputs:
1346 request
1550 request
1347 """
1551 """
1348 madDB = madrigal.metadata.MadrigalDB()
1552 madDB = madrigal.metadata.MadrigalDB()
1349 bg_color = madDB.getBackgroundColor()
1553 bg_color = madDB.getBackgroundColor()
1350 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1554 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1351 siteName, siteList = madWebObj.getSiteInfo()
1555 siteName, siteList = madWebObj.getSiteInfo()
1352 madParmObj = madrigal.data.MadrigalParameters(madDB)
1556 madParmObj = madrigal.data.MadrigalParameters(madDB)
1353 madParmCatObj = madrigal.metadata.MadrigalParmCategory(madDB)
1557 madParmCatObj = madrigal.metadata.MadrigalParmCategory(madDB)
1354 parmDict = {} # key is category string, value is list of category tuples (mnemonic, description, units, code)
1558 parmDict = {} # key is category string, value is list of category tuples (mnemonic, description, units, code)
1355 parmList = [] # list of tuples, each tuple either a single category, or (mnemonic, description, units, code)
1559 parmList = [] # list of tuples, each tuple either a single category, or (mnemonic, description, units, code)
1356 categoryList = []
1560 categoryList = []
1357 categoryUrlList = []
1561 categoryUrlList = []
1358 for mnemonic in madParmObj.getSortedMnemonicList():
1562 for mnemonic in madParmObj.getSortedMnemonicList():
1359 description = madParmObj.getSimpleParmDescription(mnemonic)
1563 description = madParmObj.getSimpleParmDescription(mnemonic)
1360 units = madParmObj.getParmUnits(mnemonic)
1564 units = madParmObj.getParmUnits(mnemonic)
1361 code = madParmObj.getParmCodeFromMnemonic(mnemonic)
1565 code = madParmObj.getParmCodeFromMnemonic(mnemonic)
1362 category = madParmObj.getParmCategory(mnemonic)
1566 category = madParmObj.getParmCategory(mnemonic)
1363 if category is None:
1567 if category is None:
1364 # deprecated prolog parm
1568 # deprecated prolog parm
1365 continue
1569 continue
1366 if category in list(parmDict.keys()):
1570 if category in list(parmDict.keys()):
1367 parmDict[category].append((mnemonic, description, units, code))
1571 parmDict[category].append((mnemonic, description, units, code))
1368 else:
1572 else:
1369 parmDict[category] = [(mnemonic, description, units, code)]
1573 parmDict[category] = [(mnemonic, description, units, code)]
1370
1574
1371 # now loop through all categories
1575 # now loop through all categories
1372 for thisCategory, catId in madParmCatObj.getCategoryList():
1576 for thisCategory, catId in madParmCatObj.getCategoryList():
1373 parmList.append((thisCategory,))
1577 parmList.append((thisCategory,))
1374 categoryList.append(thisCategory)
1578 categoryList.append(thisCategory)
1375 categoryAnchor = thisCategory.replace(' ','_')
1579 categoryAnchor = thisCategory.replace(' ','_')
1376 categoryUrlList.append('<a href="#%s">%s</a>' % (categoryAnchor, thisCategory))
1580 categoryUrlList.append('<a href="#%s">%s</a>' % (categoryAnchor, thisCategory))
1377 for values in parmDict[thisCategory]:
1581 for values in parmDict[thisCategory]:
1378 parmList.append(values)
1582 parmList.append(values)
1379
1583
1380 responseDict = {'parm_active': 'class="active"', 'parmList': parmList,
1584 responseDict = {'parm_active': 'class="active"', 'parmList': parmList,
1381 'categoryUrlList':categoryUrlList,
1585 'categoryUrlList':categoryUrlList,
1382 'site_name': siteName, 'site_list': siteList, 'bg_color': bg_color}
1586 'site_name': siteName, 'site_list': siteList, 'bg_color': bg_color}
1383 return render(request, 'madweb/parameter_metadata.html', responseDict)
1587 return render(request, 'madweb/parameter_metadata.html', responseDict)
1384
1588
1385
1589
1386 def kindat_metadata(request):
1590 def kindat_metadata(request):
1387 """kindat_metadata returns the kindat_metadata page.
1591 """kindat_metadata returns the kindat_metadata page.
1388
1592
1389 Inputs:
1593 Inputs:
1390 request
1594 request
1391 """
1595 """
1392 # create a list of tuples of (kindat, description, kinst, instrument_name)
1596 # create a list of tuples of (kindat, description, kinst, instrument_name)
1393 madDB = madrigal.metadata.MadrigalDB()
1597 madDB = madrigal.metadata.MadrigalDB()
1394 bg_color = madDB.getBackgroundColor()
1598 bg_color = madDB.getBackgroundColor()
1395 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1599 madKindatObj = madrigal.metadata.MadrigalKindat(madDB)
1396 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1600 madInstObj = madrigal.metadata.MadrigalInstrument(madDB)
1397 madInstKindatObj = madrigal.metadata.MadrigalInstrumentKindats(madDB)
1601 madInstKindatObj = madrigal.metadata.MadrigalInstrumentKindats(madDB)
1398 # create a dict of key = kindat code, value list of associated instruments
1602 # create a dict of key = kindat code, value list of associated instruments
1399 kindatDict = {}
1603 kindatDict = {}
1400 for name, mnem, kinst in madInstObj.getInstrumentList():
1604 for name, mnem, kinst in madInstObj.getInstrumentList():
1401 thisKindatList = madInstKindatObj.getKindatListForInstruments(kinst)
1605 thisKindatList = madInstKindatObj.getKindatListForInstruments(kinst)
1402 for kindat in thisKindatList:
1606 for kindat in thisKindatList:
1403 if kindat not in kindatDict:
1607 if kindat not in kindatDict:
1404 kindatDict[kindat] = [kinst]
1608 kindatDict[kindat] = [kinst]
1405 else:
1609 else:
1406 kindatDict[kindat].append(kinst)
1610 kindatDict[kindat].append(kinst)
1407
1611
1408 kindatList = []
1612 kindatList = []
1409 for description, code_str in madKindatObj.getKindatList():
1613 for description, code_str in madKindatObj.getKindatList():
1410 try:
1614 try:
1411 kinst, kindat = code_str.split('_')
1615 kinst, kindat = code_str.split('_')
1412 instName = madInstObj.getInstrumentName(int(kinst))
1616 instName = madInstObj.getInstrumentName(int(kinst))
1413 except:
1617 except:
1414 kindat = code_str
1618 kindat = code_str
1415 try:
1619 try:
1416 kinst = str(kindatDict[int(kindat)][0])
1620 kinst = str(kindatDict[int(kindat)][0])
1417 instName = madInstObj.getInstrumentName(int(kinst))
1621 instName = madInstObj.getInstrumentName(int(kinst))
1418 except KeyError:
1622 except KeyError:
1419 kinst = '-'
1623 kinst = '-'
1420 instName = 'Unspecified'
1624 instName = 'Unspecified'
1421 kindatList.append((kindat, description, kinst, instName))
1625 kindatList.append((kindat, description, kinst, instName))
1422 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1626 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1423 siteName, siteList = madWebObj.getSiteInfo()
1627 siteName, siteList = madWebObj.getSiteInfo()
1424
1628
1425 responseDict = {'kindat_active': 'class="active"', 'kindatList': kindatList,
1629 responseDict = {'kindat_active': 'class="active"', 'kindatList': kindatList,
1426 'site_name': siteName, 'site_list': siteList, 'bg_color': bg_color}
1630 'site_name': siteName, 'site_list': siteList, 'bg_color': bg_color}
1427 return render(request, 'madweb/kindat_metadata.html', responseDict)
1631 return render(request, 'madweb/kindat_metadata.html', responseDict)
1428
1632
1429
1633
1430 def madrigal_calculator(request):
1634 def madrigal_calculator(request):
1431 """madrigal_calculator returns the Madrigal Calculator page.
1635 """madrigal_calculator returns the Madrigal Calculator page.
1432
1636
1433 Inputs:
1637 Inputs:
1434 request
1638 request
1435 """
1639 """
1436 madDB = madrigal.metadata.MadrigalDB()
1640 madDB = madrigal.metadata.MadrigalDB()
1437 bg_color = madDB.getBackgroundColor()
1641 bg_color = madDB.getBackgroundColor()
1438 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1642 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1439 siteName, siteList = madWebObj.getSiteInfo()
1643 siteName, siteList = madWebObj.getSiteInfo()
1440 # original blank form
1644 # original blank form
1441 madCalculatorForm = madweb.forms.MadCalculatorForm()
1645 madCalculatorForm = madweb.forms.MadCalculatorForm()
1442 parmList = [(parm, madCalculatorForm.parmDescDict[parm]) for parm in list(madCalculatorForm.parmDescDict.keys())]
1646 parmList = [(parm, madCalculatorForm.parmDescDict[parm]) for parm in list(madCalculatorForm.parmDescDict.keys())]
1443 return render(request, 'madweb/madrigal_calculator.html', {'madCalculator_active': 'class="active"',
1647 return render(request, 'madweb/madrigal_calculator.html', {'madCalculator_active': 'class="active"',
1444 'form': madCalculatorForm,
1648 'form': madCalculatorForm,
1445 'parmList': parmList,
1649 'parmList': parmList,
1446 'site_name': siteName, 'site_list': siteList,
1650 'site_name': siteName, 'site_list': siteList,
1447 'bg_color': bg_color, 'datetime': True})
1651 'bg_color': bg_color, 'datetime': True})
1448
1652
1449 def madrigal_calculator_output(request):
1653 def madrigal_calculator_output(request):
1450 """madrigal_calculator returns the output from the Madrigal Calculator page.
1654 """madrigal_calculator returns the output from the Madrigal Calculator page.
1451
1655
1452 Inputs:
1656 Inputs:
1453 request
1657 request
1454 """
1658 """
1455 madDB = madrigal.metadata.MadrigalDB()
1659 madDB = madrigal.metadata.MadrigalDB()
1456 bg_color = madDB.getBackgroundColor()
1660 bg_color = madDB.getBackgroundColor()
1457 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1661 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1458 siteName, siteList = madWebObj.getSiteInfo()
1662 siteName, siteList = madWebObj.getSiteInfo()
1459
1663
1460 madCalculatorForm = madweb.forms.MadCalculatorForm(request.GET)
1664 madCalculatorForm = madweb.forms.MadCalculatorForm(request.GET)
1461
1665
1462 try:
1666 try:
1463 if not madCalculatorForm.is_valid():
1667 if not madCalculatorForm.is_valid():
1464 return(HttpResponse(str(madCalculatorForm.errors)))
1668 return(HttpResponse(str(madCalculatorForm.errors)))
1465 except KeyError:
1669 except KeyError:
1466 return(HttpResponse('<p>Missing arguments in madCalculatorOutput</p>'))
1670 return(HttpResponse('<p>Missing arguments in madCalculatorOutput</p>'))
1467
1671
1468 text = madWebObj.runMadrigalCalculatorFromForm(madCalculatorForm.cleaned_data)
1672 text = madWebObj.runMadrigalCalculatorFromForm(madCalculatorForm.cleaned_data)
1469
1673
1470 return render(request, 'madweb/madrigal_calculator_output.html', {'madCalculator_active': 'class="active"',
1674 return render(request, 'madweb/madrigal_calculator_output.html', {'madCalculator_active': 'class="active"',
1471 'text': text,
1675 'text': text,
1472 'site_name': siteName, 'site_list': siteList,
1676 'site_name': siteName, 'site_list': siteList,
1473 'bg_color': bg_color})
1677 'bg_color': bg_color})
1474
1678
1475
1679
1476 def get_metadata(request):
1680 def get_metadata(request):
1477 """get_metadata allows local metadata files to be downloaded.
1681 """get_metadata allows local metadata files to be downloaded.
1478
1682
1479 Inputs:
1683 Inputs:
1480 request
1684 request
1481 """
1685 """
1482 fileDict = {'0':'expTab.txt',
1686 fileDict = {'0':'expTab.txt',
1483 '1': 'fileTab.txt',
1687 '1': 'fileTab.txt',
1484 '3': 'instTab.txt',
1688 '3': 'instTab.txt',
1485 '4': 'parmCodes.txt',
1689 '4': 'parmCodes.txt',
1486 '5': 'siteTab.txt',
1690 '5': 'siteTab.txt',
1487 '6': 'typeTab.txt',
1691 '6': 'typeTab.txt',
1488 '7': 'instKindatTab.txt',
1692 '7': 'instKindatTab.txt',
1489 '8': 'instParmTab.txt',
1693 '8': 'instParmTab.txt',
1490 '9': 'madCatTab.txt',
1694 '9': 'madCatTab.txt',
1491 '10': 'instType.txt'}
1695 '10': 'instType.txt'}
1492 form = madweb.forms.GetMetadataForm(request.GET)
1696 form = madweb.forms.GetMetadataForm(request.GET)
1493 if form.is_valid():
1697 if form.is_valid():
1494 madDB = madrigal.metadata.MadrigalDB()
1698 madDB = madrigal.metadata.MadrigalDB()
1495 downloadFile = os.path.join(madDB.getMetadataDir(),
1699 downloadFile = os.path.join(madDB.getMetadataDir(),
1496 fileDict[form.cleaned_data['fileType']])
1700 fileDict[form.cleaned_data['fileType']])
1497
1701
1498
1702
1499 f = open(downloadFile, 'rb')
1703 f = open(downloadFile, 'rb')
1500 filename = os.path.basename(downloadFile)
1704 filename = os.path.basename(downloadFile)
1501 chunk_size = 8192
1705 chunk_size = 8192
1502 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
1706 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
1503 content_type=mimetypes.guess_type(downloadFile)[0])
1707 content_type=mimetypes.guess_type(downloadFile)[0])
1504 response['Content-Length'] = os.path.getsize(downloadFile)
1708 response['Content-Length'] = os.path.getsize(downloadFile)
1505 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
1709 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
1506 return(response)
1710 return(response)
1507
1711
1508 else:
1712 else:
1509 madDB = madrigal.metadata.MadrigalDB()
1713 madDB = madrigal.metadata.MadrigalDB()
1510 bg_color = madDB.getBackgroundColor()
1714 bg_color = madDB.getBackgroundColor()
1511 form = madweb.forms.GetMetadataForm()
1715 form = madweb.forms.GetMetadataForm()
1512 return render(request, 'madweb/get_metadata.html', {'form': form, 'bg_color': bg_color})
1716 return render(request, 'madweb/get_metadata.html', {'form': form, 'bg_color': bg_color})
1513
1717
1514
1718
1515 def looker_main(request):
1719 def looker_main(request):
1516 """looker_main loads the main looker selection form.
1720 """looker_main loads the main looker selection form.
1517
1721
1518 Inputs:
1722 Inputs:
1519 request
1723 request
1520 """
1724 """
1521 madDB = madrigal.metadata.MadrigalDB()
1725 madDB = madrigal.metadata.MadrigalDB()
1522 bg_color = madDB.getBackgroundColor()
1726 bg_color = madDB.getBackgroundColor()
1523 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1727 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1524 siteName, siteList = madWebObj.getSiteInfo()
1728 siteName, siteList = madWebObj.getSiteInfo()
1525 lookerSelectForm = madweb.forms.LookerSelectForm()
1729 lookerSelectForm = madweb.forms.LookerSelectForm()
1526 return render(request, 'madweb/looker_main.html', {'looker_active': 'class="active"',
1730 return render(request, 'madweb/looker_main.html', {'looker_active': 'class="active"',
1527 'form': lookerSelectForm,
1731 'form': lookerSelectForm,
1528 'site_name': siteName, 'site_list': siteList,
1732 'site_name': siteName, 'site_list': siteList,
1529 'bg_color': bg_color})
1733 'bg_color': bg_color})
1530
1734
1531
1735
1532 def looker_form(request):
1736 def looker_form(request):
1533 """looker_form loads the appropriate looker form.
1737 """looker_form loads the appropriate looker form.
1534
1738
1535 Inputs:
1739 Inputs:
1536 request
1740 request
1537 """
1741 """
1538 madDB = madrigal.metadata.MadrigalDB()
1742 madDB = madrigal.metadata.MadrigalDB()
1539 bg_color = madDB.getBackgroundColor()
1743 bg_color = madDB.getBackgroundColor()
1540 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1744 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1541 siteName, siteList = madWebObj.getSiteInfo()
1745 siteName, siteList = madWebObj.getSiteInfo()
1542 if not 'looker_options' in request.GET:
1746 if not 'looker_options' in request.GET:
1543 return(HttpResponse('<p>looker form requires looker_options</p>'))
1747 return(HttpResponse('<p>looker form requires looker_options</p>'))
1544 form = madweb.forms.LookerSelectForm(request.GET)
1748 form = madweb.forms.LookerSelectForm(request.GET)
1545 if form.is_valid():
1749 if form.is_valid():
1546 option = form.cleaned_data['looker_options']
1750 option = form.cleaned_data['looker_options']
1547 if option == '1':
1751 if option == '1':
1548 form = madweb.forms.LookerGeodeticRadar()
1752 form = madweb.forms.LookerGeodeticRadar()
1549 return render(request, 'madweb/looker_geodetic_to_radar.html', {'looker_active': 'class="active"',
1753 return render(request, 'madweb/looker_geodetic_to_radar.html', {'looker_active': 'class="active"',
1550 'form': form,
1754 'form': form,
1551 'site_name': siteName, 'site_list': siteList,
1755 'site_name': siteName, 'site_list': siteList,
1552 'bg_color': bg_color})
1756 'bg_color': bg_color})
1553 elif option == '2':
1757 elif option == '2':
1554 form = madweb.forms.LookerGeomagRadar()
1758 form = madweb.forms.LookerGeomagRadar()
1555 return render(request, 'madweb/looker_geomagnetic_to_radar.html', {'looker_active': 'class="active"',
1759 return render(request, 'madweb/looker_geomagnetic_to_radar.html', {'looker_active': 'class="active"',
1556 'form': form,
1760 'form': form,
1557 'site_name': siteName, 'site_list': siteList,
1761 'site_name': siteName, 'site_list': siteList,
1558 'bg_color': bg_color})
1762 'bg_color': bg_color})
1559 elif option == '3':
1763 elif option == '3':
1560 form = madweb.forms.LookerGeomagFromGeodetic()
1764 form = madweb.forms.LookerGeomagFromGeodetic()
1561 return render(request, 'madweb/looker_geomagnetic_from_geodetic.html', {'looker_active': 'class="active"',
1765 return render(request, 'madweb/looker_geomagnetic_from_geodetic.html', {'looker_active': 'class="active"',
1562 'form': form,
1766 'form': form,
1563 'site_name': siteName, 'site_list': siteList,
1767 'site_name': siteName, 'site_list': siteList,
1564 'bg_color': bg_color})
1768 'bg_color': bg_color})
1565 elif option == '4':
1769 elif option == '4':
1566 form = madweb.forms.LookerGeomagFromRadar()
1770 form = madweb.forms.LookerGeomagFromRadar()
1567 return render(request, 'madweb/looker_geomagnetic_from_radar.html', {'looker_active': 'class="active"',
1771 return render(request, 'madweb/looker_geomagnetic_from_radar.html', {'looker_active': 'class="active"',
1568 'form': form,
1772 'form': form,
1569 'site_name': siteName, 'site_list': siteList,
1773 'site_name': siteName, 'site_list': siteList,
1570 'bg_color': bg_color})
1774 'bg_color': bg_color})
1571 elif option == '5':
1775 elif option == '5':
1572 form = madweb.forms.LookerFieldLineFromRadar()
1776 form = madweb.forms.LookerFieldLineFromRadar()
1573 return render(request, 'madweb/looker_field_line_from_radar.html', {'looker_active': 'class="active"',
1777 return render(request, 'madweb/looker_field_line_from_radar.html', {'looker_active': 'class="active"',
1574 'form': form,
1778 'form': form,
1575 'site_name': siteName, 'site_list': siteList,
1779 'site_name': siteName, 'site_list': siteList,
1576 'bg_color': bg_color})
1780 'bg_color': bg_color})
1577 elif option == '6':
1781 elif option == '6':
1578 form = madweb.forms.LookerFieldLineFromGeodetic()
1782 form = madweb.forms.LookerFieldLineFromGeodetic()
1579 return render(request, 'madweb/looker_field_line_from_geodetic.html', {'looker_active': 'class="active"',
1783 return render(request, 'madweb/looker_field_line_from_geodetic.html', {'looker_active': 'class="active"',
1580 'form': form,
1784 'form': form,
1581 'site_name': siteName, 'site_list': siteList,
1785 'site_name': siteName, 'site_list': siteList,
1582 'bg_color': bg_color})
1786 'bg_color': bg_color})
1583 elif option == '7':
1787 elif option == '7':
1584 form = madweb.forms.LookerFieldLineFromApex()
1788 form = madweb.forms.LookerFieldLineFromApex()
1585 return render(request, 'madweb/looker_field_line_from_apex.html', {'looker_active': 'class="active"',
1789 return render(request, 'madweb/looker_field_line_from_apex.html', {'looker_active': 'class="active"',
1586 'form': form,
1790 'form': form,
1587 'site_name': siteName, 'site_list': siteList,
1791 'site_name': siteName, 'site_list': siteList,
1588 'bg_color': bg_color})
1792 'bg_color': bg_color})
1589 elif option == '8':
1793 elif option == '8':
1590 form = madweb.forms.LookerConjugateFromGeodetic()
1794 form = madweb.forms.LookerConjugateFromGeodetic()
1591 return render(request, 'madweb/looker_conjugate_from_geodetic.html', {'looker_active': 'class="active"',
1795 return render(request, 'madweb/looker_conjugate_from_geodetic.html', {'looker_active': 'class="active"',
1592 'form': form,
1796 'form': form,
1593 'site_name': siteName, 'site_list': siteList,
1797 'site_name': siteName, 'site_list': siteList,
1594 'bg_color': bg_color,
1798 'bg_color': bg_color,
1595 'datetime': True})
1799 'datetime': True})
1596 else:
1800 else:
1597 raise ValueError(str(form.errors))
1801 raise ValueError(str(form.errors))
1598
1802
1599
1803
1600 def looker_output(request):
1804 def looker_output(request):
1601 """looker_output loads the appropriate looker output.
1805 """looker_output loads the appropriate looker output.
1602
1806
1603 Inputs:
1807 Inputs:
1604 request
1808 request
1605 """
1809 """
1606 madDB = madrigal.metadata.MadrigalDB()
1810 madDB = madrigal.metadata.MadrigalDB()
1607 bg_color = madDB.getBackgroundColor()
1811 bg_color = madDB.getBackgroundColor()
1608 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1812 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
1609 siteName, siteList = madWebObj.getSiteInfo()
1813 siteName, siteList = madWebObj.getSiteInfo()
1610
1814
1611 if not 'looker_options' in request.GET:
1815 if not 'looker_options' in request.GET:
1612 return(HttpResponse('<p>looker missing arguments</p>'))
1816 return(HttpResponse('<p>looker missing arguments</p>'))
1613
1817
1614 if request.GET['looker_options'] == "1":
1818 if request.GET['looker_options'] == "1":
1615 form = madweb.forms.LookerGeodeticRadar(request.GET)
1819 form = madweb.forms.LookerGeodeticRadar(request.GET)
1616 if form.is_valid():
1820 if form.is_valid():
1617 text = madWebObj.runLookerFromForm(form.cleaned_data)
1821 text = madWebObj.runLookerFromForm(form.cleaned_data)
1618 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1822 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1619 'type': 'Az, El, Range to Geodetic points',
1823 'type': 'Az, El, Range to Geodetic points',
1620 'text': text,
1824 'text': text,
1621 'site_name': siteName, 'site_list': siteList,
1825 'site_name': siteName, 'site_list': siteList,
1622 'bg_color': bg_color})
1826 'bg_color': bg_color})
1623 else:
1827 else:
1624 raise ValueError(str(form.errors))
1828 raise ValueError(str(form.errors))
1625 elif request.GET['looker_options'] == "2":
1829 elif request.GET['looker_options'] == "2":
1626 form = madweb.forms.LookerGeomagRadar(request.GET)
1830 form = madweb.forms.LookerGeomagRadar(request.GET)
1627 if form.is_valid():
1831 if form.is_valid():
1628 text = madWebObj.runLookerFromForm(form.cleaned_data)
1832 text = madWebObj.runLookerFromForm(form.cleaned_data)
1629 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1833 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1630 'type': 'Az, El, Range to Geomagnetic (apex) points',
1834 'type': 'Az, El, Range to Geomagnetic (apex) points',
1631 'text': text,
1835 'text': text,
1632 'site_name': siteName, 'site_list': siteList,
1836 'site_name': siteName, 'site_list': siteList,
1633 'bg_color': bg_color})
1837 'bg_color': bg_color})
1634 else:
1838 else:
1635 raise ValueError(str(form.errors))
1839 raise ValueError(str(form.errors))
1636 elif request.GET['looker_options'] == "3":
1840 elif request.GET['looker_options'] == "3":
1637 form = madweb.forms.LookerGeomagFromGeodetic(request.GET)
1841 form = madweb.forms.LookerGeomagFromGeodetic(request.GET)
1638 if form.is_valid():
1842 if form.is_valid():
1639 text = madWebObj.runLookerFromForm(form.cleaned_data)
1843 text = madWebObj.runLookerFromForm(form.cleaned_data)
1640 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1844 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1641 'type': 'Apex Geomagnetic coordinates from Geodetic grid',
1845 'type': 'Apex Geomagnetic coordinates from Geodetic grid',
1642 'text': text,
1846 'text': text,
1643 'site_name': siteName, 'site_list': siteList,
1847 'site_name': siteName, 'site_list': siteList,
1644 'bg_color': bg_color})
1848 'bg_color': bg_color})
1645 else:
1849 else:
1646 raise ValueError(str(form.errors))
1850 raise ValueError(str(form.errors))
1647 elif request.GET['looker_options'] == "4":
1851 elif request.GET['looker_options'] == "4":
1648 form = madweb.forms.LookerGeomagFromRadar(request.GET)
1852 form = madweb.forms.LookerGeomagFromRadar(request.GET)
1649 if form.is_valid():
1853 if form.is_valid():
1650 text = madWebObj.runLookerFromForm(form.cleaned_data)
1854 text = madWebObj.runLookerFromForm(form.cleaned_data)
1651 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1855 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1652 'type': 'Apex Geomagnetic and geodetic coordinates and aspect angle from a grid of azimuth, elevation, and range',
1856 'type': 'Apex Geomagnetic and geodetic coordinates and aspect angle from a grid of azimuth, elevation, and range',
1653 'text': text,
1857 'text': text,
1654 'site_name': siteName, 'site_list': siteList,
1858 'site_name': siteName, 'site_list': siteList,
1655 'bg_color': bg_color})
1859 'bg_color': bg_color})
1656 else:
1860 else:
1657 raise ValueError(str(form.errors))
1861 raise ValueError(str(form.errors))
1658 elif request.GET['looker_options'] == "5":
1862 elif request.GET['looker_options'] == "5":
1659 form = madweb.forms.LookerFieldLineFromRadar(request.GET)
1863 form = madweb.forms.LookerFieldLineFromRadar(request.GET)
1660 if form.is_valid():
1864 if form.is_valid():
1661 text = madWebObj.runLookerFromForm(form.cleaned_data)
1865 text = madWebObj.runLookerFromForm(form.cleaned_data)
1662 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1866 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1663 'type': 'Field line coordinates for a field line set by radar parameters',
1867 'type': 'Field line coordinates for a field line set by radar parameters',
1664 'text': text,
1868 'text': text,
1665 'site_name': siteName, 'site_list': siteList,
1869 'site_name': siteName, 'site_list': siteList,
1666 'bg_color': bg_color})
1870 'bg_color': bg_color})
1667 else:
1871 else:
1668 raise ValueError(str(form.errors))
1872 raise ValueError(str(form.errors))
1669 elif request.GET['looker_options'] == "6":
1873 elif request.GET['looker_options'] == "6":
1670 form = madweb.forms.LookerFieldLineFromGeodetic(request.GET)
1874 form = madweb.forms.LookerFieldLineFromGeodetic(request.GET)
1671 if form.is_valid():
1875 if form.is_valid():
1672 text = madWebObj.runLookerFromForm(form.cleaned_data)
1876 text = madWebObj.runLookerFromForm(form.cleaned_data)
1673 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1877 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1674 'type': 'Field line coordinates and radar look parameters for given field line',
1878 'type': 'Field line coordinates and radar look parameters for given field line',
1675 'text': text,
1879 'text': text,
1676 'site_name': siteName, 'site_list': siteList,
1880 'site_name': siteName, 'site_list': siteList,
1677 'bg_color': bg_color})
1881 'bg_color': bg_color})
1678 else:
1882 else:
1679 raise ValueError(str(form.errors))
1883 raise ValueError(str(form.errors))
1680 elif request.GET['looker_options'] == "7":
1884 elif request.GET['looker_options'] == "7":
1681 form = madweb.forms.LookerFieldLineFromApex(request.GET)
1885 form = madweb.forms.LookerFieldLineFromApex(request.GET)
1682 if form.is_valid():
1886 if form.is_valid():
1683 text = madWebObj.runLookerFromForm(form.cleaned_data)
1887 text = madWebObj.runLookerFromForm(form.cleaned_data)
1684 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1888 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1685 'type': 'Field line coordinates and radar look parameters for given field line',
1889 'type': 'Field line coordinates and radar look parameters for given field line',
1686 'text': text,
1890 'text': text,
1687 'site_name': siteName, 'site_list': siteList,
1891 'site_name': siteName, 'site_list': siteList,
1688 'bg_color': bg_color})
1892 'bg_color': bg_color})
1689 else:
1893 else:
1690 raise ValueError(str(form.errors))
1894 raise ValueError(str(form.errors))
1691 elif request.GET['looker_options'] == "8":
1895 elif request.GET['looker_options'] == "8":
1692 form = madweb.forms.LookerConjugateFromGeodetic(request.GET)
1896 form = madweb.forms.LookerConjugateFromGeodetic(request.GET)
1693 if form.is_valid():
1897 if form.is_valid():
1694 text = madWebObj.runLookerFromForm(form.cleaned_data)
1898 text = madWebObj.runLookerFromForm(form.cleaned_data)
1695 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1899 return render(request, 'madweb/looker_output.html', {'looker_active': 'class="active"',
1696 'type': 'Point/Magnetic Conjugate Point vs Latitude, Longitude, Altitude',
1900 'type': 'Point/Magnetic Conjugate Point vs Latitude, Longitude, Altitude',
1697 'datetime': form.cleaned_data['datetime'],
1901 'datetime': form.cleaned_data['datetime'],
1698 'text': text,
1902 'text': text,
1699 'site_name': siteName, 'site_list': siteList,
1903 'site_name': siteName, 'site_list': siteList,
1700 'bg_color': bg_color})
1904 'bg_color': bg_color})
1701 else:
1905 else:
1702 raise ValueError(str(form.errors))
1906 raise ValueError(str(form.errors))
1703
1907
1704 else:
1908 else:
1705 raise ValueError('Unknown looker_option <%s>' % (str(request.GET['looker_options'])))
1909 raise ValueError('Unknown looker_option <%s>' % (str(request.GET['looker_options'])))
1706
1910
1707
1911
1708
1912
1709 def get_version_service(request):
1913 def get_version_service(request):
1710 """get_version_service runs the getVersionService.py service.
1914 """get_version_service runs the getVersionService.py service.
1711
1915
1712 Inputs:
1916 Inputs:
1713 request (ignored)
1917 request (ignored)
1714
1918
1715 Returns a single line of text, with the version in the form <major_version_int>.<minor_version_int>[.<sub_version_int>]
1919 Returns a single line of text, with the version in the form <major_version_int>.<minor_version_int>[.<sub_version_int>]
1716 """
1920 """
1717 madDB = madrigal.metadata.MadrigalDB()
1921 madDB = madrigal.metadata.MadrigalDB()
1718 siteID = madDB.getSiteID()
1922 siteID = madDB.getSiteID()
1719 madSiteObj = madrigal.metadata.MadrigalSite(madDB)
1923 madSiteObj = madrigal.metadata.MadrigalSite(madDB)
1720 return(HttpResponse(madSiteObj.getSiteVersion(siteID)))
1924 return(HttpResponse(madSiteObj.getSiteVersion(siteID)))
1721
1925
1722
1926
1723
1927
1724 def get_instruments_service(request):
1928 def get_instruments_service(request):
1725 """get_instruments_service runs the getInstrumentsService.py service.
1929 """get_instruments_service runs the getInstrumentsService.py service.
1726
1930
1727 Inputs:
1931 Inputs:
1728 request (ignored)
1932 request (ignored)
1729
1933
1730 Returns comma-delimited data, one line for each experiment, with the following fields:
1934 Returns comma-delimited data, one line for each experiment, with the following fields:
1731
1935
1732 1. instrument.name Example: 'Millstone Hill Incoherent Scatter Radar'
1936 1. instrument.name Example: 'Millstone Hill Incoherent Scatter Radar'
1733
1937
1734 2. instrument.code Example: 30
1938 2. instrument.code Example: 30
1735
1939
1736 3. instrument.mnemonic (3 char string) Example: 'mlh'
1940 3. instrument.mnemonic (3 char string) Example: 'mlh'
1737
1941
1738 4. instrument.latitude Example: 45.0
1942 4. instrument.latitude Example: 45.0
1739
1943
1740 5. instrument.longitude Example: 110.0
1944 5. instrument.longitude Example: 110.0
1741
1945
1742 6. instrument.altitude Example: 0.015 (km)
1946 6. instrument.altitude Example: 0.015 (km)
1743
1947
1744 7. instrument.category Example: 'Incoherent Scatter Radars'
1948 7. instrument.category Example: 'Incoherent Scatter Radars'
1745
1949
1746 8. contact name
1950 8. contact name
1747
1951
1748 9. contact email
1952 9. contact email
1749 """
1953 """
1750 # create MadrigalDB obj
1954 # create MadrigalDB obj
1751 madDBObj = madrigal.metadata.MadrigalDB()
1955 madDBObj = madrigal.metadata.MadrigalDB()
1752
1956
1753 # create MadrigalInstument object
1957 # create MadrigalInstument object
1754 madInst = madrigal.metadata.MadrigalInstrument(madDBObj)
1958 madInst = madrigal.metadata.MadrigalInstrument(madDBObj)
1755
1959
1756 # get instrument list
1960 # get instrument list
1757 instList = madInst.getInstrumentList()
1961 instList = madInst.getInstrumentList()
1758
1962
1759 # loop through each instrument
1963 # loop through each instrument
1760 instStr = ''
1964 instStr = ''
1761 for inst in instList:
1965 for inst in instList:
1762 name = inst[0]
1966 name = inst[0]
1763 code = inst[2]
1967 code = inst[2]
1764 mnemonic = inst[1]
1968 mnemonic = inst[1]
1765 latitude = madInst.getLatitude(code)
1969 latitude = madInst.getLatitude(code)
1766 if latitude == None:
1970 if latitude == None:
1767 latitude = 0.0
1971 latitude = 0.0
1768 longitude = madInst.getLongitude(code)
1972 longitude = madInst.getLongitude(code)
1769 if longitude == None:
1973 if longitude == None:
1770 longitude = 0.0
1974 longitude = 0.0
1771 altitude = madInst.getAltitude(code)
1975 altitude = madInst.getAltitude(code)
1772 if altitude == None:
1976 if altitude == None:
1773 altitude = 0.0
1977 altitude = 0.0
1774 category = madInst.getCategory(code)
1978 category = madInst.getCategory(code)
1775 if category == None:
1979 if category == None:
1776 category = ''
1980 category = ''
1777 # print data
1981 # print data
1778 contactName = madInst.getContactName(code)
1982 contactName = madInst.getContactName(code)
1779 contactEmail = madInst.getContactEmail(code)
1983 contactEmail = madInst.getContactEmail(code)
1780 instStr += '%s,%i,%s,%f,%f,%f,%s,%s,%s\n' % (name,
1984 instStr += '%s,%i,%s,%f,%f,%f,%s,%s,%s\n' % (name,
1781 code,
1985 code,
1782 mnemonic,
1986 mnemonic,
1783 latitude,
1987 latitude,
1784 longitude,
1988 longitude,
1785 altitude,
1989 altitude,
1786 category,
1990 category,
1787 str(contactName),
1991 str(contactName),
1788 str(contactEmail))
1992 str(contactEmail))
1789
1993
1790 return render(request, 'madweb/service.html', {'text': instStr})
1994 return render(request, 'madweb/service.html', {'text': instStr})
1791
1995
1792
1996
1793 def get_experiments_service(request):
1997 def get_experiments_service(request):
1794 """get_experiments_service runs the getExperimentsService.py service.
1998 """get_experiments_service runs the getExperimentsService.py service.
1795
1999
1796 Inputs:
2000 Inputs:
1797 request/url - contains arguments:
2001 request/url - contains arguments:
1798
2002
1799 code - one or more kindat values
2003 code - one or more kindat values
1800
2004
1801 startyear, startmonth, startday, starthour, startmin, startsec
2005 startyear, startmonth, startday, starthour, startmin, startsec
1802
2006
1803 endyear, endmonth, endday, endhour, endmin, endsec
2007 endyear, endmonth, endday, endhour, endmin, endsec
1804
2008
1805 local (defaults to True)
2009 local (defaults to True)
1806
2010
1807 Returns comma-delimited data, one line for each experiment, with the following fields:
2011 Returns comma-delimited data, one line for each experiment, with the following fields:
1808
2012
1809 1. experiment.id (int) Example: 10000111
2013 1. experiment.id (int) Example: 10000111
1810
2014
1811 2. experiment.url (string) Example: 'http://www.haystack.mit.edu/cgi-bin/madtoc/1997/mlh/03dec97'
2015 2. experiment.url (string) Example: 'http://www.haystack.mit.edu/cgi-bin/madtoc/1997/mlh/03dec97'
1812
2016
1813 3. experiment.name (string) Example: 'Wide Latitude Substorm Study'
2017 3. experiment.name (string) Example: 'Wide Latitude Substorm Study'
1814
2018
1815 4. experiment.siteid (int) Example: 1
2019 4. experiment.siteid (int) Example: 1
1816
2020
1817 5. experiment.sitename (string) Example: 'Millstone Hill Observatory'
2021 5. experiment.sitename (string) Example: 'Millstone Hill Observatory'
1818
2022
1819 6. experiment.instcode (int) Code of instrument. Example: 30
2023 6. experiment.instcode (int) Code of instrument. Example: 30
1820
2024
1821 7. experiment.instname (string) Instrument name. Example: 'Millstone Hill Incoherent Scatter Radar'
2025 7. experiment.instname (string) Instrument name. Example: 'Millstone Hill Incoherent Scatter Radar'
1822
2026
1823 8. experiment.start year (int) year of experiment start
2027 8. experiment.start year (int) year of experiment start
1824
2028
1825 9. experiment.start month (int) month of experiment start
2029 9. experiment.start month (int) month of experiment start
1826
2030
1827 10. experiment.start day (int) day of experiment start
2031 10. experiment.start day (int) day of experiment start
1828
2032
1829 11. experiment.start hour (int) hour of experiment start
2033 11. experiment.start hour (int) hour of experiment start
1830
2034
1831 12. experiment.start minute (int) min of experiment start
2035 12. experiment.start minute (int) min of experiment start
1832
2036
1833 13. experiment.start second (int) sec of experiment start
2037 13. experiment.start second (int) sec of experiment start
1834
2038
1835 14. experiment.end year (int) year of experiment end
2039 14. experiment.end year (int) year of experiment end
1836
2040
1837 15. experiment.end month (int) month of experiment end
2041 15. experiment.end month (int) month of experiment end
1838
2042
1839 16. experiment.end day (int) day of experiment end
2043 16. experiment.end day (int) day of experiment end
1840
2044
1841 17. experiment.end hour (int) hour of experiment end
2045 17. experiment.end hour (int) hour of experiment end
1842
2046
1843 18. experiment.end minute (int) min of experiment end
2047 18. experiment.end minute (int) min of experiment end
1844
2048
1845 19. experiment.end second (int) sec of experiment end
2049 19. experiment.end second (int) sec of experiment end
1846
2050
1847 20. experiment.isLocal (int) 1 if local, 0 if not
2051 20. experiment.isLocal (int) 1 if local, 0 if not
1848
2052
1849 21.experiment.PI (string) Experiment PI name Example: 'Phil Erickson'
2053 21.experiment.PI (string) Experiment PI name Example: 'Phil Erickson'
1850
2054
1851 22. experiment.PIEmail (string) Experiment PI email Example: 'perickson@haystack.mit.edu'
2055 22. experiment.PIEmail (string) Experiment PI email Example: 'perickson@haystack.mit.edu'
1852
2056
1853 23. utc timestamp of last update to experiment
2057 23. utc timestamp of last update to experiment
1854
2058
1855 24. security value
2059 24. security value
1856
2060
1857 """
2061 """
1858 codeList = request.GET.getlist('code')
2062 codeList = request.GET.getlist('code')
1859 codeList = [int(code) for code in codeList]
2063 codeList = [int(code) for code in codeList]
1860 startyear = int(request.GET['startyear'])
2064 startyear = int(request.GET['startyear'])
1861 startmonth = int(request.GET['startmonth'])
2065 startmonth = int(request.GET['startmonth'])
1862 startday = int(request.GET['startday'])
2066 startday = int(request.GET['startday'])
1863 starthour = int(request.GET['starthour'])
2067 starthour = int(request.GET['starthour'])
1864 startmin = int(request.GET['startmin'])
2068 startmin = int(request.GET['startmin'])
1865 startsec = int(request.GET['startsec'])
2069 startsec = int(request.GET['startsec'])
1866 endyear = int(request.GET['endyear'])
2070 endyear = int(request.GET['endyear'])
1867 endmonth = int(request.GET['endmonth'])
2071 endmonth = int(request.GET['endmonth'])
1868 endday = int(request.GET['endday'])
2072 endday = int(request.GET['endday'])
1869 endhour = int(request.GET['endhour'])
2073 endhour = int(request.GET['endhour'])
1870 endmin = int(request.GET['endmin'])
2074 endmin = int(request.GET['endmin'])
1871 endsec = int(request.GET['endsec'])
2075 endsec = int(request.GET['endsec'])
1872 try:
2076 try:
1873 local = int(request.GET['local'])
2077 local = int(request.GET['local'])
1874 except:
2078 except:
1875 local = 1
2079 local = 1
1876
2080
1877
2081
1878 # if startsec or endsec in (60, 61), handle correctly
2082 # if startsec or endsec in (60, 61), handle correctly
1879 if startsec in (60, 61):
2083 if startsec in (60, 61):
1880 tmpTime = datetime.datetime(startyear,
2084 tmpTime = datetime.datetime(startyear,
1881 startmonth,
2085 startmonth,
1882 startday,
2086 startday,
1883 starthour,
2087 starthour,
1884 startmin,
2088 startmin,
1885 59)
2089 59)
1886 tmpTime += datetime.timedelta(0, startsec - 59)
2090 tmpTime += datetime.timedelta(0, startsec - 59)
1887 startyear = tmpTime.year
2091 startyear = tmpTime.year
1888 startmonth = tmpTime.month
2092 startmonth = tmpTime.month
1889 startday = tmpTime.day
2093 startday = tmpTime.day
1890 starthour = tmpTime.hour
2094 starthour = tmpTime.hour
1891 startmin = tmpTime.minute
2095 startmin = tmpTime.minute
1892 startsec = tmpTime.second
2096 startsec = tmpTime.second
1893
2097
1894 if endsec in (60, 61):
2098 if endsec in (60, 61):
1895 tmpTime = datetime.datetime(endyear,
2099 tmpTime = datetime.datetime(endyear,
1896 endmonth,
2100 endmonth,
1897 endday,
2101 endday,
1898 endhour,
2102 endhour,
1899 endmin,
2103 endmin,
1900 59)
2104 59)
1901 tmpTime += datetime.timedelta(0, endsec - 59)
2105 tmpTime += datetime.timedelta(0, endsec - 59)
1902 endyear = tmpTime.year
2106 endyear = tmpTime.year
1903 endmonth = tmpTime.month
2107 endmonth = tmpTime.month
1904 endday = tmpTime.day
2108 endday = tmpTime.day
1905 endhour = tmpTime.hour
2109 endhour = tmpTime.hour
1906 endmin = tmpTime.minute
2110 endmin = tmpTime.minute
1907 endsec = tmpTime.second
2111 endsec = tmpTime.second
1908
2112
1909 # if codeList is empty or contains 0, change it to only contain 0
2113 # if codeList is empty or contains 0, change it to only contain 0
1910 if len(codeList) == 0 or 0 in codeList:
2114 if len(codeList) == 0 or 0 in codeList:
1911 codeList = [0]
2115 codeList = [0]
1912
2116
1913 retStr = ''
2117 retStr = ''
1914
2118
1915 # create MadrigalDB obj
2119 # create MadrigalDB obj
1916 madDBObj = madrigal.metadata.MadrigalDB()
2120 madDBObj = madrigal.metadata.MadrigalDB()
1917
2121
1918 # get the local site id
2122 # get the local site id
1919 localSiteId = madDBObj.getSiteID()
2123 localSiteId = madDBObj.getSiteID()
1920
2124
1921 # create MadrigalInstrument obj to convert kinst to instrument names
2125 # create MadrigalInstrument obj to convert kinst to instrument names
1922 madInstObj = madrigal.metadata.MadrigalInstrument(madDBObj)
2126 madInstObj = madrigal.metadata.MadrigalInstrument(madDBObj)
1923
2127
1924 # create MadrigalSite obj to convert site id to site name
2128 # create MadrigalSite obj to convert site id to site name
1925 madSiteObj = madrigal.metadata.MadrigalSite(madDBObj)
2129 madSiteObj = madrigal.metadata.MadrigalSite(madDBObj)
1926
2130
1927 madWebObj = madrigal.ui.web.MadrigalWeb(madDBObj)
2131 madWebObj = madrigal.ui.web.MadrigalWeb(madDBObj)
1928 trusted = madWebObj.isTrusted()
2132 trusted = madWebObj.isTrusted()
1929
2133
1930 # create starttime for filter, if possible
2134 # create starttime for filter, if possible
1931 if startyear != None:
2135 if startyear != None:
1932 startTimeFilter = datetime.datetime(startyear,
2136 startTimeFilter = datetime.datetime(startyear,
1933 startmonth,
2137 startmonth,
1934 startday,
2138 startday,
1935 starthour,
2139 starthour,
1936 startmin,
2140 startmin,
1937 startsec)
2141 startsec)
1938 else:
2142 else:
1939 startTimeFilter = None
2143 startTimeFilter = None
1940
2144
1941 # create endtime for filter, if possible
2145 # create endtime for filter, if possible
1942 if endyear != None:
2146 if endyear != None:
1943 endTimeFilter = datetime.datetime(endyear,
2147 endTimeFilter = datetime.datetime(endyear,
1944 endmonth,
2148 endmonth,
1945 endday,
2149 endday,
1946 endhour,
2150 endhour,
1947 endmin,
2151 endmin,
1948 endsec)
2152 endsec)
1949 else:
2153 else:
1950 endTimeFilter = None
2154 endTimeFilter = None
1951
2155
1952 # create MadrigalExperiments for local or all files
2156 # create MadrigalExperiments for local or all files
1953 if local == 1:
2157 if local == 1:
1954 madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj)
2158 madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj)
1955 else:
2159 else:
1956 # use file expTabAll.txt to get all experiments
2160 # use file expTabAll.txt to get all experiments
1957 filename = madDBObj.getMadroot()
2161 filename = madDBObj.getMadroot()
1958 if filename[-1] != '/':
2162 if filename[-1] != '/':
1959 filename += '/'
2163 filename += '/'
1960 filename += 'metadata/expTabAll.txt'
2164 filename += 'metadata/expTabAll.txt'
1961 madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj, filename)
2165 madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj, filename)
1962
2166
1963 madExpObj.sortByDateSite()
2167 madExpObj.sortByDateSite()
1964
2168
1965
2169
1966 # loop through the data
2170 # loop through the data
1967 if not startTimeFilter is None:
2171 if not startTimeFilter is None:
1968 position = madExpObj.getStartPosition(startTimeFilter)
2172 position = madExpObj.getStartPosition(startTimeFilter)
1969 else:
2173 else:
1970 position = 0
2174 position = 0
1971 while(True):
2175 while(True):
1972 thisId = madExpObj.getExpIdByPosition(position)
2176 thisId = madExpObj.getExpIdByPosition(position)
1973 # check for end
2177 # check for end
1974 if thisId == None:
2178 if thisId == None:
1975 break
2179 break
1976 thisUrl = madExpObj.getExpUrlByPosition(position)
2180 thisUrl = madExpObj.getExpUrlByPosition(position)
1977 thisName = madExpObj.getExpNameByPosition(position)
2181 thisName = madExpObj.getExpNameByPosition(position)
1978 thisSiteId = madExpObj.getExpSiteIdByPosition(position)
2182 thisSiteId = madExpObj.getExpSiteIdByPosition(position)
1979 thisSiteName = madSiteObj.getSiteName(thisSiteId)
2183 thisSiteName = madSiteObj.getSiteName(thisSiteId)
1980 thisInstCode = madExpObj.getKinstByPosition(position)
2184 thisInstCode = madExpObj.getKinstByPosition(position)
1981 thisInstName =madInstObj.getInstrumentName(thisInstCode)
2185 thisInstName =madInstObj.getInstrumentName(thisInstCode)
1982 thisStart = madExpObj.getExpStartDateTimeByPosition(position)
2186 thisStart = madExpObj.getExpStartDateTimeByPosition(position)
1983 thisEnd = madExpObj.getExpEndDateTimeByPosition(position)
2187 thisEnd = madExpObj.getExpEndDateTimeByPosition(position)
1984 thisSecurity = madExpObj.getSecurityByPosition(position)
2188 thisSecurity = madExpObj.getSecurityByPosition(position)
1985 if thisSiteId == localSiteId:
2189 if thisSiteId == localSiteId:
1986 thisLocal = 1
2190 thisLocal = 1
1987 else:
2191 else:
1988 thisLocal = 0
2192 thisLocal = 0
1989 thisPI = madExpObj.getPIByPosition(position)
2193 thisPI = madExpObj.getPIByPosition(position)
1990 if thisPI in (None, ''):
2194 if thisPI in (None, ''):
1991 thisPI = madInstObj.getContactName(thisInstCode)
2195 thisPI = madInstObj.getContactName(thisInstCode)
1992 thisPIEmail = madExpObj.getPIEmailByPosition(position)
2196 thisPIEmail = madExpObj.getPIEmailByPosition(position)
1993 if thisPIEmail in (None, ''):
2197 if thisPIEmail in (None, ''):
1994 thisPIEmail = madInstObj.getContactEmail(thisInstCode)
2198 thisPIEmail = madInstObj.getContactEmail(thisInstCode)
1995 expDir = madExpObj.getExpDirByPosition(position)
2199 expDir = madExpObj.getExpDirByPosition(position)
1996
2200
1997 position += 1
2201 position += 1
1998
2202
1999 # some experiments set the end of the day to 24:00:00 - not
2203 # some experiments set the end of the day to 24:00:00 - not
2000 # technically correct - reset to 23:59:59
2204 # technically correct - reset to 23:59:59
2001
2205
2002 if (thisStart[3] == 24 and thisStart[4] == 0 and thisStart[5] == 0):
2206 if (thisStart[3] == 24 and thisStart[4] == 0 and thisStart[5] == 0):
2003 thisStart[3] = 23
2207 thisStart[3] = 23
2004 thisStart[4] = 59
2208 thisStart[4] = 59
2005 thisStart[5] = 59
2209 thisStart[5] = 59
2006
2210
2007 if (thisEnd[3] == 24 and thisEnd[4] == 0 and thisEnd[5] == 0):
2211 if (thisEnd[3] == 24 and thisEnd[4] == 0 and thisEnd[5] == 0):
2008 thisEnd[3] = 23
2212 thisEnd[3] = 23
2009 thisEnd[4] = 59
2213 thisEnd[4] = 59
2010 thisEnd[5] = 59
2214 thisEnd[5] = 59
2011
2215
2012 # apply filters
2216 # apply filters
2013
2217
2014 # first apply instrument code filter
2218 # first apply instrument code filter
2015 if codeList[0] != 0:
2219 if codeList[0] != 0:
2016 if thisInstCode not in codeList:
2220 if thisInstCode not in codeList:
2017 continue
2221 continue
2018
2222
2019 # apply starttime and endtime filters
2223 # apply starttime and endtime filters
2020 thisStartTime = datetime.datetime(thisStart[0],
2224 thisStartTime = datetime.datetime(thisStart[0],
2021 thisStart[1],
2225 thisStart[1],
2022 thisStart[2],
2226 thisStart[2],
2023 thisStart[3],
2227 thisStart[3],
2024 thisStart[4],
2228 thisStart[4],
2025 thisStart[5])
2229 thisStart[5])
2026
2230
2027 thisEndTime = datetime.datetime(thisEnd[0],
2231 thisEndTime = datetime.datetime(thisEnd[0],
2028 thisEnd[1],
2232 thisEnd[1],
2029 thisEnd[2],
2233 thisEnd[2],
2030 thisEnd[3],
2234 thisEnd[3],
2031 thisEnd[4],
2235 thisEnd[4],
2032 thisEnd[5])
2236 thisEnd[5])
2033
2237
2034 if startTimeFilter != None:
2238 if startTimeFilter != None:
2035 if thisEndTime < startTimeFilter:
2239 if thisEndTime < startTimeFilter:
2036 continue
2240 continue
2037
2241
2038 if endTimeFilter != None:
2242 if endTimeFilter != None:
2039 if thisStartTime > endTimeFilter:
2243 if thisStartTime > endTimeFilter:
2040 continue
2244 continue
2041
2245
2042 # apply local filer
2246 # apply local filer
2043 if local == 1 and thisLocal == 0:
2247 if local == 1 and thisLocal == 0:
2044 continue
2248 continue
2045
2249
2046 # apply security filter
2250 # apply security filter
2047 if trusted == 0 and thisSecurity not in (0,2):
2251 if trusted == 0 and thisSecurity not in (0,2):
2048 continue
2252 continue
2049
2253
2050 # create exp timestamp
2254 # create exp timestamp
2051 if local == 1:
2255 if local == 1:
2052 thisUTTimestamp = int(os.stat(expDir).st_mtime + time.timezone)
2256 thisUTTimestamp = int(os.stat(expDir).st_mtime + time.timezone)
2053 else:
2257 else:
2054 thisUTTimestamp = 0
2258 thisUTTimestamp = 0
2055
2259
2056 # add this experiment
2260 # add this experiment
2057 retStr += '%i,%s,%s,%i,%s,%i,%s,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%s,%s,%i,%i\n' % \
2261 retStr += '%i,%s,%s,%i,%s,%i,%s,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%s,%s,%i,%i\n' % \
2058 (thisId,
2262 (thisId,
2059 thisUrl,
2263 thisUrl,
2060 thisName,
2264 thisName,
2061 thisSiteId,
2265 thisSiteId,
2062 thisSiteName,
2266 thisSiteName,
2063 thisInstCode,
2267 thisInstCode,
2064 thisInstName,
2268 thisInstName,
2065 thisStart[0],
2269 thisStart[0],
2066 thisStart[1],
2270 thisStart[1],
2067 thisStart[2],
2271 thisStart[2],
2068 thisStart[3],
2272 thisStart[3],
2069 thisStart[4],
2273 thisStart[4],
2070 thisStart[5],
2274 thisStart[5],
2071 thisEnd[0],
2275 thisEnd[0],
2072 thisEnd[1],
2276 thisEnd[1],
2073 thisEnd[2],
2277 thisEnd[2],
2074 thisEnd[3],
2278 thisEnd[3],
2075 thisEnd[4],
2279 thisEnd[4],
2076 thisEnd[5],
2280 thisEnd[5],
2077 thisLocal,
2281 thisLocal,
2078 str(thisPI),
2282 str(thisPI),
2079 str(thisPIEmail),
2283 str(thisPIEmail),
2080 thisUTTimestamp,
2284 thisUTTimestamp,
2081 thisSecurity)
2285 thisSecurity)
2082
2286
2083 return render(request, 'madweb/service.html', {'text': retStr})
2287 return render(request, 'madweb/service.html', {'text': retStr})
2084
2288
2085
2289
2086 def get_experiment_files_service(request):
2290 def get_experiment_files_service(request):
2087 """get_experiment_files_service runs the getExperimentFilesService.py service.
2291 """get_experiment_files_service runs the getExperimentFilesService.py service.
2088
2292
2089 Inputs:
2293 Inputs:
2090 request/url - contains arguments:
2294 request/url - contains arguments:
2091
2295
2092 id - local experiment id
2296 id - local experiment id
2093
2297
2094 Returns comma-delimited data, one line for each experiment file, with the following fields:
2298 Returns comma-delimited data, one line for each experiment file, with the following fields:
2095
2299
2096 1. file.name (string) Example '/opt/mdarigal/blah/mlh980120g.001'
2300 1. file.name (string) Example '/opt/mdarigal/blah/mlh980120g.001'
2097
2301
2098 2. file.kindat (int) Kindat code. Example: 3001
2302 2. file.kindat (int) Kindat code. Example: 3001
2099
2303
2100 3. file.kindat desc (string) Kindat description: Example 'Basic Derived Parameters'
2304 3. file.kindat desc (string) Kindat description: Example 'Basic Derived Parameters'
2101
2305
2102 4. file.category (int) (1=default, 2=variant, 3=history, 4=real-time)
2306 4. file.category (int) (1=default, 2=variant, 3=history, 4=real-time)
2103
2307
2104 5. file.status (string)('preliminary', 'final', or any other description)
2308 5. file.status (string)('preliminary', 'final', or any other description)
2105
2309
2106 6. file.permission (int) 0 for public, 1 for private. For now will not return private files.
2310 6. file.permission (int) 0 for public, 1 for private. For now will not return private files.
2107
2311
2108 7. file DOI (string) - citable url to file
2312 7. file DOI (string) - citable url to file
2109
2313
2110 Returns empty string if experiment id not found. Skips files that are not Hdf5
2314 Returns empty string if experiment id not found. Skips files that are not Hdf5
2111 """
2315 """
2112 id = int(request.GET['id'])
2316 id = int(request.GET['id'])
2113
2317
2114 # create MadrigalDB obj
2318 # create MadrigalDB obj
2115 madDBObj = madrigal.metadata.MadrigalDB()
2319 madDBObj = madrigal.metadata.MadrigalDB()
2116
2320
2117 # create MadrigalExperiments object to get full file name
2321 # create MadrigalExperiments object to get full file name
2118 madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj)
2322 madExpObj = madrigal.metadata.MadrigalExperiment(madDBObj)
2119
2323
2120 # create Madrigal Kindat to get Kindat descriptions
2324 # create Madrigal Kindat to get Kindat descriptions
2121 madKindatObj = madrigal.metadata.MadrigalKindat(madDBObj)
2325 madKindatObj = madrigal.metadata.MadrigalKindat(madDBObj)
2122
2326
2123 madWebObj = madrigal.ui.web.MadrigalWeb(madDBObj)
2327 madWebObj = madrigal.ui.web.MadrigalWeb(madDBObj)
2124 trusted = madWebObj.isTrusted()
2328 trusted = madWebObj.isTrusted()
2125
2329
2126
2330
2127 retStr = ''
2331 retStr = ''
2128 thisUrl = madExpObj.getExpUrlByExpId(id)
2332 thisUrl = madExpObj.getExpUrlByExpId(id)
2129 if thisUrl is None:
2333 if thisUrl is None:
2130 raise IOError('No such id: %i' % (id))
2334 raise IOError('No such id: %i' % (id))
2131 expPath = madExpObj.getExpDirByExpId(id)
2335 expPath = madExpObj.getExpDirByExpId(id)
2132 kinst = madExpObj.getKinstByExpId(id)
2336 kinst = madExpObj.getKinstByExpId(id)
2133 if os.access(os.path.join(expPath, 'fileTab.txt'), os.R_OK):
2337 if os.access(os.path.join(expPath, 'fileTab.txt'), os.R_OK):
2134 madFileObj = madrigal.metadata.MadrigalMetaFile(madDBObj, os.path.join(expPath, 'fileTab.txt'))
2338 madFileObj = madrigal.metadata.MadrigalMetaFile(madDBObj, os.path.join(expPath, 'fileTab.txt'))
2135 for i in range(madFileObj.getFileCount()):
2339 for i in range(madFileObj.getFileCount()):
2136 basename = madFileObj.getFilenameByPosition(i)
2340 basename = madFileObj.getFilenameByPosition(i)
2137 name = os.path.join(expPath, basename)
2341 name = os.path.join(expPath, basename)
2138 base_filename, file_extension = os.path.splitext(name)
2342 base_filename, file_extension = os.path.splitext(name)
2139 if file_extension not in ('.hdf5', '.hdf', '.h5'):
2343 if file_extension not in ('.hdf5', '.hdf', '.h5'):
2140 continue
2344 continue
2141 kindat = madFileObj.getKindatByPosition(i)
2345 kindat = madFileObj.getKindatByPosition(i)
2142 kindatdesc = madKindatObj.getKindatDescription(kindat, kinst)
2346 kindatdesc = madKindatObj.getKindatDescription(kindat, kinst)
2143 category = madFileObj.getCategoryByPosition(i)
2347 category = madFileObj.getCategoryByPosition(i)
2144 status = madFileObj.getStatusByPosition(i)
2348 status = madFileObj.getStatusByPosition(i)
2145 permission = madFileObj.getAccessByPosition(i)
2349 permission = madFileObj.getAccessByPosition(i)
2146 doi = madFileObj.getFileDOIUrlByPosition(i)
2350 doi = madFileObj.getFileDOIUrlByPosition(i)
2147
2351
2148 # skip private files if not trusted
2352 # skip private files if not trusted
2149 if trusted == 0 and int(permission) != 0:
2353 if trusted == 0 and int(permission) != 0:
2150 continue
2354 continue
2151
2355
2152 retStr += '%s,%i,%s,%i,%s,%i,%s\n' % \
2356 retStr += '%s,%i,%s,%i,%s,%i,%s\n' % \
2153 (name,
2357 (name,
2154 kindat,
2358 kindat,
2155 kindatdesc,
2359 kindatdesc,
2156 category,
2360 category,
2157 status,
2361 status,
2158 permission,
2362 permission,
2159 doi)
2363 doi)
2160
2364
2161
2365
2162
2366
2163 return render(request, 'madweb/service.html', {'text': django.utils.safestring.mark_safe(retStr)})
2367 return render(request, 'madweb/service.html', {'text': django.utils.safestring.mark_safe(retStr)})
2164
2368
2165
2369
2166 def get_parameters_service(request):
2370 def get_parameters_service(request):
2167 """get_parameters_service runs the getParametersService.py service.
2371 """get_parameters_service runs the getParametersService.py service.
2168
2372
2169 Inputs:
2373 Inputs:
2170 request/url - contains arguments:
2374 request/url - contains arguments:
2171
2375
2172 filename=<full path to data file>
2376 filename=<full path to data file>
2173
2377
2174 Returns backslash-delimited data, one for each parameter either measured or derivable, with the following fields:
2378 Returns backslash-delimited data, one for each parameter either measured or derivable, with the following fields:
2175
2379
2176 1. parameter.mnemonic (string) Example 'dti'
2380 1. parameter.mnemonic (string) Example 'dti'
2177
2381
2178 2. parameter.description (string) Example:
2382 2. parameter.description (string) Example:
2179 "F10.7 Multiday average observed (Ott)"
2383 "F10.7 Multiday average observed (Ott)"
2180
2384
2181 3. parameter.isError (int) 1 if error parameter, 0 if not
2385 3. parameter.isError (int) 1 if error parameter, 0 if not
2182
2386
2183 4. parameter.units (string) Example "W/m2/Hz"
2387 4. parameter.units (string) Example "W/m2/Hz"
2184
2388
2185 5. parameter.isMeasured (int) 1 if measured, 0 if derivable
2389 5. parameter.isMeasured (int) 1 if measured, 0 if derivable
2186
2390
2187 6. parameter.category (string) Example: "Time Related Parameter"
2391 6. parameter.category (string) Example: "Time Related Parameter"
2188
2392
2189 7. parameter.isSure (int) - 1 if parameter can be found for every record, 0 if can only be found for some.
2393 7. parameter.isSure (int) - 1 if parameter can be found for every record, 0 if can only be found for some.
2190 Not relevant to Madrigal 3, where always 1
2394 Not relevant to Madrigal 3, where always 1
2191
2395
2192 8. parameter.isAddIncrement - 1 if additional increment, 0 if normal (Added in Madrigal 2.5)
2396 8. parameter.isAddIncrement - 1 if additional increment, 0 if normal (Added in Madrigal 2.5)
2193 Not relevant to Madrigal 3, where always -1
2397 Not relevant to Madrigal 3, where always -1
2194 """
2398 """
2195 filename = request.GET['filename']
2399 filename = request.GET['filename']
2196
2400
2197 # create MadrigalDB obj
2401 # create MadrigalDB obj
2198 madDBObj = madrigal.metadata.MadrigalDB()
2402 madDBObj = madrigal.metadata.MadrigalDB()
2199
2403
2200 # create Madrigal File object
2404 # create Madrigal File object
2201 madFileObj = madrigal.data.MadrigalFile(filename, madDBObj)
2405 madFileObj = madrigal.data.MadrigalFile(filename, madDBObj)
2202
2406
2203 # create Madrigal Parameter object
2407 # create Madrigal Parameter object
2204 madParmObj = madrigal.data.MadrigalParameters(madDBObj)
2408 madParmObj = madrigal.data.MadrigalParameters(madDBObj)
2205
2409
2206 # create Madrigal web object
2410 # create Madrigal web object
2207 madWebObj = madrigal.ui.web.MadrigalWebFormat()
2411 madWebObj = madrigal.ui.web.MadrigalWebFormat()
2208
2412
2209
2413
2210 # create lists of parameters
2414 # create lists of parameters
2211 measParmList = []
2415 measParmList = []
2212 derivedParmList = []
2416 derivedParmList = []
2213 allParmList = []
2417 allParmList = []
2214 sureParmList = []
2418 sureParmList = []
2215
2419
2216 # use the comprehensive list of parameters to check if derivable
2420 # use the comprehensive list of parameters to check if derivable
2217 parmList = madWebObj.getFormat('Comprehensive')
2421 parmList = madWebObj.getFormat('Comprehensive')
2218
2422
2219 # populate lists
2423 # populate lists
2220 madFileObj.getMeasDervBothParmLists(parmList,
2424 madFileObj.getMeasDervBothParmLists(parmList,
2221 measParmList,
2425 measParmList,
2222 derivedParmList,
2426 derivedParmList,
2223 allParmList,
2427 allParmList,
2224 sureParmList)
2428 sureParmList)
2225
2429
2226 retStr = ''
2430 retStr = ''
2227
2431
2228 # loop through allParmList and output results
2432 # loop through allParmList and output results
2229 for parm in allParmList:
2433 for parm in allParmList:
2230 description = madParmObj.getSimpleParmDescription(parm)
2434 description = madParmObj.getSimpleParmDescription(parm)
2231 isNorm = madParmObj.getParmType(parm)
2435 isNorm = madParmObj.getParmType(parm)
2232 if isNorm == 1:
2436 if isNorm == 1:
2233 isError = 0
2437 isError = 0
2234 else:
2438 else:
2235 isError = 1
2439 isError = 1
2236 units = madParmObj.getParmUnits(parm)
2440 units = madParmObj.getParmUnits(parm)
2237 if parm in measParmList:
2441 if parm in measParmList:
2238 isMeasured = 1
2442 isMeasured = 1
2239 else:
2443 else:
2240 isMeasured = 0
2444 isMeasured = 0
2241 if parm in sureParmList:
2445 if parm in sureParmList:
2242 isSure = 1
2446 isSure = 1
2243 else:
2447 else:
2244 isSure = 0
2448 isSure = 0
2245 category = madParmObj.getParmCategory(parm)
2449 category = madParmObj.getParmCategory(parm)
2246 try:
2450 try:
2247 if madParmObj.isAddIncrement(parm):
2451 if madParmObj.isAddIncrement(parm):
2248 isAddIncrement = 1
2452 isAddIncrement = 1
2249 else:
2453 else:
2250 isAddIncrement = 0
2454 isAddIncrement = 0
2251 except:
2455 except:
2252 isAddIncrement = -1
2456 isAddIncrement = -1
2253 # print out this parm
2457 # print out this parm
2254 retStr += '%s\\%s\\%i\\%s\\%i\\%s\\%i\\%i\n' % (parm,
2458 retStr += '%s\\%s\\%i\\%s\\%i\\%s\\%i\\%i\n' % (parm,
2255 description,
2459 description,
2256 isError,
2460 isError,
2257 units,
2461 units,
2258 isMeasured,
2462 isMeasured,
2259 category,
2463 category,
2260 isSure,
2464 isSure,
2261 isAddIncrement)
2465 isAddIncrement)
2262
2466
2263 return render(request, 'madweb/service.html', {'text': retStr})
2467 return render(request, 'madweb/service.html', {'text': retStr})
2264
2468
2265
2469
2266
2470
2267 def isprint_service(request):
2471 def isprint_service(request):
2268 """isprint_service runs the isprintService.py service.
2472 """isprint_service runs the isprintService.py service.
2269
2473
2270 Inputs:
2474 Inputs:
2271 request/url - contains arguments:
2475 request/url - contains arguments:
2272
2476
2273 'file': The full path to the file to be analyzed by isprint. If over 50 MB, returns error message.
2477 'file': The full path to the file to be analyzed by isprint. If over 50 MB, returns error message.
2274
2478
2275 'parms': Multiple requested parameters, space (+) separated.
2479 'parms': Multiple requested parameters, space (+) separated.
2276
2480
2277 'filters': Multiple of filters desired, as in isprint command
2481 'filters': Multiple of filters desired, as in isprint command
2278
2482
2279 'user_fullname' user name
2483 'user_fullname' user name
2280
2484
2281 'user_email' user email
2485 'user_email' user email
2282
2486
2283 'user_affiliation' user affiliation
2487 'user_affiliation' user affiliation
2284
2488
2285 'output' - option argument specifying output file basename. Will be Hdf5 format if extension in
2489 'output' - option argument specifying output file basename. Will be Hdf5 format if extension in
2286 ('hdf5', 'h5', 'hdf'). Will be netCDF4 is extension is '.nc'. Otherwise ascii. If not
2490 ('hdf5', 'h5', 'hdf'). Will be netCDF4 is extension is '.nc'. Otherwise ascii. If not
2287 given, output is ascii.
2491 given, output is ascii.
2288
2492
2289 'header': t for headers, f for no header. Defaults to no header. Ignored if not ascii output
2493 'header': t for headers, f for no header. Defaults to no header. Ignored if not ascii output
2290
2494
2291 Returns data as either column delimited ascii, Hdf5, or netCDF4.
2495 Returns data as either column delimited ascii, Hdf5, or netCDF4.
2292 """
2496 """
2293 madDB = madrigal.metadata.MadrigalDB()
2497 madDB = madrigal.metadata.MadrigalDB()
2294 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
2498 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
2295
2499
2296 # get required arguments
2500 # get required arguments
2297 thisFile = request.GET['file']
2501 thisFile = request.GET['file']
2298 parms = request.GET.getlist('parms')
2502 parms = request.GET.getlist('parms')
2299 filters = request.GET.getlist('filters')
2503 filters = request.GET.getlist('filters')
2300 user_fullname = request.GET['user_fullname']
2504 user_fullname = request.GET['user_fullname']
2301 user_email = request.GET['user_email']
2505 user_email = request.GET['user_email']
2302 user_affiliation = request.GET['user_affiliation']
2506 user_affiliation = request.GET['user_affiliation']
2303
2507
2304 # get optional arguments
2508 # get optional arguments
2305 try:
2509 try:
2306 output = os.path.basename(request.GET['output'])
2510 output = os.path.basename(request.GET['output'])
2307 filename, file_extension = os.path.splitext(output)
2511 filename, file_extension = os.path.splitext(output)
2308 if file_extension in ('.hdf5', '.h5', '.hdf'):
2512 if file_extension in ('.hdf5', '.h5', '.hdf'):
2309 format = 'Hdf5'
2513 format = 'Hdf5'
2310 elif file_extension in ('.nc',):
2514 elif file_extension in ('.nc',):
2311 format = 'netCDF4'
2515 format = 'netCDF4'
2312 else:
2516 else:
2313 format = 'ascii'
2517 format = 'ascii'
2314 except:
2518 except:
2315 format = 'ascii'
2519 format = 'ascii'
2316 output = None
2520 output = None
2317
2521
2318 # verify thisFile exists, not too big
2522 # verify thisFile exists, not too big
2319 errorMessage = None
2523 errorMessage = None
2320 if not os.access(thisFile, os.R_OK):
2524 if not os.access(thisFile, os.R_OK):
2321 errorMessage = 'File %s not found' % (thisFile)
2525 errorMessage = 'File %s not found' % (thisFile)
2322 elif os.path.getsize(thisFile) > 200.0E6:
2526 elif os.path.getsize(thisFile) > 200.0E6:
2323 errorMessage = 'File %s greater than 200 MB in size - running dynamic file creation not possible. Please use -- download as is -- instead.' % (thisFile)
2527 errorMessage = 'File %s greater than 200 MB in size - running dynamic file creation not possible. Please use -- download as is -- instead.' % (thisFile)
2324 if not errorMessage is None:
2528 if not errorMessage is None:
2325 return render(request, 'madweb/service.html', {'text': errorMessage})
2529 return render(request, 'madweb/service.html', {'text': errorMessage})
2326
2530
2327 if not output is None:
2531 if not output is None:
2328 # we need to write to a download file
2532 # we need to write to a download file
2329 downloadFile = os.path.join(tempfile.gettempdir(), output)
2533 downloadFile = os.path.join(tempfile.gettempdir(), output)
2330 if os.access(downloadFile, os.R_OK):
2534 if os.access(downloadFile, os.R_OK):
2331 try:
2535 try:
2332 os.remove(downloadFile)
2536 os.remove(downloadFile)
2333 except:
2537 except:
2334 pass
2538 pass
2335 try:
2539 try:
2336 header = request.GET['header']
2540 header = request.GET['header']
2337 if header not in ('t', 'f'):
2541 if header not in ('t', 'f'):
2338 raise ValueError('Unknown header value <%s>' % (header))
2542 raise ValueError('Unknown header value <%s>' % (header))
2339 except:
2543 except:
2340 header = 'f'
2544 header = 'f'
2341
2545
2342 # log data access
2546 # log data access
2343 madWebObj.logDataAccess(thisFile, user_fullname, user_email, user_affiliation)
2547 madWebObj.logDataAccess(thisFile, user_fullname, user_email, user_affiliation)
2344
2548
2345 # run isprint command
2549 # run isprint command
2346 cmd = '%s/bin/isprint file=%s ' % (madDB.getMadroot(), thisFile)
2550 cmd = '%s/bin/isprint file=%s ' % (madDB.getMadroot(), thisFile)
2347 if not output is None:
2551 if not output is None:
2348 cmd += 'output=%s ' % (downloadFile)
2552 cmd += 'output=%s ' % (downloadFile)
2349 delimiter = ' '
2553 delimiter = ' '
2350 cmd += delimiter.join(parms) + ' '
2554 cmd += delimiter.join(parms) + ' '
2351 filterStr = delimiter.join(filters)
2555 filterStr = delimiter.join(filters)
2352 cmd += filterStr + ' '
2556 cmd += filterStr + ' '
2353 if format == 'ascii':
2557 if format == 'ascii':
2354 cmd += 'summary=f '
2558 cmd += 'summary=f '
2355 cmd += 'header=%s ' % (header)
2559 cmd += 'header=%s ' % (header)
2356
2560
2357 if output is None:
2561 if output is None:
2358 # text response
2562 # text response
2359 #result = subprocess.check_output(cmd.split())
2563 #result = subprocess.check_output(cmd.split())
2360 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
2564 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
2361 result,errtext = p.communicate()
2565 result,errtext = p.communicate()
2362 if p.returncode != 0:
2566 if p.returncode != 0:
2363 result = errtext
2567 result = errtext
2364 if type(result) in (bytes, numpy.bytes_):
2568 if type(result) in (bytes, numpy.bytes_):
2365 result = result.decode('utf-8')
2569 result = result.decode('utf-8')
2366 if header == 'f':
2570 if header == 'f':
2367 index = result.find('\n')
2571 index = result.find('\n')
2368 result = result[index+1:]
2572 result = result[index+1:]
2369 return render(request, 'madweb/service.html', {'text': result})
2573 return render(request, 'madweb/service.html', {'text': result})
2370 else:
2574 else:
2371 # file download response
2575 # file download response
2372 #subprocess.check_call(cmd.split())
2576 #subprocess.check_call(cmd.split())
2373 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
2577 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
2374 result,errtext = p.communicate()
2578 result,errtext = p.communicate()
2375 if p.returncode != 0:
2579 if p.returncode != 0:
2376 # write the error to result file
2580 # write the error to result file
2377 f = open(downloadFile, 'w')
2581 f = open(downloadFile, 'w')
2378 if type(errtext) in (bytes, numpy.bytes_):
2582 if type(errtext) in (bytes, numpy.bytes_):
2379 errtext = errtext.decode('utf-8')
2583 errtext = errtext.decode('utf-8')
2380 f.write(errtext)
2584 f.write(errtext)
2381 f.close()
2585 f.close()
2382
2586
2383 f = open(downloadFile, 'rb')
2587 f = open(downloadFile, 'rb')
2384 filename = os.path.basename(downloadFile)
2588 filename = os.path.basename(downloadFile)
2385 chunk_size = 8192
2589 chunk_size = 8192
2386 file_type = mimetypes.guess_type(downloadFile)[0]
2590 file_type = mimetypes.guess_type(downloadFile)[0]
2387 if file_type is None:
2591 if file_type is None:
2388 file_type = 'application/octet-stream'
2592 file_type = 'application/octet-stream'
2389 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
2593 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
2390 content_type=file_type)
2594 content_type=file_type)
2391 response['Content-Length'] = os.path.getsize(downloadFile)
2595 response['Content-Length'] = os.path.getsize(downloadFile)
2392 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
2596 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
2393 os.remove(downloadFile)
2597 os.remove(downloadFile)
2394 return(response)
2598 return(response)
2395
2599
2396
2600
2397 def get_madfile_service(request):
2601 def get_madfile_service(request):
2398 """get_madfile_service runs the getMadfile.cgi service.
2602 """get_madfile_service runs the getMadfile.cgi service.
2399
2603
2400 Inputs:
2604 Inputs:
2401 request/url - contains arguments:
2605 request/url - contains arguments:
2402
2606
2403 'fileName': The full path to the file to be downloaded as.
2607 'fileName': The full path to the file to be downloaded as.
2404
2608
2405 'fileType': -1 for ascii, -2 for Hdf5, -3 for netCDF4. No other values supported
2609 'fileType': -1 for ascii, -2 for Hdf5, -3 for netCDF4. No other values supported
2406
2610
2407 'user_fullname' user name
2611 'user_fullname' user name
2408
2612
2409 'user_email' user email
2613 'user_email' user email
2410
2614
2411 'user_affiliation' user affiliation
2615 'user_affiliation' user affiliation
2412
2616
2413 Returns file as either column delimited ascii, Hdf5, or netCDF4.
2617 Returns file as either column delimited ascii, Hdf5, or netCDF4.
2414 """
2618 """
2415 madDB = madrigal.metadata.MadrigalDB()
2619 madDB = madrigal.metadata.MadrigalDB()
2416 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
2620 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
2417
2621
2418 # get required arguments
2622 # get required arguments
2419 fileName = request.GET['fileName']
2623 fileName = request.GET['fileName']
2420 fileType = int(request.GET['fileType'])
2624 fileType = int(request.GET['fileType'])
2421 user_fullname = request.GET['user_fullname']
2625 user_fullname = request.GET['user_fullname']
2422 user_email = request.GET['user_email']
2626 user_email = request.GET['user_email']
2423 user_affiliation = request.GET['user_affiliation']
2627 user_affiliation = request.GET['user_affiliation']
2424
2628
2425 if fileType not in (-1, -2, -3):
2629 if fileType not in (-1, -2, -3):
2426 return(HttpResponse('<p>fileType %i not allowed: -1 for ascii, -2 for Hdf5, -3 for netCDF4</p>' % (fileType)))
2630 return(HttpResponse('<p>fileType %i not allowed: -1 for ascii, -2 for Hdf5, -3 for netCDF4</p>' % (fileType)))
2427
2631
2428 # log data access
2632 # log data access
2429 madWebObj.logDataAccess(fileName, user_fullname, user_email, user_affiliation)
2633 madWebObj.logDataAccess(fileName, user_fullname, user_email, user_affiliation)
2430
2634
2431 if fileType in (-1, -3):
2635 if fileType in (-1, -3):
2432 # may need to create temp file
2636 # may need to create temp file
2433 filepath, file_extension = os.path.splitext(fileName)
2637 filepath, file_extension = os.path.splitext(fileName)
2434 basename = os.path.basename(filepath)
2638 basename = os.path.basename(filepath)
2435 dirname = os.path.dirname(fileName)
2639 dirname = os.path.dirname(fileName)
2436 if fileType == -1:
2640 if fileType == -1:
2437 cachedTxtFile = os.path.join(dirname, 'overview', os.path.basename(fileName) + '.txt.gz')
2641 cachedTxtFile = os.path.join(dirname, 'overview', os.path.basename(fileName) + '.txt.gz')
2438 tmpFile = os.path.join(tempfile.gettempdir(), basename + '.txt.gz')
2642 tmpFile = os.path.join(tempfile.gettempdir(), basename + '.txt.gz')
2439 if os.access(cachedTxtFile, os.R_OK):
2643 if os.access(cachedTxtFile, os.R_OK):
2440 shutil.copy(cachedTxtFile, tmpFile)
2644 shutil.copy(cachedTxtFile, tmpFile)
2441 else:
2645 else:
2442 tmpFile = os.path.join(tempfile.gettempdir(), basename + '.txt')
2646 tmpFile = os.path.join(tempfile.gettempdir(), basename + '.txt')
2443 madrigal.cedar.convertToText(fileName, tmpFile)
2647 madrigal.cedar.convertToText(fileName, tmpFile)
2444 else:
2648 else:
2445 cachedNCFile = os.path.join(dirname, 'overview', os.path.basename(fileName) + '.nc')
2649 cachedNCFile = os.path.join(dirname, 'overview', os.path.basename(fileName) + '.nc')
2446 tmpFile = os.path.join(tempfile.gettempdir(), basename + '.nc')
2650 tmpFile = os.path.join(tempfile.gettempdir(), basename + '.nc')
2447 if os.access(cachedNCFile, os.R_OK):
2651 if os.access(cachedNCFile, os.R_OK):
2448 shutil.copy(cachedNCFile, tmpFile)
2652 shutil.copy(cachedNCFile, tmpFile)
2449 else:
2653 else:
2450 try:
2654 try:
2451 madrigal.cedar.convertToNetCDF4(fileName, tmpFile)
2655 madrigal.cedar.convertToNetCDF4(fileName, tmpFile)
2452 except IOError:
2656 except IOError:
2453 cedarObj = madrigal.cedar.MadrigalCedarFile(fileName)
2657 cedarObj = madrigal.cedar.MadrigalCedarFile(fileName)
2454 cedarObj.write('netCDF4', tmpFile)
2658 cedarObj.write('netCDF4', tmpFile)
2455
2659
2456 else:
2660 else:
2457 tmpFile = fileName
2661 tmpFile = fileName
2458
2662
2459 f = open(tmpFile, 'rb')
2663 f = open(tmpFile, 'rb')
2460 filename = os.path.basename(tmpFile)
2664 filename = os.path.basename(tmpFile)
2461 chunk_size = 8192
2665 chunk_size = 8192
2462 file_type = mimetypes.guess_type(tmpFile)[0]
2666 file_type = mimetypes.guess_type(tmpFile)[0]
2463 if file_type is None:
2667 if file_type is None:
2464 file_type = 'application/octet-stream'
2668 file_type = 'application/octet-stream'
2465 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
2669 response = StreamingHttpResponse(FileWrapper(f, chunk_size),
2466 content_type=file_type)
2670 content_type=file_type)
2467 response['Content-Length'] = os.path.getsize(tmpFile)
2671 response['Content-Length'] = os.path.getsize(tmpFile)
2468 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
2672 response['Content-Disposition'] = "attachment; filename=%s" % (filename)
2469 if fileType in (-1, -3):
2673 if fileType in (-1, -3):
2470 os.remove(tmpFile)
2674 os.remove(tmpFile)
2471 return(response)
2675 return(response)
2472
2676
2473
2677
2474 def mad_calculator_service(request):
2678 def mad_calculator_service(request):
2475 """mad_calculator_service runs the madCalculator service.
2679 """mad_calculator_service runs the madCalculator service.
2476
2680
2477 Inputs:
2681 Inputs:
2478 request/url - contains arguments:
2682 request/url - contains arguments:
2479
2683
2480 year, month, day, hour, min, sec
2684 year, month, day, hour, min, sec
2481
2685
2482 startLat - Starting geodetic latitude, -90 to 90 (float)
2686 startLat - Starting geodetic latitude, -90 to 90 (float)
2483
2687
2484 endLat - Ending geodetic latitude, -90 to 90 (float)
2688 endLat - Ending geodetic latitude, -90 to 90 (float)
2485
2689
2486 stepLat - Latitude step (0.1 to 90) (float)
2690 stepLat - Latitude step (0.1 to 90) (float)
2487
2691
2488 startLong - Starting geodetic longitude, -180 to 180 (float)
2692 startLong - Starting geodetic longitude, -180 to 180 (float)
2489
2693
2490 endLong - Ending geodetic longitude, -180 to 180 (float)
2694 endLong - Ending geodetic longitude, -180 to 180 (float)
2491
2695
2492 stepLong - Longitude step (0.1 to 180) (float)
2696 stepLong - Longitude step (0.1 to 180) (float)
2493
2697
2494 startAlt - Starting geodetic altitude, >= 0 (float)
2698 startAlt - Starting geodetic altitude, >= 0 (float)
2495
2699
2496 endAlt - Ending geodetic altitude, > 0 (float)
2700 endAlt - Ending geodetic altitude, > 0 (float)
2497
2701
2498 stepAlt - Altitude step (>= 0.1) (float)
2702 stepAlt - Altitude step (>= 0.1) (float)
2499
2703
2500 parms - comma delimited string of Madrigal parameters desired
2704 parms - comma delimited string of Madrigal parameters desired
2501
2705
2502 oneD - zero or more mnemonics,float values to set input 1D values
2706 oneD - zero or more mnemonics,float values to set input 1D values
2503
2707
2504 Returns comma-delimited data, one line for each combination of lat, long, and alt,
2708 Returns comma-delimited data, one line for each combination of lat, long, and alt,
2505 with the following fields:
2709 with the following fields:
2506
2710
2507 1. latitude
2711 1. latitude
2508
2712
2509 2. longitude
2713 2. longitude
2510
2714
2511 3. altitude
2715 3. altitude
2512
2716
2513 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace
2717 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace
2514 """
2718 """
2515 year = int(request.GET['year'])
2719 year = int(request.GET['year'])
2516 month = int(request.GET['month'])
2720 month = int(request.GET['month'])
2517 day = int(request.GET['day'])
2721 day = int(request.GET['day'])
2518 hour = int(request.GET['hour'])
2722 hour = int(request.GET['hour'])
2519 minute = int(request.GET['min'])
2723 minute = int(request.GET['min'])
2520 second = int(request.GET['sec'])
2724 second = int(request.GET['sec'])
2521 try:
2725 try:
2522 dt = datetime.datetime(year, month, day, hour, minute, second)
2726 dt = datetime.datetime(year, month, day, hour, minute, second)
2523 except:
2727 except:
2524 return(HttpResponse('Illegal time: year %i, month %i, day %i, hour %i, minute %i, second %i' % (year, month, day, hour, minute, second)))
2728 return(HttpResponse('Illegal time: year %i, month %i, day %i, hour %i, minute %i, second %i' % (year, month, day, hour, minute, second)))
2525
2729
2526 startLat = float(request.GET['startLat'])
2730 startLat = float(request.GET['startLat'])
2527 endLat = float(request.GET['endLat'])
2731 endLat = float(request.GET['endLat'])
2528 if startLat == endLat:
2732 if startLat == endLat:
2529 endLat += 0.001
2733 endLat += 0.001
2530 elif startLat > endLat:
2734 elif startLat > endLat:
2531 return(HttpResponse('startLat %s cannot be greater than endLat %s' % (str(startLat), str(endLat))))
2735 return(HttpResponse('startLat %s cannot be greater than endLat %s' % (str(startLat), str(endLat))))
2532 stepLat = float(request.GET['stepLat'])
2736 stepLat = float(request.GET['stepLat'])
2533 if stepLat < 0.0:
2737 if stepLat < 0.0:
2534 return(HttpResponse('stepLat %s cannot be less than zero' % (str(stepLat))))
2738 return(HttpResponse('stepLat %s cannot be less than zero' % (str(stepLat))))
2535 elif stepLat == 0.0:
2739 elif stepLat == 0.0:
2536 stepLat = 0.001
2740 stepLat = 0.001
2537 latList = list(numpy.arange(startLat, endLat, stepLat))
2741 latList = list(numpy.arange(startLat, endLat, stepLat))
2538
2742
2539 startLong = float(request.GET['startLong'])
2743 startLong = float(request.GET['startLong'])
2540 endLong = float(request.GET['endLong'])
2744 endLong = float(request.GET['endLong'])
2541 if startLong == endLong:
2745 if startLong == endLong:
2542 endLong += 0.001
2746 endLong += 0.001
2543 elif startLong > endLong:
2747 elif startLong > endLong:
2544 return(HttpResponse('startLong %s cannot be greater than endLong %s' % (str(startLong), str(endLong))))
2748 return(HttpResponse('startLong %s cannot be greater than endLong %s' % (str(startLong), str(endLong))))
2545 stepLong = float(request.GET['stepLong'])
2749 stepLong = float(request.GET['stepLong'])
2546 if stepLong < 0.0:
2750 if stepLong < 0.0:
2547 return(HttpResponse('stepLong %s cannot be less than zero' % (str(stepLong))))
2751 return(HttpResponse('stepLong %s cannot be less than zero' % (str(stepLong))))
2548 elif stepLong == 0.0:
2752 elif stepLong == 0.0:
2549 stepLong = 0.001
2753 stepLong = 0.001
2550 lonList = list(numpy.arange(startLong, endLong, stepLong))
2754 lonList = list(numpy.arange(startLong, endLong, stepLong))
2551
2755
2552 startAlt = float(request.GET['startAlt'])
2756 startAlt = float(request.GET['startAlt'])
2553 endAlt = float(request.GET['endAlt'])
2757 endAlt = float(request.GET['endAlt'])
2554 if startAlt == endAlt:
2758 if startAlt == endAlt:
2555 endAlt += 0.001
2759 endAlt += 0.001
2556 elif startAlt > endAlt:
2760 elif startAlt > endAlt:
2557 return(HttpResponse('startAlt %s cannot be greater than endAlt %s' % (str(startAlt), str(endAlt))))
2761 return(HttpResponse('startAlt %s cannot be greater than endAlt %s' % (str(startAlt), str(endAlt))))
2558 stepAlt = float(request.GET['stepAlt'])
2762 stepAlt = float(request.GET['stepAlt'])
2559 if stepAlt < 0.0:
2763 if stepAlt < 0.0:
2560 return(HttpResponse('stepAlt %s cannot be less than zero' % (str(stepAlt))))
2764 return(HttpResponse('stepAlt %s cannot be less than zero' % (str(stepAlt))))
2561 elif stepAlt == 0.0:
2765 elif stepAlt == 0.0:
2562 stepAlt = 0.01
2766 stepAlt = 0.01
2563 altList = list(numpy.arange(startAlt, endAlt, stepAlt))
2767 altList = list(numpy.arange(startAlt, endAlt, stepAlt))
2564
2768
2565 # limit total calculations to 1E5
2769 # limit total calculations to 1E5
2566 total = len(latList) * len(lonList) * len(altList)
2770 total = len(latList) * len(lonList) * len(altList)
2567 if total > 1.0E5:
2771 if total > 1.0E5:
2568 return(HttpResponse('Too many points for madCalculatorService: %i' % (total)))
2772 return(HttpResponse('Too many points for madCalculatorService: %i' % (total)))
2569
2773
2570 parms = request.GET['parms']
2774 parms = request.GET['parms']
2571 desiredParmList = [item.strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')]
2775 desiredParmList = [item.strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')]
2572
2776
2573 oneDList = request.GET.getlist('oneD')
2777 oneDList = request.GET.getlist('oneD')
2574 oneDParmDict = {}
2778 oneDParmDict = {}
2575 for oneDStr in oneDList:
2779 for oneDStr in oneDList:
2576 mnem, strValue = oneDStr.split(',')
2780 mnem, strValue = oneDStr.split(',')
2577 oneDParmDict[mnem] = [float(strValue)]
2781 oneDParmDict[mnem] = [float(strValue)]
2578
2782
2579 # capture stdout
2783 # capture stdout
2580 old_stdout = sys.stdout
2784 old_stdout = sys.stdout
2581 sys.stdout = mystdout = io.StringIO()
2785 sys.stdout = mystdout = io.StringIO()
2582 madrigal.isprint.MadCalculatorGrid(None, desiredParmList, [dt], latList, lonList, altList,
2786 madrigal.isprint.MadCalculatorGrid(None, desiredParmList, [dt], latList, lonList, altList,
2583 oneDParmDict, summary=None)
2787 oneDParmDict, summary=None)
2584 text = mystdout.getvalue()
2788 text = mystdout.getvalue()
2585 sys.stdout = old_stdout
2789 sys.stdout = old_stdout
2586
2790
2587 return render(request, 'madweb/service.html', {'text': text})
2791 return render(request, 'madweb/service.html', {'text': text})
2588
2792
2589
2793
2590 def mad_time_calculator_service(request):
2794 def mad_time_calculator_service(request):
2591 """mad_time_calculator_service runs the madTimeCalculator service. Input parameters must not be location dependent
2795 """mad_time_calculator_service runs the madTimeCalculator service. Input parameters must not be location dependent
2592
2796
2593 Inputs:
2797 Inputs:
2594 request/url - contains arguments:
2798 request/url - contains arguments:
2595
2799
2596 1. startyear - int
2800 1. startyear - int
2597
2801
2598 2. startmonth - int
2802 2. startmonth - int
2599
2803
2600 3. startday - int
2804 3. startday - int
2601
2805
2602 4. starthour - int
2806 4. starthour - int
2603
2807
2604 5. startmin - int
2808 5. startmin - int
2605
2809
2606 6. startsec - int
2810 6. startsec - int
2607
2811
2608 7. endyear - int
2812 7. endyear - int
2609
2813
2610 8. endmonth - int
2814 8. endmonth - int
2611
2815
2612 9. endday - int
2816 9. endday - int
2613
2817
2614 10. endhour - int
2818 10. endhour - int
2615
2819
2616 11. endmin - int
2820 11. endmin - int
2617
2821
2618 12. endsec - int
2822 12. endsec - int
2619
2823
2620 13. stephours - float - number of hours per time step
2824 13. stephours - float - number of hours per time step
2621
2825
2622 14. parms - comma delimited string of Madrigal parameters desired (must not depend on location)
2826 14. parms - comma delimited string of Madrigal parameters desired (must not depend on location)
2623
2827
2624 Returns comma-delimited data, one line for each year, month, day, hour, minute, and second,
2828 Returns comma-delimited data, one line for each year, month, day, hour, minute, and second,
2625 with the following fields:
2829 with the following fields:
2626
2830
2627 1-6: year, month, day, hour, minute, and second
2831 1-6: year, month, day, hour, minute, and second
2628
2832
2629 2. requested parm fields
2833 2. requested parm fields
2630 """
2834 """
2631 startyear = int(request.GET['startyear'])
2835 startyear = int(request.GET['startyear'])
2632 startmonth = int(request.GET['startmonth'])
2836 startmonth = int(request.GET['startmonth'])
2633 startday = int(request.GET['startday'])
2837 startday = int(request.GET['startday'])
2634 starthour = int(request.GET['starthour'])
2838 starthour = int(request.GET['starthour'])
2635 startminute = int(request.GET['startmin'])
2839 startminute = int(request.GET['startmin'])
2636 startsecond = int(request.GET['startsec'])
2840 startsecond = int(request.GET['startsec'])
2637 endyear = int(request.GET['endyear'])
2841 endyear = int(request.GET['endyear'])
2638 endmonth = int(request.GET['endmonth'])
2842 endmonth = int(request.GET['endmonth'])
2639 endday = int(request.GET['endday'])
2843 endday = int(request.GET['endday'])
2640 endhour = int(request.GET['endhour'])
2844 endhour = int(request.GET['endhour'])
2641 endminute = int(request.GET['endmin'])
2845 endminute = int(request.GET['endmin'])
2642 endsecond = int(request.GET['endsec'])
2846 endsecond = int(request.GET['endsec'])
2643 dt1 = datetime.datetime(startyear, startmonth, startday, starthour, startminute, startsecond)
2847 dt1 = datetime.datetime(startyear, startmonth, startday, starthour, startminute, startsecond)
2644 dt2 = datetime.datetime(endyear, endmonth, endday, endhour, endminute, endsecond)
2848 dt2 = datetime.datetime(endyear, endmonth, endday, endhour, endminute, endsecond)
2645 if dt1 > dt2:
2849 if dt1 > dt2:
2646 return(HttpResponse('End Datetime %s cannot be before start datetime %s' % (str(dt2), str(dt1))))
2850 return(HttpResponse('End Datetime %s cannot be before start datetime %s' % (str(dt2), str(dt1))))
2647
2851
2648 stephours = float(request.GET['stephours'])
2852 stephours = float(request.GET['stephours'])
2649 if stephours <= 0.0:
2853 if stephours <= 0.0:
2650 return(HttpResponse('stephours cannot be non-positive: %f' % (stephours)))
2854 return(HttpResponse('stephours cannot be non-positive: %f' % (stephours)))
2651
2855
2652 dtList = []
2856 dtList = []
2653 while dt1 <= dt2:
2857 while dt1 <= dt2:
2654 dtList.append(dt1)
2858 dtList.append(dt1)
2655 dt1 += datetime.timedelta(hours=stephours)
2859 dt1 += datetime.timedelta(hours=stephours)
2656
2860
2657 parms = request.GET['parms']
2861 parms = request.GET['parms']
2658 desiredParmList = [item.strip() for item in ['year','month','day','hour','min','sec'] + parms.split(',')]
2862 desiredParmList = [item.strip() for item in ['year','month','day','hour','min','sec'] + parms.split(',')]
2659
2863
2660 # no spatial data
2864 # no spatial data
2661 latList = lonList = altList = []
2865 latList = lonList = altList = []
2662 # capture stdout
2866 # capture stdout
2663 old_stdout = sys.stdout
2867 old_stdout = sys.stdout
2664 sys.stdout = mystdout = io.StringIO()
2868 sys.stdout = mystdout = io.StringIO()
2665 madrigal.isprint.MadCalculatorGrid(None, desiredParmList, dtList, latList, lonList, altList,
2869 madrigal.isprint.MadCalculatorGrid(None, desiredParmList, dtList, latList, lonList, altList,
2666 summary=None)
2870 summary=None)
2667 text = mystdout.getvalue()
2871 text = mystdout.getvalue()
2668 sys.stdout = old_stdout
2872 sys.stdout = old_stdout
2669
2873
2670 return render(request, 'madweb/service.html', {'text': text})
2874 return render(request, 'madweb/service.html', {'text': text})
2671
2875
2672
2876
2673
2877
2674 @csrf_exempt
2878 @csrf_exempt
2675 def mad_calculator2_service(request):
2879 def mad_calculator2_service(request):
2676 """mad_calculator2_service runs the madCalculator2 service.
2880 """mad_calculator2_service runs the madCalculator2 service.
2677
2881
2678 Differs from madCalulator in that positions are a list rather than a grid.
2882 Differs from madCalulator in that positions are a list rather than a grid.
2679
2883
2680 Inputs:
2884 Inputs:
2681 request/url - contains arguments:
2885 request/url - contains arguments:
2682
2886
2683 year, month, day, hour, min, sec
2887 year, month, day, hour, min, sec
2684
2888
2685 lats - comma separated list of latitudes to analyze
2889 lats - comma separated list of latitudes to analyze
2686
2890
2687 longs - comma separated list of longitudes to analyze. Len must == len(lats)
2891 longs - comma separated list of longitudes to analyze. Len must == len(lats)
2688
2892
2689 alts - comma separated list of altitudes to analyze. Len must == len(lats)
2893 alts - comma separated list of altitudes to analyze. Len must == len(lats)
2690
2894
2691 parms - comma delimited string of Madrigal parameters desired
2895 parms - comma delimited string of Madrigal parameters desired
2692
2896
2693 oneD - zero or more mnemonics,float values to set input 1D values
2897 oneD - zero or more mnemonics,float values to set input 1D values
2694 Example: &oneD=kinst,31.0&oneD=elm,45.0
2898 Example: &oneD=kinst,31.0&oneD=elm,45.0
2695
2899
2696 twoD - zero or more mnemonics,comma-separate float list of len(lats) to set input 2D values
2900 twoD - zero or more mnemonics,comma-separate float list of len(lats) to set input 2D values
2697 Example: twoD=te,1000,1100,1200 twoD=ti,1000,1000,1000
2901 Example: twoD=te,1000,1100,1200 twoD=ti,1000,1000,1000
2698 where there are 3 lats
2902 where there are 3 lats
2699
2903
2700 Returns comma-delimited data, one line for each lat value,
2904 Returns comma-delimited data, one line for each lat value,
2701 with the following fields:
2905 with the following fields:
2702
2906
2703 1. latitude
2907 1. latitude
2704
2908
2705 2. longitude
2909 2. longitude
2706
2910
2707 3. altitude
2911 3. altitude
2708
2912
2709 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace
2913 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace
2710 """
2914 """
2711 if request.method == 'POST':
2915 if request.method == 'POST':
2712 reqDict = request.POST
2916 reqDict = request.POST
2713 else:
2917 else:
2714 reqDict = request.GET
2918 reqDict = request.GET
2715 try:
2919 try:
2716 year = int(reqDict.get('year'))
2920 year = int(reqDict.get('year'))
2717 except TypeError:
2921 except TypeError:
2718 return(HttpResponse('<p>madCalculator2Service requires year</p>'))
2922 return(HttpResponse('<p>madCalculator2Service requires year</p>'))
2719 month = int(reqDict['month'])
2923 month = int(reqDict['month'])
2720 day = int(reqDict['day'])
2924 day = int(reqDict['day'])
2721 hour = int(reqDict['hour'])
2925 hour = int(reqDict['hour'])
2722 minute = int(reqDict['min'])
2926 minute = int(reqDict['min'])
2723 second = int(reqDict['sec'])
2927 second = int(reqDict['sec'])
2724 dt = datetime.datetime(year, month, day, hour, minute, second)
2928 dt = datetime.datetime(year, month, day, hour, minute, second)
2725
2929
2726 latsStr = reqDict['lats']
2930 latsStr = reqDict['lats']
2727 lats = [float(item) for item in latsStr.split(',')]
2931 lats = [float(item) for item in latsStr.split(',')]
2728 longsStr = reqDict['longs']
2932 longsStr = reqDict['longs']
2729 longs = [float(item) for item in longsStr.split(',')]
2933 longs = [float(item) for item in longsStr.split(',')]
2730 altsStr = reqDict['alts']
2934 altsStr = reqDict['alts']
2731 alts = [float(item) for item in altsStr.split(',')]
2935 alts = [float(item) for item in altsStr.split(',')]
2732
2936
2733 parms = reqDict['parms']
2937 parms = reqDict['parms']
2734 desiredParmList = [item.strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')]
2938 desiredParmList = [item.strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')]
2735
2939
2736 oneDList = reqDict.getlist('oneD')
2940 oneDList = reqDict.getlist('oneD')
2737 oneDParmDict = {}
2941 oneDParmDict = {}
2738 for oneDStr in oneDList:
2942 for oneDStr in oneDList:
2739 mnem, strValue = oneDStr.split(',')
2943 mnem, strValue = oneDStr.split(',')
2740 oneDParmDict[mnem] = [float(strValue)]
2944 oneDParmDict[mnem] = [float(strValue)]
2741
2945
2742 twoDList = reqDict.getlist('twoD')
2946 twoDList = reqDict.getlist('twoD')
2743
2947
2744 twoDParmDict = {}
2948 twoDParmDict = {}
2745 for twoDStr in twoDList:
2949 for twoDStr in twoDList:
2746 items = twoDStr.split(',')
2950 items = twoDStr.split(',')
2747 if len(items) != 1 + len(lats):
2951 if len(items) != 1 + len(lats):
2748 raise ValueError('twoDstr %s not correct number of points' % (str(twoDStr)))
2952 raise ValueError('twoDstr %s not correct number of points' % (str(twoDStr)))
2749 mnem = items[0]
2953 mnem = items[0]
2750 floatValues = [float(item) for item in items[1:]]
2954 floatValues = [float(item) for item in items[1:]]
2751 # now we need to expand these values to be two dimensional 1 x len(lats)
2955 # now we need to expand these values to be two dimensional 1 x len(lats)
2752 values = numpy.zeros((1,len(lats)), dtype=numpy.float)
2956 values = numpy.zeros((1,len(lats)), dtype=numpy.float)
2753 values[0][:] = floatValues
2957 values[0][:] = floatValues
2754 twoDParmDict[mnem] = values
2958 twoDParmDict[mnem] = values
2755
2959
2756 # capture stdout
2960 # capture stdout
2757 old_stdout = sys.stdout
2961 old_stdout = sys.stdout
2758 sys.stdout = mystdout = io.StringIO()
2962 sys.stdout = mystdout = io.StringIO()
2759 madrigal.isprint.MadCalculatorList(None, desiredParmList, [dt], lats, longs, alts,
2963 madrigal.isprint.MadCalculatorList(None, desiredParmList, [dt], lats, longs, alts,
2760 oneDParmDict, twoDParmDict, summary=None)
2964 oneDParmDict, twoDParmDict, summary=None)
2761 text = mystdout.getvalue()
2965 text = mystdout.getvalue()
2762 sys.stdout = old_stdout
2966 sys.stdout = old_stdout
2763
2967
2764 return render(request, 'madweb/service.html', {'text': text})
2968 return render(request, 'madweb/service.html', {'text': text})
2765
2969
2766
2970
2767
2971
2768
2972
2769 @csrf_exempt
2973 @csrf_exempt
2770 def mad_calculator3_service(request):
2974 def mad_calculator3_service(request):
2771 """mad_calculator3_service runs the madCalculator3 service.
2975 """mad_calculator3_service runs the madCalculator3 service.
2772
2976
2773 Differs from madCalulator in that multiple times, each with a unique list of positions, can be passed in.
2977 Differs from madCalulator in that multiple times, each with a unique list of positions, can be passed in.
2774
2978
2775 Inputs:
2979 Inputs:
2776 request/url - contains arguments:
2980 request/url - contains arguments:
2777
2981
2778 year - a comma-separated list of years - (required)
2982 year - a comma-separated list of years - (required)
2779
2983
2780 month - a comma-separated list of months - (required)
2984 month - a comma-separated list of months - (required)
2781
2985
2782 day - a comma-separated list of days - (required)
2986 day - a comma-separated list of days - (required)
2783
2987
2784 hour - a comma-separated list of hours - (required)
2988 hour - a comma-separated list of hours - (required)
2785
2989
2786 min - a comma-separated list of minutes - (required)
2990 min - a comma-separated list of minutes - (required)
2787
2991
2788 sec - a comma-separated list of seconds - (required)
2992 sec - a comma-separated list of seconds - (required)
2789
2993
2790 numPos - a comma-sepatated list of the number of positions for each time - (required)
2994 numPos - a comma-sepatated list of the number of positions for each time - (required)
2791
2995
2792 lats - a comma-separated list of geodetic latitudes, -90 to 90 (required). Listed
2996 lats - a comma-separated list of geodetic latitudes, -90 to 90 (required). Listed
2793 for first time, then second, etc. Total must be equal to the sum
2997 for first time, then second, etc. Total must be equal to the sum
2794 of numPos.
2998 of numPos.
2795
2999
2796 longs - a comma-separated list of longitudes (required) Listed
3000 longs - a comma-separated list of longitudes (required) Listed
2797 for first time, then second, etc. Total must be equal to the sum
3001 for first time, then second, etc. Total must be equal to the sum
2798 of numPos.
3002 of numPos.
2799
3003
2800 alts - a comma-separated list of geodetic altitudes in km (required) Listed
3004 alts - a comma-separated list of geodetic altitudes in km (required) Listed
2801 for first time, then second, etc. Total must be equal to the sum
3005 for first time, then second, etc. Total must be equal to the sum
2802 of numPos.
3006 of numPos.
2803
3007
2804 parms - comma delimited string of Madrigal parameters desired (required)
3008 parms - comma delimited string of Madrigal parameters desired (required)
2805
3009
2806 oneD - string in form <parm>,<comma-separated values> This argument allows the user to
3010 oneD - string in form <parm>,<comma-separated values> This argument allows the user to
2807 set any number of one-D parameters to be used in the calculation.
3011 set any number of one-D parameters to be used in the calculation.
2808 Value must be parameter name, comma, list of values as double,
3012 Value must be parameter name, comma, list of values as double,
2809 where length of list is equal to number of times.
3013 where length of list is equal to number of times.
2810 Example: &oneD=kinst,31.0,31.0&oneD=elm,45.0,50
3014 Example: &oneD=kinst,31.0,31.0&oneD=elm,45.0,50
2811 (optional - 0 or more allowed)
3015 (optional - 0 or more allowed)
2812
3016
2813 twoD=<parm>,<values> (optional - 0 or more allowed) This argument allows the user to
3017 twoD=<parm>,<values> (optional - 0 or more allowed) This argument allows the user to
2814 set any number of two-D parameters to be used in the calculation.
3018 set any number of two-D parameters to be used in the calculation.
2815 Value must be parameter name, comma, comma-separated values.
3019 Value must be parameter name, comma, comma-separated values.
2816 Number of values must equal the sum of numPos. Order is
3020 Number of values must equal the sum of numPos. Order is
2817 first time values first, then second time values, etc
3021 first time values first, then second time values, etc
2818 Example: twoD=te,1000,1100,1200,1000,1100,1200 &twoD=ti,1000,1000,1000,1000,1000,1000
3022 Example: twoD=te,1000,1100,1200,1000,1100,1200 &twoD=ti,1000,1000,1000,1000,1000,1000
2819 where numPos=3,3
3023 where numPos=3,3
2820
3024
2821 Returns comma-delimited data, one line for each location. Separate times are delimited by line
3025 Returns comma-delimited data, one line for each location. Separate times are delimited by line
2822
3026
2823 TIME MM/DD/YYYY HH:MM:SS
3027 TIME MM/DD/YYYY HH:MM:SS
2824
3028
2825 Data lines have the following fields:
3029 Data lines have the following fields:
2826
3030
2827 1. latitude
3031 1. latitude
2828
3032
2829 2. longitude
3033 2. longitude
2830
3034
2831 3. altitude
3035 3. altitude
2832
3036
2833 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace
3037 4. Values for each Madrigal parameter listed in argument parms, separated by whitespace
2834 """
3038 """
2835 if request.method == 'POST':
3039 if request.method == 'POST':
2836 reqDict = request.POST
3040 reqDict = request.POST
2837 else:
3041 else:
2838 reqDict = request.GET
3042 reqDict = request.GET
2839 try:
3043 try:
2840 yearList = [int(item) for item in reqDict.get('year').split(',')]
3044 yearList = [int(item) for item in reqDict.get('year').split(',')]
2841 except AttributeError:
3045 except AttributeError:
2842 return(HttpResponse('<p>madCalculator3Service requires year</p>'))
3046 return(HttpResponse('<p>madCalculator3Service requires year</p>'))
2843 monthList = [int(item) for item in reqDict.get('month').split(',')]
3047 monthList = [int(item) for item in reqDict.get('month').split(',')]
2844 dayList = [int(item) for item in reqDict.get('day').split(',')]
3048 dayList = [int(item) for item in reqDict.get('day').split(',')]
2845 hourList = [int(item) for item in reqDict.get('hour').split(',')]
3049 hourList = [int(item) for item in reqDict.get('hour').split(',')]
2846 minList = [int(item) for item in reqDict.get('min').split(',')]
3050 minList = [int(item) for item in reqDict.get('min').split(',')]
2847 secList = [int(item) for item in reqDict.get('sec').split(',')]
3051 secList = [int(item) for item in reqDict.get('sec').split(',')]
2848 dtList = [datetime.datetime(yearList[i], monthList[i], dayList[i],
3052 dtList = [datetime.datetime(yearList[i], monthList[i], dayList[i],
2849 hourList[i], minList[i], secList[i]) for i in range(len(yearList))]
3053 hourList[i], minList[i], secList[i]) for i in range(len(yearList))]
2850 numPosStr = reqDict['numPos']
3054 numPosStr = reqDict['numPos']
2851 numPosList = [int(item) for item in numPosStr.split(',')]
3055 numPosList = [int(item) for item in numPosStr.split(',')]
2852 totalPos = 0
3056 totalPos = 0
2853 for numPos in numPosList:
3057 for numPos in numPosList:
2854 totalPos += numPos
3058 totalPos += numPos
2855 latsStr = reqDict['lats']
3059 latsStr = reqDict['lats']
2856 lats = [float(item) for item in latsStr.split(',')]
3060 lats = [float(item) for item in latsStr.split(',')]
2857 if len(lats) != totalPos:
3061 if len(lats) != totalPos:
2858 return(HttpResponse('wrong number of lats, expected %i' % (totalPos)))
3062 return(HttpResponse('wrong number of lats, expected %i' % (totalPos)))
2859 longsStr = reqDict['longs']
3063 longsStr = reqDict['longs']
2860 longs = [float(item) for item in longsStr.split(',')]
3064 longs = [float(item) for item in longsStr.split(',')]
2861 if len(longs) != totalPos:
3065 if len(longs) != totalPos:
2862 return(HttpResponse('wrong number of longs, expected %i' % (totalPos)))
3066 return(HttpResponse('wrong number of longs, expected %i' % (totalPos)))
2863 altsStr = reqDict['alts']
3067 altsStr = reqDict['alts']
2864 alts = [float(item) for item in altsStr.split(',')]
3068 alts = [float(item) for item in altsStr.split(',')]
2865 if len(alts) != totalPos:
3069 if len(alts) != totalPos:
2866 return(HttpResponse('wrong number of alts, expected %i' % (totalPos)))
3070 return(HttpResponse('wrong number of alts, expected %i' % (totalPos)))
2867
3071
2868 parms = reqDict['parms']
3072 parms = reqDict['parms']
2869 desiredParmList = [item.strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')]
3073 desiredParmList = [item.strip() for item in ['gdlat','glon','gdalt'] + parms.split(',')]
2870
3074
2871 oneDList = reqDict.getlist('oneD')
3075 oneDList = reqDict.getlist('oneD')
2872 twoDList = reqDict.getlist('twoD')
3076 twoDList = reqDict.getlist('twoD')
2873
3077
2874 # since the positions can change with each call, we need to call madrigal.isprint.MadCalculatorGrid once for each time
3078 # since the positions can change with each call, we need to call madrigal.isprint.MadCalculatorGrid once for each time
2875 startIndex = 0
3079 startIndex = 0
2876 endIndex = 0
3080 endIndex = 0
2877 fullText = ''
3081 fullText = ''
2878 for timeIndex, numPos in enumerate(numPosList):
3082 for timeIndex, numPos in enumerate(numPosList):
2879 startIndex = endIndex
3083 startIndex = endIndex
2880 endIndex += numPos
3084 endIndex += numPos
2881 thisLats = lats[startIndex:endIndex]
3085 thisLats = lats[startIndex:endIndex]
2882 thisLongs = longs[startIndex:endIndex]
3086 thisLongs = longs[startIndex:endIndex]
2883 thisAlts = alts[startIndex:endIndex]
3087 thisAlts = alts[startIndex:endIndex]
2884
3088
2885 oneDParmDict = {}
3089 oneDParmDict = {}
2886 for oneDStr in oneDList:
3090 for oneDStr in oneDList:
2887 values = oneDStr.split(',')
3091 values = oneDStr.split(',')
2888 if len(values) != 1+len(dtList):
3092 if len(values) != 1+len(dtList):
2889 return(HttpResponse('wrong number of values given for 1D parm %s' % (values[0])))
3093 return(HttpResponse('wrong number of values given for 1D parm %s' % (values[0])))
2890 oneDParmDict[values[0]] = [float(values[timeIndex+1])]
3094 oneDParmDict[values[0]] = [float(values[timeIndex+1])]
2891
3095
2892 twoDParmDict = {}
3096 twoDParmDict = {}
2893
3097
2894 for twoDStr in twoDList:
3098 for twoDStr in twoDList:
2895 values = twoDStr.split(',')
3099 values = twoDStr.split(',')
2896 if len(values) != 1 + totalPos:
3100 if len(values) != 1 + totalPos:
2897 return(HttpResponse('twoDstr %s not correct number of points' % (str(twoDStr))))
3101 return(HttpResponse('twoDstr %s not correct number of points' % (str(twoDStr))))
2898 mnem = values[0]
3102 mnem = values[0]
2899 floatValues = [float(item) for item in values[1+startIndex:1+endIndex]]
3103 floatValues = [float(item) for item in values[1+startIndex:1+endIndex]]
2900 # now we need to expand these values to be two dimensional - 1,len(thisLats)
3104 # now we need to expand these values to be two dimensional - 1,len(thisLats)
2901 values2D = numpy.zeros((1,len(thisLats)), dtype=numpy.float)
3105 values2D = numpy.zeros((1,len(thisLats)), dtype=numpy.float)
2902 values2D[0][:] = floatValues
3106 values2D[0][:] = floatValues
2903 twoDParmDict[mnem] = values2D
3107 twoDParmDict[mnem] = values2D
2904
3108
2905
3109
2906
3110
2907 # capture stdout
3111 # capture stdout
2908 old_stdout = sys.stdout
3112 old_stdout = sys.stdout
2909 sys.stdout = mystdout = io.StringIO()
3113 sys.stdout = mystdout = io.StringIO()
2910 madrigal.isprint.MadCalculatorList(None, desiredParmList, [dtList[timeIndex]], thisLats,
3114 madrigal.isprint.MadCalculatorList(None, desiredParmList, [dtList[timeIndex]], thisLats,
2911 thisLongs, thisAlts,
3115 thisLongs, thisAlts,
2912 oneDParmDict, twoDParmDict, summary=None)
3116 oneDParmDict, twoDParmDict, summary=None)
2913 text = mystdout.getvalue()
3117 text = mystdout.getvalue()
2914 sys.stdout = old_stdout
3118 sys.stdout = old_stdout
2915
3119
2916 fullText += 'TIME %s\n' % (dtList[timeIndex].strftime('%m/%d/%Y %H:%M:%S'))
3120 fullText += 'TIME %s\n' % (dtList[timeIndex].strftime('%m/%d/%Y %H:%M:%S'))
2917 fullText += text
3121 fullText += text
2918
3122
2919 return render(request, 'madweb/service.html', {'text': fullText})
3123 return render(request, 'madweb/service.html', {'text': fullText})
2920
3124
2921
3125
2922
3126
2923 def geodetic_to_radar_service(request):
3127 def geodetic_to_radar_service(request):
2924 """geodetic_to_radar_service runs the geodeticToRadar service.
3128 """geodetic_to_radar_service runs the geodeticToRadar service.
2925
3129
2926 Inputs:
3130 Inputs:
2927 request/url - contains arguments:
3131 request/url - contains arguments:
2928
3132
2929 slatgd - radar geodetic latitude
3133 slatgd - radar geodetic latitude
2930
3134
2931 slon - radar longitude
3135 slon - radar longitude
2932
3136
2933 saltgd - radar geodetic altitude
3137 saltgd - radar geodetic altitude
2934
3138
2935 gdlat - a comma-separated list of geodetic latitude of point
3139 gdlat - a comma-separated list of geodetic latitude of point
2936
3140
2937 glon - a comma-separated list of longitude of point. Len must be same as gdlat
3141 glon - a comma-separated list of longitude of point. Len must be same as gdlat
2938
3142
2939 gdalt - a comma-separated list of geodetic altitude of point. Len must be same as gdlat
3143 gdalt - a comma-separated list of geodetic altitude of point. Len must be same as gdlat
2940
3144
2941
3145
2942 Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids):
3146 Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids):
2943
3147
2944 1. radar azimuth in degrees (0 = north)
3148 1. radar azimuth in degrees (0 = north)
2945
3149
2946 2. radar elevation in degrees
3150 2. radar elevation in degrees
2947
3151
2948 3. radar range in km
3152 3. radar range in km
2949 """
3153 """
2950 slatgd = float(request.GET['slatgd'])
3154 slatgd = float(request.GET['slatgd'])
2951 slon = float(request.GET['slon'])
3155 slon = float(request.GET['slon'])
2952 saltgd = float(request.GET['saltgd'])
3156 saltgd = float(request.GET['saltgd'])
2953 oneDParmDict = {'GDLATR': [slatgd],
3157 oneDParmDict = {'GDLATR': [slatgd],
2954 'GDLONR': [slon],
3158 'GDLONR': [slon],
2955 'GALTR': [saltgd]}
3159 'GALTR': [saltgd]}
2956 gdlatStr = request.GET['gdlat']
3160 gdlatStr = request.GET['gdlat']
2957 gdlatList = [float(item) for item in gdlatStr.split(',')]
3161 gdlatList = [float(item) for item in gdlatStr.split(',')]
2958 glonStr = request.GET['glon']
3162 glonStr = request.GET['glon']
2959 glonList = [float(item) for item in glonStr.split(',')]
3163 glonList = [float(item) for item in glonStr.split(',')]
2960 gdaltStr = request.GET['gdalt']
3164 gdaltStr = request.GET['gdalt']
2961 gdaltList = [float(item) for item in gdaltStr.split(',')]
3165 gdaltList = [float(item) for item in gdaltStr.split(',')]
2962 desiredParmList = ['azm', 'elm', 'range']
3166 desiredParmList = ['azm', 'elm', 'range']
2963 dtList = [datetime.datetime(2001,1,1)] # not relevant
3167 dtList = [datetime.datetime(2001,1,1)] # not relevant
2964 if len(gdlatList) != len(glonList) or len(gdlatList) != len(gdaltList):
3168 if len(gdlatList) != len(glonList) or len(gdlatList) != len(gdaltList):
2965 return(HttpResponse('all point list lengths must be equal'))
3169 return(HttpResponse('all point list lengths must be equal'))
2966
3170
2967 fullText = ''
3171 fullText = ''
2968
3172
2969 delimiter = ','
3173 delimiter = ','
2970 for i in range(len(gdlatList)):
3174 for i in range(len(gdlatList)):
2971 # capture stdout
3175 # capture stdout
2972 old_stdout = sys.stdout
3176 old_stdout = sys.stdout
2973 sys.stdout = mystdout = io.StringIO()
3177 sys.stdout = mystdout = io.StringIO()
2974 madrigal.isprint.MadCalculatorGrid(None, desiredParmList, dtList, [gdlatList[i]],
3178 madrigal.isprint.MadCalculatorGrid(None, desiredParmList, dtList, [gdlatList[i]],
2975 [glonList[i]], [gdaltList[i]], summary=None,
3179 [glonList[i]], [gdaltList[i]], summary=None,
2976 oneDParmDict=oneDParmDict)
3180 oneDParmDict=oneDParmDict)
2977 text = mystdout.getvalue()
3181 text = mystdout.getvalue()
2978 sys.stdout = old_stdout
3182 sys.stdout = old_stdout
2979 for line in text.split('\n'):
3183 for line in text.split('\n'):
2980 items = line.split()
3184 items = line.split()
2981 fullText += delimiter.join(items) + '\n'
3185 fullText += delimiter.join(items) + '\n'
2982
3186
2983 return render(request, 'madweb/service.html', {'text': fullText})
3187 return render(request, 'madweb/service.html', {'text': fullText})
2984
3188
2985
3189
2986 def radar_to_geodetic_service(request):
3190 def radar_to_geodetic_service(request):
2987 """radar_to_geodetic_service runs the radarToGeodetic service.
3191 """radar_to_geodetic_service runs the radarToGeodetic service.
2988
3192
2989 Inputs:
3193 Inputs:
2990 request/url - contains arguments:
3194 request/url - contains arguments:
2991
3195
2992 slatgd - radar geodetic latitude
3196 slatgd - radar geodetic latitude
2993
3197
2994 slon - radar longitude
3198 slon - radar longitude
2995
3199
2996 saltgd - radar geodetic altitude
3200 saltgd - radar geodetic altitude
2997
3201
2998 azs - a comma-separated list of azimuths of point
3202 azs - a comma-separated list of azimuths of point
2999
3203
3000 els - a comma-separated list of elevations of point. Len must be same as azs
3204 els - a comma-separated list of elevations of point. Len must be same as azs
3001
3205
3002 ranges - a comma-separated list of ranges to point. Len must be same as azs
3206 ranges - a comma-separated list of ranges to point. Len must be same as azs
3003
3207
3004
3208
3005 Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids):
3209 Returns comma-delimited data, one line for point in lists (points treated as individual combinations, not grids):
3006
3210
3007 1. geodetic latitude
3211 1. geodetic latitude
3008
3212
3009 2. longitude (-180 to 180)
3213 2. longitude (-180 to 180)
3010
3214
3011 3. geodetic altitude in km
3215 3. geodetic altitude in km
3012 """
3216 """
3013 slatgd = float(request.GET['slatgd'])
3217 slatgd = float(request.GET['slatgd'])
3014 slon = float(request.GET['slon'])
3218 slon = float(request.GET['slon'])
3015 saltgd = float(request.GET['saltgd'])
3219 saltgd = float(request.GET['saltgd'])
3016 azStr = request.GET['az']
3220 azStr = request.GET['az']
3017 azList = [float(item) for item in azStr.split(',')]
3221 azList = [float(item) for item in azStr.split(',')]
3018 elStr = request.GET['el']
3222 elStr = request.GET['el']
3019 elList = [float(item) for item in elStr.split(',')]
3223 elList = [float(item) for item in elStr.split(',')]
3020 rangeStr = request.GET['range']
3224 rangeStr = request.GET['range']
3021 rangeList = [float(item) for item in rangeStr.split(',')]
3225 rangeList = [float(item) for item in rangeStr.split(',')]
3022 if len(azList) != len(elList) or len(azList) != len(rangeList):
3226 if len(azList) != len(elList) or len(azList) != len(rangeList):
3023 return(HttpResponse('all point list lengths must be equal'))
3227 return(HttpResponse('all point list lengths must be equal'))
3024
3228
3025 fullText = ''
3229 fullText = ''
3026
3230
3027 for i in range(len(azList)):
3231 for i in range(len(azList)):
3028 gdlat,glon,gdalt = madrigal._derive.radarToGeodetic(slatgd, slon, saltgd,
3232 gdlat,glon,gdalt = madrigal._derive.radarToGeodetic(slatgd, slon, saltgd,
3029 azList[i], elList[i], rangeList[i])
3233 azList[i], elList[i], rangeList[i])
3030 fullText += '%f,%f,%f\n' % (gdlat,glon,gdalt)
3234 fullText += '%f,%f,%f\n' % (gdlat,glon,gdalt)
3031
3235
3032 return render(request, 'madweb/service.html', {'text': fullText})
3236 return render(request, 'madweb/service.html', {'text': fullText})
3033
3237
3034
3238
3035
3239
3036 def list_file_times_service(request):
3240 def list_file_times_service(request):
3037 """list_file_times_service runs the listFileTimes service.
3241 """list_file_times_service runs the listFileTimes service.
3038
3242
3039 Inputs:
3243 Inputs:
3040 request/url - contains arguments:
3244 request/url - contains arguments:
3041
3245
3042 Optional: expDir - experiment directory to list. Can be absolute or relative to
3246 Optional: expDir - experiment directory to list. Can be absolute or relative to
3043 experiments[0-9]*. Default is all files in $MADROOT/experiments*
3247 experiments[0-9]*. Default is all files in $MADROOT/experiments*
3044
3248
3045 Returns comma-delimited data, one for each file:
3249 Returns comma-delimited data, one for each file:
3046
3250
3047 1. Full path of file
3251 1. Full path of file
3048
3252
3049 2. File modification time in form YYYY-MM-DD HH:MM:SS (UT time)
3253 2. File modification time in form YYYY-MM-DD HH:MM:SS (UT time)
3050 """
3254 """
3051 expDir = None
3255 expDir = None
3052 try:
3256 try:
3053 expDir = request.GET['expDir']
3257 expDir = request.GET['expDir']
3054 except:
3258 except:
3055 pass
3259 pass
3056 madDB = madrigal.metadata.MadrigalDB()
3260 madDB = madrigal.metadata.MadrigalDB()
3057 fileList = madDB.listFileTimes(expDir)
3261 fileList = madDB.listFileTimes(expDir)
3058 fullText = '\n\n'
3262 fullText = '\n\n'
3059 for filename, filetime in fileList:
3263 for filename, filetime in fileList:
3060 fullText += "\'%s\', %s\n" % (filename, filetime.strftime('%Y-%m-%d %H:%M:%S'))
3264 fullText += "\'%s\', %s\n" % (filename, filetime.strftime('%Y-%m-%d %H:%M:%S'))
3061
3265
3062 return render(request, 'madweb/service.html', {'text': django.utils.safestring.mark_safe(fullText)})
3266 return render(request, 'madweb/service.html', {'text': django.utils.safestring.mark_safe(fullText)})
3063
3267
3064
3268
3065 def download_web_file_service(request):
3269 def download_web_file_service(request):
3066 """download_web_file_service runs the downloadWebFile service.
3270 """download_web_file_service runs the downloadWebFile service.
3067
3271
3068 Inputs:
3272 Inputs:
3069 request/url - contains arguments:
3273 request/url - contains arguments:
3070
3274
3071 expPath - path to file starting at experiments*
3275 expPath - path to file starting at experiments*
3072
3276
3073 Returns comma-delimited data, one for each file:
3277 Returns comma-delimited data, one for each file:
3074
3278
3075 1. Full path of file
3279 1. Full path of file
3076
3280
3077 2. File modification time in form YYYY-MM-DD HH:MM:SS (UT time)
3281 2. File modification time in form YYYY-MM-DD HH:MM:SS (UT time)
3078 """
3282 """
3079 expPath = request.GET['expPath']
3283 expPath = request.GET['expPath']
3080 madDB = madrigal.metadata.MadrigalDB()
3284 madDB = madrigal.metadata.MadrigalDB()
3081 downloadFile = os.path.join(madDB.getMadroot(), expPath)
3285 downloadFile = os.path.join(madDB.getMadroot(), expPath)
3082 f = open(downloadFile, 'rb')
3286 f = open(downloadFile, 'rb')
3083 thisFile = django.core.files.File(f)
3287 thisFile = django.core.files.File(f)
3084 response = HttpResponse(thisFile, content_type='application/x-octet-stream')
3288 response = HttpResponse(thisFile, content_type='application/x-octet-stream')
3085 response['Content-Disposition'] = 'attachment; filename="' + os.path.basename(downloadFile) + '"'
3289 response['Content-Disposition'] = 'attachment; filename="' + os.path.basename(downloadFile) + '"'
3086 response['Content-Length'] = os.path.getsize(downloadFile)
3290 response['Content-Length'] = os.path.getsize(downloadFile)
3087 return(response)
3291 return(response)
3088
3292
3089
3293
3090 def trace_magnetic_field_service(request):
3294 def trace_magnetic_field_service(request):
3091 """trace_magnetic_field_service runs the traceMagneticField service.
3295 """trace_magnetic_field_service runs the traceMagneticField service.
3092
3296
3093 Inputs:
3297 Inputs:
3094 request/url - contains arguments:
3298 request/url - contains arguments:
3095
3299
3096 year, month, day, hour, min, sec
3300 year, month, day, hour, min, sec
3097
3301
3098 inputType (0 for geodetic, 1 for GSM)
3302 inputType (0 for geodetic, 1 for GSM)
3099
3303
3100 outputType (0 for geodetic, 1 for GSM)
3304 outputType (0 for geodetic, 1 for GSM)
3101
3305
3102 The following parameter depend on inputType:
3306 The following parameter depend on inputType:
3103
3307
3104 in1 - a comma-separated list of geodetic altitudes or ZGSMs of starting point
3308 in1 - a comma-separated list of geodetic altitudes or ZGSMs of starting point
3105
3309
3106 in2 - a comma-separated list of geodetic latitudes or XGSMs of starting point
3310 in2 - a comma-separated list of geodetic latitudes or XGSMs of starting point
3107
3311
3108 in3 - a comma-separated list of longitude or YGSM of starting point
3312 in3 - a comma-separated list of longitude or YGSM of starting point
3109
3313
3110 Length of all three lists must be the same
3314 Length of all three lists must be the same
3111
3315
3112 model - 0 for Tsyganenko, 1 for IGRF
3316 model - 0 for Tsyganenko, 1 for IGRF
3113
3317
3114 qualifier - 0 for conjugate, 1 for north_alt, 2 for south_alt, 3 for apex, 4 for GSM XY plane
3318 qualifier - 0 for conjugate, 1 for north_alt, 2 for south_alt, 3 for apex, 4 for GSM XY plane
3115
3319
3116 stopAlt - altitude in km to stop trace at, if qualifier is north_alt or south_alt.
3320 stopAlt - altitude in km to stop trace at, if qualifier is north_alt or south_alt.
3117
3321
3118 If other qualifier, this parameter is not required.
3322 If other qualifier, this parameter is not required.
3119
3323
3120 Returns comma-delimited data, one line for point in in lists:
3324 Returns comma-delimited data, one line for point in in lists:
3121
3325
3122 1. geodetic altitude or ZGSM of ending point
3326 1. geodetic altitude or ZGSM of ending point
3123
3327
3124 2. geodetic latitude or XGSM of ending point
3328 2. geodetic latitude or XGSM of ending point
3125
3329
3126 3. longitude or YGSM of ending point
3330 3. longitude or YGSM of ending point
3127 """
3331 """
3128 year = int(request.GET['year'])
3332 year = int(request.GET['year'])
3129 month = int(request.GET['month'])
3333 month = int(request.GET['month'])
3130 day = int(request.GET['day'])
3334 day = int(request.GET['day'])
3131 hour = int(request.GET['hour'])
3335 hour = int(request.GET['hour'])
3132 minute = int(request.GET['min'])
3336 minute = int(request.GET['min'])
3133 second = int(request.GET['sec'])
3337 second = int(request.GET['sec'])
3134 dt = datetime.datetime(year, month, day, hour, minute, second)
3338 dt = datetime.datetime(year, month, day, hour, minute, second)
3135 inputType = int(request.GET['inputType'])
3339 inputType = int(request.GET['inputType'])
3136 if inputType not in (0,1):
3340 if inputType not in (0,1):
3137 return(HttpResponse('inputType must be 0 or 1, not %i' % (inputType)))
3341 return(HttpResponse('inputType must be 0 or 1, not %i' % (inputType)))
3138 outputType = int(request.GET['outputType'])
3342 outputType = int(request.GET['outputType'])
3139 if outputType not in (0,1):
3343 if outputType not in (0,1):
3140 return(HttpResponse('outputType must be 0 or 1, not %i' % (outputType)))
3344 return(HttpResponse('outputType must be 0 or 1, not %i' % (outputType)))
3141 in1Str = request.GET['in1']
3345 in1Str = request.GET['in1']
3142 in1List = [float(item) for item in in1Str.split(',')]
3346 in1List = [float(item) for item in in1Str.split(',')]
3143 in2Str = request.GET['in2']
3347 in2Str = request.GET['in2']
3144 in2List = [float(item) for item in in2Str.split(',')]
3348 in2List = [float(item) for item in in2Str.split(',')]
3145 in3Str = request.GET['in3']
3349 in3Str = request.GET['in3']
3146 in3List = [float(item) for item in in3Str.split(',')]
3350 in3List = [float(item) for item in in3Str.split(',')]
3147 if len(in1List) != len(in2List) or len(in1List) != len(in3List):
3351 if len(in1List) != len(in2List) or len(in1List) != len(in3List):
3148 return(HttpResponse('All three in* lists must have same length'))
3352 return(HttpResponse('All three in* lists must have same length'))
3149 model = int(request.GET['model'])
3353 model = int(request.GET['model'])
3150 if model not in (0,1):
3354 if model not in (0,1):
3151 return(HttpResponse('model must be 0 or 1, not %i' % (model)))
3355 return(HttpResponse('model must be 0 or 1, not %i' % (model)))
3152 qualifier = int(request.GET['qualifier'])
3356 qualifier = int(request.GET['qualifier'])
3153 if qualifier not in (0,1,2,3,4):
3357 if qualifier not in (0,1,2,3,4):
3154 return(HttpResponse('model must be in 0,1,2,3,4 not %i' % (model)))
3358 return(HttpResponse('model must be in 0,1,2,3,4 not %i' % (model)))
3155 try:
3359 try:
3156 stopAlt = float(request.GET['stopAlt'])
3360 stopAlt = float(request.GET['stopAlt'])
3157 except:
3361 except:
3158 stopAlt = 0.0
3362 stopAlt = 0.0
3159
3363
3160 fullText = ''
3364 fullText = ''
3161 resultArr = numpy.zeros((3,), dtype='f8')
3365 resultArr = numpy.zeros((3,), dtype='f8')
3162 madDB = madrigal.metadata.MadrigalDB()
3366 madDB = madrigal.metadata.MadrigalDB()
3163 madDeriveObj = madrigal.derivation.MadrigalDerivationMethods(madDB.getMadroot())
3367 madDeriveObj = madrigal.derivation.MadrigalDerivationMethods(madDB.getMadroot())
3164 for i in range(len(in1List)):
3368 for i in range(len(in1List)):
3165 madDeriveObj.traceMagneticField(year, month, day, hour, minute, second,
3369 madDeriveObj.traceMagneticField(year, month, day, hour, minute, second,
3166 inputType, outputType, in1List[i], in2List[i], in3List[i],
3370 inputType, outputType, in1List[i], in2List[i], in3List[i],
3167 model, qualifier, stopAlt, resultArr)
3371 model, qualifier, stopAlt, resultArr)
3168 fullText += '%f,%f,%f\n' % (resultArr[0], resultArr[1], resultArr[2])
3372 fullText += '%f,%f,%f\n' % (resultArr[0], resultArr[1], resultArr[2])
3169
3373
3170 return render(request, 'madweb/service.html', {'text': fullText})
3374 return render(request, 'madweb/service.html', {'text': fullText})
3171
3375
3172
3376
3173 def global_file_search_service(request):
3377 def global_file_search_service(request):
3174 """global_file_search_service returns a list of full paths to files or citable urls based on search arguments
3378 """global_file_search_service returns a list of full paths to files or citable urls based on search arguments
3175
3379
3176 Inputs:
3380 Inputs:
3177 request/url - contains arguments:
3381 request/url - contains arguments:
3178
3382
3179 startDate: start date in form YYYY-MM-DD to filter experiments before
3383 startDate: start date in form YYYY-MM-DD to filter experiments before
3180 endDate: end date in form YYYY-MM-DD to filter experiments after
3384 endDate: end date in form YYYY-MM-DD to filter experiments after
3181 inst: (optional, multiple allowed) an instrument code or name. For names,
3385 inst: (optional, multiple allowed) an instrument code or name. For names,
3182 fnmatch will be used. If not set, all instruments used.
3386 fnmatch will be used. If not set, all instruments used.
3183 kindat: (optional, multiple allowed) a kind of data codes or name. For names,
3387 kindat: (optional, multiple allowed) a kind of data codes or name. For names,
3184 fnmatch will be used. If not set, all kinds of data used.
3388 fnmatch will be used. If not set, all kinds of data used.
3185 seasonalStartDate: (optional) in form MM/DD, rejects all days earlier in year. If not set
3389 seasonalStartDate: (optional) in form MM/DD, rejects all days earlier in year. If not set
3186 implies 01/01
3390 implies 01/01
3187 seasonalEndDate: (optional) in form MM/DD, rejects all days later in year. If not set
3391 seasonalEndDate: (optional) in form MM/DD, rejects all days later in year. If not set
3188 implies 12/31
3392 implies 12/31
3189 includeNonDefault: (optional) if "True", include realtime files when there are no default.
3393 includeNonDefault: (optional) if "True", include realtime files when there are no default.
3190 If not set, only default files.
3394 If not set, only default files.
3191 expName: (optional) - filter experiments by the experiment name. fnmatch rules
3395 expName: (optional) - filter experiments by the experiment name. fnmatch rules
3192 If not set, no filtering by experiment name.
3396 If not set, no filtering by experiment name.
3193 excludeExpName: (optional) - exclude experiments by the experiment name. fnmatch rules
3397 excludeExpName: (optional) - exclude experiments by the experiment name. fnmatch rules
3194 If not set, no excluding experiments by experiment name.
3398 If not set, no excluding experiments by experiment name.
3195 fileDesc: (optional) filter files using input file Description string via fnmatch.
3399 fileDesc: (optional) filter files using input file Description string via fnmatch.
3196 If not set, in no filtering by file name
3400 If not set, in no filtering by file name
3197 returnCitation: (optional) if True, return a list of file citations. If not set, return
3401 returnCitation: (optional) if True, return a list of file citations. If not set, return
3198 a list of full paths to the files selected
3402 a list of full paths to the files selected
3199
3403
3200 """
3404 """
3201 madDB = madrigal.metadata.MadrigalDB()
3405 madDB = madrigal.metadata.MadrigalDB()
3202 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
3406 madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
3203
3407
3204 # get required arguments
3408 # get required arguments
3205 startDate = request.GET['startDate']
3409 startDate = request.GET['startDate']
3206 endDate = request.GET['endDate']
3410 endDate = request.GET['endDate']
3207 startDate = datetime.datetime.strptime(startDate, '%Y-%m-%d')
3411 startDate = datetime.datetime.strptime(startDate, '%Y-%m-%d')
3208 endDate = datetime.datetime.strptime(endDate, '%Y-%m-%d')
3412 endDate = datetime.datetime.strptime(endDate, '%Y-%m-%d')
3209
3413
3210 # get optional arguments
3414 # get optional arguments
3211 inst = request.GET.getlist('inst')
3415 inst = request.GET.getlist('inst')
3212 if inst == []:
3416 if inst == []:
3213 inst = None
3417 inst = None
3214 kindat = request.GET.getlist('kindat')
3418 kindat = request.GET.getlist('kindat')
3215 if kindat == []:
3419 if kindat == []:
3216 kindat = None
3420 kindat = None
3217 seasonalStartDate = request.GET.get('seasonalStartDate', default = None)
3421 seasonalStartDate = request.GET.get('seasonalStartDate', default = None)
3218 seasonalEndDate = request.GET.get('seasonalEndDate', default = None)
3422 seasonalEndDate = request.GET.get('seasonalEndDate', default = None)
3219 includeNonDefault = bool(request.GET.get('includeNonDefault', default = False))
3423 includeNonDefault = bool(request.GET.get('includeNonDefault', default = False))
3220 expName = request.GET.get('expName', default = None)
3424 expName = request.GET.get('expName', default = None)
3221 excludeExpName = request.GET.get('excludeExpName', default = None)
3425 excludeExpName = request.GET.get('excludeExpName', default = None)
3222 fileDesc = request.GET.get('fileDesc', default = None)
3426 fileDesc = request.GET.get('fileDesc', default = None)
3223 returnCitation = bool(request.GET.get('returnCitation', default = False))
3427 returnCitation = bool(request.GET.get('returnCitation', default = False))
3224
3428
3225 result = madWebObj.global_file_search(startDate, endDate, inst, kindat,
3429 result = madWebObj.global_file_search(startDate, endDate, inst, kindat,
3226 seasonalStartDate, seasonalEndDate,
3430 seasonalStartDate, seasonalEndDate,
3227 includeNonDefault, expName, excludeExpName,
3431 includeNonDefault, expName, excludeExpName,
3228 fileDesc, returnCitation)
3432 fileDesc, returnCitation)
3229
3433
3230 fullText = ''
3434 fullText = ''
3231 for item in result:
3435 for item in result:
3232 fullText += '%s\n' % (item)
3436 fullText += '%s\n' % (item)
3233
3437
3234 return render(request, 'madweb/service.html', {'text': django.utils.safestring.mark_safe(fullText)})
3438 return render(request, 'madweb/service.html', {'text': django.utils.safestring.mark_safe(fullText)})
3235
3439
3236
3440
3237
3441
3238
3442
3239 def get_url_list_from_group_id_service(request):
3443 def get_url_list_from_group_id_service(request):
3240 """get_url_list_from_group_id_service returns a list of citable urls associated with group id.
3444 """get_url_list_from_group_id_service returns a list of citable urls associated with group id.
3241
3445
3242 Inputs:
3446 Inputs:
3243 request/url - contains arguments:
3447 request/url - contains arguments:
3244
3448
3245 id - group id
3449 id - group id
3246
3450
3247 Returns one line for each citable url
3451 Returns one line for each citable url
3248
3452
3249 Returns empty string if experiment id not found. Skips files that are not Hdf5
3453 Returns empty string if experiment id not found. Skips files that are not Hdf5
3250 """
3454 """
3251 id = int(request.GET['id'])
3455 id = int(request.GET['id'])
3252
3456
3253 # create MadrigalDB obj
3457 # create MadrigalDB obj
3254 madDBObj = madrigal.metadata.MadrigalDB()
3458 madDBObj = madrigal.metadata.MadrigalDB()
3255
3459
3256 urlList = madDBObj.getListFromGroupId(id)
3460 urlList = madDBObj.getListFromGroupId(id)
3257
3461
3258 retStr = ''
3462 retStr = ''
3259 for url in urlList:
3463 for url in urlList:
3260 retStr += '%s\n' % (url)
3464 retStr += '%s\n' % (url)
3261
3465
3262 return render(request, 'madweb/service.html', {'text': django.utils.safestring.mark_safe(retStr)})
3466 return render(request, 'madweb/service.html', {'text': django.utils.safestring.mark_safe(retStr)})
3263
3467
3264
3468
3265 def set_group_id_from_url_list_service(request):
3469 def set_group_id_from_url_list_service(request):
3266 """set_group_id_from_url_list sets a list of citable urls to a group id .
3470 """set_group_id_from_url_list sets a list of citable urls to a group id .
3267
3471
3268 Inputs:
3472 Inputs:
3269 request/url - contains arguments:
3473 request/url - contains arguments:
3270
3474
3271 'user_fullname' user name
3475 'user_fullname' user name
3272
3476
3273 'user_email' user email
3477 'user_email' user email
3274
3478
3275 'user_affiliation' user affiliation
3479 'user_affiliation' user affiliation
3276
3480
3277 'url' - citable url. Multiple arguments allowed
3481 'url' - citable url. Multiple arguments allowed
3278
3482
3279 Returns group id (integer) set
3483 Returns group id (integer) set
3280 """
3484 """
3281 madDB = madrigal.metadata.MadrigalDB()
3485 madDB = madrigal.metadata.MadrigalDB()
3282
3486
3283 print(request.GET)
3487 print(request.GET)
3284
3488
3285 # get required arguments
3489 # get required arguments
3286 urls = request.GET.getlist('url')
3490 urls = request.GET.getlist('url')
3287 user_fullname = request.GET['user_fullname']
3491 user_fullname = request.GET['user_fullname']
3288 user_email = request.GET['user_email']
3492 user_email = request.GET['user_email']
3289 user_affiliation = request.GET['user_affiliation']
3493 user_affiliation = request.GET['user_affiliation']
3290
3494
3291 id = madDB.createGroupIdWithList(user_fullname, user_email, user_affiliation, urls)
3495 id = madDB.createGroupIdWithList(user_fullname, user_email, user_affiliation, urls)
3292
3496
3293 return render(request, 'madweb/service.html', {'text': str(id)})
3497 return render(request, 'madweb/service.html', {'text': str(id)})
3294
3498
3295
3499
3296 ### doc pages ###
3500 ### doc pages ###
3297
3501
3298 def docs(request, name):
3502 def docs(request, name):
3299 madDB = madrigal.metadata.MadrigalDB()
3503 madDB = madrigal.metadata.MadrigalDB()
3300 openMadObj = madrigal.openmadrigal.OpenMadrigal(madDB)
3504 openMadObj = madrigal.openmadrigal.OpenMadrigal(madDB)
3301 bg_color = madDB.getBackgroundColor()
3505 bg_color = madDB.getBackgroundColor()
3302 if name.find('..') != -1:
3506 if name.find('..') != -1:
3303 # no trying to look elsewhere
3507 # no trying to look elsewhere
3304 return(HttpResponse('Illegal name passed to docs: <%s>' % (name)))
3508 return(HttpResponse('Illegal name passed to docs: <%s>' % (name)))
3305 # check if siteSpecitic.html
3509 # check if siteSpecitic.html
3306 siteSpecificPath = os.path.join(madDB.getMadroot(), 'source/madpy/djangoMad/madweb/templates/madweb/siteSpecific.html')
3510 siteSpecificPath = os.path.join(madDB.getMadroot(), 'source/madpy/djangoMad/madweb/templates/madweb/siteSpecific.html')
3307 if os.access(siteSpecificPath, os.R_OK):
3511 if os.access(siteSpecificPath, os.R_OK):
3308 siteSpecific = reverse('docs', args=['siteSpecific.html'])
3512 siteSpecific = reverse('docs', args=['siteSpecific.html'])
3309 else:
3513 else:
3310 siteSpecific = '#'
3514 siteSpecific = '#'
3311 openmadrigal = openMadObj.getOpenMadrigalUrl()
3515 openmadrigal = openMadObj.getOpenMadrigalUrl()
3312 # since google insists filenames are case insensitive, convert to right name if there is no direct match if possible
3516 # since google insists filenames are case insensitive, convert to right name if there is no direct match if possible
3313 this_file = os.path.join(madDB.getMadroot(), 'source/madpy/djangoMad/madweb/templates/madweb', name)
3517 this_file = os.path.join(madDB.getMadroot(), 'source/madpy/djangoMad/madweb/templates/madweb', name)
3314 if not os.access(this_file, os.R_OK):
3518 if not os.access(this_file, os.R_OK):
3315 found = False
3519 found = False
3316 existing_files = glob.glob(os.path.join(madDB.getMadroot(), 'source/madpy/djangoMad/madweb/templates/madweb/*.html'))
3520 existing_files = glob.glob(os.path.join(madDB.getMadroot(), 'source/madpy/djangoMad/madweb/templates/madweb/*.html'))
3317 for existing_file in existing_files:
3521 for existing_file in existing_files:
3318 if name.lower() == os.path.basename(existing_file).lower():
3522 if name.lower() == os.path.basename(existing_file).lower():
3319 name = os.path.basename(existing_file)
3523 name = os.path.basename(existing_file)
3320 found = True
3524 found = True
3321 break # correct name found and name modified
3525 break # correct name found and name modified
3322 if not found:
3526 if not found:
3323 return(HttpResponse('<p>Cannot find %s</p>' % (str(name))))
3527 return(HttpResponse('<p>Cannot find %s</p>' % (str(name))))
3324
3528
3325 if os.path.isdir(this_file):
3529 if os.path.isdir(this_file):
3326 return(HttpResponse('<p>%s is a directory</p>' % (str(name))))
3530 return(HttpResponse('<p>%s is a directory</p>' % (str(name))))
3327
3531
3328 return render(request, 'madweb/%s' % (name), {'bg_color': bg_color, 'siteSpecific': siteSpecific,
3532 return render(request, 'madweb/%s' % (name), {'bg_color': bg_color, 'siteSpecific': siteSpecific,
3329 'openmadrigal': openmadrigal})
3533 'openmadrigal': openmadrigal})
3330
3534
3331 No newline at end of file
3535
@@ -1,118 +1,120
1 {% load bootstrap3 %}
1 {% load bootstrap3 %}
2
2
3 {% comment %}
3 {% comment %}
4 Written by Bill Rideout brideout@haystack.mit.edu
4 Written by Bill Rideout brideout@haystack.mit.edu
5
5
6 Base template for Madrigal single experiment web interface
6 Base template for Madrigal single experiment web interface
7
7
8 $Id: base_single.html 7320 2021-03-04 21:23:07Z brideout $
8 $Id: base_single.html 7320 2021-03-04 21:23:07Z brideout $
9 {% endcomment %}
9 {% endcomment %}
10
10
11 {# Load CSS and JavaScript #}
11 {# Load CSS and JavaScript #}
12 {% bootstrap_css %}
12 {% bootstrap_css %}
13 {% bootstrap_javascript %}
13 {% bootstrap_javascript %}
14 {% load static %}
14 {% load static %}
15
15
16 <link rel="stylesheet" href="{% static "bootstrap_calendar/css/bootstrap_calendar.css" %}" type="text/css" />
16 <link rel="stylesheet" href="{% static "bootstrap_calendar/css/bootstrap_calendar.css" %}" type="text/css" />
17 <script type="text/javascript" src="{% static "bootstrap_calendar/js/bootstrap_calendar.js" %}"></script>
17 <script type="text/javascript" src="{% static "bootstrap_calendar/js/bootstrap_calendar.js" %}"></script>
18
18
19 <!DOCTYPE html>
19 <!DOCTYPE html>
20 <html>
20 <html>
21 <head>
21 <head>
22 <meta charset="UTF-8">
22 <meta charset="UTF-8">
23 <meta name="viewport" content="width=device-width, initial-scale=1.0">
23 <meta name="viewport" content="width=device-width, initial-scale=1.0">
24 <link rel="shortcut icon" type="image/png" href="/static/favicon.ico"/>
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 <title>{% block title %}Madrigal Database{% endblock %}</title>
26 <title>{% block title %}Madrigal Database{% endblock %}</title>
26 <style type="text/css">
27 <style type="text/css">
27 html body {
28 html body {
28 background-color: {{bg_color}};
29 background-color: {{bg_color}};
29 }
30 }
30 .breadcrumb > li + li:before {
31 .breadcrumb > li + li:before {
31 content: none;
32 content: none;
32 }
33 }
33 </style>
34 </style>
34 {% block extra_head %}{% endblock %}
35 {% block extra_head %}{% endblock %}
35 {% block ajax_js %}{% endblock %}
36 {% block ajax_js %}{% endblock %}
36 </head>
37 </head>
37 <body>
38 <body>
38 <div class="loader" style="display:none"></div>
39 <div class="loader" style="display:none"></div>
39 <div class="container-fluid">
40 <div class="container-fluid">
40 {% include "navbar.html" %}
41 {% include "navbar.html" %}
41
42
42 <center><h4>Select single Madrigal experiment</h4></center>
43 <center><h4>Select single Madrigal experiment</h4></center>
43
44
44 <div class="row">
45 <div class="row">
45 <div class="col-sm-12">
46 <div class="col-sm-12">
46 {% bootstrap_messages %}
47 {% bootstrap_messages %}
47 </div>
48 </div>
48 </div>
49 </div>
49
50
50 {% if form.errors %}
51 {% if form.errors %}
51 <div class="row">
52 <div class="row">
52 <div class="col-sm-12">
53 <div class="col-sm-12">
53 <p style="color: red;">
54 <p style="color: red;">
54 Please correct the error{{ form.errors|pluralize }} below.
55 Please correct the error{{ form.errors|pluralize }} below.
55 {{ form.errors }}
56 {{ form.errors }}
56 </p>
57 </p>
57 </div>
58 </div>
58 </div>
59 </div>
59 {% endif %}
60 {% endif %}
60
61
61 <div class="row">
62 <div class="row">
62
63
63 <div class="col-sm-3">
64 <div class="col-sm-3">
64 {% block isGlobal %}{% endblock %}
65 {% block isGlobal %}{% endblock %}
65 {% block categories %}{% endblock %}
66 {% block categories %}{% endblock %}
66 {% block instruments %}{% endblock %}
67 {% block instruments %}{% endblock %}
67 {% block years %}{% endblock %}
68 {% block years %}{% endblock %}
68 {% block months %}{% endblock %}
69 {% block months %}{% endblock %}
69 {% block calendar %}{% endblock %}
70 {% block calendar %}{% endblock %}
70 </div>
71 </div>
71
72
72 <div class="col-sm-9">
73 <div class="col-sm-9">
73 {% block experiment_select %}{% endblock %}
74 {% block experiment_select %}{% endblock %}
74 {% block file_select %}{% endblock %}
75 {% block file_select %}{% endblock %}
75 {% block file_buttons %}{% endblock %}
76 {% block file_buttons %}{% endblock %}
76 {% block file_data %}{% endblock %}
77 {% block file_data %}{% endblock %}
78 {% block file_plot %}{% endblock %}
77 </div>
79 </div>
78
80
79 </div>
81 </div>
80 <p></p>
82 <p></p>
81
83
82 {% comment %}
84 {% comment %}
83
85
84 <div class="row">
86 <div class="row">
85 <div class="col-sm-12">{% block download %}{% endblock %}</div>
87 <div class="col-sm-12">{% block download %}{% endblock %}</div>
86 </div>
88 </div>
87 <p></p>
89 <p></p>
88
90
89 <div class="row">
91 <div class="row">
90 <div class="col-sm-12">{% block information %}{% endblock %}</div>
92 <div class="col-sm-12">{% block information %}{% endblock %}</div>
91 </div>{% endcomment %}
93 </div>{% endcomment %}
92
94
93 <p><hr></p>
95 <p><hr></p>
94
96
95 <footer class="row">
97 <footer class="row">
96 <div class="col-sm-6">
98 <div class="col-sm-6">
97 <p>Madrigal database</p>
99 <p>Madrigal database</p>
98 </div>
100 </div>
99 <div class="col-sm-6" style="text-align:right">
101 <div class="col-sm-6" style="text-align:right">
100 <p>
102 <p>
101 </p>
103 </p>
102 </div>
104 </div>
103 </footer>
105 </footer>
104
106
105 </div> <!-- container-fluid -->
107 </div> <!-- container-fluid -->
106
108
107 <script>
109 <script>
108 $('[data-toggle="tooltip"]').tooltip();
110 $('[data-toggle="tooltip"]').tooltip();
109 $('[data-toggle="tooltip"]').on('show.bs.tooltip', function() {
111 $('[data-toggle="tooltip"]').on('show.bs.tooltip', function() {
110 // Only one tooltip should ever be open at a time
112 // Only one tooltip should ever be open at a time
111 $('.tooltip').not(this).hide();
113 $('.tooltip').not(this).hide();
112 });
114 });
113 $('.my-dropdown').dropdown();
115 $('.my-dropdown').dropdown();
114 $('.my-dropdown').tooltip();
116 $('.my-dropdown').tooltip();
115 </script>
117 </script>
116
118
117 </body>
119 </body>
118 </html> No newline at end of file
120 </html>
@@ -1,130 +1,131
1 {% comment %}
1 {% comment %}
2 Written by Bill Rideout brideout@haystack.mit.edu
2 Written by Bill Rideout brideout@haystack.mit.edu
3
3
4 Generic navbar code shared by all Madrigal pages
4 Generic navbar code shared by all Madrigal pages
5
5
6 $Id: navbar.html 6641 2018-11-06 18:02:21Z brideout $
6 $Id: navbar.html 6641 2018-11-06 18:02:21Z brideout $
7 {% endcomment %}
7 {% endcomment %}
8 <style>
8 <style>
9 /* --- Style --- This CSS for a custom color navbar for Madrigal was generated using url http://work.smarchal.com/twbscolor/css/e74c3cc0392becf0f1ffbbbc0 */
9 /* --- Style --- This CSS for a custom color navbar for Madrigal was generated using url http://work.smarchal.com/twbscolor/css/e74c3cc0392becf0f1ffbbbc0 */
10 .navbar-default {
10 .navbar-default {
11 background-color: #21A7EB;
11 background-color: #21A7EB;
12 border-color: #2182EB;
12 border-color: #2182EB;
13 }
13 }
14 .navbar-default .navbar-brand {
14 .navbar-default .navbar-brand {
15 color: #ecf0f1;
15 color: #ecf0f1;
16 }
16 }
17 .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus {
17 .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus {
18 color: #ffbbbc;
18 color: #ffbbbc;
19 }
19 }
20 .navbar-default .navbar-text {
20 .navbar-default .navbar-text {
21 color: #ecf0f1;
21 color: #ecf0f1;
22 }
22 }
23 .navbar-default .navbar-nav > li > a {
23 .navbar-default .navbar-nav > li > a {
24 color: #ecf0f1;
24 color: #ecf0f1;
25 }
25 }
26 .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus {
26 .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus {
27 color: #ffbbbc;
27 color: #ffbbbc;
28 }
28 }
29 .navbar-default .navbar-nav > li > .dropdown-menu {
29 .navbar-default .navbar-nav > li > .dropdown-menu {
30 background-color: #21A7EB;
30 background-color: #21A7EB;
31 }
31 }
32 .navbar-default .navbar-nav > li > .dropdown-menu > li > a {
32 .navbar-default .navbar-nav > li > .dropdown-menu > li > a {
33 color: #ecf0f1;
33 color: #ecf0f1;
34 }
34 }
35 .navbar-default .navbar-nav > li > .dropdown-menu > li > a:hover,
35 .navbar-default .navbar-nav > li > .dropdown-menu > li > a:hover,
36 .navbar-default .navbar-nav > li > .dropdown-menu > li > a:focus {
36 .navbar-default .navbar-nav > li > .dropdown-menu > li > a:focus {
37 color: #ffbbbc;
37 color: #ffbbbc;
38 background-color: #2182EB;
38 background-color: #2182EB;
39 }
39 }
40 .navbar-default .navbar-nav > li > .dropdown-menu > li > .divider {
40 .navbar-default .navbar-nav > li > .dropdown-menu > li > .divider {
41 background-color: #21A7EB;
41 background-color: #21A7EB;
42 }
42 }
43 .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus {
43 .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus {
44 color: #ffbbbc;
44 color: #ffbbbc;
45 background-color: #2182EB;
45 background-color: #2182EB;
46 }
46 }
47 .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus {
47 .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus {
48 color: #ffbbbc;
48 color: #ffbbbc;
49 background-color: #2182EB;
49 background-color: #2182EB;
50 }
50 }
51 .navbar-default .navbar-toggle {
51 .navbar-default .navbar-toggle {
52 border-color: #2182EB;
52 border-color: #2182EB;
53 }
53 }
54 .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus {
54 .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus {
55 background-color: #2182EB;
55 background-color: #2182EB;
56 }
56 }
57 .navbar-default .navbar-toggle .icon-bar {
57 .navbar-default .navbar-toggle .icon-bar {
58 background-color: #ecf0f1;
58 background-color: #ecf0f1;
59 }
59 }
60 .navbar-default .navbar-collapse,
60 .navbar-default .navbar-collapse,
61 .navbar-default .navbar-form {
61 .navbar-default .navbar-form {
62 border-color: #ecf0f1;
62 border-color: #ecf0f1;
63 }
63 }
64 .navbar-default .navbar-link {
64 .navbar-default .navbar-link {
65 color: #ecf0f1;
65 color: #ecf0f1;
66 }
66 }
67 .navbar-default .navbar-link:hover {
67 .navbar-default .navbar-link:hover {
68 color: #ffbbbc;
68 color: #ffbbbc;
69 }
69 }
70
70
71 @media (max-width: 767px) {
71 @media (max-width: 767px) {
72 .navbar-default .navbar-nav .open .dropdown-menu > li > a {
72 .navbar-default .navbar-nav .open .dropdown-menu > li > a {
73 color: #ecf0f1;
73 color: #ecf0f1;
74 }
74 }
75 .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
75 .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
76 color: #ffbbbc;
76 color: #ffbbbc;
77 }
77 }
78 .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
78 .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
79 color: #ffbbbc;
79 color: #ffbbbc;
80 background-color: #2182EB;
80 background-color: #2182EB;
81 }
81 }
82 }
82 }
83 </style>
83 </style>
84 <nav class="navbar navbar-default" role="navigation">
84 <nav class="navbar navbar-default" role="navigation">
85 <div class="navbar-header">
85 <div class="navbar-header">
86 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#collapse">
86 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#collapse">
87 <span class="sr-only">Toggle navigation</span>
87 <span class="sr-only">Toggle navigation</span>
88 <span class="glyphicon glyphicon-arrow-down"></span>
88 <span class="glyphicon glyphicon-arrow-down"></span>
89 MENU
89 MENU
90 </button>
90 </button>
91 </div>
91 </div>
92 <div class="collapse navbar-collapse" id="collapse">
92 <div class="collapse navbar-collapse" id="collapse">
93 <ul class="nav navbar-nav">
93 <ul class="nav navbar-nav">
94 <li {{ home_active|safe }}><a href="{% url 'index' %}" data-toggle="tooltip" data-original-title="Click here to return to the home page of the {{ site_name }} Madrigal site." data-placement="bottom">{{ site_name }} Home</a></li>
94 <li {{ home_active|safe }}><a href="{% url 'index' %}" data-toggle="tooltip" data-original-title="Click here to return to the home page of the {{ site_name }} Madrigal site." data-placement="bottom">{{ site_name }} Home</a></li>
95 <li class="dropdown"><a href="#" data-toggle="dropdown" class="my-dropdown" title="Use this dropdown menu to access all data anywhere on any Madrigal site. See the tooltips for each choice for more information." data-placement="right">Access data<span class="caret"></span></a>
95 <li class="dropdown"><a href="#" data-toggle="dropdown" class="my-dropdown" title="Use this dropdown menu to access all data anywhere on any Madrigal site. See the tooltips for each choice for more information." data-placement="right">Access data<span class="caret"></span></a>
96 <ul class="dropdown-menu">
96 <ul class="dropdown-menu">
97 <li {{ list_active|safe }}><a href="{% url 'view_list' %}" data-toggle="tooltip" data-original-title="List a range of experiments on any Madrigal site that you can then choose from, and then access its data" data-placement="right">List experiments</a></li>
97 <li {{ list_active|safe }}><a href="{% url 'view_list' %}" data-toggle="tooltip" data-original-title="List a range of experiments on any Madrigal site that you can then choose from, and then access its data" data-placement="right">List experiments</a></li>
98 <li {{ single_active|safe }}><a href="{% url 'view_single' %}" data-toggle="tooltip" data-original-title="Navigate to a single experiment on any Madrigal site, and access that experiment&#39;s data" data-placement="right">Select single experiment</a></li>
98 <li {{ single_active|safe }}><a href="{% url 'view_single' %}" data-toggle="tooltip" data-original-title="Navigate to a single experiment on any Madrigal site, and access that experiment&#39;s data" data-placement="right">Select single experiment</a></li>
99 <li {{ script_active|safe }}><a href="{% url 'choose_script' %}" data-toggle="tooltip" data-original-title="Use this link to create a command that will download data from a range of experiments at once" data-placement="right">Create a command to download multiple exps</a></li>
99 <li {{ script_active|safe }}><a href="{% url 'choose_script' %}" data-toggle="tooltip" data-original-title="Use this link to create a command that will download data from a range of experiments at once" data-placement="right">Create a command to download multiple exps</a></li>
100 <li {{ ftp_active|safe }}><a href="{% url 'ftp' %}" data-toggle="tooltip" data-original-title="Simple ftp-like UI" data-placement="right">FTP-like access</a></li>
100 <li {{ ftp_active|safe }}><a href="{% url 'ftp' %}" data-toggle="tooltip" data-original-title="Simple ftp-like UI" data-placement="right">FTP-like access</a></li>
101 </ul>
101 </ul>
102 </li>
102 </li>
103 <li class="dropdown"><a href="#" data-toggle="dropdown" class="my-dropdown" title="Use this dropdown menu to access all Madrigal metadata. See the tooltips for each choice for more information." data-placement="right">Access metadata<span class="caret"></span></a>
103 <li class="dropdown"><a href="#" data-toggle="dropdown" class="my-dropdown" title="Use this dropdown menu to access all Madrigal metadata. See the tooltips for each choice for more information." data-placement="right">Access metadata<span class="caret"></span></a>
104 <ul class="dropdown-menu">
104 <ul class="dropdown-menu">
105 <li {{ site_active|safe }}><a href="{% url 'site_metadata' %}" data-toggle="tooltip" data-original-title="List all metadata related to individual Madrigal sites." data-placement="right">Madrigal site metadata</a></li>
105 <li {{ site_active|safe }}><a href="{% url 'site_metadata' %}" data-toggle="tooltip" data-original-title="List all metadata related to individual Madrigal sites." data-placement="right">Madrigal site metadata</a></li>
106 <li {{ inst_active|safe }}><a href="{% url 'instrument_metadata' %}" data-toggle="tooltip" data-original-title="List all metadata related to individual Madrigal instruments." data-placement="right">Instrument metadata</a></li>
106 <li {{ inst_active|safe }}><a href="{% url 'instrument_metadata' %}" data-toggle="tooltip" data-original-title="List all metadata related to individual Madrigal instruments." data-placement="right">Instrument metadata</a></li>
107 <li {{ parm_active|safe }}><a href="{% url 'parameter_metadata' %}" data-toggle="tooltip" data-original-title="List all metadata related to individual CEDAR parameters." data-placement="right">CEDAR Parameters</a></li>
107 <li {{ parm_active|safe }}><a href="{% url 'parameter_metadata' %}" data-toggle="tooltip" data-original-title="List all metadata related to individual CEDAR parameters." data-placement="right">CEDAR Parameters</a></li>
108 <li {{ kindat_active|safe }}><a href="{% url 'kindat_metadata' %}" data-toggle="tooltip" data-original-title="List all metadata related to individual Madrigal kind of data file codes (also called kindats). Each Madrigal file has a single kind of data code." data-placement="right">Kind of data metadata</a></li>
108 <li {{ kindat_active|safe }}><a href="{% url 'kindat_metadata' %}" data-toggle="tooltip" data-original-title="List all metadata related to individual Madrigal kind of data file codes (also called kindats). Each Madrigal file has a single kind of data code." data-placement="right">Kind of data metadata</a></li>
109 <li {{ filter_active|safe }}><a href="{% url 'docs' 'filter_desc.html' %}" data-toggle="tooltip" data-original-title="Describe use of filters in Madrigal." data-placement="right">Filter string metadata</a></li>
109 <li {{ filter_active|safe }}><a href="{% url 'docs' 'filter_desc.html' %}" data-toggle="tooltip" data-original-title="Describe use of filters in Madrigal." data-placement="right">Filter string metadata</a></li>
110 </ul>
110 </ul>
111 </li>
111 </li>
112 <li class="dropdown"><a href="#" data-toggle="dropdown" class="my-dropdown" title="Click here to access modeling tools associated with Madrigal." data-placement="right">Run models<span class="caret"></span></a>
112 <li class="dropdown"><a href="#" data-toggle="dropdown" class="my-dropdown" title="Click here to access modeling tools associated with Madrigal." data-placement="right">Run models<span class="caret"></span></a>
113 <ul class="dropdown-menu">
113 <ul class="dropdown-menu">
114 <li {{ madCalculator_active|safe }}><a href="{% url 'madrigal_calculator' %}" data-toggle="tooltip" data-original-title="Calculate any Madrigal parameter for a given time and range of lat, lon, and alt." data-placement="right">Run Madrigal derivation engine</a></li>
114 <li {{ madCalculator_active|safe }}><a href="{% url 'madrigal_calculator' %}" data-toggle="tooltip" data-original-title="Calculate any Madrigal parameter for a given time and range of lat, lon, and alt." data-placement="right">Run Madrigal derivation engine</a></li>
115 <li {{ looker_active|safe }}><a href="{% url 'looker_main' %}" data-toggle="tooltip" data-original-title="Simple Geodetic and Geomagnetic (IGRF) coordinate transformations (aka looker)." data-placement="right">Looker</a></li>
115 <li {{ looker_active|safe }}><a href="{% url 'looker_main' %}" data-toggle="tooltip" data-original-title="Simple Geodetic and Geomagnetic (IGRF) coordinate transformations (aka looker)." data-placement="right">Looker</a></li>
116 <li><a href="http://models.haystack.mit.edu/models/" data-toggle="tooltip" data-original-title="Run ISR empirical models developed from historical ISR data by Shunrong Zhang." data-placement="right">ISR empirical models</a></li>
116 <li><a href="http://models.haystack.mit.edu/models/" data-toggle="tooltip" data-original-title="Run ISR empirical models developed from historical ISR data by Shunrong Zhang." data-placement="right">ISR empirical models</a></li>
117 </ul>
117 </ul>
118 </li>
118 </li>
119 <li {{ doc_active|safe }}><a href="docs/name/madContents.html" data-toggle="tooltip" data-original-title="Click here to see Madrigal documentation on the web interface, using scripts to automate data access, Madrigal administration, and information for Madrigal developers." data-placement="bottom">Documentation</a></li>
119 <li {{ doc_active|safe }}><a href="docs/name/madContents.html" data-toggle="tooltip" data-original-title="Click here to see Madrigal documentation on the web interface, using scripts to automate data access, Madrigal administration, and information for Madrigal developers." data-placement="bottom">Documentation</a></li>
120 <li class="dropdown"><a href="#" data-toggle="dropdown" class="my-dropdown" title="Use this dropdown menu to navigate to another Madrigal site." data-placement="left">Other Madrigal sites<span class="caret"></span></a>
120 <li class="dropdown"><a href="#" data-toggle="dropdown" class="my-dropdown" title="Use this dropdown menu to navigate to another Madrigal site." data-placement="left">Other Madrigal sites<span class="caret"></span></a>
121 <ul class="dropdown-menu">
121 <ul class="dropdown-menu">
122 {% for siteName, siteUrl in site_list %}
122 {% for siteName, siteUrl in site_list %}
123 <li><a href="{{ siteUrl }}" data-toggle="tooltip" data-original-title="Navigate to Madrigal site at {{ siteName }}" data-placement="left">{{ siteName }}</a></li>
123 <li><a href="{{ siteUrl }}" data-toggle="tooltip" data-original-title="Navigate to Madrigal site at {{ siteName }}" data-placement="left">{{ siteName }}</a></li>
124 {% endfor %}
124 {% endfor %}
125 </ul>
125 </ul>
126 </li>
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&#39;s in python, Matlab, and IDL to run Madrigal scripts, and access Madrigal&#39;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&#39;s in python, Matlab, and IDL to run Madrigal scripts, and access Madrigal&#39;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 </ul>
129 </ul>
129 </div>
130 </div>
130 </nav> No newline at end of file
131 </nav>
General Comments 0
You need to be logged in to leave comments. Login now