diff --git a/config.yml b/config.yml index 887545e..88617db 100644 --- a/config.yml +++ b/config.yml @@ -66,7 +66,8 @@ targets: slug: 'mercury' name: 'Mercury' title: 'Mercury (coming soon)' - orbit: 'mercury_orb_all' + orbit: + model: 'mercury_orb_all' models: - slug: 'tao_mercury_sw' started_at: "1990-01-01T01:30:00" @@ -76,62 +77,76 @@ targets: - type: 'planet' slug: 'venus' name: 'Venus' - title: 'Venus (coming soon)' - orbit: 'venus_orb_all' + title: 'Venus' + orbit: + model: 'venus_orb_all' + semimajor: 0.72333199 + semiminor: 0.7233154 models: - slug: 'tao_venus_sw' started_at: "1990-01-01T01:30:00" stopped_at: "2017-02-19T00:00:00" - locked: true + locked: false default: true - type: 'planet' slug: 'earth' name: 'Earth' title: 'Earth (coming soon)' - orbit: 'earth_orb_all' + orbit: + model: 'earth_orb_all' #model: 'tao_earth_sw' locked: true default: true - type: 'planet' slug: 'mars' name: 'Mars' - title: 'Mars (coming soon)' - orbit: 'mars_orb_all' + title: 'Mars' models: - slug: 'tao_mars_sw' started_at: "1990-01-01T01:30:00" stopped_at: "2017-02-19T00:00:00" + orbit: + model: 'mars_orb_all' + semimajor: 1.52366231 + semiminor: 1.51700011 locked: false default: true - type: 'planet' slug: 'jupiter' name: 'Jupiter' title: 'Jupiter' - orbit: 'jupiter_orb_all' models: - slug: 'tao_jup_sw' started_at: "1990-01-01T01:30:00" stopped_at: "2017-02-19T00:00:00" - started_at: "1990-01-01T01:30:00" - stopped_at: "2017-02-19T00:00:00" +# started_at: "1990-01-01T01:30:00" +# stopped_at: "2017-02-19T00:00:00" + orbit: + model: 'jupiter_orb_all' + semimajor: 5.45516759 + semiminor: 4.95155843 locked: false default: true - type: 'planet' slug: 'saturn' name: 'Saturn' - title: 'Saturn (coming soon)' - orbit: 'saturn_orb_all' + title: 'Saturn' + orbit: + model: 'saturn_orb_all' + semimajor: 9.53707032 + semiminor: 9.5230773 models: - slug: 'tao_sat_sw' started_at: "1990-01-01T01:30:00" stopped_at: "2017-02-19T00:00:00" - locked: true + locked: false default: true - type: 'probe' slug: 'rosetta' name: 'Rosetta' title: 'Rosetta (coming soon)' - orbit: 'ros_orb_cruise' + orbit: + model: 'ros_orb_cruise' models: - slug: 'tao_ros_sw' started_at: "1990-01-01T01:30:00" @@ -142,7 +157,8 @@ targets: slug: 'juno' name: 'Juno' title: 'Juno (coming soon)' - orbit: 'juno_cruise_all' + orbit: + model: 'juno_cruise_all' models: - slug: 'tao_juno_sw' started_at: "1990-01-01T01:30:00" @@ -153,7 +169,8 @@ targets: slug: 'tchouri' name: 'Tchouri' title: 'Tchouri (coming soon)' - orbit: 'p67_orb_all' + orbit: + model: 'p67_orb_all' locked: true default: false diff --git a/web/run.py b/web/run.py index 1f14906..4485953 100755 --- a/web/run.py +++ b/web/run.py @@ -281,7 +281,7 @@ def get_orbiter_csv(source): # 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 # http://cdpp.irap.omp.eu/BASE/DATA/TAO/JUPITER/SW/sw_2014.nc.gz model_files = retrieve_data(source, model_slug, started_at, stopped_at) - orbits_files = retrieve_data(source, source_config['orbit'], started_at, stopped_at) + orbits_files = retrieve_data(source, source_config['orbit']['model'], started_at, stopped_at) si = StringIO.StringIO() cw = csv_writer(si) diff --git a/web/static/js/swapp.js b/web/static/js/swapp.js index 43edd06..b5c43ea 100644 --- a/web/static/js/swapp.js +++ b/web/static/js/swapp.js @@ -46,10 +46,11 @@ return this; }; SpaceWeather.prototype.resize = function(){ + var ref$; timeSeries.forEach(function(ts){ return ts.resize(); }); - return typeof orbits != 'undefined' && orbits !== null ? orbits.resize() : void 8; + return (ref$ = this.orbits) != null ? ref$.resize() : void 8; }; SpaceWeather.prototype.init = function(){ var active_sources, res$, k, this$ = this; @@ -60,10 +61,13 @@ } } active_sources = res$; + this.orbits = new Orbits(this.configuration.orbits_container, this.configuration); return active_sources.forEach(function(source){ return this$.loadData(source.slug, '2016-01-01T00:00:00', '2023-01-01T00:00:00').then(function(data){ + console.info("Loaded CSV data for " + source.slug + "."); this$.createTimeSeries(source, data); - return this$.orbits = new Orbits(this$.configuration.sources, data['hci'], this$.configuration.orbits_container, this$.configuration); + console.log("HOOOOOO"); + return this$.orbits.initOrbiter(source.slug, source.config, data['hci']); }, function(data){ return console.error('Failed to load SW data.', data); }); @@ -317,28 +321,24 @@ out$.Orbits = Orbits = (function(){ Orbits.displayName = 'Orbits'; var prototype = Orbits.prototype, constructor = Orbits; - function Orbits(orbiters, data, container, options){ - this.orbiters = orbiters; - this.data = data; + function Orbits(container, options){ this.container = container; this.options = options != null ? options : {}; - console.log("Create orbits"); this.init(); } Orbits.prototype.init = function(){ - var slug, ref$, config; - console.log("Initialize orbits", this.data, this.options); + console.log("Initializing orbits...", this.options); this.margin = { top: 30, right: 20, bottom: 42, left: 60 }; - this.extremum = 1.11 * d3.max(this.data, function(d){ - return Math.max(Math.abs(d.x), Math.abs(d.y)); - }); + this.data = {}; + this.orbiters = {}; + this.extremum = 1; this.xScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); this.yScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); this.xAxis = d3.axisBottom().ticks(10); @@ -361,18 +361,20 @@ this.yAxisTitle.attr('transform', 'rotate(-90)'); this.sun = this.plotWrapper.append("svg:image").attr('xlink:href', this.options.sun.img).attr('width', '32px').attr('height', '32px'); this.sun.append('svg:title').text("Sol"); - for (slug in ref$ = this.orbiters) { - config = ref$[slug]; - this.initOrbiter(slug, config); - } return this.resize(); }; Orbits.prototype.orbitersElements = {}; - Orbits.prototype.initOrbiter = function(slug, config){ + Orbits.prototype.initOrbiter = function(slug, config, data){ var orbit_ellipse, orbiter, orbit_line, orbit_section, this$ = this; + console.log("Initializing target " + slug + "'s orbit...", config, data); if (slug in this.orbitersElements) { throw new Error("Second init of " + slug); } + this.extremum = Math.max(this.extremum, 1.11 * d3.max(data, function(d){ + return Math.max(Math.abs(d.x), Math.abs(d.y)); + })); + this.xScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); + this.yScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); orbit_ellipse = this.plotWrapper.append("svg:ellipse").classed('orbit orbit_ellipse', true); orbiter = this.plotWrapper.append("svg:image").attr('xlink:href', config['img']).attr('width', '32px').attr('height', '32px'); orbit_line = d3.line().x(function(d){ @@ -380,13 +382,16 @@ }).y(function(d){ return this$.yScale(d.y); }); - orbit_section = this.plotWrapper.append('path').datum(this.data).classed('orbit orbit_section', true); + orbit_section = this.plotWrapper.append('path').datum(data).classed('orbit orbit_section', true); + this.orbiters[slug] = config; + this.data[slug] = data; this.orbitersElements[slug] = { orbiter: orbiter, orbit_ellipse: orbit_ellipse, orbit_section: orbit_section, orbit_line: orbit_line }; + this.resize(); return this; }; Orbits.prototype.resize = function(){ @@ -423,16 +428,16 @@ cx = width / 2 - c; cy = height / 2; this.yScale.range([0, height]); - el['orbit_ellipse'].attr('cx', cx).attr('cy', cy).attr('rx', this.xScale(a) - this.xScale(0)).attr('ry', this.yScale(b) - this.yScale(0)).attr('transform', 'rotate(66,' + (cx + c) + ', ' + cy + ')'); + el['orbit_ellipse'].attr('cx', cx).attr('cy', cy).attr('rx', this.xScale(a) - this.xScale(0)).attr('ry', this.yScale(b) - this.yScale(0)); this.yScale.range([height, 0]); - data = this.data; + data = this.data[slug]; el['orbiter'].attr('x', this.xScale(data[data.length - 1].x) - 16); el['orbiter'].attr('y', this.yScale(data[data.length - 1].y) - 16); return this; }; Orbits.prototype.repositionOrbiter = function(slug, datum){ var data, el; - data = this.data; + data = this.data[slug]; datum == null && (datum = data[data.length - 1]); el = this.orbitersElements[slug]; el['orbiter'].attr('x', this.xScale(datum.x) - 16); @@ -443,10 +448,13 @@ return d.t; }).left; Orbits.prototype.moveToDate = function(t){ - var slug, ref$, el, data, i, d0, d1, d, results$ = []; + var slug, ref$, el, data, i, d0, d1, d; + if (!t) { + console.log("Trying to move to an undefined date"); + } for (slug in ref$ = this.orbitersElements) { el = ref$[slug]; - data = this.data; + data = this.data[slug]; i = this.bisectDate(data, t, 1); d0 = data[i - 1]; d1 = data[i]; @@ -454,9 +462,9 @@ continue; } d = t - d0.t > d1.t - t ? d1 : d0; - results$.push(this.repositionOrbiter(slug, d)); + this.repositionOrbiter(slug, d); } - return results$; + return this; }; return Orbits; }()); diff --git a/web/static/js/swapp.ls b/web/static/js/swapp.ls index 483ab3a..2fd54c4 100644 --- a/web/static/js/swapp.ls +++ b/web/static/js/swapp.ls @@ -1,6 +1,9 @@ # Livescript transpiles to javascript, and is easier on the eyes and brain. # http://livescript.net +# To compile it to javascript, and generate `swapp.js` : +# $ lsc --compile swapp.ls + const GOLDEN_RATIO = 2 / (1 + Math.sqrt(5)) ############################################################################### @@ -39,16 +42,19 @@ export class SpaceWeather resize: -> timeSeries.forEach((ts) -> ts.resize()) - orbits?.resize(); + @orbits?.resize(); init: -> active_sources = [ @sources[k] for k of @sources when @sources[k].config.active ] +# @orbits = new Orbits(@configuration.sources, data['hci'], @configuration.orbits_container, @configuration) + @orbits = new Orbits(@configuration.orbits_container, @configuration) active_sources.forEach((source) ~> @loadData(source.slug, '2016-01-01T00:00:00', '2023-01-01T00:00:00').then( (data) ~> + console.info "Loaded CSV data for #{source.slug}." @createTimeSeries(source, data) - # fixme: don't create a new Orbits instance every time - @orbits = new Orbits(@configuration.sources, data['hci'], @configuration.orbits_container, @configuration) + console.log "HOOOOOO" + @orbits.initOrbiter(source.slug, source.config, data['hci']) , (data) ~> console.error('Failed to load SW data.', data) ) @@ -328,12 +334,11 @@ export class Orbits # View of the solar system from above, with orbits segments for selected time # interval, from real data. - (@orbiters, @data, @container, @options = {}) -> - console.log "Create orbits" + (@container, @options = {}) -> @init() init: -> - console.log "Initialize orbits", @data, @options + console.log "Initializing orbits...", @options @margin = { top: 30, @@ -341,11 +346,10 @@ export class Orbits bottom: 42, left: 60 } - - @extremum = 1.11 * d3.max(@data, (d) -> - Math.max(Math.abs(d.x), Math.abs(d.y)) - ) + @data = {} # slug => HCI array + @orbiters = {} # slug => config + @extremum = 1 @xScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) @yScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) @@ -381,15 +385,22 @@ export class Orbits .attr('width', '32px').attr('height', '32px') @sun.append('svg:title').text("Sol") - for slug, config of @orbiters - @initOrbiter(slug, config) +# for slug, config of @orbiters +# @initOrbiter(slug, config) @resize() orbitersElements: {} - initOrbiter: (slug, config) -> + initOrbiter: (slug, config, data) -> + console.log("Initializing target #{slug}'s orbit...", config, data) if slug of @orbitersElements then throw new Error("Second init of #{slug}") + @extremum = Math.max(@extremum, 1.11 * d3.max(data, (d) -> + Math.max(Math.abs(d.x), Math.abs(d.y)) + )) + @xScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) + @yScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) + # The order is important, as it will define the default z-order orbit_ellipse = @plotWrapper.append("svg:ellipse") .classed('orbit orbit_ellipse', true) @@ -402,15 +413,19 @@ export class Orbits .y((d) ~> @yScale(d.y)) orbit_section = @plotWrapper.append('path') - .datum(@data) # fixme + .datum(data) .classed('orbit orbit_section', true) + @orbiters[slug] = config + @data[slug] = data @orbitersElements[slug] = orbiter: orbiter orbit_ellipse: orbit_ellipse orbit_section: orbit_section orbit_line: orbit_line + @resize() + this resize: -> @@ -465,10 +480,10 @@ export class Orbits el['orbit_ellipse'].attr('cx', cx).attr('cy', cy) .attr('rx', @xScale(a) - @xScale(0)) .attr('ry', @yScale(b) - @yScale(0)) - .attr('transform', 'rotate(66,'+(cx+c)+', '+cy+')') +# .attr('transform', 'rotate(66,'+(cx+c)+', '+cy+')') @yScale.range([height, 0]) - data = @data # todo: multiple orbiters + data = @data[slug] el['orbiter'].attr('x', @xScale(data[data.length - 1].x) - 16) el['orbiter'].attr('y', @yScale(data[data.length - 1].y) - 16) @@ -476,24 +491,25 @@ export class Orbits this repositionOrbiter: (slug, datum) -> - data = @data # todo + data = @data[slug] datum ?= data[data.length - 1] el = @orbitersElements[slug] el['orbiter'].attr('x', @xScale(datum.x) - 16) el['orbiter'].attr('y', @yScale(datum.y) - 16) - this bisectDate: d3.bisector((d) -> d.t).left moveToDate: (t) -> + console.log("Trying to move to an undefined date") unless t for slug, el of @orbitersElements - data = @data # todo: multiple orbiters + data = @data[slug] i = @bisectDate(data, t, 1) d0 = data[i - 1] d1 = data[i] continue unless d1 and d0 d = if t - d0.t > d1.t - t then d1 else d0 @repositionOrbiter(slug, d) # fixme + this diff --git a/web/view/home.html.jinja2 b/web/view/home.html.jinja2 index 43b6020..54e901a 100755 --- a/web/view/home.html.jinja2 +++ b/web/view/home.html.jinja2 @@ -165,24 +165,25 @@ var configuration = { img: '{{ static('img/sun_128.png') }}' }, sources : { - jupiter: { - slug: 'jupiter', - name: 'Jupiter', +{% for target in targets if not target.locked%} + {% if not loop.first %},{% endif %} + '{{ target.slug }}': { + slug: '{{ target.slug }}', + name: '{{ target.name }}', active: true, - minDate: '1990-01-01T01:30:00', - maxDate: '2017-02-19T00:00:00', - orbit: { a: 5.45516759, b: 4.95155843 }, - img: '{{ static('img/target/jupiter_128.png') }}' - }, - mars: { - slug: 'mars', - name: 'Mars', - active: true, - minDate: '1990-01-01T01:30:00', - maxDate: '2017-02-19T00:00:00', - orbit: { a: 5.25516759, b: 4.85155843 }, - img: '{{ static('img/target/mars_128.png') }}' + orbit: { a: {{ target.orbit.semimajor }}, b: {{ target.orbit.semiminor }} }, + img: '{{ static('img/target/'~target.slug~'_128.png') }}' } +{% endfor %} +{# jupiter: {#} +{# slug: 'jupiter',#} +{# name: 'Jupiter',#} +{# active: true,#} +{# minDate: '1990-01-01T01:30:00',#} +{# maxDate: '2017-02-19T00:00:00',#} +{# orbit: { a: 5.45516759, b: 4.95155843 },#} +{# img: '{{ static('img/target/jupiter_128.png') }}'#} +{# },#} }, {# todo @Nicolas Define -somehow- error margins of each parameter #} parameters : [ diff --git a/web/view/layout.html.jinja2 b/web/view/layout.html.jinja2 index 0d3640b..0327d64 100755 --- a/web/view/layout.html.jinja2 +++ b/web/view/layout.html.jinja2 @@ -32,7 +32,7 @@
- CDPP / Solar Wind Prediction @ Planets + CDPP / Heliopropa
-- libgit2 0.21.2