##// END OF EJS Templates
Reorganize models, smaller docker, others
jespinoza -
r2:ccdf3a6b9025
parent child
Show More
@@ -0,0 +1,110
1 [
2 {
3 "code" : 100,
4 "name" : "HF JRO"
5 },
6 {
7 "code" : 101,
8 "name" : "HF Huancayo"
9 },
10 {
11 "code" : 102,
12 "name" : "HF Ica"
13 },
14 {
15 "code" : 110,
16 "name" : "ISR EW Drifts"
17 },
18 {
19 "code" : 111,
20 "name" : "ISR Faraday"
21 },
22 {
23 "code" : 112,
24 "name" : "ISR Imaging"
25 },
26 {
27 "code" : 120,
28 "name" : "Faraday"
29 },
30 {
31 "code" : 121,
32 "name" : "Faraday Long Pulse"
33 },
34 {
35 "code" : 122,
36 "name" : "Faraday Codded LP"
37 },
38 {
39 "code" : 123,
40 "name" : "Faraday Double Pulse"
41 },
42 {
43 "code" : 124,
44 "name" : "Faraday AC"
45 },
46 {
47 "code" : 125,
48 "name" : "Faraday Differential Phase"
49 },
50 {
51 "code" : 150,
52 "name" : "JASMET 50"
53 },
54 {
55 "code" : 151,
56 "name" : "JASMET 30"
57 },
58 {
59 "code" : 170,
60 "name" : "BLTR Huancayo"
61 },
62 {
63 "code" : 171,
64 "name" : "CIRI Huancayo"
65 },
66 {
67 "code" : 172,
68 "name" : "CLAIRE Huancayo"
69 },
70 {
71 "code" : 180,
72 "name" : "MST"
73 },
74 {
75 "code" : 181,
76 "name" : "ISR"
77 },
78 {
79 "code" : 182,
80 "name" : "EEJ"
81 },
82 {
83 "code" : 190,
84 "name" : "JULIA 150km (Natalia)"
85 },
86 {
87 "code" : 191,
88 "name" : "JULIA SpreadF (Natalia)"
89 },
90 {
91 "code" : 200,
92 "name" : "JULIA 150km"
93 },
94 {
95 "code" : 201,
96 "name" : "JULIA EEJ"
97 },
98 {
99 "code" : 202,
100 "name" : "JULIA SpreadF"
101 },
102 {
103 "code" : 203,
104 "name" : "JULIA Imaging"
105 },
106 {
107 "code" : 203,
108 "name" : "JULIA Bistatic"
109 }
110 ] No newline at end of file
1 NO CONTENT: modified file
NO CONTENT: modified file
@@ -1,55 +1,55
1 version: '2'
1 version: '2'
2
2
3 services:
3 services:
4 web:
4 web:
5 container_name: 'realtime_web'
5 container_name: 'realtime_web'
6 build: .
6 build: .
7 image: realtime
7 image: realtime
8 command: python manage.py runserver 0.0.0.0:8000
8 command: python manage.py runserver 0.0.0.0:8000
9 env_file: .env
9 env_file: .env
10 ports:
10 ports:
11 - "8000:8000"
11 - "8000:8000"
12 links:
12 links:
13 - redis
13 - redis
14 - mongo
14 - mongo
15 volumes:
15 volumes:
16 - './:/app'
16 - './:/app'
17 depends_on:
17 depends_on:
18 - redis
18 - redis
19 - mongo
19 - mongo
20
20
21 zmq_server:
21 zmq_server:
22 container_name: 'zmq_server'
22 container_name: 'zmq_server'
23 image: 'realtime'
23 image: 'realtime'
24 ports:
24 ports:
25 - '127.0.0.1:4444:4444'
25 - '4444:4444'
26 command: 'python -u scripts/server.py'
26 command: 'python -u scripts/server.py'
27 env_file: .env
27 env_file: .env
28 links:
28 links:
29 - redis
29 - redis
30 - mongo
30 - mongo
31 volumes:
31 volumes:
32 - './:/app'
32 - './:/app'
33 depends_on:
33 depends_on:
34 - web
34 - web
35
35
36 redis:
36 redis:
37 container_name: 'redis'
37 container_name: 'redis'
38 image: 'redis:3.2-alpine'
38 image: 'redis:3.2-alpine'
39 ports:
39 ports:
40 - '127.0.0.1:6379:6379'
40 - '127.0.0.1:6379:6379'
41 volumes:
41 volumes:
42 - 'redisdata:/data'
42 - 'redisdata:/data'
43
43
44 mongo:
44 mongo:
45 container_name: 'mongo'
45 container_name: 'mongo'
46 image: 'mongo:3.3'
46 image: 'mongo:3.3'
47 command: '--storageEngine wiredTiger'
47 command: '--storageEngine wiredTiger'
48 ports:
48 ports:
49 - '127.0.0.1:27017:27017'
49 - '127.0.0.1:27017:27017'
50 volumes:
50 volumes:
51 - 'mongodata:/data/db'
51 - 'mongodata:/data/db'
52
52
53 volumes:
53 volumes:
54 redisdata:
54 redisdata:
55 mongodata: No newline at end of file
55 mongodata:
@@ -1,51 +1,52
1 import os
1 import os
2 import json
2 import json
3 import numpy as np
3
4 from datetime import datetime
4 from datetime import datetime
5
5
6 from pymongo import MongoClient
6 from pymongo import MongoClient
7
7
8 from models import Experiment, Data
9
10 from channels.handler import AsgiHandler
8 from channels.handler import AsgiHandler
11 from channels.auth import channel_session_user
9 from channels.auth import channel_session_user
12 from channels import Group
10 from channels import Group
13
11
14 host = os.environ.get('HOST_MONGO', 'localhost')
12 host = os.environ.get('HOST_MONGO', 'localhost')
15 CLIENT = MongoClient('{}:27017'.format(host))
13 CLIENT = MongoClient('{}:27017'.format(host))
16 DB = CLIENT['dbplots']
14 DB = CLIENT['dbplots']
17
15
18 # Connected to websocket.connect
16 # Connected to websocket.connect
19 def ws_connect(message, code, plot):
17 def ws_connect(message, code, plot):
20 # Accept the incoming connection
21 message.reply_channel.send({'accept': True})
18 message.reply_channel.send({'accept': True})
22 # Add them to the chat group
19 pk = message.content['query_string'].split('=')[1]
23 Group('{}_{}'.format(code, plot)).add(message.reply_channel)
20 Group('{}_{}'.format(pk, plot)).add(message.reply_channel)
21 print('New connection from: {}, creating Group: {}_{}'.format(message.content['client'][0], pk, plot))
24
22
25 def ws_message(message, code, plot):
23 def ws_message(message, code, plot):
26 # Accept the incoming connection
24 # Accept the incoming connection
27
25 print 'incoming message'
28 dt = datetime.strptime(str(json.loads(message.content['text'])['date']), '%d/%m/%Y')
26 dt = datetime.strptime(str(json.loads(message.content['text'])['date']), '%d/%m/%Y')
29 e = DB.experiment.find_one({'date': dt})
27 exp = DB.exp_meta.find_one({'code': int(code), 'date': dt})
30 if e:
28 print exp
29 if exp:
31 if plot == 'spc':
30 if plot == 'spc':
32 datas = DB.data.find({'experiment': e['_id']}, ['time', 'data']).sort('time', -1).limit(1)[0]
31 datas = DB.exp_data.find({'expmeta': exp['_id']}, ['time', 'data']).sort('time', -1).limit(1)[0]
33 e['time'] = [datas['time']]
32 exp['time'] = [datas['time']]
34 e['spc'] = datas['data']['spc']
33 exp['spc'] = datas['data']['spc']
35 e['rti'] = datas['data']['rti']
34 exp['rti'] = datas['data']['rti']
36 e['noise'] = datas['data']['noise']
35 exp['noise'] = datas['data']['noise']
37 else:
36 else:
38 datas = DB.data.find({'experiment': e['_id']}, ['time', 'data']).sort('time', 1)
37 datas = DB.exp_data.find({'expmeta': exp['_id']}, ['time', 'data']).sort('time', 1)
38 print 'Counting...'
39 print datas.count()
39 dum = [(d['time'], d['data'][plot]) for d in datas]
40 dum = [(d['time'], d['data'][plot]) for d in datas]
40 e['time'] = [d[0] for d in dum]
41 exp['time'] = [d[0] for d in dum]
41 dum = [d[1] for d in dum]
42 dum = [d[1] for d in dum]
42 e[plot] = map(list, zip(*dum))
43 exp[plot] = map(list, zip(*dum))
43 e.pop('date', None)
44 exp.pop('date', None)
44 e.pop('_id', None)
45 exp.pop('_id', None)
45 message.reply_channel.send({'text': json.dumps(e)})
46 message.reply_channel.send({'text': json.dumps(exp)})
46 else:
47 else:
47 message.reply_channel.send({'text': json.dumps({'interval': 0})})
48 message.reply_channel.send({'text': json.dumps({'interval': 0})})
48
49
49 # Connected to websocket.disconnect
50 # Connected to websocket.disconnect
50 def ws_disconnect(message, code, plot):
51 def ws_disconnect(message, code, plot):
51 Group('{}_{}'.format(code, plot)).discard(message.reply_channel)
52 Group('{}_{}'.format(code, plot)).discard(message.reply_channel)
@@ -1,31 +1,33
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 from __future__ import unicode_literals
2 from __future__ import unicode_literals
3
3
4 from django.db import models
4 from django.db import models
5 from mongoengine import *
5 from mongoengine import *
6
6
7 class Experiment(Document):
7 class Experiment(Document):
8 code = IntField(unique=True)
9 name = StringField(max_length=40)
10
11 class ExpMeta(Document):
8 code = IntField()
12 code = IntField()
9 name = StringField(max_length=40, default='Experiment')
10 date = DateTimeField()
13 date = DateTimeField()
11 pairs = ListField(default=list)
14 pairs = ListField(default=list)
12 yrange = ListField(FloatField())
15 yrange = ListField(FloatField())
13 xrange = ListField(FloatField())
16 xrange = ListField(FloatField())
14 interval = FloatField()
17 interval = FloatField()
18 plots = ListField(StringField())
15 localtime = BooleanField()
19 localtime = BooleanField()
16
20
17 meta = {
21 meta = {
18 'indexes': [[("code", 1), ("date", 1)]]
22 'indexes': [[("code", 1), ("date", 1)]]
19 }
23 }
20
24
21 class Data(Document):
25 class ExpData(Document):
22 experiment = LazyReferenceField(Experiment)
26 expmeta = LazyReferenceField(ExpMeta)
23 time = FloatField()
27 time = FloatField()
24 data = DictField()
28 data = DictField()
25
29
26 meta = {
30 meta = {
27 'indexes': ["experiment", "+time"]
31 'indexes': ["expmeta", "+time"]
28 }
32 }
29
33
30 # connect('dbplots')
31 # Experiment.drop_collection()
@@ -1,454 +1,454
1
1
2
2
3 class PcolorBuffer{
3 class PcolorBuffer{
4 constructor({div, data, key, props}){
4 constructor({div, data, key, props}){
5 this.div = document.getElementById(div);
5 this.div = document.getElementById(div);
6 this.n = 0
6 this.n = 0
7 this.divs = [];
7 this.divs = [];
8 this.wait = false;
8 this.wait = false;
9 this.key = key;
9 this.key = key;
10 this.timer = (props.throttle || 30)*1000;
10 this.timer = (props.throttle || 30)*1000;
11 this.lastRan = Date.now();
11 this.lastRan = Date.now();
12 this.lastFunc = null;
12 this.lastFunc = null;
13 this.zbuffer = [];
13 this.zbuffer = [];
14 this.xbuffer = [];
14 this.xbuffer = [];
15 this.empty = Array(data.yrange.length).fill(null);
15 this.empty = Array(data.yrange.length).fill(null);
16 this.props = props;
16 this.props = props;
17 this.setup(data);
17 this.setup(data);
18 }
18 }
19
19
20 setup(data){
20 setup(data){
21 this.last = data.time.slice(-1);
21 this.last = data.time.slice(-1);
22 if (data.time.length == 1){
22 if (data.time.length == 1){
23 var values = { 'time': data.time, 'data': data[this.key].map(function(x) {return [x]})};
23 var values = { 'time': data.time, 'data': data[this.key].map(function(x) {return [x]})};
24 }else{
24 }else{
25 var values = this.fill_gaps(data.time, data[this.key], data.interval, data[this.key].length);
25 var values = this.fill_gaps(data.time, data[this.key], data.interval, data[this.key].length);
26 }
26 }
27
27
28 var t = values.time.map(function(x) { return new Date(x*1000); });
28 var t = values.time.map(function(x) { return new Date(x*1000); });
29
29
30 for (var i = 0; i < data[this.key].length; i++){
30 for (var i = 0; i < data[this.key].length; i++){
31 var layout = {
31 var layout = {
32 xaxis: {
32 xaxis: {
33 title: 'Time',
33 title: 'Time',
34 showgrid: false,
34 showgrid: false,
35 },
35 },
36 yaxis: {
36 yaxis: {
37 title: 'km',
37 title: 'km',
38 showgrid: false,
38 showgrid: false,
39 },
39 },
40 titlefont: {
40 titlefont: {
41 size: 14,
41 size: 14,
42 }
42 }
43 };
43 };
44 var iDiv = document.createElement('div');
44 var iDiv = document.createElement('div');
45 iDiv.id = 'plot-' + i;
45 iDiv.id = 'plot-' + i;
46 this.zbuffer.push([]);
46 this.zbuffer.push([]);
47 this.n = this.n + 1;
47 this.n = this.n + 1;
48 this.div.appendChild(iDiv);
48 this.div.appendChild(iDiv);
49 this.divs.push(iDiv.id);
49 this.divs.push(iDiv.id);
50 var trace = {
50 var trace = {
51 z: values.data[i],
51 z: values.data[i],
52 x: t,
52 x: t,
53 y: data.yrange,
53 y: data.yrange,
54 colorscale: this.props.colormap || 'Viridis',
54 colorscale: this.props.colormap || 'Viridis',
55 transpose: true,
55 transpose: true,
56 type: 'heatmap'
56 type: 'heatmap'
57 };
57 };
58
58
59 if (this.props.zmin) {trace.zmin = this.props.zmin}
59 if (this.props.zmin) {trace.zmin = this.props.zmin}
60 if (this.props.zmax) {trace.zmax = this.props.zmax}
60 if (this.props.zmax) {trace.zmax = this.props.zmax}
61
61
62 layout.title = 'Channel ' + i + ' - ' + t.slice(-1).toLocaleString();
62 layout.title = 'Channel ' + i + ' - ' + t.slice(-1).toLocaleString();
63 var conf = {
63 var conf = {
64 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
64 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
65 displaylogo: false,
65 displaylogo: false,
66 showTips: true
66 showTips: true
67 };
67 };
68 Plotly.newPlot('plot-'+i, [trace], layout, conf);
68 Plotly.newPlot('plot-'+i, [trace], layout, conf);
69 }
69 }
70 }
70 }
71
71
72 getSize(){
72 getSize(){
73 var div = document.getElementById(this.divs[0]);
73 var div = document.getElementById(this.divs[0]);
74 var t = this.xbuffer.slice(-1)[0];
74 var t = this.xbuffer.slice(-1)[0];
75 var n = 0;
75 var n = 0;
76 var timespan = (this.props.timespan || 8)*1000*60*60;
76 var timespan = (this.props.timespan || 8)*1000*60*60;
77
77
78 while ((t-div.data[0].x[n]) > timespan){
78 while ((t-div.data[0].x[n]) > timespan){
79 n += 1;
79 n += 1;
80 }
80 }
81 return n;
81 return n;
82 }
82 }
83
83
84 fill_gaps(xBuffer, zBuffer, interval, N){
84 fill_gaps(xBuffer, zBuffer, interval, N){
85
85
86 var x = [xBuffer[0]];
86 var x = [xBuffer[0]];
87 var z = [];
87 var z = [];
88 var last;
88 var last;
89
89
90 for (var j = 0; j < N; j++){
90 for (var j = 0; j < N; j++){
91 z.push([zBuffer[j][0]]);
91 z.push([zBuffer[j][0]]);
92 }
92 }
93
93
94 for (var i = 1; i < xBuffer.length; i++){
94 for (var i = 1; i < xBuffer.length; i++){
95 var cnt = 0;
95 var cnt = 0;
96 last = x.slice(-1)[0];
96 last = x.slice(-1)[0];
97 while (Math.abs(parseFloat(xBuffer[i])-last-parseFloat(interval))>0.5){
97 while (Math.abs(parseFloat(xBuffer[i])-last-parseFloat(interval))>0.5){
98 cnt += 1;
98 cnt += 1;
99 last = last+interval;
99 last = last+interval;
100 x.push(last);
100 x.push(last);
101 for (var j = 0; j < N; j++){
101 for (var j = 0; j < N; j++){
102 z[j].push(this.empty);
102 z[j].push(this.empty);
103 }
103 }
104 // Avoid infinite loop
104 // Avoid infinite loop
105 if (cnt==100){break;}
105 if (cnt==100){break;}
106 }
106 }
107 x.push(xBuffer[i]);
107 x.push(xBuffer[i]);
108 for (var j = 0; j < N; j++){
108 for (var j = 0; j < N; j++){
109 z[j].push(zBuffer[j][i]);
109 z[j].push(zBuffer[j][i]);
110 }
110 }
111 }
111 }
112
112
113 return {'time':x, 'data':z};
113 return {'time':x, 'data':z};
114 }
114 }
115
115
116 plot(){
116 plot(){
117 // add new data to plots and empty buffers
117 // add new data to plots and empty buffers
118 var N = this.getSize();
118 var N = this.getSize();
119 console.log('Plotting...');
119 console.log('Plotting...');
120 for (var i = 0; i < this.n; i++){
120 for (var i = 0; i < this.n; i++){
121 var div = document.getElementById(this.divs[i]);
121 var div = document.getElementById(this.divs[i]);
122 if (N > 0){
122 if (N > 0){
123 div.data[0].z = div.data[0].z.slice(N,)
123 div.data[0].z = div.data[0].z.slice(N,)
124 div.data[0].x = div.data[0].x.slice(N,)
124 div.data[0].x = div.data[0].x.slice(N,)
125 }
125 }
126 Plotly.extendTraces(div, {
126 Plotly.extendTraces(div, {
127 z: [this.zbuffer[i]],
127 z: [this.zbuffer[i]],
128 x: [this.xbuffer]
128 x: [this.xbuffer]
129 }, [0]);
129 }, [0]);
130 this.zbuffer[i] = [];
130 this.zbuffer[i] = [];
131 }
131 }
132 this.xbuffer = [];
132 this.xbuffer = [];
133 }
133 }
134
134
135 update(obj){
135 update(obj){
136
136
137 // fill data gaps
137 // fill data gaps
138 var cnt = 0;
138 var cnt = 0;
139 while (Math.abs(parseFloat(obj.time[0])-this.last-parseFloat(obj.interval))>0.5){
139 while (Math.abs(parseFloat(obj.time[0])-this.last-parseFloat(obj.interval))>0.5){
140 cnt += 1;
140 cnt += 1;
141 this.last += obj.interval;
141 this.last += obj.interval;
142 var newt = new Date((this.last)*1000);
142 var newt = new Date((this.last)*1000);
143 this.xbuffer.push(newt);
143 this.xbuffer.push(newt);
144 for (var i = 0; i < obj[this.key].length; i++){
144 for (var i = 0; i < obj[this.key].length; i++){
145 this.zbuffer[i].push(this.empty);
145 this.zbuffer[i].push(this.empty);
146 }
146 }
147 // Avoid infinite loop
147 // Avoid infinite loop
148 if (cnt==100){break;}
148 if (cnt==100){break;}
149 }
149 }
150
150
151 // update buffers
151 // update buffers
152 this.last = parseFloat(obj.time[0]);
152 this.last = parseFloat(obj.time[0]);
153 var t = new Date(obj.time[0]*1000);
153 var t = new Date(obj.time[0]*1000);
154 this.xbuffer.push(t);
154 this.xbuffer.push(t);
155 for (var i = 0; i < obj[this.key].length; i++){
155 for (var i = 0; i < obj[this.key].length; i++){
156 this.zbuffer[i].push(obj[this.key][i]);
156 this.zbuffer[i].push(obj[this.key][i]);
157 // update title
157 // update title
158 var div = document.getElementById(this.divs[i]);
158 var div = document.getElementById(this.divs[i]);
159 Plotly.relayout(div, {
159 Plotly.relayout(div, {
160 title: 'Channel ' + i + ' - ' + t.toLocaleString(),
160 title: 'Channel ' + i + ' - ' + t.toLocaleString(),
161 });
161 });
162 }
162 }
163
163
164 // plot when ready (every 10 secs)
164 // plot when ready (every 10 secs)
165 if (!this.wait){
165 if (!this.wait){
166 this.plot();
166 this.plot();
167 this.wait = true;
167 this.wait = true;
168 } else {
168 } else {
169 clearTimeout(this.lastFunc)
169 clearTimeout(this.lastFunc)
170 this.lastFunc = setTimeout(function(scope) {
170 this.lastFunc = setTimeout(function(scope) {
171 if ((Date.now() - scope.lastRan) >= scope.timer) {
171 if ((Date.now() - scope.lastRan) >= scope.timer) {
172 scope.plot()
172 scope.plot()
173 scope.lastRan = Date.now()
173 scope.lastRan = Date.now()
174 }
174 }
175 }, this.timer - (Date.now() - this.lastRan), this)
175 }, this.timer - (Date.now() - this.lastRan), this)
176 }
176 }
177 }
177 }
178 }
178 }
179
179
180 class Pcolor{
180 class Pcolor{
181 constructor({div, data, props}){
181 constructor({div, data, props}){
182 this.div = document.getElementById(div);
182 this.div = document.getElementById(div);
183 this.n = 0
183 this.n = 0
184 this.divs = [];
184 this.divs = [];
185 this.props = props;
185 this.props = props;
186 this.setup(data);
186 this.setup(data);
187 }
187 }
188
188
189 setup(data){
189 setup(data){
190 console.log(data);
190 console.log(data);
191 for (var i = 0; i < data.spc.length; i++){
191 for (var i = 0; i < data.spc.length; i++){
192 var layout = {
192 var layout = {
193 height: 400,
193 height: 400,
194 xaxis: {
194 xaxis: {
195 title: 'Velocity',
195 title: 'Velocity',
196 showgrid: false,
196 showgrid: false,
197 zeroline: false,
197 zeroline: false,
198 domain: [0, 0.7],
198 domain: [0, 0.7],
199 },
199 },
200 yaxis: {
200 yaxis: {
201 title: 'km',
201 title: 'km',
202 showgrid: false,
202 showgrid: false,
203 },
203 },
204 xaxis2: {
204 xaxis2: {
205 title: 'dB',
205 title: 'dB',
206 domain: [0.75, 1],
206 domain: [0.75, 1],
207 ticks: 'outside',
207 ticks: 'outside',
208 },
208 },
209 titlefont: {
209 titlefont: {
210 size: 14,
210 size: 14,
211 }
211 }
212 };
212 };
213 var iDiv = document.createElement('div');
213 var iDiv = document.createElement('div');
214 iDiv.id = 'plot-' + i;
214 iDiv.id = 'plot-' + i;
215 iDiv.className += iDiv.className ? ' col-md-6' : 'col-md-6';
215 iDiv.className += iDiv.className ? ' col-md-6' : 'col-md-6';
216 this.n = this.n + 1;
216 this.n = this.n + 1;
217 this.div.appendChild(iDiv);
217 this.div.appendChild(iDiv);
218 this.divs.push(iDiv.id);
218 this.divs.push(iDiv.id);
219
219
220 var trace1 = {
220 var trace1 = {
221 z: data.spc[i],
221 z: data.spc[i],
222 x: data.xrange,
222 x: data.xrange,
223 y: data.yrange,
223 y: data.yrange,
224 colorscale: this.props.colormap || 'Viridis',
224 colorscale: this.props.colormap || 'Viridis',
225 transpose: true,
225 transpose: true,
226 type: 'heatmap'
226 type: 'heatmap'
227 };
227 };
228
228
229 var trace2 = {
229 var trace2 = {
230 x: data.rti[i],
230 x: data.rti[i],
231 y: data.yrange,
231 y: data.yrange,
232 xaxis: 'x2',
232 xaxis: 'x2',
233 yaxis: 'y',
233 yaxis: 'y',
234 type: 'scatter',
234 type: 'scatter',
235 };
235 };
236
236
237 if (this.props.zmin) {
237 if (this.props.zmin) {
238 trace1.zmin = this.props.zmin
238 trace1.zmin = this.props.zmin
239 }
239 }
240 if (this.props.zmax) {
240 if (this.props.zmax) {
241 trace1.zmax = this.props.zmax;
241 trace1.zmax = this.props.zmax;
242 layout.xaxis2.range = [this.props.zmin, this.props.zmax]
242 layout.xaxis2.range = [this.props.zmin, this.props.zmax]
243 }
243 }
244
244
245 var t = new Date(data.time*1000);
245 var t = new Date(data.time*1000);
246 layout.title = 'Channel ' + i + ': ' + data.noise[i]+'dB - ' + t.toLocaleString();
246 layout.title = 'Channel ' + i + ': ' + data.noise[i]+'dB - ' + t.toLocaleString();
247 var conf = {
247 var conf = {
248 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
248 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
249 displaylogo: false,
249 displaylogo: false,
250 showTips: true
250 showTips: true
251 };
251 };
252 Plotly.newPlot('plot-'+i, [trace1, trace2], layout, conf);
252 Plotly.newPlot('plot-'+i, [trace1, trace2], layout, conf);
253 }
253 }
254 }
254 }
255
255
256 plot(obj){
256 plot(obj){
257
257
258 // add new data to plots and empty buffers
258 // add new data to plots and empty buffers
259 console.log('Plotting...');
259 console.log('Plotting...');
260 var t = new Date(obj.time[0]*1000);
260 var t = new Date(obj.time[0]*1000);
261 for (var i = 0; i < this.n; i++){
261 for (var i = 0; i < this.n; i++){
262 var div = document.getElementById(this.divs[i]);
262 var div = document.getElementById(this.divs[i]);
263 Plotly.relayout(div, {
263 Plotly.relayout(div, {
264 title: 'Channel ' + i + ': ' + obj.noise[i]+'dB - ' + t.toLocaleString(),
264 title: 'Channel ' + i + ': ' + obj.noise[i]+'dB - ' + t.toLocaleString(),
265 });
265 });
266 Plotly.restyle(div, {
266 Plotly.restyle(div, {
267 z: [obj.spc[i], null],
267 z: [obj.spc[i], null],
268 x: [obj.xrange, obj.rti[i]]
268 x: [obj.xrange, obj.rti[i]]
269 }, [0, 1]);
269 }, [0, 1]);
270 }
270 }
271 }
271 }
272 }
272 }
273
273
274 class Scatter{
274 class Scatter{
275 constructor({div, data, key, props}){
275 constructor({div, data, key, props}){
276 this.div = document.getElementById(div);
276 this.div = document.getElementById(div);
277 this.n = 0
277 this.n = 0
278 this.key = key;
278 this.key = key;
279 this.wait = false;
279 this.wait = false;
280 this.timer = (props.throttle || 30)*1000;
280 this.timer = (props.throttle || 30)*1000;
281 this.lastRan = Date.now();
281 this.lastRan = Date.now();
282 this.lastFunc = null;
282 this.lastFunc = null;
283 this.ybuffer = [];
283 this.ybuffer = [];
284 this.xbuffer = [];
284 this.xbuffer = [];
285 this.props = props;
285 this.props = props;
286 this.setup(data);
286 this.setup(data);
287 }
287 }
288
288
289 setup(data){
289 setup(data){
290
290
291 var traces = [];
291 var traces = [];
292 this.last = data.time.slice(-1);
292 this.last = data.time.slice(-1);
293 if (data.time.length == 1){
293 if (data.time.length == 1){
294 var values = { 'time': data.time, 'data': data[this.key] };
294 var values = { 'time': data.time, 'data': data[this.key] };
295 }else{
295 }else{
296 var values = this.fill_gaps(data.time, data[this.key], data.interval, data[this.key].length);
296 var values = this.fill_gaps(data.time, data[this.key], data.interval, data[this.key].length);
297 }
297 }
298
298
299 var t = values.time.map(function(x) { return new Date(x*1000); });
299 var t = values.time.map(function(x) { return new Date(x*1000); });
300
300
301 for (var i = 0; i < data[this.key].length; i++){
301 for (var i = 0; i < data[this.key].length; i++){
302
302
303 this.n = this.n + 1;
303 this.n = this.n + 1;
304 this.ybuffer.push([]);
304 this.ybuffer.push([]);
305 var trace = {
305 var trace = {
306 x: t,
306 x: t,
307 y: data[this.key][i],
307 y: data[this.key][i],
308 mode: 'lines',
308 mode: 'lines',
309 type: 'scatter',
309 type: 'scatter',
310 name: 'Channel ' + i
310 name: 'Channel ' + i
311 };
311 };
312
312
313 traces.push(trace);
313 traces.push(trace);
314 }
314 }
315 var title = this.props.title || ''
315 var title = this.props.title || ''
316 var layout = {
316 var layout = {
317 // autosize: false,
317 // autosize: false,
318 // width: 800,
318 // width: 800,
319 // height: 400,
319 // height: 400,
320 title: title + ' - ' + t.slice(-1).toLocaleString(),
320 title: title + ' - ' + t.slice(-1).toLocaleString(),
321 xaxis: {
321 xaxis: {
322 title: 'Time',
322 title: 'Time',
323 linecolor: 'black',
323 linecolor: 'black',
324 },
324 },
325 yaxis: {
325 yaxis: {
326 title: this.props.ylabel || 'dB',
326 title: this.props.ylabel || 'dB',
327 linecolor: 'black',
327 linecolor: 'black',
328 },
328 },
329 titlefont: {
329 titlefont: {
330 size: 14,
330 size: 14,
331 }
331 }
332 };
332 };
333
333
334 if (this.props.ymin) {layout.yaxis.range = [this.props.ymin, this.props.ymax] }
334 if (this.props.ymin) {layout.yaxis.range = [this.props.ymin, this.props.ymax] }
335
335
336 var conf = {
336 var conf = {
337 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
337 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
338 displaylogo: false,
338 displaylogo: false,
339 showTips: true
339 showTips: true
340 };
340 };
341 Plotly.newPlot('plot', traces, layout, conf);
341 Plotly.newPlot('plot', traces, layout, conf);
342 }
342 }
343
343
344 getSize(){
344 getSize(){
345 var t = this.xbuffer.slice(-1)[0];
345 var t = this.xbuffer.slice(-1)[0];
346 var n = 0;
346 var n = 0;
347 var timespan = (this.props.timespan || 12)*1000*60*60;
347 var timespan = (this.props.timespan || 12)*1000*60*60;
348
348
349 while ((t-this.div.data[0].x[n]) > timespan){
349 while ((t-this.div.data[0].x[n]) > timespan){
350 n += 1;
350 n += 1;
351 }
351 }
352 return n;
352 return n;
353 }
353 }
354
354
355 fill_gaps(xBuffer, yBuffer, interval, N){
355 fill_gaps(xBuffer, yBuffer, interval, N){
356
356
357 var x = [xBuffer[0]];
357 var x = [xBuffer[0]];
358 var y = [];
358 var y = [];
359
359
360 for (var j = 0; j < N; j++){
360 for (var j = 0; j < N; j++){
361 y.push([yBuffer[j][0]]);
361 y.push([yBuffer[j][0]]);
362 }
362 }
363
363
364 var last;
364 var last;
365
365
366 for (var i = 1; i < xBuffer.length; i++){
366 for (var i = 1; i < xBuffer.length; i++){
367 var cnt = 0;
367 var cnt = 0;
368 last = x.slice(-1)[0];
368 last = x.slice(-1)[0];
369 while (Math.abs(parseFloat(xBuffer[i])-last-parseFloat(interval))>0.5){
369 while (Math.abs(parseFloat(xBuffer[i])-last-parseFloat(interval))>0.5){
370 cnt += 1;
370 cnt += 1;
371 last = last+interval;
371 last = last+interval;
372 x.push(last);
372 x.push(last);
373 for (var j = 0; j < N; j++){
373 for (var j = 0; j < N; j++){
374 z[j].push(null);
374 y[j].push(null);
375 }
375 }
376 // Avoid infinite loop
376 // Avoid infinite loop
377 if (cnt==100){break;}
377 if (cnt==100){break;}
378 }
378 }
379 x.push(xBuffer[i]);
379 x.push(xBuffer[i]);
380
380
381 for (var j = 0; j < N; j++){
381 for (var j = 0; j < N; j++){
382 y[j].push(yBuffer[j][i]);
382 y[j].push(yBuffer[j][i]);
383 }
383 }
384 }
384 }
385 return {'time':x, 'data':y};
385 return {'time':x, 'data':y};
386 }
386 }
387
387
388 plot(){
388 plot(){
389 // add new data to plots and empty buffers
389 // add new data to plots and empty buffers
390 var xvalues = [];
390 var xvalues = [];
391 var yvalues = [];
391 var yvalues = [];
392 var traces = [];
392 var traces = [];
393 var N = this.getSize();
393 var N = this.getSize();
394 console.log('Plotting...');
394 console.log('Plotting...');
395 for (var i = 0; i < this.n; i++){
395 for (var i = 0; i < this.n; i++){
396 if (N > 0){
396 if (N > 0){
397 this.div.data[i].y = this.div.data[i].y.slice(N,)
397 this.div.data[i].y = this.div.data[i].y.slice(N,)
398 this.div.data[i].x = this.div.data[i].x.slice(N,)
398 this.div.data[i].x = this.div.data[i].x.slice(N,)
399 }
399 }
400 yvalues.push(this.ybuffer[i]);
400 yvalues.push(this.ybuffer[i]);
401 xvalues.push(this.xbuffer);
401 xvalues.push(this.xbuffer);
402 traces.push(i);
402 traces.push(i);
403 this.ybuffer[i] = [];
403 this.ybuffer[i] = [];
404 }
404 }
405 Plotly.extendTraces(this.div, {
405 Plotly.extendTraces(this.div, {
406 y: yvalues,
406 y: yvalues,
407 x: xvalues
407 x: xvalues
408 }, traces);
408 }, traces);
409 this.xbuffer = [];
409 this.xbuffer = [];
410 }
410 }
411
411
412 update(obj){
412 update(obj){
413
413
414 // fill data gaps
414 // fill data gaps
415 var cnt = 0;
415 var cnt = 0;
416 while (Math.abs(parseFloat(obj.time[0])-this.last-parseFloat(obj.interval))>0.5){
416 while (Math.abs(parseFloat(obj.time[0])-this.last-parseFloat(obj.interval))>0.5){
417 cnt += 1;
417 cnt += 1;
418 this.last += obj.interval;
418 this.last += obj.interval;
419 var newt = new Date((this.last)*1000);
419 var newt = new Date((this.last)*1000);
420 this.xbuffer.push(newt);
420 this.xbuffer.push(newt);
421 for (var i = 0; i < this.n; i++){
421 for (var i = 0; i < this.n; i++){
422 this.ybuffer[i].push(null);
422 this.ybuffer[i].push(null);
423 }
423 }
424 // Avoid infinite loop
424 // Avoid infinite loop
425 if (cnt==100){break;}
425 if (cnt==100){break;}
426 }
426 }
427
427
428 // update buffers
428 // update buffers
429 this.last = parseFloat(obj.time[0]);
429 this.last = parseFloat(obj.time[0]);
430 var t = new Date(obj.time[0]*1000);
430 var t = new Date(obj.time[0]*1000);
431 this.xbuffer.push(t);
431 this.xbuffer.push(t);
432 for (var i = 0; i < this.n; i++){
432 for (var i = 0; i < this.n; i++){
433 this.ybuffer[i].push(obj[this.key][i][0]);
433 this.ybuffer[i].push(obj[this.key][i][0]);
434 }
434 }
435 var title = this.props.title || ''
435 var title = this.props.title || ''
436 Plotly.relayout(this.div, {
436 Plotly.relayout(this.div, {
437 title: title + ' - ' + t.toLocaleString(),
437 title: title + ' - ' + t.toLocaleString(),
438 });
438 });
439
439
440 // plot when ready (every 10 secs)
440 // plot when ready (every 10 secs)
441 if (!this.wait){
441 if (!this.wait){
442 this.plot();
442 this.plot();
443 this.wait = true;
443 this.wait = true;
444 } else {
444 } else {
445 clearTimeout(this.lastFunc)
445 clearTimeout(this.lastFunc)
446 this.lastFunc = setTimeout(function(scope) {
446 this.lastFunc = setTimeout(function(scope) {
447 if ((Date.now() - scope.lastRan) >= scope.timer) {
447 if ((Date.now() - scope.lastRan) >= scope.timer) {
448 scope.plot()
448 scope.plot()
449 scope.lastRan = Date.now()
449 scope.lastRan = Date.now()
450 }
450 }
451 }, this.timer - (Date.now() - this.lastRan), this)
451 }, this.timer - (Date.now() - this.lastRan), this)
452 }
452 }
453 }
453 }
454 }
454 }
@@ -1,112 +1,118
1 {% load static %} {% load bootstrap3 %}
1 {% load static %} {% load bootstrap3 %}
2 <!doctype html>
2 <!doctype html>
3 <html lang="en">
3 <html lang="en">
4
4
5 <head>
5 <head>
6 <meta charset="utf-8">
6 <meta charset="utf-8">
7 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
7 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
8 <meta http-equiv="X-UA-Compatible" content="ie=edge">
8 <meta http-equiv="X-UA-Compatible" content="ie=edge">
9 <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
9 <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
10 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
10 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
11 <script src="{% static 'js/jquery.min.js' %}"></script>
11 <script src="{% static 'js/jquery.min.js' %}"></script>
12 <style>
12 <style>
13 /* Paste this css to your style sheet file or under head tag */
13 /* Paste this css to your style sheet file or under head tag */
14
14
15 /* This only works with JavaScript,
15 /* This only works with JavaScript,
16 if it's not present, don't show loader */
16 if it's not present, don't show loader */
17
17
18 .loader {
18 .loader {
19 width: 100%;
19 width: 100%;
20 height: 10px;
20 height: 10px;
21 position: relative;
21 position: relative;
22 z-index: 9999;
22 z-index: 9999;
23 background: url("{% static 'images/loader.gif' %}") center no-repeat #fff;
23 background: url("{% static 'images/loader.gif' %}") center no-repeat #fff;
24 }
24 }
25
25
26 .no-data {
26 .no-data {
27 text-align: center;
27 text-align: center;
28 background-color: #d58512;
28 background-color: #d58512;
29 padding: 8px 16px;
29 padding: 8px 16px;
30 border-radius: 5px;
30 border-radius: 5px;
31 color: #FEFEFE;
31 color: #FEFEFE;
32 font: 20px 'Helvetica';
32 font: 20px 'Helvetica';
33 text-transform: uppercase;
33 text-transform: uppercase;
34 }
34 }
35 </style>
35 </style>
36 <title>Realtime plots at JRO</title>
36 <title>Realtime plots at JRO</title>
37 </head>
37 </head>
38
38
39 <body>
39 <body>
40 <div class="container">
40 <div class="container">
41 <div id="page" class="row" style="min-height:600px">
41 <div id="page" class="row" style="min-height:600px">
42 {% bootstrap_messages %}
42 {% bootstrap_messages %}
43 <div class="page-header">
43 <div class="page-header">
44 <h1>{% block content-title %}Realtime{% endblock %}
44 <h1>{% block content-title %}Realtime{% endblock %}
45 <small>{% block content-suptitle %}Plots{% endblock %}</small>
45 <small>{% block content-suptitle %}Plots{% endblock %}</small>
46 </h1>
46 </h1>
47 </div>
47 </div>
48 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
48 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
49 <div id="sidebar">
49 <div id="sidebar">
50 {% if form.is_multipart %}
50 {% if form.is_multipart %}
51 <form class="form" enctype="multipart/form-data" method="post" action="{{action}}">
51 <form class="form" enctype="multipart/form-data" method="post" action="{{action}}">
52 {% else %}
52 {% else %}
53 <form class="form" method="post" action="{{action}}">
53 <form class="form" method="post" action="{{action}}">
54 {% endif %} {% csrf_token %} {% bootstrap_form form layout='inline' size='medium' %}
54 {% endif %} {% csrf_token %} {% bootstrap_form form layout='inline' size='medium' %}
55 <div style="clear: both;"></div>
55 <div style="clear: both;"></div>
56 <br>
56 <br>
57 <div class="pull-left">
57 <div class="pull-left">
58 <button type="button" id="bt_show" class="btn btn-primary">Show</button>
58 <button type="button" id="bt_show" class="btn btn-primary">Show</button>
59 </div>
59 </div>
60 </form>
60 </form>
61 </div>
61 </div>
62 </div>
62 </div>
63 <div class="col-md-9 col-xs-12" role="main">
63 <div class="col-md-9 col-xs-12" role="main">
64 <div id="loader" class="loader"></div>
64 <div id="loader" class="loader"></div>
65 {% block content %} {% endblock %}
65 {% block content %} {% endblock %}
66 </div>
66 </div>
67 </div>
67 </div>
68 <!--/row-->
68 <!--/row-->
69 </div>
69 </div>
70 <script src="{% static 'js/plotly-latest.min.js' %}"></script>
70 <script src="{% static 'js/plotly-latest.min.js' %}"></script>
71 <script src="{% static 'js/moment.min.js' %}"></script>
71 <script src="{% static 'js/moment.min.js' %}"></script>
72 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
72 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
73 <script src="{% static 'js/jroplots.js' %}"></script>
73 <script src="{% static 'js/jroplots.js' %}"></script>
74 <script type="text/javascript">
74 <script type="text/javascript">
75 $('#id_date').datetimepicker({
75 $('#id_date').datetimepicker({
76 pickTime: false,
76 pickTime: false,
77 format: 'DD/MM/YYYY',
77 format: 'DD/MM/YYYY',
78 });
78 });
79 $("#bt_show").click(function () {
79 $("#bt_show").click(function () {
80 document.location = '/' + $("#id_experiment").val() + '/' + $("#id_plot").val() + '/?date=' + $("#id_date").val();
80 document.location = '/' + $("#id_experiment").val() + '/' + $("#id_plot").val() + '/?date=' + $("#id_date").val();
81 });
81 });
82
82
83 var socket = new WebSocket('ws://' + window.location.host + '/{{code}}/{{plot}}/');
83 {% if date %}
84 $("#loader").css("display", "block");
85 var socket = new WebSocket('ws://' + window.location.host + '/{{code}}/{{plot}}/?' + 'pk={{id}}');
84 socket.onopen = function open() {
86 socket.onopen = function open() {
85 console.log('WebSockets connection created.');
87 console.log('WebSockets connection created.');
86 {% if date %}
88 {% if date %}
87 socket.send('{"date": "{{date}}" }');
89 socket.send('{"date": "{{date}}" }');
88 {% else %}
90 {% else %}
89 socket.send('{"date": "{% now "d/m/Y" %}" }');
91 socket.send('{"date": "{% now "d/m/Y" %}" }');
90 {% endif %}
92 {% endif %}
91 };
93 };
92
94
93 socket.onmessage = function message(event) {
95 socket.onmessage = function message(event) {
94 var data = JSON.parse(event.data);
96 var data = JSON.parse(event.data);
97 console.log(data);
95 if (data.interval == 0) {
98 if (data.interval == 0) {
96 $("#loader").removeClass("loader").addClass("no-data");
99 $("#loader").removeClass("loader").addClass("no-data");
97 $("#loader").html("No data found");
100 $("#loader").html("No data found");
98 } else {
101 } else {
99 var first = plot(data);
102 var first = plot(data);
100 if (first == true) {
103 if (first == true) {
101 $("#loader").css("display", "none");
104 $("#loader").css("display", "none");
102 }
105 }
103 }
106 }
104 }
107 }
105
108
106 if (socket.readyState == WebSocket.OPEN) {
109 if (socket.readyState == WebSocket.OPEN) {
107 socket.onopen();
110 socket.onopen();
108 }
111 }
112 {% else %}
113 $("#loader").css("display", "none");
114 {% endif %}
109 </script> {% block script %}{% endblock script %}
115 </script> {% block script %}{% endblock script %}
110 </body>
116 </body>
111
117
112 </html> No newline at end of file
118 </html>
@@ -1,81 +1,84
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 from __future__ import unicode_literals
2 from __future__ import unicode_literals
3
3
4 import os
4 import os
5 from datetime import datetime
5 from datetime import datetime
6
6
7 from django import forms
7 from django import forms
8 from django.contrib import messages
8 from django.contrib import messages
9 from django.utils.safestring import mark_safe
9 from django.utils.safestring import mark_safe
10 from django.shortcuts import render
10 from django.shortcuts import render
11
11
12 from bootstrap3_datetime.widgets import DateTimePicker
12 from bootstrap3_datetime.widgets import DateTimePicker
13
13
14 from pymongo import MongoClient
14 import mongoengine
15
15
16 host = os.environ.get('HOST_MONGO', 'localhost')
16 from plotter.models import Experiment, ExpMeta
17
17
18 CLIENT = MongoClient('{}:27017'.format(host))
18 host = os.environ.get('HOST_MONGO', 'localhost')
19 DB = CLIENT['dbplots']
19 mongoengine.connect('dbplots', host=host, port=27017)
20
20
21 # Forms
21 # Forms
22 class SearchForm(forms.Form):
22 class SearchForm(forms.Form):
23
23
24 experiment = forms.ChoiceField()
24 experiment = forms.ChoiceField()
25 plot = forms.ChoiceField(
25 plot = forms.ChoiceField(
26 choices = [(0, 'Select Plot'), ('rti', 'RTI'),('spc', 'Spectra'),('noise', 'Noise')]
26 choices = [(0, 'Select Plot'), ('rti', 'RTI'),('spc', 'Spectra'),('noise', 'Noise')]
27 )
27 )
28 date = forms.DateField(
28 date = forms.DateField(
29 widget=DateTimePicker(options={"format": "DD/MM/YYYY"})
29 widget=DateTimePicker(options={"format": "DD/MM/YYYY"})
30 )
30 )
31
31
32 def __init__(self, *args, **kwargs):
32 def __init__(self, *args, **kwargs):
33
33
34 exp_choices = kwargs.pop('exp_choices', [])
34 exp_choices = kwargs.pop('exp_choices', [])
35 super(SearchForm, self).__init__(*args, **kwargs)
35 super(SearchForm, self).__init__(*args, **kwargs)
36 self.fields['experiment'].choices = [(0, 'Select Experiment')] + exp_choices
36 self.fields['experiment'].choices = [(0, 'Select Experiment')] + exp_choices
37
37
38 # Create your views here.
38 # Create your views here.
39 def main(request, code=None, plot=None):
39 def main(request, code=None, plot=None):
40
40
41 initial = {}
41 initial = {}
42 date = request.GET.get('date', datetime.now().strftime('%d/%m/%Y'))
42 date = request.GET.get('date', datetime.now().strftime('%d/%m/%Y'))
43 initial['date'] = date
43 initial['date'] = date
44
44
45 if code is not None:
45 if code is not None:
46 initial['experiment'] = code
46 initial['experiment'] = code
47 if plot is not None:
47 if plot is not None:
48 initial['plot'] = plot
48 initial['plot'] = plot
49
49
50 print 'hola'
50 exps = [(q['code'], q['name']) for q in Experiment.objects.all()]
51 codes = DB.experiment.find().distinct('code')
51
52 print codes
53 exps = [DB.experiment.find_one({'code': c}, ['name']) for c in codes]
54 print exps
55 names = [q['name'] for q in exps]
56 print names
57 form = SearchForm(
52 form = SearchForm(
58 initial = initial,
53 initial = initial,
59 exp_choices = [(e[0], e[1]) for e in zip(codes, names)]
54 exp_choices = [(e[0], e[1]) for e in exps]
60 )
55 )
61
56
57 try:
58 exp = ExpMeta.objects.get(code=int(code), date=datetime.strptime(date, '%d/%m/%Y'))
59 exp_id = exp.id
60 except:
61 exp_id = 0
62
63
62 kwargs = {
64 kwargs = {
63 'code': code,
65 'code': code,
64 'plot': plot,
66 'plot': plot,
65 'date': date,
67 'date': date,
66 'form': form,
68 'form': form,
69 'id': exp_id
67 }
70 }
68
71
69 if code and codes:
72 if code and exps:
70 kwargs['title'] = [t[1] for t in zip(codes, names) if t[0]==int(code)][0]
73 kwargs['title'] = [t[1] for t in exps if t[0]==int(code)][0]
71 else:
74 else:
72 kwargs['title'] = 'JRO'
75 kwargs['title'] = 'JRO'
73
76
74 if plot == 'rti':
77 if plot == 'rti':
75 return render(request, 'rti.html', kwargs)
78 return render(request, 'rti.html', kwargs)
76 elif plot == 'spc':
79 elif plot == 'spc':
77 return render(request, 'spectra.html', kwargs)
80 return render(request, 'spectra.html', kwargs)
78 elif plot == 'noise':
81 elif plot == 'noise':
79 return render(request, 'scatter.html', kwargs)
82 return render(request, 'scatter.html', kwargs)
80 else:
83 else:
81 return render(request, 'base.html', kwargs) No newline at end of file
84 return render(request, 'base.html', kwargs)
1 NO CONTENT: modified file
NO CONTENT: modified file
@@ -1,135 +1,135
1 """
1 """
2 Django settings for realtime project.
2 Django settings for realtime project.
3
3
4 Generated by 'django-admin startproject' using Django 1.11.7.
4 Generated by 'django-admin startproject' using Django 1.11.7.
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.11/topics/settings/
7 https://docs.djangoproject.com/en/1.11/topics/settings/
8
8
9 For the full list of settings and their values, see
9 For the full list of settings and their values, see
10 https://docs.djangoproject.com/en/1.11/ref/settings/
10 https://docs.djangoproject.com/en/1.11/ref/settings/
11 """
11 """
12
12
13 import os
13 import os
14
14
15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17
17
18
18
19 # Quick-start development settings - unsuitable for production
19 # Quick-start development settings - unsuitable for production
20 # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
20 # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
21
21
22 # SECURITY WARNING: keep the secret key used in production secret!
22 # SECURITY WARNING: keep the secret key used in production secret!
23 SECRET_KEY = '(htjox+v27sda)$61vjhuveeh_q$gw5+z^cn71!h2m-!!s!7ra'
23 SECRET_KEY = '(htjox+v27sda)$61vjhuveeh_q$gw5+z^cn71!h2m-!!s!7ra'
24
24
25 # SECURITY WARNING: don't run with debug turned on in production!
25 # SECURITY WARNING: don't run with debug turned on in production!
26 DEBUG = True
26 DEBUG = True
27
27
28 ALLOWED_HOSTS = ['*']
28 ALLOWED_HOSTS = ['*']
29
29
30
30
31 # Application definition
31 # Application definition
32
32
33 INSTALLED_APPS = [
33 INSTALLED_APPS = [
34 'django.contrib.admin',
34 'django.contrib.admin',
35 'django.contrib.auth',
35 'django.contrib.auth',
36 'django.contrib.contenttypes',
36 'django.contrib.contenttypes',
37 'django.contrib.sessions',
37 'django.contrib.sessions',
38 'django.contrib.messages',
38 'django.contrib.messages',
39 'django.contrib.staticfiles',
39 'django.contrib.staticfiles',
40 'bootstrap3',
40 'bootstrap3',
41 'channels',
41 'channels',
42 'plotter',
42 'plotter',
43 ]
43 ]
44
44
45 MIDDLEWARE = [
45 MIDDLEWARE = [
46 'django.middleware.security.SecurityMiddleware',
46 'django.middleware.security.SecurityMiddleware',
47 'django.contrib.sessions.middleware.SessionMiddleware',
47 'django.contrib.sessions.middleware.SessionMiddleware',
48 'django.middleware.common.CommonMiddleware',
48 'django.middleware.common.CommonMiddleware',
49 'django.middleware.csrf.CsrfViewMiddleware',
49 'django.middleware.csrf.CsrfViewMiddleware',
50 'django.contrib.auth.middleware.AuthenticationMiddleware',
50 'django.contrib.auth.middleware.AuthenticationMiddleware',
51 'django.contrib.messages.middleware.MessageMiddleware',
51 'django.contrib.messages.middleware.MessageMiddleware',
52 'django.middleware.clickjacking.XFrameOptionsMiddleware',
52 'django.middleware.clickjacking.XFrameOptionsMiddleware',
53 ]
53 ]
54
54
55 ROOT_URLCONF = 'realtime.urls'
55 ROOT_URLCONF = 'realtime.urls'
56
56
57 TEMPLATES = [
57 TEMPLATES = [
58 {
58 {
59 'BACKEND': 'django.template.backends.django.DjangoTemplates',
59 'BACKEND': 'django.template.backends.django.DjangoTemplates',
60 'DIRS': [],
60 'DIRS': [],
61 'APP_DIRS': True,
61 'APP_DIRS': True,
62 'OPTIONS': {
62 'OPTIONS': {
63 'context_processors': [
63 'context_processors': [
64 'django.template.context_processors.debug',
64 'django.template.context_processors.debug',
65 'django.template.context_processors.request',
65 'django.template.context_processors.request',
66 'django.contrib.auth.context_processors.auth',
66 'django.contrib.auth.context_processors.auth',
67 'django.contrib.messages.context_processors.messages',
67 'django.contrib.messages.context_processors.messages',
68 ],
68 ],
69 },
69 },
70 },
70 },
71 ]
71 ]
72
72
73 WSGI_APPLICATION = 'realtime.wsgi.application'
73 WSGI_APPLICATION = 'realtime.wsgi.application'
74
74
75
75
76 # Database
76 # Database
77 # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
77 # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
78
78
79 DATABASES = {
79 DATABASES = {
80 'default': {
80 'default': {
81 'ENGINE': 'django.db.backends.sqlite3',
81 'ENGINE': 'django.db.backends.sqlite3',
82 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
82 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
83 }
83 }
84 }
84 }
85
85
86
86
87 # Password validation
87 # Password validation
88 # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
88 # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
89
89
90 AUTH_PASSWORD_VALIDATORS = [
90 AUTH_PASSWORD_VALIDATORS = [
91 {
91 {
92 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
92 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
93 },
93 },
94 {
94 {
95 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
95 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
96 },
96 },
97 {
97 {
98 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
98 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
99 },
99 },
100 {
100 {
101 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
101 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
102 },
102 },
103 ]
103 ]
104
104
105
105
106 # Internationalization
106 # Internationalization
107 # https://docs.djangoproject.com/en/1.11/topics/i18n/
107 # https://docs.djangoproject.com/en/1.11/topics/i18n/
108
108
109 LANGUAGE_CODE = 'en-us'
109 LANGUAGE_CODE = 'en-us'
110
110
111 TIME_ZONE = 'UTC'
111 TIME_ZONE = 'UTC'
112
112
113 USE_I18N = True
113 USE_I18N = True
114
114
115 USE_L10N = True
115 USE_L10N = True
116
116
117 USE_TZ = True
117 USE_TZ = True
118
118
119
119
120 # Static files (CSS, JavaScript, Images)
120 # Static files (CSS, JavaScript, Images)
121 # https://docs.djangoproject.com/en/1.11/howto/static-files/
121 # https://docs.djangoproject.com/en/1.11/howto/static-files/
122
122
123 STATIC_URL = '/static/'
123 STATIC_URL = '/static/'
124
124
125 host = os.environ.get('HOST_REDIS', 'localhost')
125 host = os.environ.get('HOST_REDIS', '127.0.0.1')
126
126
127 CHANNEL_LAYERS = {
127 CHANNEL_LAYERS = {
128 "default": {
128 "default": {
129 "BACKEND": "asgi_redis.RedisChannelLayer",
129 "BACKEND": "asgi_redis.RedisChannelLayer",
130 "CONFIG": {
130 "CONFIG": {
131 "hosts": [(host, 6379)],
131 "hosts": [(host, 6379)],
132 },
132 },
133 "ROUTING": "realtime.routing.channel_routing",
133 "ROUTING": "realtime.routing.channel_routing",
134 },
134 },
135 } No newline at end of file
135 }
@@ -1,12 +1,11
1 asgi-redis==1.4.3
1 asgi-redis==1.4.3
2 Django==1.11.7
2 Django==1.11.7
3 django-bootstrap3==9.1.0
3 django-bootstrap3==9.1.0
4 django-bootstrap3-datetimepicker-2==2.5.0
4 django-bootstrap3-datetimepicker-2==2.5.0
5 channels==1.1.8
5 channels==1.1.8
6 mongoengine==0.15.0
6 mongoengine==0.15.0
7 numpy==1.13.3
8 pymongo==3.5.1
7 pymongo==3.5.1
9 pyzmq==16.0.3
8 pyzmq==16.0.3
10 redis==2.10.6
9 redis==2.10.6
11 requests==2.18.4
10 requests==2.18.4
12 simplejson==3.12.0
11 simplejson==3.12.0
@@ -1,94 +1,84
1 import os
1 import os
2 import sys
2 import sys
3 import json
3 import simplejson
4 import simplejson
4 from datetime import datetime
5 from datetime import datetime
5 import zmq
6 import zmq
6 import redis
7 import redis
7 import asgi_redis
8 import asgi_redis
8 import mongoengine
9 import mongoengine
9
10
10 sys.path.append('/app')
11 sys.path.append('/app')
11 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "realtime.settings")
12 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "realtime.settings")
12
13
13 from plotter.models import Experiment, Data
14 from plotter.models import Experiment, ExpMeta, ExpData
14
15
15
16 host_mongo = os.environ.get('HOST_MONGO', 'localhost')
16 host_mongo = os.environ.get('HOST_MONGO', 'localhost')
17 mongoengine.connect('dbplots', host=host_mongo, port=27017)
17 mongoengine.connect('dbplots', host=host_mongo, port=27017)
18
18
19
19
20 host_redis = os.environ.get('HOST_REDIS', 'localhost')
20 host_redis = os.environ.get('HOST_REDIS', 'localhost')
21 channel = asgi_redis.RedisChannelLayer(hosts=[(host_redis, 6379)])
21 channel = asgi_redis.RedisChannelLayer(hosts=[(host_redis, 6379)])
22
22
23 context = zmq.Context()
23 context = zmq.Context()
24 receiver = context.socket(zmq.SUB)
24 receiver = context.socket(zmq.SUB)
25
25
26 receiver.bind("tcp://0.0.0.0:4444")
26 receiver.bind("tcp://0.0.0.0:4444")
27 receiver.setsockopt(zmq.SUBSCRIBE, '')
27 receiver.setsockopt(zmq.SUBSCRIBE, '')
28
28
29 def loaddata():
30 print('Loading Experiments...')
31 for tup in json.load(open('scripts/experiments.json')):
32 print(tup['name'])
33 exp = Experiment.objects(code=tup['code']).modify(
34 upsert=True,
35 new=True,
36 set__code=tup['code'],
37 set__name=tup['name'],
38 )
39 exp.save()
29
40
30
41 def update(buffer):
31 def update_db(buffer):
32 dt = datetime.utcfromtimestamp(buffer['time'])
42 dt = datetime.utcfromtimestamp(buffer['time'])
33 exp = Experiment.objects(code=buffer['exp_code'], date=dt.date()).first()
43 exp = ExpMeta.objects(code=buffer['exp_code'], date=dt.date()).modify(
34 if exp is None:
44 upsert=True,
35 exp = Experiment(
45 new=True,
36 code=buffer['exp_code'],
46 set__code=buffer['exp_code'],
37 date=dt.date(),
47 set__date=dt.date(),
38 yrange = buffer['yrange'],
48 set__yrange = buffer['yrange'],
39 xrange = buffer['xrange'],
49 set__xrange = buffer['xrange'],
40 interval = buffer['interval'],
50 set__interval = buffer['interval'],
41 localtime = buffer['localtime'],
51 set__localtime = buffer['localtime'],
42 name = buffer['name'],
52 set__plots = buffer['data'].keys()
43 )
53 )
44 exp.save()
54 exp.save()
45
55
46 data = Data.objects(experiment=exp, time=buffer['time']).first()
56 data = ExpData.objects(expmeta=exp, time=buffer['time']).modify(
57 upsert=True,
58 new=True,
59 set__expmeta = exp,
60 set__time = buffer['time'],
61 set__data = buffer['data']
62 )
47
63
48 if data is None:
49 data = Data(
50 experiment = exp,
51 time = buffer['time'],
52 data = buffer['data']
53 ).save()
54 new = True
55 else:
56 data.data = buffer['data']
57 data.save()
64 data.save()
58 new = False
59
65
60 return new
66 return exp.id
61 print 'Starting...'
67
68 def main():
69 print('Starting ZMQ server...')
62 while True:
70 while True:
63 buffer = receiver.recv_json()
71 buffer = receiver.recv_json()
64 if 'xrange' not in buffer:
72 code = update(buffer)
65 buffer['xrange'] = []
73 for plot in buffer['data']:
66 if 'name' not in buffer:
67 buffer['name'] = 'Experiment'
68 if update_db(buffer):
69 dum = buffer.copy()
74 dum = buffer.copy()
70 dum['time'] = [buffer['time']]
75 dum['time'] = [buffer['time']]
71 dum['rti'] = buffer['data']['rti']
76 dum[plot] = buffer['data'][plot]
72 # dum['noise'] = buffer['data']['noise']
73 dum.pop('data')
77 dum.pop('data')
74 code = dum.pop('exp_code')
78 dum.pop('exp_code')
75 channel.send_group(u'{}_rti'.format(code), {'text': simplejson.dumps(dum, ignore_nan=True)})
79 channel.send_group(u'{}_{}'.format(code, plot), {'text': simplejson.dumps(dum, ignore_nan=True)})
76 print 'Sending...{} - {} bytes'.format('rti', len(str(dum)))
80 print('Sending...{} - {} bytes'.format(plot, len(str(dum))))
77
78 # dum = buffer.copy()
79 # dum['time'] = [buffer['time']]
80 # dum['rti'] = buffer['data']['rti']
81 # dum['spc'] = buffer['data']['spc']
82 # dum['noise'] = buffer['data']['noise']
83 # dum.pop('data')
84 # code = dum.pop('exp_code')
85 # channel.send_group(u'{}_spc'.format(code), {'text': simplejson.dumps(dum, ignore_nan=True)})
86 # print 'Sending...{} - {} bytes'.format('spc', len(str(dum)))
87
81
88 # dum = buffer.copy()
82 if __name__=='__main__':
89 # dum['time'] = [buffer['time']]
83 loaddata()
90 # dum['noise'] = [[x] for x in buffer['data']['noise']]
84 main() No newline at end of file
91 # dum.pop('data')
92 # code = dum.pop('exp_code')
93 # channel.send_group(u'{}_noise'.format(code), {'text': simplejson.dumps(dum, ignore_nan=True)})
94 # print 'Sending...{} - {} bytes'.format('noise', len(str(dum)))
General Comments 0
You need to be logged in to leave comments. Login now