Commit f75faf5fc10b7165139fd1787dd8288dad60ecbc

Authored by Goutte
1 parent 01d09323

WIP

CHANGELOG.md
  1 +## TO DO
  2 +
  3 +- Add source name on time series
1 4 - Start/Stop datetime fields
2 5 - Play button to start time dimension
3   -- Download raw data for time interval
  6 +- Download raw data (as CSV) for time interval
4 7 - Same via SAMP
5 8  
6   -- Planets
7   -- Probes
8   - - Rosetta
9   - - Juno
10   -- Comets (the one visited by rosetta)
11   -
12 9 ## 0.0.0
13 10  
14 11 - Initial website skeleton
... ... @@ -18,5 +15,10 @@
18 15 - Density `N` (cm^-3)
19 16 - Angle Planet-Sun-Earth `Delta_angle` (degrees)
20 17 - Magnetism => B Tangential
  18 +- Planets
  19 +- Probes
  20 + - Rosetta
  21 + - Juno
  22 +- Comets (the one visited by rosetta)
21 23 - Orbits axes titles
22 24 - Logo Europlanet
... ...
web/run.py
... ... @@ -10,6 +10,7 @@ import csv
10 10 import json
11 11 import gzip
12 12 import urllib
  13 +import logging
13 14 from pprint import pprint
14 15 from csv import writer as csv_writer
15 16 from yaml import load as yaml_load
... ... @@ -19,9 +20,6 @@ from flask import request
19 20 from jinja2 import Environment, FileSystemLoader
20 21 from netCDF4 import Dataset
21 22  
22   -# from model.Config import Config
23   -# from model.News import NewsCollection, News
24   -
25 23  
26 24 # PATH RELATIVITY #############################################################
27 25  
... ... @@ -43,6 +41,13 @@ with open(get_path('../config.yml'), 'r') as config_file:
43 41 config = yaml_load(config_file.read())
44 42  
45 43  
  44 +# LOGGING #####################################################################
  45 +
  46 +log = logging.getLogger("HelioPropa")
  47 +log.setLevel(logging.INFO)
  48 +log.addHandler(logging.FileHandler(get_path('run.log')))
  49 +
  50 +
46 51 # SETUP FLASK ENGINE ##########################################################
47 52  
48 53 app = Flask(__name__, root_path=THIS_DIRECTORY)
... ... @@ -249,12 +254,11 @@ def analyze_cdf():
249 254 return si.getvalue()
250 255  
251 256  
252   -@app.route("/<orbiter>_data.csv")
253   -def get_orbiter_csv(orbiter):
  257 +@app.route("/<source>/data.csv")
  258 +def get_orbiter_csv(source):
254 259 # http://cdpp1.cesr.fr/BASE/DDService/getDataUrl.php?dataSet=tao_ros_sw&StartTime=2014-02-23T10:00&StopTime=2016-02-24T23:59
255 260 # Process input parameters
256   - if orbiter not in config['models']:
257   - abort(400, "Invalid orbiter '%s'." % orbiter)
  261 + source_config = get_source_config(source)
258 262 date_fmt = "%Y-%m-%dT%H:%M:%S"
259 263 started_at = request.args.get('started_at')
260 264 try:
... ... @@ -267,19 +271,17 @@ def get_orbiter_csv(orbiter):
267 271 except:
268 272 abort(400, "Invalid stopped_at parameter : '%s'." % stopped_at)
269 273  
270   -
271   - source_config = get_source_config(orbiter)
272 274 # todo: iterate on models when there are many
273 275 try:
274 276 model_slug = source_config['models'][0]['slug']
275 277 except:
276   - abort(500, "Invalid model configuration for '%s'." % orbiter)
  278 + abort(500, "Invalid model configuration for '%s'." % source)
277 279  
278 280 # Grab the list of netCDF files from Myriam's API
279 281 # http://cdpp.irap.omp.eu/BASE/DDService/getDataUrl.php?dataSet=jupiter_orb_all&StartTime=2014-02-23T10:00:10&StopTime=2017-02-24T23:59:00
280 282 # http://cdpp.irap.omp.eu/BASE/DATA/TAO/JUPITER/SW/sw_2014.nc.gz
281   - model_files = retrieve_data(orbiter, model_slug, started_at, stopped_at)
282   - orbits_files = retrieve_data(orbiter, source_config['orbit'], started_at, stopped_at)
  283 + model_files = retrieve_data(source, model_slug, started_at, stopped_at)
  284 + orbits_files = retrieve_data(source, source_config['orbit'], started_at, stopped_at)
283 285  
284 286 si = StringIO.StringIO()
285 287 cw = csv_writer(si)
... ...
web/static/js/swapp.js
... ... @@ -6,15 +6,83 @@
6 6 SpaceWeather.displayName = 'SpaceWeather';
7 7 var prototype = SpaceWeather.prototype, constructor = SpaceWeather;
8 8 function SpaceWeather(configuration){
  9 + this.configuration = configuration;
9 10 console.info("Creating Space Weather app...", configuration);
  11 + this.sources = {};
10 12 }
  13 + SpaceWeather.prototype.buildDataUrlForSource = function(source_slug){
  14 + var url;
  15 + url = this.configuration['api']['data_for_interval'];
  16 + url = url.replace('<source>', source_slug);
  17 + return url;
  18 + };
  19 + SpaceWeather.prototype.addSource = function(source){
  20 + this.sources[source.slug] = source;
  21 + return this;
  22 + };
  23 + SpaceWeather.prototype.showAllSources = function(){
  24 + var slug, ref$, source;
  25 + for (slug in ref$ = this.sources) {
  26 + source = ref$[slug];
  27 + source.show();
  28 + }
  29 + return this;
  30 + };
  31 + SpaceWeather.prototype.showSource = function(source){
  32 + source.show();
  33 + return this;
  34 + };
  35 + SpaceWeather.prototype.hideSource = function(source){
  36 + source.hide();
  37 + return this;
  38 + };
  39 + SpaceWeather.prototype.loadData = function(source_slug, started_at, stopped_at){
  40 + var sw, promise;
  41 + sw = this;
  42 + promise = new Promise(function(resolve, reject){
  43 + var url;
  44 + url = sw.buildDataUrlForSource(source_slug);
  45 + return d3.csv(url + ("?started_at=" + started_at + "&stopped_at=" + stopped_at), function(csv){
  46 + var timeFormat, data;
  47 + timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z');
  48 + data = {
  49 + 'hci': []
  50 + };
  51 + configuration['parameters'].forEach(function(parameter){
  52 + return data[parameter['id']] = [];
  53 + });
  54 + csv.forEach(function(d){
  55 + var dtime;
  56 + dtime = timeFormat(d['time']);
  57 + configuration['parameters'].forEach(function(parameter){
  58 + var id;
  59 + id = parameter['id'];
  60 + return data[id].push({
  61 + x: dtime,
  62 + y: parseFloat(d[id])
  63 + });
  64 + });
  65 + if (d['xhci'] && d['yhci']) {
  66 + return data['hci'].push({
  67 + t: dtime,
  68 + x: parseFloat(d['xhci']),
  69 + y: parseFloat(d['yhci'])
  70 + });
  71 + }
  72 + });
  73 + return resolve(data);
  74 + });
  75 + });
  76 + return promise;
  77 + };
11 78 return SpaceWeather;
12 79 }());
13 80 Source = (function(){
14 81 Source.displayName = 'Source';
15 82 var prototype = Source.prototype, constructor = Source;
16   - function Source(slug){
  83 + function Source(slug, config){
17 84 this.slug = slug;
  85 + this.config = config;
18 86 this.time_series = {};
19 87 }
20 88 Source.prototype.addTimeSeries = function(ts){
... ...
web/static/js/swapp.ls
... ... @@ -7,16 +7,60 @@ const GOLDEN_RATIO = 2 / (1 + Math.sqrt(5))
7 7  
8 8 export class SpaceWeather
9 9  
10   - (configuration) ->
  10 + (@configuration) ->
11 11 console.info "Creating Space Weather app...", configuration
  12 + @sources = {}
12 13  
13   - # fixme
  14 + buildDataUrlForSource: (source_slug) ->
  15 + url = @configuration['api']['data_for_interval']
  16 + url = url.replace('<source>', source_slug)
  17 + url
14 18  
  19 + addSource: (source) ->
  20 + @sources[source.slug] = source
  21 + this
  22 +
  23 + showAllSources: ->
  24 + for slug, source of @sources
  25 + source.show()
  26 + this
  27 +
  28 + showSource: (source) ->
  29 + source.show()
  30 + this
  31 +
  32 + hideSource: (source) ->
  33 + source.hide()
  34 + this
  35 +
  36 + loadData: (source_slug, started_at, stopped_at) ->
  37 + sw = this
  38 + promise = new Promise((resolve, reject) ->
  39 + url = sw.buildDataUrlForSource(source_slug)
  40 + d3.csv(url+"?started_at=#{started_at}&stopped_at=#{stopped_at}", (csv) ->
  41 + timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z')
  42 + data = {'hci': []};
  43 + configuration['parameters'].forEach((parameter) ->
  44 + data[parameter['id']] = []
  45 + )
  46 + csv.forEach((d) ->
  47 + dtime = timeFormat(d['time'])
  48 + configuration['parameters'].forEach((parameter) ->
  49 + id = parameter['id']
  50 + data[id].push({x: dtime, y: parseFloat(d[id])})
  51 + )
  52 + if (d['xhci'] && d['yhci'])
  53 + data['hci'].push({t: dtime, x: parseFloat(d['xhci']), y: parseFloat(d['yhci'])});
  54 + )
  55 + resolve(data)
  56 + )
  57 + )
  58 + promise
15 59  
16 60  
17 61  
18 62 class Source
19   - (@slug) ->
  63 + (@slug, @config) ->
20 64 @time_series = {}
21 65  
22 66 addTimeSeries: (ts) ->
... ...
web/view/home.html.jinja2
... ... @@ -157,6 +157,10 @@
157 157 var configuration = {
158 158 time_series_container: '#time_series',
159 159 orbits_container: '#orbits',
  160 + api : {
  161 + 'data_for_interval': "{{ request.url_root }}<source>/data.csv"
  162 + // ?started_at=<started_at>&stopped_at=<stopped_at>
  163 + },
160 164 sources : {
161 165 jupiter: {
162 166 slug: 'jupiter',
... ... @@ -168,30 +172,37 @@ var configuration = {
168 172 img: '{{ static('img/planet/jupiter_128.png') }}'
169 173 }
170 174 },
  175 +{# todo @Nicolas Define -somehow- error margins of each parameter #}
171 176 parameters : [
172 177 {
173 178 id: 'pdyn',
174   - title: "Dynamic Pressure (nPa)"
  179 + title: "Dynamic Pressure (nPa)",
  180 + unit: "nPa"
175 181 },
176 182 {
177 183 id: 'magn',
178   - title: "Magnetism (nT)"
  184 + title: "Magnetism (nT)",
  185 + unit: "nT"
179 186 },
180 187 {
181 188 id: 'vlen',
182   - title: "Velocity (km/s)"
  189 + title: "Velocity (km/s)",
  190 + unit: "km/s"
183 191 },
184 192 {
185 193 id: 'temp',
186   - title: "Temperature (K)"
  194 + title: "Temperature (K)",
  195 + unit: "K"
187 196 },
188 197 {
189 198 id: 'dens',
190   - title: "Density N (cm⁻³)"
  199 + title: "Density N (cm⁻³)",
  200 + unit: "cm⁻³"
191 201 },
192 202 {
193 203 id: 'angl',
194   - title: "Angle S-S-E (deg)"
  204 + title: "Angle S-S-E (deg)",
  205 + unit: "deg"
195 206 }
196 207 ]
197 208 };
... ... @@ -201,10 +212,17 @@ jQuery().ready(function($){
201 212 var orbits;
202 213  
203 214 var sw = new SpaceWeather(configuration);
  215 + sw.loadData('jupiter', '2016-01-01T00:00:00', '2023-01-01T00:00:00').then(
  216 + function (data) { console.log('OK', data); },
  217 + function (data) { console.log('Failed', data); }
  218 + );
204 219  
205   - d3.csv('{{ url_for('get_orbiter_csv', orbiter='jupiter', started_at='2016-03-19T00:00:00', stopped_at='2022-01-01T00:00:00') }}', function(csv){
  220 + d3.csv('{{ url_for('get_orbiter_csv', source='jupiter', started_at='2016-03-19T00:00:00', stopped_at='2022-01-01T00:00:00') }}', function(csv){
206 221 var timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z');
207   - var data = {'pdyn': [], 'magn': [], 'vlen': [], 'temp': [], 'dens': [], 'angl': [], 'hci': []};
  222 + var data = {'hci': []};
  223 + configuration['parameters'].forEach(function(parameter){
  224 + data[parameter['id']] = [];
  225 + });
208 226 csv.forEach(function (d) {
209 227 var dtime = timeFormat(d['time']);
210 228 configuration['parameters'].forEach(function(parameter){
... ... @@ -221,9 +239,7 @@ jQuery().ready(function($){
221 239 configuration['parameters'].forEach(function(parameter){
222 240 var id = parameter['id'];
223 241 var title = parameter['title'];
224   - timeSeries.push(new TimeSeries(
225   - id, title, data[id], container
226   - ));
  242 + timeSeries.push(new TimeSeries(id, title, data[id], container));
227 243 });
228 244 // move outside (after promises)
229 245 timeSeries.forEach(function(ts){
... ...