@@ -1,55 +1,82 | |||||
1 |
version: ' |
|
1 | version: '3' | |
2 |
|
2 | |||
3 | services: |
|
3 | services: | |
4 | web: |
|
4 | web: | |
5 | container_name: 'realtime' |
|
5 | container_name: 'realtime' | |
6 | build: . |
|
6 | build: . | |
7 | restart: always |
|
7 | restart: always | |
8 | image: realtime |
|
8 | image: realtime | |
9 | command: python manage.py runserver 0.0.0.0:8000 |
|
9 | # command: python manage.py runserver 0.0.0.0:8000 | |
|
10 | # command: gunicorn realtime.wsgi:application --bind 0.0.0.0:8080 | |||
|
11 | command: daphne -b 0.0.0.0 -p 8080 realtime.asgi:application | |||
10 | env_file: .env |
|
12 | env_file: .env | |
11 | ports: |
|
13 | # ports: | |
12 |
- "80 |
|
14 | # - "8081:8081" | |
|
15 | # expose: | |||
|
16 | # - 8000 | |||
13 | links: |
|
17 | links: | |
14 | - redis |
|
18 | - redis | |
15 | - mongo |
|
19 | - mongo | |
16 | volumes: |
|
20 | volumes: | |
17 | - './:${APP_DIR}' |
|
21 | - './:${APP_DIR}' | |
|
22 | - './static:/static' | |||
18 | depends_on: |
|
23 | depends_on: | |
19 | - redis |
|
24 | - redis | |
20 | - mongo |
|
25 | - mongo | |
21 |
|
26 | |||
22 | zmq_server: |
|
27 | zmq_server: | |
23 | container_name: 'realtime_zmq' |
|
28 | container_name: 'realtime_zmq' | |
24 | restart: always |
|
29 | restart: always | |
25 | image: 'realtime' |
|
30 | image: 'realtime' | |
26 | ports: |
|
31 | ports: | |
27 | - '4444:4444' |
|
32 | - '4444:4444' | |
28 | command: 'python -u scripts/server.py' |
|
33 | command: 'python -u scripts/server.py' | |
29 | env_file: .env |
|
34 | env_file: .env | |
30 | links: |
|
35 | links: | |
31 | - redis |
|
36 | - redis | |
32 | - mongo |
|
37 | - mongo | |
33 | volumes: |
|
38 | volumes: | |
34 | - './:${APP_DIR}' |
|
39 | - './:${APP_DIR}' | |
35 | depends_on: |
|
40 | depends_on: | |
36 | - web |
|
41 | - web | |
37 |
|
42 | |||
38 | redis: |
|
43 | redis: | |
39 | container_name: 'realtime_redis' |
|
44 | container_name: 'realtime_redis' | |
40 |
image: 'redis: |
|
45 | image: 'redis:5.0-alpine' | |
41 | volumes: |
|
46 | volumes: | |
42 |
- 'redis |
|
47 | - '/data/dockers/realtime/redis:/data' | |
43 |
|
48 | |||
44 | mongo: |
|
49 | mongo: | |
45 | container_name: 'realtime_mongo' |
|
50 | container_name: 'realtime_mongo' | |
46 | image: 'mongo:4.0' |
|
51 | image: 'mongo:4.0' | |
47 | command: '--storageEngine wiredTiger' |
|
52 | command: '--storageEngine wiredTiger' | |
48 | ports: |
|
53 | ports: | |
49 | - '127.0.0.1:27017:27017' |
|
54 | - '127.0.0.1:27017:27017' | |
50 | volumes: |
|
55 | volumes: | |
51 |
- 'mongo |
|
56 | - '/data/dockers/realtime/mongo:/data/db' | |
|
57 | ||||
|
58 | #volumes: | |||
|
59 | # redisdata: | |||
|
60 | # mongodata: | |||
|
61 | ||||
|
62 | nginx: | |||
|
63 | image: nginx:1.15-alpine | |||
|
64 | volumes: | |||
|
65 | - ./static:/static | |||
|
66 | - ./nginx:/etc/nginx/conf.d | |||
|
67 | - ./certbot/conf:/etc/letsencrypt | |||
|
68 | - ./certbot/www:/var/www/certbot | |||
|
69 | ports: | |||
|
70 | - "8000:8000" | |||
|
71 | - "443:443" | |||
|
72 | depends_on: | |||
|
73 | - web | |||
|
74 | command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" | |||
|
75 | ||||
|
76 | certbot: | |||
|
77 | image: certbot/certbot:latest | |||
|
78 | volumes: | |||
|
79 | - ./certbot/conf:/etc/letsencrypt | |||
|
80 | - ./certbot/www:/var/www/certbot | |||
|
81 | entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" | |||
52 |
|
82 | |||
53 | volumes: |
|
|||
54 | redisdata: |
|
|||
55 | mongodata: No newline at end of file |
|
@@ -1,138 +1,138 | |||||
1 | #!/usr/bin/python |
|
1 | #!/usr/bin/python | |
2 | # -*- coding: UTF-8 -*- |
|
2 | # -*- coding: UTF-8 -*- | |
3 | import os |
|
3 | import os | |
4 | import json |
|
4 | import json | |
5 | import simplejson |
|
5 | import simplejson | |
6 | from datetime import datetime, timedelta |
|
6 | from datetime import datetime, timedelta | |
7 | import numpy |
|
7 | import numpy | |
8 | from pymongo import MongoClient |
|
8 | from pymongo import MongoClient | |
9 | # import mongoengine |
|
9 | # import mongoengine | |
10 | from asgiref.sync import async_to_sync |
|
10 | from asgiref.sync import async_to_sync | |
11 | from channels.generic.websocket import WebsocketConsumer |
|
11 | from channels.generic.websocket import WebsocketConsumer | |
12 |
|
12 | |||
13 | # from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData |
|
13 | # from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData | |
14 |
|
14 | |||
15 | # Here we create the db named "dbplots" |
|
15 | # Here we create the db named "dbplots" | |
16 | host = os.environ.get('HOST_MONGO', 'localhost') |
|
16 | host = os.environ.get('HOST_MONGO', 'localhost') | |
17 | # mongoengine.connect('dbplots', host=host, port=27017) |
|
17 | # mongoengine.connect('dbplots', host=host, port=27017) | |
18 |
|
18 | |||
19 | CLIENT = MongoClient('{}:27017'.format(host)) |
|
19 | CLIENT = MongoClient('{}:27017'.format(host)) | |
20 | DB = CLIENT['dbplots'] |
|
20 | DB = CLIENT['dbplots'] | |
21 |
|
21 | |||
22 | class MainConsumer(WebsocketConsumer): |
|
22 | class MainConsumer(WebsocketConsumer): | |
23 |
|
23 | |||
24 | def connect(self): |
|
24 | def connect(self): | |
25 | self.group_name = 'main' |
|
25 | self.group_name = 'main' | |
26 | async_to_sync(self.channel_layer.group_add)( |
|
26 | async_to_sync(self.channel_layer.group_add)( | |
27 | self.group_name, |
|
27 | self.group_name, | |
28 | self.channel_name |
|
28 | self.channel_name | |
29 | ) |
|
29 | ) | |
30 | self.accept() |
|
30 | self.accept() | |
31 |
|
31 | |||
32 | def disconnect(self, close_code): |
|
32 | def disconnect(self, close_code): | |
33 | async_to_sync(self.channel_layer.group_discard)( |
|
33 | async_to_sync(self.channel_layer.group_discard)( | |
34 | self.group_name, |
|
34 | self.group_name, | |
35 | self.channel_name |
|
35 | self.channel_name | |
36 | ) |
|
36 | ) | |
37 |
|
37 | |||
38 | def receive(self, text_data): |
|
38 | def receive(self, text_data): | |
39 | pass |
|
39 | pass | |
40 |
|
40 | |||
41 | def zmq_message(self, event): |
|
41 | def zmq_message(self, event): | |
42 | # Send message to WebSocket |
|
42 | # Send message to WebSocket | |
43 | self.send(text_data=event['message']) |
|
43 | self.send(text_data=event['message']) | |
44 |
|
44 | |||
45 | class PlotConsumer(WebsocketConsumer): |
|
45 | class PlotConsumer(WebsocketConsumer): | |
46 |
|
46 | |||
47 | def connect(self): |
|
47 | def connect(self): | |
48 |
|
48 | |||
49 | if 'realtime' in self.scope['path']: |
|
49 | if 'realtime' in self.scope['path']: | |
50 | self.realtime = True |
|
50 | self.realtime = True | |
51 | self.group_name = '{}_{}'.format( |
|
51 | self.group_name = '{}_{}'.format( | |
52 | self.scope['url_route']['kwargs']['code'], |
|
52 | self.scope['url_route']['kwargs']['code'], | |
53 | self.scope['url_route']['kwargs']['plot'], |
|
53 | self.scope['url_route']['kwargs']['plot'], | |
54 | ) |
|
54 | ) | |
55 |
|
55 | |||
56 | async_to_sync(self.channel_layer.group_add)( |
|
56 | async_to_sync(self.channel_layer.group_add)( | |
57 | self.group_name, |
|
57 | self.group_name, | |
58 | self.channel_name |
|
58 | self.channel_name | |
59 | ) |
|
59 | ) | |
60 | else: |
|
60 | else: | |
61 | self.realtime = False |
|
61 | self.realtime = False | |
62 | self.accept() |
|
62 | self.accept() | |
63 |
|
63 | |||
64 | def disconnect(self, close_code): |
|
64 | def disconnect(self, close_code): | |
65 |
|
65 | |||
66 | if self.realtime: |
|
66 | if self.realtime: | |
67 | async_to_sync(self.channel_layer.group_discard)( |
|
67 | async_to_sync(self.channel_layer.group_discard)( | |
68 | self.group_name, |
|
68 | self.group_name, | |
69 | self.channel_name |
|
69 | self.channel_name | |
70 | ) |
|
70 | ) | |
71 |
|
71 | |||
72 | def receive(self, text_data): |
|
72 | def receive(self, text_data): | |
73 | ret = {} |
|
73 | ret = {} | |
74 | dt = datetime.strptime(text_data, '%d-%m-%Y') |
|
74 | dt = datetime.strptime(text_data, '%d-%m-%Y') | |
75 | code = self.scope['url_route']['kwargs']['code'] |
|
75 | code = self.scope['url_route']['kwargs']['code'] | |
76 | plot = self.scope['url_route']['kwargs']['plot'] |
|
76 | plot = self.scope['url_route']['kwargs']['plot'] | |
77 | exp = DB.experiment.find_one({'code': int(code)}) |
|
77 | exp = DB.experiment.find_one({'code': int(code)}) | |
78 | det0 = DB.exp_detail.find_one({ |
|
78 | det0 = DB.exp_detail.find_one({ | |
79 | 'experiment': exp['_id'], |
|
79 | 'experiment': exp['_id'], | |
80 | 'date': dt-timedelta(days=1) |
|
80 | 'date': dt-timedelta(days=1) | |
81 | }) |
|
81 | }) | |
82 | det1 = DB.exp_detail.find_one({ |
|
82 | det1 = DB.exp_detail.find_one({ | |
83 | 'experiment': exp['_id'], |
|
83 | 'experiment': exp['_id'], | |
84 | 'date': dt |
|
84 | 'date': dt | |
85 | }) |
|
85 | }) | |
86 |
|
86 | |||
87 | if det1: |
|
87 | if det1: | |
88 | meta1 = DB.plot_meta.find_one({ |
|
88 | meta1 = DB.plot_meta.find_one({ | |
89 | 'exp_detail': det1['_id'], |
|
89 | 'exp_detail': det1['_id'], | |
90 | 'plot': plot |
|
90 | 'plot': plot | |
91 | }) |
|
91 | }) | |
92 | if meta1: |
|
92 | if meta1: | |
93 | if meta1['metadata']['type'] in ('pcolor',): |
|
93 | if meta1['metadata']['type'] in ('pcolor', 'image'): | |
94 | datas = DB.plot_data.find( |
|
94 | datas = DB.plot_data.find( | |
95 | {'plot': meta1['_id']}, |
|
95 | {'plot': meta1['_id']}, | |
96 | ['time', 'data'], |
|
96 | ['time', 'data'], | |
97 | sort=[('time', -1)], |
|
97 | sort=[('time', -1)], | |
98 | limit=1)[0] |
|
98 | limit=1)[0] | |
99 | ret['time'] = [datas['time']] |
|
99 | ret['time'] = [datas['time']] | |
100 | ret['data'] = datas['data'] |
|
100 | ret['data'] = datas['data'] | |
101 | ret['metadata'] = meta1['metadata'] |
|
101 | ret['metadata'] = meta1['metadata'] | |
102 | else: |
|
102 | else: | |
103 | last = det1['last_time'] |
|
103 | last = det1['last_time'] | |
104 | metas = [meta1['_id']] |
|
104 | metas = [meta1['_id']] | |
105 | if det0: |
|
105 | if det0: | |
106 | meta0 = DB.plot_meta.find_one({ |
|
106 | meta0 = DB.plot_meta.find_one({ | |
107 | 'exp_detail': det0['_id'], |
|
107 | 'exp_detail': det0['_id'], | |
108 | 'plot': plot |
|
108 | 'plot': plot | |
109 | }) |
|
109 | }) | |
110 | if meta0: |
|
110 | if meta0: | |
111 | metas.append(meta0['_id']) |
|
111 | metas.append(meta0['_id']) | |
112 | total = DB.plot_data.count_documents({ |
|
112 | total = DB.plot_data.count_documents({ | |
113 | 'plot': {'$in': metas}, |
|
113 | 'plot': {'$in': metas}, | |
114 | 'time': {'$gt': last-12*60*60} |
|
114 | 'time': {'$gt': last-12*60*60} | |
115 | }) |
|
115 | }) | |
116 | skip = 0 if total-720<0 else total-720 |
|
116 | skip = 0 if total-720<0 else total-720 | |
117 | datas = DB.plot_data.find({ |
|
117 | datas = DB.plot_data.find({ | |
118 | 'plot': {'$in': metas}, |
|
118 | 'plot': {'$in': metas}, | |
119 | 'time': {'$gt': last-12*60*60} |
|
119 | 'time': {'$gt': last-12*60*60} | |
120 | }, ['time', 'data'], sort=[('time', 1)], limit=720, skip=skip) |
|
120 | }, ['time', 'data'], sort=[('time', 1)], limit=720, skip=skip) | |
121 |
|
121 | |||
122 | dum = [(d['time'], d['data']) for d in datas] |
|
122 | dum = [(d['time'], d['data']) for d in datas] | |
123 | ret['time'] = [d[0] for d in dum] |
|
123 | ret['time'] = [d[0] for d in dum] | |
124 | dum = numpy.array([d[1] for d in dum]) |
|
124 | dum = numpy.array([d[1] for d in dum]) | |
125 |
|
125 | |||
126 | if len(dum[0][0])==1: |
|
126 | if len(dum[0][0])==1: | |
127 | ret['data'] = dum.T[0].tolist() |
|
127 | ret['data'] = dum.T[0].tolist() | |
128 | else: |
|
128 | else: | |
129 | ret['data'] = [t for t in map(list, list(zip(*dum.tolist())))] |
|
129 | ret['data'] = [t for t in map(list, list(zip(*dum.tolist())))] | |
130 | ret['metadata'] = meta1['metadata'] |
|
130 | ret['metadata'] = meta1['metadata'] | |
131 |
|
131 | |||
132 | self.send(simplejson.dumps(ret, ignore_nan=True)) |
|
132 | self.send(simplejson.dumps(ret, ignore_nan=True)) | |
133 | else: |
|
133 | else: | |
134 | self.send(json.dumps({'interval': 0})) |
|
134 | self.send(json.dumps({'interval': 0})) | |
135 |
|
135 | |||
136 | def zmq_message(self, event): |
|
136 | def zmq_message(self, event): | |
137 | # Send message to WebSocket |
|
137 | # Send message to WebSocket | |
138 | self.send(text_data=event['message']) |
|
138 | self.send(text_data=event['message']) |
@@ -1,9 +1,9 | |||||
1 |
from django. |
|
1 | from django.urls import re_path | |
2 |
|
2 | |||
3 | from . import consumers |
|
3 | from . import consumers | |
4 |
|
4 | |||
5 | websocket_urlpatterns = [ |
|
5 | websocket_urlpatterns = [ | |
6 |
|
|
6 | re_path(r'^ws/main/$', consumers.MainConsumer.as_asgi()), | |
7 |
|
|
7 | re_path(r'^ws/realtime/(?P<code>[^/]+)/(?P<plot>[^/]+)/$', consumers.PlotConsumer.as_asgi()), | |
8 |
|
|
8 | re_path(r'^ws/database/(?P<code>[^/]+)/(?P<plot>[^/]+)/$', consumers.PlotConsumer.as_asgi()), | |
9 | ] No newline at end of file |
|
9 | ] |
@@ -1,45 +1,45 | |||||
1 | {% load static %} {% load bootstrap4 %} |
|
1 | {% load static %} {% load bootstrap4 %} | |
2 | <footer> |
|
2 | <footer> | |
3 | <div class="container"> |
|
3 | <div class="container"> | |
4 | <ul class="footer-contact"> |
|
4 | <ul class="footer-contact"> | |
5 | <li> |
|
5 | <li> | |
6 | <span class="fa fa-fax"></span><div><p>Atención al ciudadano</p> |
|
6 | <span class="fa fa-fax"></span><div><p>Atención al ciudadano</p> | |
7 | <p>Lunes a Viernes de 8:30 a 16:30</p></div> |
|
7 | <p>Lunes a Viernes de 8:30 a 16:30</p></div> | |
8 | </li> |
|
8 | </li> | |
9 | <li> |
|
9 | <li> | |
10 | <span class="fa fa-map-marker-alt"></span><div> |
|
10 | <span class="fa fa-map-marker-alt"></span><div> | |
11 | <p>Calle Badajoz Nº 169 Urb. Mayorazgo</p> |
|
11 | <p>Calle Badajoz Nº 169 Urb. Mayorazgo</p> | |
12 | <p>I Etapa Ate, Lima 15012 - Perú</p></div> |
|
12 | <p>I Etapa Ate, Lima 15012 - Perú</p></div> | |
13 | </li> |
|
13 | </li> | |
14 | <li> |
|
14 | <li> | |
15 | <span class="fa fa-envelope"></span> |
|
15 | <span class="fa fa-envelope"></span> | |
16 | roj@igp.gob.pe |
|
16 | roj@igp.gob.pe | |
17 | </li> |
|
17 | </li> | |
18 | <li> |
|
18 | <li> | |
19 | <span class="fa fa-phone"></span> |
|
19 | <span class="fa fa-phone"></span> | |
20 | (511)317-2313 |
|
20 | (511)317-2313 | |
21 | </li> |
|
21 | </li> | |
22 | </ul> |
|
22 | </ul> | |
23 | <ul class="nav-social social-footer"> |
|
23 | <ul class="nav-social social-footer"> | |
24 | <li> |
|
24 | <li> | |
25 | <a href="https://www.facebook.com/igp.peru"><i class="fab fa-facebook-f"></i></a> |
|
25 | <a href="https://www.facebook.com/igp.peru"><i class="fab fa-facebook-f"></i></a> | |
26 | </li> |
|
26 | </li> | |
27 | <li> |
|
27 | <li> | |
28 | <a href="https://twitter.com/igp_peru"><i class="fab fa-twitter"></i></a> |
|
28 | <a href="https://twitter.com/igp_peru"><i class="fab fa-twitter"></i></a> | |
29 | </li> |
|
29 | </li> | |
30 | <li> |
|
30 | <li> | |
31 | <a href="https://www.linkedin.com/company/igpperu/"><i class="fab fa-linkedin-in"></i></a> |
|
31 | <a href="https://www.linkedin.com/company/igpperu/"><i class="fab fa-linkedin-in"></i></a> | |
32 | </li> |
|
32 | </li> | |
33 | <li> |
|
33 | <li> | |
34 | <a href="https://www.instagram.com/igp.peru"><i class="fab fa-instagram"></i></a> |
|
34 | <a href="https://www.instagram.com/igp.peru"><i class="fab fa-instagram"></i></a> | |
35 | </li> |
|
35 | </li> | |
36 | <li> |
|
36 | <li> | |
37 | <a href="https://www.youtube.com/igp_videos"><i class="fab fa-youtube"></i></a> |
|
37 | <a href="https://www.youtube.com/igp_videos"><i class="fab fa-youtube"></i></a> | |
38 | </li> |
|
38 | </li> | |
39 | </ul> |
|
39 | </ul> | |
40 | </div> |
|
40 | </div> | |
41 | <iframe class="map d-none d-sm-block" |
|
41 | <iframe class="map d-none d-sm-block" | |
42 | src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d3901.828012758223!2d-76.94633793139629!3d-12.055351713347235!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x7ea774b6fa66a3c6!2sInstituto+Geof%C3%ADsico+del+Per%C3%BA!5e0!3m2!1ses-419!2spe!4v1545658855595" |
|
42 | src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d31226.562310315738!2d-76.89329626296218!3d-11.952312343404692!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x9105c3290814e129%3A0x61f92c3cfc90797b!2sRadio%20Observatorio%20de%20Jicamarca!5e0!3m2!1sen!2spe!4v1613758699300!5m2!1sen!2spe" | |
43 |
|
|
43 | width="100%" height="100%" frameborder="0" allowfullscreen="false">  | |
44 | </iframe> |
|
44 | </iframe> | |
45 | </footer> No newline at end of file |
|
45 | </footer> |
@@ -1,64 +1,65 | |||||
1 | {% extends 'base.html' %} |
|
1 | {% extends 'base.html' %} | |
2 | {% load static%} |
|
2 | {% load static%} | |
3 | {% block extra-header %} |
|
3 | {% block extra-header %} | |
4 | {% endblock %} |
|
4 | {% endblock %} | |
5 | {% block sidebar_content %} |
|
5 | {% block sidebar_content %} | |
6 | <nav class="nav flex-column"> |
|
6 | <nav class="nav flex-column"> | |
7 | {% for tag in tags %} |
|
7 | {% for tag in tags %} | |
8 | <a class="nav-link {{tag.active}}" href="{% url 'url_main' tag.name %}">{{tag.name | title}} <span class="badge badge-primary text-left">{{tag.n | stringformat:"02d"}} </span></a> |
|
8 | <a class="nav-link {{tag.active}}" href="{% url 'url_main' tag.name %}">{{tag.name | title}} <span class="badge badge-primary text-left">{{tag.n | stringformat:"02d"}} </span></a> | |
9 | {% endfor %} |
|
9 | {% endfor %} | |
10 | </nav> |
|
10 | </nav> | |
11 | {% endblock %} |
|
11 | {% endblock %} | |
12 | {% block content %} |
|
12 | {% block content %} | |
13 | <div class="row"> |
|
13 | <div class="row"> | |
14 | {% for exp in experiments %} |
|
14 | {% for exp in experiments %} | |
15 | <div class="col-12 col-sm-6 col-md-4 col-lg-3 p-1"> |
|
15 | <div class="col-12 col-sm-6 col-md-4 col-lg-3 p-1"> | |
16 | <div id="card_{{exp.code}}" class="card m-1 box-shadow text-{{exp.style}} border-{{exp.style}}"> |
|
16 | <div id="card_{{exp.code}}" class="card m-1 box-shadow text-{{exp.style}} border-{{exp.style}}"> | |
17 | <div id="card_header_{{exp.code}}" class="card-header bg-{{exp.style}} text-white">{{exp.name}}</div> |
|
17 | <div id="card_header_{{exp.code}}" class="card-header bg-{{exp.style}} text-white">{{exp.name}}</div> | |
18 | <div id="card_body_{{exp.code}}" class="card-body"> |
|
18 | <div id="card_body_{{exp.code}}" class="card-body"> | |
19 | <div id="date_{{exp.code}}">Last data: {{exp.date | date:"H:i:s" }}</div> |
|
19 | <div id="date_{{exp.code}}">Last data: {{exp.date | date:"H:i:s" }}</div> | |
20 | {% for plot in exp.plots %} |
|
20 | {% for plot in exp.plots %} | |
21 | <a class="btn btn-sm btn-outline-{{exp.style}} mt-1" href="{% url 'url-plot' exp.code plot.plot %}" role="button">{{plot.name}}</a> |
|
21 | <a class="btn btn-sm btn-outline-{{exp.style}} mt-1" href="{% url 'url-plot' exp.code plot.plot %}" role="button">{{plot.name}}</a> | |
22 | {% endfor %} |
|
22 | {% endfor %} | |
23 | </div> |
|
23 | </div> | |
24 | </div> |
|
24 | </div> | |
25 | </div> |
|
25 | </div> | |
26 | {% endfor %} |
|
26 | {% endfor %} | |
27 | </div> |
|
27 | </div> | |
28 | {% if experiments %} |
|
28 | {% if experiments %} | |
29 | <div class="row"> |
|
29 | <div class="row"> | |
30 | <ul class="legend"> |
|
30 | <ul class="legend"> | |
31 | <li>Time format: 24h (UTC-5)</li> |
|
31 | <li>Time format: 24h (UTC-5)</li> | |
32 | <li><i class="fas fa-circle text-success"></i><span>Instrument online</span></li> |
|
32 | <li><i class="fas fa-circle text-success"></i><span>Instrument online</span></li> | |
33 | <li><i class="fas fa-circle text-warning"></i><span>Instrument delayed</span></li> |
|
33 | <li><i class="fas fa-circle text-warning"></i><span>Instrument delayed</span></li> | |
34 | <li><i class="fas fa-circle text-danger"></i><span>Instrument offline</span></li> |
|
34 | <li><i class="fas fa-circle text-danger"></i><span>Instrument offline</span></li> | |
35 | </ul> |
|
35 | </ul> | |
36 | </div> |
|
36 | </div> | |
37 | {% endif %} |
|
37 | {% endif %} | |
38 | {% endblock %} |
|
38 | {% endblock %} | |
39 | {% block script %} |
|
39 | {% block script %} | |
40 |
<script> |
|
40 | <script> | |
41 | var socket = new WebSocket('ws://' + window.location.host +'/ws/main/'); |
|
41 | var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws"; | |
|
42 | var socket = new WebSocket(ws_scheme + '://' + window.location.host +'/ws/main/'); | |||
42 | socket.onopen = function open() { |
|
43 | socket.onopen = function open() { | |
43 | console.log('Main WebSockets connection created.'); |
|
44 | console.log('Main WebSockets connection created.'); | |
44 | }; |
|
45 | }; | |
45 |
|
46 | |||
46 | socket.onmessage = function(event) { |
|
47 | socket.onmessage = function(event) { | |
47 | var data = JSON.parse(event.data); |
|
48 | var data = JSON.parse(event.data); | |
48 | // console.log(data); |
|
49 | // console.log(data); | |
49 | var code = data['code']; |
|
50 | var code = data['code']; | |
50 | console.log(code); |
|
51 | console.log(code); | |
51 | var value = data['value']; |
|
52 | var value = data['value']; | |
52 | var time = moment(new Date(data['time']*1000)).format('HH:mm:ss'); |
|
53 | var time = moment(new Date(data['time']*1000)).format('HH:mm:ss'); | |
53 |
|
54 | |||
54 | $("#date_"+code).text("Last data: "+time); |
|
55 | $("#date_"+code).text("Last data: "+time); | |
55 | $("#card_"+code).removeClass().addClass("card m-1 box-shadow text-"+value+" border-"+value); |
|
56 | $("#card_"+code).removeClass().addClass("card m-1 box-shadow text-"+value+" border-"+value); | |
56 | $("#card_header_"+code).removeClass().addClass("card-header text-white bg-"+value); |
|
57 | $("#card_header_"+code).removeClass().addClass("card-header text-white bg-"+value); | |
57 | $("#card_body_"+code).find("a").removeClass().addClass("btn btn-sm mt-1 btn-outline-"+value); |
|
58 | $("#card_body_"+code).find("a").removeClass().addClass("btn btn-sm mt-1 btn-outline-"+value); | |
58 | }; |
|
59 | }; | |
59 |
|
60 | |||
60 | if (socket.readyState == WebSocket.OPEN) { |
|
61 | if (socket.readyState == WebSocket.OPEN) { | |
61 | socket.onopen(); |
|
62 | socket.onopen(); | |
62 | }; |
|
63 | }; | |
63 | </script> |
|
64 | </script> | |
64 | {% endblock script %} |
|
65 | {% endblock script %} |
@@ -1,105 +1,106 | |||||
1 | {% extends 'base.html' %} {% load static %} {% load bootstrap4 %} |
|
1 | {% extends 'base.html' %} {% load static %} {% load bootstrap4 %} | |
2 |
|
2 | |||
3 | {% block sidebar_content %} |
|
3 | {% block sidebar_content %} | |
4 | <h5>{{name}}</h5> |
|
4 | <h5>{{name}}</h5> | |
5 | <nav class="nav flex-column"> |
|
5 | <nav class="nav flex-column"> | |
6 | {% for plot in plots %} |
|
6 | {% for plot in plots %} | |
7 | <a class="nav-link" href="{% url 'url-plot' code plot.plot %}">{{plot.name}}</a> |
|
7 | <a class="nav-link" href="{% url 'url-plot' code plot.plot %}">{{plot.name}}</a> | |
8 | {% endfor %} |
|
8 | {% endfor %} | |
9 | </nav> |
|
9 | </nav> | |
10 | {% endblock %} |
|
10 | {% endblock %} | |
11 |
|
11 | |||
12 | {% block content %} |
|
12 | {% block content %} | |
13 | <div class="row justify-content-center"> |
|
13 | <div class="row justify-content-center"> | |
14 | <div id="loader" class="spinner-border" role="status"> |
|
14 | <div id="loader" class="spinner-border" role="status"> | |
15 | <span class="sr-only">Loading...</span> |
|
15 | <span class="sr-only">Loading...</span> | |
16 | </div> |
|
16 | </div> | |
17 | </div> |
|
17 | </div> | |
18 | <div id="plot" {%if meta.metadata.type == 'pcolor' %}class="row"{%endif%}> |
|
18 | <div id="plot" {%if meta.metadata.type == 'pcolor' %}class="row"{%endif%}> | |
19 | {% if image %} |
|
19 | {% if image %} | |
20 | <img id="image" class="img-fluid"/> |
|
20 | <img id="image" class="img-fluid"/> | |
21 | {% endif %} |
|
21 | {% endif %} | |
22 | </div> |
|
22 | </div> | |
23 | {% endblock content %} |
|
23 | {% endblock content %} | |
24 |
|
24 | |||
25 | {% block modal %} |
|
25 | {% block modal %} | |
26 | <!-- Modal --> |
|
26 | <!-- Modal --> | |
27 | {% if setup_form %} |
|
27 | {% if setup_form %} | |
28 | <div class="modal fade" id="setup" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> |
|
28 | <div class="modal fade" id="setup" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> | |
29 | <div class="modal-dialog modal-sm" role="document"> |
|
29 | <div class="modal-dialog modal-sm" role="document"> | |
30 | <div class="modal-content"> |
|
30 | <div class="modal-content"> | |
31 | <div class="modal-header"> |
|
31 | <div class="modal-header"> | |
32 | <button type="button" class="close" data-dismiss="modal" aria-label="Close"> |
|
32 | <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | |
33 | <span aria-hidden="true">×</span> |
|
33 | <span aria-hidden="true">×</span> | |
34 | </button> |
|
34 | </button> | |
35 | <h4 class="modal-title" id="myModalLabel">Setup plot</h4> |
|
35 | <h4 class="modal-title" id="myModalLabel">Setup plot</h4> | |
36 | </div> |
|
36 | </div> | |
37 | <div class="modal-body"> |
|
37 | <div class="modal-body"> | |
38 | {% if code and plot %} |
|
38 | {% if code and plot %} | |
39 | <form id="form_setup"> |
|
39 | <form id="form_setup"> | |
40 | {% bootstrap_form setup_form layout='grid' size='small' %} |
|
40 | {% bootstrap_form setup_form layout='grid' size='small' %} | |
41 | </form> |
|
41 | </form> | |
42 | {% endif %} |
|
42 | {% endif %} | |
43 | </div> |
|
43 | </div> | |
44 | <div class="modal-footer"> |
|
44 | <div class="modal-footer"> | |
45 | <button id="bt_update" type="button" class="btn btn-primary">Update</button> |
|
45 | <button id="bt_update" type="button" class="btn btn-primary">Update</button> | |
46 | </div> |
|
46 | </div> | |
47 | </div> |
|
47 | </div> | |
48 | </div> |
|
48 | </div> | |
49 | </div> |
|
49 | </div> | |
50 | {% endif %} |
|
50 | {% endif %} | |
51 | {% endblock modal%} {% block script %} |
|
51 | {% endblock modal%} {% block script %} | |
52 | <script src="{% static 'js/jroplots.js' %}"></script> |
|
52 | <script src="{% static 'js/jroplots.js' %}"></script> | |
53 | <script> |
|
53 | <script> | |
54 | /* This conditional is used to know if we have to setup the data |
|
54 | /* This conditional is used to know if we have to setup the data | |
55 | or just update the last data*/ |
|
55 | or just update the last data*/ | |
56 | $("#loader").css("display", "block"); |
|
56 | $("#loader").css("display", "block"); | |
|
57 | var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws"; | |||
57 | {% if realtime %} |
|
58 | {% if realtime %} | |
58 |
var socket = new WebSocket( |
|
59 | var socket = new WebSocket(ws_scheme + '://' + window.location.host + '/ws/realtime/{{code}}/{{plot}}/'); | |
59 | {% else %} |
|
60 | {% else %} | |
60 |
var socket = new WebSocket( |
|
61 | var socket = new WebSocket(ws_scheme + '://' + window.location.host + '/ws/database/{{code}}/{{plot}}/'); | |
61 | {% endif %} |
|
62 | {% endif %} | |
62 | socket.onopen = function open() { |
|
63 | socket.onopen = function open() { | |
63 | console.log('WebSockets connection created: ' + socket.url); |
|
64 | console.log('WebSockets connection created: ' + socket.url); | |
64 | socket.send('{{date}}') |
|
65 | socket.send('{{date}}') | |
65 | }; |
|
66 | }; | |
66 |
|
67 | |||
67 | socket.onmessage = function message(event) { |
|
68 | socket.onmessage = function message(event) { | |
68 | var data = JSON.parse(event.data); |
|
69 | var data = JSON.parse(event.data); | |
69 | if (data.interval == 0) { |
|
70 | if (data.interval == 0) { | |
70 | $("#loader").removeClass("loader").addClass("no-data"); |
|
71 | $("#loader").removeClass("loader").addClass("no-data"); | |
71 | $("#loader").html("No data found"); |
|
72 | $("#loader").html("No data found"); | |
72 | } else { |
|
73 | } else { | |
73 | var first = plot(data); |
|
74 | var first = plot(data); | |
74 | if (first == true) { |
|
75 | if (first == true) { | |
75 | $("#loader").css("display", "none"); |
|
76 | $("#loader").css("display", "none"); | |
76 | } |
|
77 | } | |
77 | } |
|
78 | } | |
78 | } |
|
79 | } | |
79 |
|
80 | |||
80 | if (socket.readyState == WebSocket.OPEN) { |
|
81 | if (socket.readyState == WebSocket.OPEN) { | |
81 | socket.onopen(); |
|
82 | socket.onopen(); | |
82 | } |
|
83 | } | |
83 |
|
84 | |||
84 | let flag = true; |
|
85 | let flag = true; | |
85 | function plot(data) { |
|
86 | function plot(data) { | |
86 | if (flag === true) { |
|
87 | if (flag === true) { | |
87 | flag = false; |
|
88 | flag = false; | |
88 | plt = new {{ fn_plot }} ({ |
|
89 | plt = new {{ fn_plot }} ({ | |
89 | div: 'plot', |
|
90 | div: 'plot', | |
90 | data: data, |
|
91 | data: data, | |
91 | }); |
|
92 | }); | |
92 | return true; |
|
93 | return true; | |
93 | } else { |
|
94 | } else { | |
94 | plt.update(data); |
|
95 | plt.update(data); | |
95 | return false; |
|
96 | return false; | |
96 | } |
|
97 | } | |
97 | } |
|
98 | } | |
98 | /*It is the button to make changes in my plot parameters defined in block modal*/ |
|
99 | /*It is the button to make changes in my plot parameters defined in block modal*/ | |
99 | $("#bt_update").click(function () { |
|
100 | $("#bt_update").click(function () { | |
100 | $("#setup").modal('hide'); |
|
101 | $("#setup").modal('hide'); | |
101 | var values = $("#form_setup").serializeArray(); |
|
102 | var values = $("#form_setup").serializeArray(); | |
102 | plt.restyle(values); |
|
103 | plt.restyle(values); | |
103 | }); |
|
104 | }); | |
104 |
|
105 | |||
105 | </script> {% endblock script %} No newline at end of file |
|
106 | </script> {% endblock script %} |
@@ -1,238 +1,238 | |||||
1 | #!/usr/bin/python |
|
1 | #!/usr/bin/python | |
2 | # -*- coding: UTF-8 -*- |
|
2 | # -*- coding: UTF-8 -*- | |
3 |
|
3 | |||
4 |
|
4 | |||
5 | import os |
|
5 | import os | |
6 | import time |
|
6 | import time | |
7 | from datetime import datetime |
|
7 | from datetime import datetime | |
8 |
|
8 | |||
9 | from django import forms |
|
9 | from django import forms | |
10 | from django.contrib import messages |
|
10 | from django.contrib import messages | |
11 | from django.utils.safestring import mark_safe |
|
11 | from django.utils.safestring import mark_safe | |
12 | from django.shortcuts import render |
|
12 | from django.shortcuts import render | |
13 | from django.http import HttpResponse |
|
13 | from django.http import HttpResponse | |
14 |
|
14 | |||
15 | import mongoengine |
|
15 | import mongoengine | |
16 |
|
16 | |||
17 | from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData |
|
17 | from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData | |
18 |
|
18 | |||
19 | from utils.plots import skynoise_plot |
|
19 | from utils.plots import skynoise_plot | |
20 |
|
20 | |||
21 | host = os.environ.get('HOST_MONGO', 'localhost') |
|
21 | host = os.environ.get('HOST_MONGO', 'localhost') | |
22 | mongoengine.connect('dbplots', host=host, port=27017) |
|
22 | mongoengine.connect('dbplots', host=host, port=27017) | |
23 |
|
23 | |||
24 |
|
24 | |||
25 | # Forms |
|
25 | # Forms | |
26 | class SearchForm(forms.Form): |
|
26 | class SearchForm(forms.Form): | |
27 |
|
27 | |||
28 | experiment = forms.ChoiceField() |
|
28 | experiment = forms.ChoiceField() | |
29 | plot = forms.ChoiceField() |
|
29 | plot = forms.ChoiceField() | |
30 |
|
30 | |||
31 | def __init__(self, *args, **kwargs): |
|
31 | def __init__(self, *args, **kwargs): | |
32 |
|
32 | |||
33 | exp_choices = kwargs.pop('exp_choices', []) |
|
33 | exp_choices = kwargs.pop('exp_choices', []) | |
34 | plt_choices = kwargs.pop('plt_choices', []) |
|
34 | plt_choices = kwargs.pop('plt_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 | self.fields['plot'].choices = [(0, 'Select Plot')] + plt_choices |
|
37 | self.fields['plot'].choices = [(0, 'Select Plot')] + plt_choices | |
38 | # we use this class to change the parameter in Scatter plot using the function plotly.restyle in jroplot.js |
|
38 | # we use this class to change the parameter in Scatter plot using the function plotly.restyle in jroplot.js | |
39 | class ScatterSetupForm(forms.Form): |
|
39 | class ScatterSetupForm(forms.Form): | |
40 |
|
40 | |||
41 | plotdiv = forms.CharField(widget=forms.HiddenInput()) |
|
41 | plotdiv = forms.CharField(widget=forms.HiddenInput()) | |
42 | ymax = forms.CharField(initial=30) |
|
42 | ymax = forms.CharField(initial=30) | |
43 | ymin = forms.CharField(initial=10) |
|
43 | ymin = forms.CharField(initial=10) | |
44 |
|
44 | |||
45 | # we use this class to change the parameter in RTI plot using the function plotly.restyle in jroplot.js |
|
45 | # we use this class to change the parameter in RTI plot using the function plotly.restyle in jroplot.js | |
46 | class RTISetupForm(forms.Form): |
|
46 | class RTISetupForm(forms.Form): | |
47 |
|
47 | |||
48 | plotdiv = forms.CharField(widget=forms.HiddenInput()) |
|
48 | plotdiv = forms.CharField(widget=forms.HiddenInput()) | |
49 | colormap = forms.ChoiceField(choices=[('Jet', 'Jet'), ('Viridis', 'Viridis'), ('RdBu', 'RdBu')]) |
|
49 | colormap = forms.ChoiceField(choices=[('Jet', 'Jet'), ('Viridis', 'Viridis'), ('RdBu', 'RdBu')]) | |
50 | zmax = forms.CharField(initial=30) |
|
50 | zmax = forms.CharField(initial=30) | |
51 | zmin = forms.CharField(initial=10) |
|
51 | zmin = forms.CharField(initial=10) | |
52 | ymax = forms.CharField(initial=180) |
|
52 | ymax = forms.CharField(initial=180) | |
53 | ymin = forms.CharField(initial=80) |
|
53 | ymin = forms.CharField(initial=80) | |
54 |
|
54 | |||
55 | # we use this class to change the parameter in SPC plot using the function plotly.restyle in jroplot.js |
|
55 | # we use this class to change the parameter in SPC plot using the function plotly.restyle in jroplot.js | |
56 | class SPCSetupForm(forms.Form): |
|
56 | class SPCSetupForm(forms.Form): | |
57 |
|
57 | |||
58 | plotdiv = forms.CharField(widget=forms.HiddenInput()) |
|
58 | plotdiv = forms.CharField(widget=forms.HiddenInput()) | |
59 | colormap = forms.ChoiceField(choices=[('Jet', 'Jet'), ('Viridis', 'Viridis'), ('RdBu', 'RdBu')]) |
|
59 | colormap = forms.ChoiceField(choices=[('Jet', 'Jet'), ('Viridis', 'Viridis'), ('RdBu', 'RdBu')]) | |
60 | #como es un perfil xmin y xmax deben ser iguales a zmin y zmax |
|
60 | #como es un perfil xmin y xmax deben ser iguales a zmin y zmax | |
61 | xmax = forms.CharField(initial=30) |
|
61 | xmax = forms.CharField(initial=30) | |
62 | xmin = forms.CharField(initial=10) |
|
62 | xmin = forms.CharField(initial=10) | |
63 | #x2max = forms.CharField(initial=30) |
|
63 | #x2max = forms.CharField(initial=30) | |
64 | #x2min = forms.CharField(initial=10) |
|
64 | #x2min = forms.CharField(initial=10) | |
65 | ymax = forms.CharField(initial=180) |
|
65 | ymax = forms.CharField(initial=180) | |
66 | ymin = forms.CharField(initial=80) |
|
66 | ymin = forms.CharField(initial=80) | |
67 | zmax = forms.CharField(initial=30) |
|
67 | zmax = forms.CharField(initial=30) | |
68 | zmin = forms.CharField(initial=10) |
|
68 | zmin = forms.CharField(initial=10) | |
69 |
|
69 | |||
70 | # Create your views here. |
|
70 | # Create your views here. | |
71 | def main(request, tag=None): |
|
71 | def main(request, tag=None): | |
72 |
|
72 | |||
73 | kwargs = {} |
|
73 | kwargs = {} | |
74 |
date = request.GET.get('date', datetime. |
|
74 | date = request.GET.get('date', datetime.now().strftime('%d-%m-%Y')) | |
75 | exps = ExpDetail.objects(date=datetime.strptime(date, '%d-%m-%Y')) |
|
75 | exps = ExpDetail.objects(date=datetime.strptime(date, '%d-%m-%Y')) | |
76 |
|
76 | |||
77 | tmp = {} |
|
77 | tmp = {} | |
78 | for exp in exps: |
|
78 | for exp in exps: | |
79 | label = exp.tag.lower().strip() if exp.tag else 'other' |
|
79 | label = exp.tag.lower().strip() if exp.tag else 'other' | |
80 | if label in tmp: |
|
80 | if label in tmp: | |
81 | tmp[label] += 1 |
|
81 | tmp[label] += 1 | |
82 | else: |
|
82 | else: | |
83 | tmp[label] = 1 |
|
83 | tmp[label] = 1 | |
84 | tags = [] |
|
84 | tags = [] | |
85 |
|
85 | |||
86 | for key, value in tmp.items(): |
|
86 | for key, value in tmp.items(): | |
87 | if tag == key: |
|
87 | if tag == key: | |
88 | tags.append({'name': key, 'n': tmp[key], 'active': 'active'}) |
|
88 | tags.append({'name': key, 'n': tmp[key], 'active': 'active'}) | |
89 | else: |
|
89 | else: | |
90 | tags.append({'name': key, 'n': tmp[key]}) |
|
90 | tags.append({'name': key, 'n': tmp[key]}) | |
91 |
|
91 | |||
92 | kwargs['tags'] = tags |
|
92 | kwargs['tags'] = tags | |
93 |
|
93 | |||
94 | if tag: |
|
94 | if tag: | |
95 | experiments = [] |
|
95 | experiments = [] | |
96 | for exp in exps: |
|
96 | for exp in exps: | |
97 | label = exp.tag.lower().strip() if exp.tag else 'other' |
|
97 | label = exp.tag.lower().strip() if exp.tag else 'other' | |
98 | if label != tag: |
|
98 | if label != tag: | |
99 | continue |
|
99 | continue | |
100 | dum = {} |
|
100 | dum = {} | |
101 | dum['code'] = exp.experiment.code |
|
101 | dum['code'] = exp.experiment.code | |
102 | dum['plots'] = [] |
|
102 | dum['plots'] = [] | |
103 | dum['name'] = exp.experiment.name |
|
103 | dum['name'] = exp.experiment.name | |
104 |
|
104 | |||
105 | t = time.time() |
|
105 | t = time.time() | |
106 |
|
106 | |||
107 | if (t-exp['last_time']) > 6*exp['interval']: |
|
107 | if (t-exp['last_time']) > 6*exp['interval']: | |
108 | status = 'Offline' |
|
108 | status = 'Offline' | |
109 | clase = 'alertas-offline' |
|
109 | clase = 'alertas-offline' | |
110 | style = 'danger' |
|
110 | style = 'danger' | |
111 | elif (t-exp['last_time']) > 3*exp['interval']: |
|
111 | elif (t-exp['last_time']) > 3*exp['interval']: | |
112 | status = 'Delayed' |
|
112 | status = 'Delayed' | |
113 | clase = 'alertas-delayed' |
|
113 | clase = 'alertas-delayed' | |
114 | style = 'warning' |
|
114 | style = 'warning' | |
115 | else: |
|
115 | else: | |
116 | status = 'Online' |
|
116 | status = 'Online' | |
117 | clase = 'alertas-online' |
|
117 | clase = 'alertas-online' | |
118 | style = 'success' |
|
118 | style = 'success' | |
119 |
|
119 | |||
120 | dum['status'] = status |
|
120 | dum['status'] = status | |
121 | dum['class'] = clase |
|
121 | dum['class'] = clase | |
122 | dum['style']= style |
|
122 | dum['style']= style | |
123 | dum['date']= datetime.fromtimestamp(exp['last_time']) |
|
123 | dum['date']= datetime.fromtimestamp(exp['last_time']) | |
124 | for plot in exp.plots(): |
|
124 | for plot in exp.plots(): | |
125 | dum['plots'].append({'plot': plot.plot, 'name': plot.plot.replace('_', ' ').title(), 'id':plot.id}) |
|
125 | dum['plots'].append({'plot': plot.plot, 'name': plot.plot.replace('_', ' ').title(), 'id':plot.id}) | |
126 | experiments.append(dum) |
|
126 | experiments.append(dum) | |
127 |
|
127 | |||
128 | kwargs['experiments'] = experiments |
|
128 | kwargs['experiments'] = experiments | |
129 | kwargs['tag'] = tag |
|
129 | kwargs['tag'] = tag | |
130 |
|
130 | |||
131 | kwargs['date'] = date |
|
131 | kwargs['date'] = date | |
132 | kwargs['title'] = 'Home' |
|
132 | kwargs['title'] = 'Home' | |
133 | kwargs['sidebar'] = True |
|
133 | kwargs['sidebar'] = True | |
134 |
|
134 | |||
135 | return render(request, 'home.html', kwargs) |
|
135 | return render(request, 'home.html', kwargs) | |
136 |
|
136 | |||
137 | def about(request): |
|
137 | def about(request): | |
138 | ''' |
|
138 | ''' | |
139 | ''' |
|
139 | ''' | |
140 | kwargs = { |
|
140 | kwargs = { | |
141 | 'title': 'About' |
|
141 | 'title': 'About' | |
142 | } |
|
142 | } | |
143 | return render(request, 'about.html', kwargs) |
|
143 | return render(request, 'about.html', kwargs) | |
144 |
|
144 | |||
145 |
|
145 | |||
146 | def tools(request): |
|
146 | def tools(request): | |
147 | ''' |
|
147 | ''' | |
148 | ''' |
|
148 | ''' | |
149 | kwargs = { |
|
149 | kwargs = { | |
150 | 'title': 'Tools', |
|
150 | 'title': 'Tools', | |
151 | 'doy': (datetime.today().date()-datetime.today().date().replace(month=1, day=1)).days + 1 |
|
151 | 'doy': (datetime.today().date()-datetime.today().date().replace(month=1, day=1)).days + 1 | |
152 | } |
|
152 | } | |
153 | return render(request, 'tools.html', kwargs) |
|
153 | return render(request, 'tools.html', kwargs) | |
154 |
|
154 | |||
155 | def reports(request): |
|
155 | def reports(request): | |
156 | ''' |
|
156 | ''' | |
157 | ''' |
|
157 | ''' | |
158 | kwargs = { |
|
158 | kwargs = { | |
159 | 'title': 'Reports', |
|
159 | 'title': 'Reports', | |
160 | } |
|
160 | } | |
161 | return render(request, 'reports.html', kwargs) |
|
161 | return render(request, 'reports.html', kwargs) | |
162 |
|
162 | |||
163 | def plot(request, code=None, plot=None): |
|
163 | def plot(request, code=None, plot=None): | |
164 | ''' |
|
164 | ''' | |
165 | ''' |
|
165 | ''' | |
166 |
|
166 | |||
167 | realtime = False |
|
167 | realtime = False | |
168 | date = request.GET.get('date', None) |
|
168 | date = request.GET.get('date', None) | |
169 | if date is None: |
|
169 | if date is None: | |
170 |
date = datetime. |
|
170 | date = datetime.now().strftime('%d-%m-%Y') | |
171 | realtime = True |
|
171 | realtime = True | |
172 | exp = Experiment.objects.get(code=int(code)) |
|
172 | exp = Experiment.objects.get(code=int(code)) | |
173 | detail = ExpDetail.objects.get(experiment=exp, date=datetime.strptime(date, '%d-%m-%Y')) |
|
173 | detail = ExpDetail.objects.get(experiment=exp, date=datetime.strptime(date, '%d-%m-%Y')) | |
174 | meta = PlotMeta.objects.get(exp_detail=detail, plot=plot) |
|
174 | meta = PlotMeta.objects.get(exp_detail=detail, plot=plot) | |
175 | tag = detail.tag.lower().strip() if detail.tag else 'other' |
|
175 | tag = detail.tag.lower().strip() if detail.tag else 'other' | |
176 |
|
176 | |||
177 | kwargs = { |
|
177 | kwargs = { | |
178 | 'code': code, |
|
178 | 'code': code, | |
179 | 'plot': plot, |
|
179 | 'plot': plot, | |
180 | 'meta':meta, |
|
180 | 'meta':meta, | |
181 | 'date': date, |
|
181 | 'date': date, | |
182 | 'id': meta.pk, |
|
182 | 'id': meta.pk, | |
183 | 'realtime': realtime, |
|
183 | 'realtime': realtime, | |
184 | 'title': 'Home', |
|
184 | 'title': 'Home', | |
185 | 'name' : exp.name, |
|
185 | 'name' : exp.name, | |
186 | 'sidebar': True, |
|
186 | 'sidebar': True, | |
187 | 'tag' : tag, |
|
187 | 'tag' : tag, | |
188 | 'plots': [] |
|
188 | 'plots': [] | |
189 | } |
|
189 | } | |
190 |
|
190 | |||
191 | for plt in detail.plots(): |
|
191 | for plt in detail.plots(): | |
192 | kwargs['plots'].append({'plot': plt.plot, 'name': plt.plot.replace('_', ' ').title()}) |
|
192 | kwargs['plots'].append({'plot': plt.plot, 'name': plt.plot.replace('_', ' ').title()}) | |
193 |
|
193 | |||
194 | # Logic to show my views |
|
194 | # Logic to show my views | |
195 | if meta.metadata['type'] == 'pcolorbuffer': |
|
195 | if meta.metadata['type'] == 'pcolorbuffer': | |
196 | kwargs['setup_form'] = RTISetupForm() |
|
196 | kwargs['setup_form'] = RTISetupForm() | |
197 | kwargs['fn_plot'] = 'PcolorBuffer' |
|
197 | kwargs['fn_plot'] = 'PcolorBuffer' | |
198 | return render(request, 'plot.html', kwargs) |
|
198 | return render(request, 'plot.html', kwargs) | |
199 | elif meta.metadata['type'] == 'pcolor': |
|
199 | elif meta.metadata['type'] == 'pcolor': | |
200 | kwargs['setup_form'] = SPCSetupForm() |
|
200 | kwargs['setup_form'] = SPCSetupForm() | |
201 | kwargs['fn_plot'] = 'Pcolor' |
|
201 | kwargs['fn_plot'] = 'Pcolor' | |
202 | return render(request, 'plot.html', kwargs) |
|
202 | return render(request, 'plot.html', kwargs) | |
203 | elif meta.metadata['type'] == 'scatterbuffer': |
|
203 | elif meta.metadata['type'] == 'scatterbuffer': | |
204 | kwargs['setup_form'] = ScatterSetupForm() |
|
204 | kwargs['setup_form'] = ScatterSetupForm() | |
205 | kwargs['fn_plot'] = 'ScatterBuffer' |
|
205 | kwargs['fn_plot'] = 'ScatterBuffer' | |
206 | return render(request, 'plot.html', kwargs) |
|
206 | return render(request, 'plot.html', kwargs) | |
207 | elif meta.metadata['type'] == 'image': |
|
207 | elif meta.metadata['type'] == 'image': | |
208 | kwargs['image'] = True |
|
208 | kwargs['image'] = True | |
209 | kwargs['fn_plot'] = 'StaticPlot' |
|
209 | kwargs['fn_plot'] = 'StaticPlot' | |
210 | return render(request, 'plot.html', kwargs) |
|
210 | return render(request, 'plot.html', kwargs) | |
211 | else: |
|
211 | else: | |
212 | return render(request, 'home.html', {}) |
|
212 | return render(request, 'home.html', {}) | |
213 |
|
213 | |||
214 | def plot_skynoise(request): |
|
214 | def plot_skynoise(request): | |
215 |
|
215 | |||
216 | date = request.GET.get('date', None) |
|
216 | date = request.GET.get('date', None) | |
217 | if date is None: |
|
217 | if date is None: | |
218 | date = datetime.now() |
|
218 | date = datetime.now() | |
219 | else: |
|
219 | else: | |
220 | date = datetime.strptime(date, '%Y-%m-%d') |
|
220 | date = datetime.strptime(date, '%Y-%m-%d') | |
221 |
|
221 | |||
222 | data = skynoise_plot(date.year, date.month, date.day) |
|
222 | data = skynoise_plot(date.year, date.month, date.day) | |
223 | response = HttpResponse(data.getvalue(), content_type='image/png') |
|
223 | response = HttpResponse(data.getvalue(), content_type='image/png') | |
224 |
|
224 | |||
225 | return response |
|
225 | return response | |
226 |
|
226 | |||
227 | def plot_overjro(request): |
|
227 | def plot_overjro(request): | |
228 |
|
228 | |||
229 | date = request.GET.get('date', None) |
|
229 | date = request.GET.get('date', None) | |
230 | if date is None: |
|
230 | if date is None: | |
231 | date = datetime.now() |
|
231 | date = datetime.now() | |
232 | else: |
|
232 | else: | |
233 | date = datetime.strptime(date, '%Y-%m-%d') |
|
233 | date = datetime.strptime(date, '%Y-%m-%d') | |
234 |
|
234 | |||
235 | data = skynoise_plot(date.year, date.month, date.day) |
|
235 | data = skynoise_plot(date.year, date.month, date.day) | |
236 | response = HttpResponse(data.getvalue(), content_type='image/png') |
|
236 | response = HttpResponse(data.getvalue(), content_type='image/png') | |
237 |
|
237 | |||
238 | return response No newline at end of file |
|
238 | return response |
@@ -1,137 +1,139 | |||||
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 = '-rgo(&lgs^!4jn6atk_^=!a)+jtt%%h48a_w5-csgn7jc@iao5' |
|
23 | SECRET_KEY = '-rgo(&lgs^!4jn6atk_^=!a)+jtt%%h48a_w5-csgn7jc@iao5' | |
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 = ['*'] #YONG |
|
28 | ALLOWED_HOSTS = ['*'] #YONG | |
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 | 'bootstrap4', |
|
40 | 'bootstrap4', | |
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 = os.environ.get('TZ', 'UTC') |
|
111 | TIME_ZONE = os.environ.get('TZ', '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 | STATIC_ROOT = '/static/' | |||
124 |
|
125 | |||
125 | #======================== YONG ================================ |
|
126 | #======================== YONG ================================ | |
126 | host = os.environ.get('HOST_REDIS', '127.0.0.1') |
|
127 | host = os.environ.get('HOST_REDIS', '127.0.0.1') | |
127 |
|
128 | |||
|
129 | ASGI_APPLICATION = 'realtime.asgi.application' | |||
|
130 | ||||
128 | CHANNEL_LAYERS = { |
|
131 | CHANNEL_LAYERS = { | |
129 | "default": { |
|
132 | "default": { | |
130 | 'BACKEND': 'channels_redis.core.RedisChannelLayer', |
|
133 | 'BACKEND': 'channels_redis.core.RedisChannelLayer', | |
131 | "CONFIG": { |
|
134 | "CONFIG": { | |
132 | "hosts": [(host, 6379)], |
|
135 | "hosts": [(host, 6379)], | |
133 | }, |
|
136 | }, | |
134 | }, |
|
137 | }, | |
135 | } |
|
138 | } | |
136 |
|
139 | |||
137 | ASGI_APPLICATION = "realtime.routing.application" |
|
@@ -1,13 +1,14 | |||||
1 | Django |
|
1 | Django | |
2 | django-bootstrap4 |
|
2 | django-bootstrap4 | |
3 | channels |
|
3 | channels | |
4 | channels_redis |
|
4 | channels_redis | |
5 | mongoengine |
|
5 | mongoengine | |
6 | pymongo |
|
6 | pymongo | |
7 | pyzmq |
|
7 | pyzmq | |
8 | redis |
|
8 | redis | |
9 | requests |
|
9 | requests | |
10 | simplejson |
|
10 | simplejson | |
11 | numpy |
|
11 | numpy | |
12 | matplotlib |
|
12 | matplotlib | |
13 | scipy No newline at end of file |
|
13 | scipy | |
|
14 | gunicorn |
@@ -1,142 +1,146 | |||||
1 | [ |
|
1 | [ | |
2 | { |
|
2 | { | |
3 | "code" : 100, |
|
3 | "code" : 100, | |
4 | "name" : "HF JRO" |
|
4 | "name" : "HF JRO" | |
5 | }, |
|
5 | }, | |
6 | { |
|
6 | { | |
7 | "code" : 101, |
|
7 | "code" : 101, | |
8 | "name" : "HF huancayo" |
|
8 | "name" : "HF huancayo" | |
9 | }, |
|
9 | }, | |
10 | { |
|
10 | { | |
11 | "code" : 102, |
|
11 | "code" : 102, | |
12 | "name" : "HF Ica" |
|
12 | "name" : "HF Ica" | |
13 | }, |
|
13 | }, | |
14 | { |
|
14 | { | |
15 | "code" : 110, |
|
15 | "code" : 110, | |
16 | "name" : "ISR EW Drifts" |
|
16 | "name" : "ISR EW Drifts" | |
17 | }, |
|
17 | }, | |
18 | { |
|
18 | { | |
19 | "code" : 111, |
|
19 | "code" : 111, | |
20 | "name" : "ISR Faraday" |
|
20 | "name" : "ISR Faraday" | |
21 | }, |
|
21 | }, | |
22 | { |
|
22 | { | |
23 | "code" : 112, |
|
23 | "code" : 112, | |
24 | "name" : "ISR Imaging" |
|
24 | "name" : "ISR Imaging" | |
25 | }, |
|
25 | }, | |
26 | { |
|
26 | { | |
27 | "code" : 120, |
|
27 | "code" : 120, | |
28 | "name" : "Faraday" |
|
28 | "name" : "Faraday" | |
29 | }, |
|
29 | }, | |
30 | { |
|
30 | { | |
31 | "code" : 121, |
|
31 | "code" : 121, | |
32 | "name" : "Faraday Long Pulse" |
|
32 | "name" : "Faraday Long Pulse" | |
33 | }, |
|
33 | }, | |
34 | { |
|
34 | { | |
35 | "code" : 122, |
|
35 | "code" : 122, | |
36 | "name" : "Faraday Codded LP" |
|
36 | "name" : "Faraday Codded LP" | |
37 | }, |
|
37 | }, | |
38 | { |
|
38 | { | |
39 | "code" : 123, |
|
39 | "code" : 123, | |
40 | "name" : "Faraday Double Pulse" |
|
40 | "name" : "Faraday Double Pulse" | |
41 | }, |
|
41 | }, | |
42 | { |
|
42 | { | |
43 | "code" : 124, |
|
43 | "code" : 124, | |
44 | "name" : "Faraday AC" |
|
44 | "name" : "Faraday AC" | |
45 | }, |
|
45 | }, | |
46 | { |
|
46 | { | |
47 | "code" : 125, |
|
47 | "code" : 125, | |
48 | "name" : "Faraday Differential Phase" |
|
48 | "name" : "Faraday Differential Phase" | |
49 | }, |
|
49 | }, | |
50 | { |
|
50 | { | |
51 | "code" : 130, |
|
51 | "code" : 130, | |
52 | "name" : "Imaging" |
|
52 | "name" : "Imaging" | |
53 | }, |
|
53 | }, | |
54 | { |
|
54 | { | |
55 | "code" : 132, |
|
55 | "code" : 132, | |
56 | "name" : "Meteors" |
|
56 | "name" : "Meteors" | |
57 | }, |
|
57 | }, | |
58 | { |
|
58 | { | |
59 | "code" : 150, |
|
59 | "code" : 150, | |
60 | "name" : "JASMET 50" |
|
60 | "name" : "JASMET 50" | |
61 | }, |
|
61 | }, | |
62 | { |
|
62 | { | |
63 | "code" : 151, |
|
63 | "code" : 151, | |
64 | "name" : "JASMET 30" |
|
64 | "name" : "JASMET 30" | |
65 | }, |
|
65 | }, | |
66 | { |
|
66 | { | |
67 | "code" : 170, |
|
67 | "code" : 170, | |
68 | "name" : "BLTR Huancayo" |
|
68 | "name" : "BLTR Huancayo" | |
69 | }, |
|
69 | }, | |
70 | { |
|
70 | { | |
71 | "code" : 171, |
|
71 | "code" : 171, | |
72 | "name" : "CIRI Huancayo" |
|
72 | "name" : "CIRI Huancayo" | |
73 | }, |
|
73 | }, | |
74 | { |
|
74 | { | |
75 | "code" : 172, |
|
75 | "code" : 172, | |
76 | "name" : "CLAIRE Huancayo" |
|
76 | "name" : "CLAIRE Huancayo" | |
77 | }, |
|
77 | }, | |
78 | { |
|
78 | { | |
79 | "code" : 180, |
|
79 | "code" : 180, | |
80 | "name" : "MST" |
|
80 | "name" : "MST" | |
81 | }, |
|
81 | }, | |
82 | { |
|
82 | { | |
83 | "code" : 181, |
|
83 | "code" : 181, | |
84 | "name" : "ISR" |
|
84 | "name" : "ISR" | |
85 | }, |
|
85 | }, | |
86 | { |
|
86 | { | |
87 | "code" : 182, |
|
87 | "code" : 182, | |
88 | "name" : "EEJ" |
|
88 | "name" : "EEJ" | |
89 | }, |
|
89 | }, | |
90 | { |
|
90 | { | |
91 | "code" : 190, |
|
91 | "code" : 190, | |
92 | "name" : "JULIA 150Km (Natalia)" |
|
92 | "name" : "JULIA 150Km (Natalia)" | |
93 | }, |
|
93 | }, | |
94 | { |
|
94 | { | |
95 | "code" : 191, |
|
95 | "code" : 191, | |
96 | "name" : "JULIA SpreadF (Natalia)" |
|
96 | "name" : "JULIA SpreadF (Natalia)" | |
97 | }, |
|
97 | }, | |
98 | { |
|
98 | { | |
99 | "code" : 200, |
|
99 | "code" : 200, | |
100 | "name" : "JULIA 150Km" |
|
100 | "name" : "JULIA 150Km" | |
101 | }, |
|
101 | }, | |
102 | { |
|
102 | { | |
103 | "code" : 201, |
|
103 | "code" : 201, | |
104 | "name" : "JULIA EEJ" |
|
104 | "name" : "JULIA EEJ" | |
105 | }, |
|
105 | }, | |
106 | { |
|
106 | { | |
107 | "code" : 202, |
|
107 | "code" : 202, | |
108 | "name" : "JULIA SpreadF" |
|
108 | "name" : "JULIA SpreadF" | |
109 | }, |
|
109 | }, | |
110 | { |
|
110 | { | |
111 | "code" : 203, |
|
111 | "code" : 203, | |
112 | "name" : "JULIA Imaging" |
|
112 | "name" : "JULIA Imaging" | |
113 | }, |
|
113 | }, | |
114 | { |
|
114 | { | |
115 | "code" : 204, |
|
115 | "code" : 204, | |
116 | "name" : "JULIA Bistatic" |
|
116 | "name" : "JULIA Bistatic" | |
117 | }, |
|
117 | }, | |
118 | { |
|
118 | { | |
|
119 | "code" : 210, | |||
|
120 | "name" : "High Altitude Drift" | |||
|
121 | }, | |||
|
122 | { | |||
119 | "code" : 230, |
|
123 | "code" : 230, | |
120 | "name" : "Valley Bottonside 150 Km" |
|
124 | "name" : "Valley Bottonside 150 Km" | |
121 | }, |
|
125 | }, | |
122 | { |
|
126 | { | |
123 | "code" : 240, |
|
127 | "code" : 240, | |
124 |
"name" : "Simone |
|
128 | "name" : "Simone Ancon" | |
125 | }, |
|
129 | }, | |
126 | { |
|
130 | { | |
127 | "code" : 241, |
|
131 | "code" : 241, | |
128 | "name" : "Simone Azpitia" |
|
132 | "name" : "Simone Azpitia" | |
129 | }, |
|
133 | }, | |
130 | { |
|
134 | { | |
131 | "code" : 242, |
|
135 | "code" : 242, | |
132 | "name" : "Simone Santa Rosa" |
|
136 | "name" : "Simone Santa Rosa" | |
133 | }, |
|
137 | }, | |
134 | { |
|
138 | { | |
135 | "code" : 243, |
|
139 | "code" : 243, | |
136 | "name" : "Simone Huancayo" |
|
140 | "name" : "Simone Huancayo" | |
137 | }, |
|
141 | }, | |
138 | { |
|
142 | { | |
139 | "code" : 244, |
|
143 | "code" : 244, | |
140 |
"name" : "Simone |
|
144 | "name" : "Simone Chaclacayo" | |
141 | } |
|
145 | } | |
142 | ] |
|
146 | ] |
@@ -1,169 +1,172 | |||||
1 | #!/usr/bin/python |
|
1 | #!/usr/bin/python | |
2 | # -*- coding: UTF-8 -*- |
|
2 | # -*- coding: UTF-8 -*- | |
3 |
|
3 | |||
4 | import os |
|
4 | import os | |
5 | import sys |
|
5 | import sys | |
6 | import json |
|
6 | import json | |
7 | import simplejson |
|
7 | import simplejson | |
8 | from datetime import datetime |
|
8 | from datetime import datetime | |
9 | import time |
|
9 | import time | |
10 | import zmq |
|
10 | import zmq | |
11 | import mongoengine |
|
11 | import mongoengine | |
12 | import django |
|
12 | import django | |
13 | from threading import Thread |
|
13 | from threading import Thread | |
14 |
|
14 | |||
15 | sys.path.append(os.environ.get('APP_DIR', '../')) |
|
15 | sys.path.append(os.environ.get('APP_DIR', '../')) | |
16 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "realtime.settings") |
|
16 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "realtime.settings") | |
17 | django.setup() |
|
17 | django.setup() | |
18 |
|
18 | |||
19 | from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData |
|
19 | from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData | |
20 |
|
20 | |||
21 | host_mongo = os.environ.get('HOST_MONGO', 'localhost') |
|
21 | host_mongo = os.environ.get('HOST_MONGO', 'localhost') | |
22 | mongoengine.connect('dbplots', host=host_mongo, port=27017) |
|
22 | mongoengine.connect('dbplots', host=host_mongo, port=27017) | |
23 |
|
23 | |||
24 | import channels.layers |
|
24 | import channels.layers | |
25 | from asgiref.sync import async_to_sync |
|
25 | from asgiref.sync import async_to_sync | |
26 |
|
26 | |||
27 | channel = channels.layers.get_channel_layer() |
|
27 | channel = channels.layers.get_channel_layer() | |
28 |
|
28 | |||
29 | def loaddata(): |
|
29 | def loaddata(): | |
30 | print('Loading Experiments...') |
|
30 | print('Loading Experiments...') | |
31 | if os.environ.get('APP_DIR', None) is not None: |
|
31 | if os.environ.get('APP_DIR', None) is not None: | |
32 | file_exp = os.path.join(os.environ.get('APP_DIR'), 'scripts', 'experiments.json') |
|
32 | file_exp = os.path.join(os.environ.get('APP_DIR'), 'scripts', 'experiments.json') | |
33 | else: |
|
33 | else: | |
34 | file_exp = './experiments.json' |
|
34 | file_exp = './experiments.json' | |
35 | for tup in json.load(open(file_exp)): |
|
35 | for tup in json.load(open(file_exp)): | |
36 | print(tup) |
|
36 | print(tup) | |
37 | exp = Experiment.objects(code=tup['code']).modify( |
|
37 | exp = Experiment.objects(code=tup['code']).modify( | |
38 | upsert=True, # To add a new row |
|
38 | upsert=True, # To add a new row | |
39 | new=True, |
|
39 | new=True, | |
40 | set__code=tup['code'], |
|
40 | set__code=tup['code'], | |
41 | set__name=tup['name'], |
|
41 | set__name=tup['name'], | |
42 | ) |
|
42 | ) | |
43 | exp.save() |
|
43 | exp.save() | |
44 |
|
44 | |||
45 | #============== funcion para modificar datos en la tabla ============== |
|
45 | #============== funcion para modificar datos en la tabla ============== | |
46 | def update(buffer): |
|
46 | def update(buffer): | |
47 |
dt = datetime. |
|
47 | dt = datetime.fromtimestamp(buffer['time']) | |
48 | interval = buffer['metadata'].pop('interval') |
|
48 | interval = buffer['metadata'].pop('interval') | |
49 | tag = buffer['metadata'].pop('tag') if 'tag' in buffer['metadata'] else '' |
|
49 | tag = buffer['metadata'].pop('tag') if 'tag' in buffer['metadata'] else '' | |
50 | exp = Experiment.objects.get(code=buffer['code']) |
|
50 | exp = Experiment.objects.get(code=buffer['code']) | |
51 |
|
51 | |||
52 | detail = ExpDetail.objects(experiment=exp, date=dt.date()).modify( |
|
52 | detail = ExpDetail.objects(experiment=exp, date=dt.date()).modify( | |
53 | upsert=True, |
|
53 | upsert=True, | |
54 | new=True, |
|
54 | new=True, | |
55 | set__experiment=exp, |
|
55 | set__experiment=exp, | |
56 | set__date=dt.date(), |
|
56 | set__date=dt.date(), | |
57 | set__last_time = buffer['time'], |
|
57 | set__last_time = buffer['time'], | |
58 | set__interval = interval, |
|
58 | set__interval = interval, | |
59 | set__tag = tag, |
|
59 | set__tag = tag, | |
60 | ) |
|
60 | ) | |
61 |
|
61 | |||
62 | label = buffer['plot'].replace(' ', '_').lower() |
|
62 | label = buffer['plot'].replace(' ', '_').lower() | |
63 | plot = PlotMeta.objects(exp_detail=detail, plot=label).modify( |
|
63 | plot = PlotMeta.objects(exp_detail=detail, plot=label).modify( | |
64 | upsert=True, |
|
64 | upsert=True, | |
65 | new=True, |
|
65 | new=True, | |
66 | set__metadata = buffer['metadata'] |
|
66 | set__metadata = buffer['metadata'] | |
67 | ) |
|
67 | ) | |
68 | #plot.save() |
|
68 | #plot.save() | |
69 |
|
69 | |||
70 | data = PlotData.objects(plot=plot, time=buffer['time']).modify( |
|
70 | data = PlotData.objects(plot=plot, time=buffer['time']).modify( | |
71 | upsert=True, # To add a new row |
|
71 | upsert=True, # To add a new row | |
72 | new=True, |
|
72 | new=True, | |
73 | set__time = buffer['time'], |
|
73 | set__time = buffer['time'], | |
74 | set__data = buffer['data'] |
|
74 | set__data = buffer['data'] | |
75 | ) |
|
75 | ) | |
76 |
|
76 | |||
77 | #data.save() |
|
77 | #data.save() | |
78 |
|
78 | |||
79 | if datetime.now().date() == dt.date(): |
|
79 | if datetime.now().date() == dt.date(): | |
80 | return True |
|
80 | return True | |
81 |
|
81 | |||
82 | return False |
|
82 | return False | |
83 |
|
83 | |||
84 | # Function that is checking the state of my clients every 30s |
|
84 | # Function that is checking the state of my clients every 30s | |
85 | def check_times(): |
|
85 | def check_times(): | |
86 |
|
86 | |||
87 | while True: |
|
87 | while True: | |
88 | dt = datetime.now() |
|
88 | dt = datetime.now() | |
89 | exps = ExpDetail.objects(date=dt.date()) |
|
89 | exps = ExpDetail.objects(date=dt.date()) | |
90 |
|
90 | |||
91 | for detail in exps: |
|
91 | for detail in exps: | |
92 | code = detail.experiment.code |
|
92 | code = detail.experiment.code | |
93 | plot = detail.plots()[0] |
|
93 | plot = detail.plots()[0] | |
94 | t = time.time() |
|
94 | t = time.time() | |
95 |
|
95 | |||
96 | message = { |
|
96 | message = { | |
97 | 'code': code, |
|
97 | 'code': code, | |
98 | 'time': detail['last_time'] |
|
98 | 'time': detail['last_time'] | |
99 | } |
|
99 | } | |
100 |
|
100 | |||
101 | if (t-detail['last_time']) > 6*detail['interval']: |
|
101 | if (t-detail['last_time']) > 6*detail['interval']: | |
102 | value = 'danger' |
|
102 | value = 'danger' | |
103 | elif (t-detail['last_time']) > 3*detail['interval']: |
|
103 | elif (t-detail['last_time']) > 3*detail['interval']: | |
104 | value = 'warning' |
|
104 | value = 'warning' | |
105 | else: |
|
105 | else: | |
106 | value = 'success' |
|
106 | value = 'success' | |
107 |
|
107 | |||
108 | print(('{} {} {} {} {}'.format(code, t, detail['last_time'], (t-detail['last_time']), value))) |
|
108 | print(('{} {} {} {} {}'.format(code, t, detail['last_time'], (t-detail['last_time']), value))) | |
109 |
|
109 | |||
110 | message['value'] = value |
|
110 | message['value'] = value | |
111 |
|
111 | |||
112 | async_to_sync(channel.group_send)( |
|
112 | async_to_sync(channel.group_send)( | |
113 | 'main', |
|
113 | 'main', | |
114 | { |
|
114 | { | |
115 | 'type': 'zmq_message', |
|
115 | 'type': 'zmq_message', | |
116 | 'message': json.dumps(message) |
|
116 | 'message': json.dumps(message) | |
117 | } |
|
117 | } | |
118 | ) |
|
118 | ) | |
119 |
|
119 | |||
120 | time.sleep(60) |
|
120 | time.sleep(60) | |
121 |
|
121 | |||
122 | def main(): |
|
122 | def main(): | |
123 | print('Starting ZMQ server...') |
|
123 | print('Starting ZMQ server...') | |
124 | context = zmq.Context() |
|
124 | context = zmq.Context() | |
125 | receiver = context.socket(zmq.REP) |
|
125 | receiver = context.socket(zmq.REP) | |
126 | receiver.bind("tcp://0.0.0.0:4444") |
|
126 | receiver.bind("tcp://0.0.0.0:4444") | |
127 | t = Thread(target=check_times) |
|
127 | t = Thread(target=check_times) | |
128 | t.start() |
|
128 | t.start() | |
129 |
|
129 | |||
130 | while True: |
|
130 | while True: | |
131 |
|
131 | |||
132 | buffer = receiver.recv_json() |
|
132 | try: | |
|
133 | buffer = receiver.recv_json() | |||
|
134 | except: | |||
|
135 | continue | |||
133 | if not isinstance(buffer, dict): |
|
136 | if not isinstance(buffer, dict): | |
134 | print('Invalid data received: {}').format(str(buffer)) |
|
137 | print('Invalid data received: {}').format(str(buffer)) | |
135 | continue |
|
138 | continue | |
136 |
|
139 | |||
137 | if not update(buffer): |
|
140 | if not update(buffer): | |
138 | print('Updating {} for code {}'.format( |
|
141 | print('Updating {} for code {}'.format( | |
139 | buffer['plot'], |
|
142 | buffer['plot'], | |
140 | buffer['code'] |
|
143 | buffer['code'] | |
141 | )) |
|
144 | )) | |
142 | else: |
|
145 | else: | |
143 | buffer['time'] = [buffer['time']] |
|
146 | buffer['time'] = [buffer['time']] | |
144 | group = '{}_{}'.format( |
|
147 | group = '{}_{}'.format( | |
145 | buffer['code'], |
|
148 | buffer['code'], | |
146 | buffer['plot'].replace(' ', '_').lower() |
|
149 | buffer['plot'].replace(' ', '_').lower() | |
147 | ) |
|
150 | ) | |
148 | async_to_sync(channel.group_send)( |
|
151 | async_to_sync(channel.group_send)( | |
149 | group, |
|
152 | group, | |
150 | { |
|
153 | { | |
151 | 'type': 'zmq_message', |
|
154 | 'type': 'zmq_message', | |
152 | 'message': simplejson.dumps(buffer, ignore_nan=True) |
|
155 | 'message': simplejson.dumps(buffer, ignore_nan=True) | |
153 | } |
|
156 | } | |
154 | ) |
|
157 | ) | |
155 |
|
158 | |||
156 | print('Sending to group {}_{} - {} bytes'.format( |
|
159 | print('Sending to group {}_{} - {} bytes'.format( | |
157 | buffer['code'], |
|
160 | buffer['code'], | |
158 | buffer['plot'].replace(' ', '_').lower(), |
|
161 | buffer['plot'].replace(' ', '_').lower(), | |
159 | len(str(buffer))) |
|
162 | len(str(buffer))) | |
160 | ) |
|
163 | ) | |
161 |
|
164 | |||
162 | receiver.send_string('ok') |
|
165 | receiver.send_string('ok') | |
163 |
|
166 | |||
164 | receiver.close() |
|
167 | receiver.close() | |
165 | context.term() |
|
168 | context.term() | |
166 |
|
169 | |||
167 | if __name__=='__main__': |
|
170 | if __name__=='__main__': | |
168 | loaddata() |
|
171 | loaddata() | |
169 | main() |
|
172 | main() |
@@ -1,430 +1,430 | |||||
1 | """ |
|
1 | """ | |
2 | The TIME_CONVERSIONS.py module gathers classes and functions for time system transformations |
|
2 | The TIME_CONVERSIONS.py module gathers classes and functions for time system transformations | |
3 | (e.g. between seconds from 1970 to datetime format). |
|
3 | (e.g. between seconds from 1970 to datetime format). | |
4 |
|
4 | |||
5 | MODULES CALLED: |
|
5 | MODULES CALLED: | |
6 | NUMPY, TIME, DATETIME, CALENDAR |
|
6 | NUMPY, TIME, DATETIME, CALENDAR | |
7 |
|
7 | |||
8 | MODIFICATION HISTORY: |
|
8 | MODIFICATION HISTORY: | |
9 | Created by Ing. Freddy Galindo (frederickgalindo@gmail.com). ROJ Aug 13, 2009. |
|
9 | Created by Ing. Freddy Galindo (frederickgalindo@gmail.com). ROJ Aug 13, 2009. | |
10 | """ |
|
10 | """ | |
11 |
|
11 | |||
12 | import numpy |
|
12 | import numpy | |
13 | import time |
|
13 | import time | |
14 | from datetime import datetime as dt |
|
14 | from datetime import datetime as dt | |
15 | import calendar |
|
15 | import calendar | |
16 |
|
16 | |||
17 | class Time: |
|
17 | class Time: | |
18 | """ |
|
18 | """ | |
19 | time(year,month,dom,hour,min,secs) |
|
19 | time(year,month,dom,hour,min,secs) | |
20 |
|
20 | |||
21 | An object represents a date and time of certain event.. |
|
21 | An object represents a date and time of certain event.. | |
22 |
|
22 | |||
23 | Parameters |
|
23 | Parameters | |
24 | ---------- |
|
24 | ---------- | |
25 | YEAR = Number of the desired year. Year must be valid values from the civil calendar. |
|
25 | YEAR = Number of the desired year. Year must be valid values from the civil calendar. | |
26 | Years B.C.E must be represented as negative integers. Years in the common era are repre- |
|
26 | Years B.C.E must be represented as negative integers. Years in the common era are repre- | |
27 | sented as positive integers. In particular, note that there is no year 0 in the civil |
|
27 | sented as positive integers. In particular, note that there is no year 0 in the civil | |
28 | calendar. 1 B.C.E. (-1) is followed by 1 C.E. (1). |
|
28 | calendar. 1 B.C.E. (-1) is followed by 1 C.E. (1). | |
29 |
|
29 | |||
30 | MONTH = Number of desired month (1=Jan, ..., 12=December). |
|
30 | MONTH = Number of desired month (1=Jan, ..., 12=December). | |
31 |
|
31 | |||
32 | DOM = Number of day of the month. |
|
32 | DOM = Number of day of the month. | |
33 |
|
33 | |||
34 | HOUR = Number of the hour of the day. By default hour=0 |
|
34 | HOUR = Number of the hour of the day. By default hour=0 | |
35 |
|
35 | |||
36 | MINS = Number of the minute of the hour. By default min=0 |
|
36 | MINS = Number of the minute of the hour. By default min=0 | |
37 |
|
37 | |||
38 | SECS = Number of the second of the minute. By default secs=0. |
|
38 | SECS = Number of the second of the minute. By default secs=0. | |
39 |
|
39 | |||
40 | Examples |
|
40 | Examples | |
41 | -------- |
|
41 | -------- | |
42 | time_info = time(2008,9,30,12,30,00) |
|
42 | time_info = time(2008,9,30,12,30,00) | |
43 |
|
43 | |||
44 | time_info = time(2008,9,30) |
|
44 | time_info = time(2008,9,30) | |
45 | """ |
|
45 | """ | |
46 |
|
46 | |||
47 | def __init__(self, year=None, month=None, dom=None, hour=0, mins=0, secs=0): |
|
47 | def __init__(self, year=None, month=None, dom=None, hour=0, mins=0, secs=0): | |
48 | # If one the first three inputs are not defined, it takes the current date. |
|
48 | # If one the first three inputs are not defined, it takes the current date. | |
49 | date = time.localtime() |
|
49 | date = time.localtime() | |
50 | if year==None:year=date[0] |
|
50 | if year==None:year=date[0] | |
51 | if month==None:month=date[1] |
|
51 | if month==None:month=date[1] | |
52 | if dom==None:dom=date[2] |
|
52 | if dom==None:dom=date[2] | |
53 |
|
53 | |||
54 | # Converting to arrays |
|
54 | # Converting to arrays | |
55 | year = numpy.array([year]); month = numpy.array([month]); dom = numpy.array([dom]) |
|
55 | year = numpy.array([year]); month = numpy.array([month]); dom = numpy.array([dom]) | |
56 | hour = numpy.array([hour]); mins = numpy.array([mins]); secs = numpy.array([secs]) |
|
56 | hour = numpy.array([hour]); mins = numpy.array([mins]); secs = numpy.array([secs]) | |
57 |
|
57 | |||
58 | # Defining time information object. |
|
58 | # Defining time information object. | |
59 | self.year = numpy.atleast_1d(year) |
|
59 | self.year = numpy.atleast_1d(year) | |
60 | self.month = numpy.atleast_1d(month) |
|
60 | self.month = numpy.atleast_1d(month) | |
61 | self.dom = numpy.atleast_1d(dom) |
|
61 | self.dom = numpy.atleast_1d(dom) | |
62 | self.hour = numpy.atleast_1d(hour) |
|
62 | self.hour = numpy.atleast_1d(hour) | |
63 | self.mins = numpy.atleast_1d(mins) |
|
63 | self.mins = numpy.atleast_1d(mins) | |
64 | self.secs = numpy.atleast_1d(secs) |
|
64 | self.secs = numpy.atleast_1d(secs) | |
65 |
|
65 | |||
66 | def change2julday(self): |
|
66 | def change2julday(self): | |
67 | """ |
|
67 | """ | |
68 | Converts a datetime to Julian days. |
|
68 | Converts a datetime to Julian days. | |
69 | """ |
|
69 | """ | |
70 |
|
70 | |||
71 | # Defining constants |
|
71 | # Defining constants | |
72 | greg = 2299171 # incorrect Julian day for Oct, 25, 1582. |
|
72 | greg = 2299171 # incorrect Julian day for Oct, 25, 1582. | |
73 | min_calendar = -4716 |
|
73 | min_calendar = -4716 | |
74 | max_calendar = 5000000 |
|
74 | max_calendar = 5000000 | |
75 |
|
75 | |||
76 | min_year = numpy.nanmin(self.year) |
|
76 | min_year = numpy.nanmin(self.year) | |
77 | max_year = numpy.nanmax(self.year) |
|
77 | max_year = numpy.nanmax(self.year) | |
78 | if (min_year<min_calendar) or (max_year>max_calendar): |
|
78 | if (min_year<min_calendar) or (max_year>max_calendar): | |
79 | print ("Value of Julian date is out of allowed range") |
|
79 | print ("Value of Julian date is out of allowed range") | |
80 | return -1 |
|
80 | return -1 | |
81 |
|
81 | |||
82 | noyear = numpy.sum(self.year==0) |
|
82 | noyear = numpy.sum(self.year==0) | |
83 | if noyear>0: |
|
83 | if noyear>0: | |
84 | print ("There is no year zero in the civil calendar") |
|
84 | print ("There is no year zero in the civil calendar") | |
85 | return -1 |
|
85 | return -1 | |
86 |
|
86 | |||
87 | # Knowing if the year is less than 0. |
|
87 | # Knowing if the year is less than 0. | |
88 | bc = self.year<0 |
|
88 | bc = self.year<0 | |
89 |
|
89 | |||
90 | # Knowing if the month is less than March. |
|
90 | # Knowing if the month is less than March. | |
91 | inJanFeb = self.month<=2 |
|
91 | inJanFeb = self.month<=2 | |
92 |
|
92 | |||
93 | jy = self.year + bc - inJanFeb |
|
93 | jy = self.year + bc - inJanFeb | |
94 | jm = self.month + (1 + 12*inJanFeb) |
|
94 | jm = self.month + (1 + 12*inJanFeb) | |
95 |
|
95 | |||
96 | # Computing Julian days. |
|
96 | # Computing Julian days. | |
97 | jul= numpy.floor(365.25*jy) + numpy.floor(30.6001*jm) + (self.dom+1720995.0) |
|
97 | jul= numpy.floor(365.25*jy) + numpy.floor(30.6001*jm) + (self.dom+1720995.0) | |
98 |
|
98 | |||
99 | # Test whether to change to Gregorian Calendar |
|
99 | # Test whether to change to Gregorian Calendar | |
100 | if numpy.min(jul) >= greg: |
|
100 | if numpy.min(jul) >= greg: | |
101 | ja = numpy.int32(0.01*jy) |
|
101 | ja = numpy.int32(0.01*jy) | |
102 | jul = jul + 2 - ja + numpy.int32(0.25*ja) |
|
102 | jul = jul + 2 - ja + numpy.int32(0.25*ja) | |
103 | else: |
|
103 | else: | |
104 | gregchange = numpy.where(jul >= greg) |
|
104 | gregchange = numpy.where(jul >= greg) | |
105 | if gregchange[0].size>0: |
|
105 | if gregchange[0].size>0: | |
106 | ja = numpy.int32(0.01 + jy[gregchange]) |
|
106 | ja = numpy.int32(0.01 + jy[gregchange]) | |
107 | jy[gregchange] = jy[gregchange] + 2 - ja + numpy.int32(0.25*ja) |
|
107 | jy[gregchange] = jy[gregchange] + 2 - ja + numpy.int32(0.25*ja) | |
108 |
|
108 | |||
109 | # Determining machine-specific parameters affecting floating-point. |
|
109 | # Determining machine-specific parameters affecting floating-point. | |
110 | eps = 0.0 # Replace this line for a function to get precision. |
|
110 | eps = 0.0 # Replace this line for a function to get precision. | |
111 | eps = abs(jul)*0.0 > eps |
|
111 | eps = abs(jul)*0.0 > eps | |
112 |
|
112 | |||
113 | jul = jul + (self.hour/24. -0.5) + (self.mins/1440.) + (self.secs/86400.) + eps |
|
113 | jul = jul + (self.hour/24. -0.5) + (self.mins/1440.) + (self.secs/86400.) + eps | |
114 |
|
114 | |||
115 | return jul[0] |
|
115 | return jul[0] | |
116 |
|
116 | |||
117 | def change2secs(self): |
|
117 | def change2secs(self): | |
118 | """ |
|
118 | """ | |
119 | Converts datetime to number of seconds respect to 1970. |
|
119 | Converts datetime to number of seconds respect to 1970. | |
120 | """ |
|
120 | """ | |
121 |
|
121 | |||
122 | dtime = dt(self.year, self.month, self.dom) |
|
122 | dtime = dt(self.year[0], self.month[0], self.dom[0]) | |
123 | return (dtime-dt(1970, 1, 1)).total_seconds() |
|
123 | return (dtime-dt(1970, 1, 1)).total_seconds() | |
124 |
|
124 | |||
125 | year = self.year |
|
125 | year = self.year | |
126 | if year.size>1: year = year[0] |
|
126 | if year.size>1: year = year[0] | |
127 |
|
127 | |||
128 | month = self.month |
|
128 | month = self.month | |
129 | if month.size>1: month = month[0] |
|
129 | if month.size>1: month = month[0] | |
130 |
|
130 | |||
131 | dom = self.dom |
|
131 | dom = self.dom | |
132 | if dom.size>1: dom = dom[0] |
|
132 | if dom.size>1: dom = dom[0] | |
133 |
|
133 | |||
134 | # Resizing hour, mins and secs if it was necessary. |
|
134 | # Resizing hour, mins and secs if it was necessary. | |
135 | hour = self.hour |
|
135 | hour = self.hour | |
136 | if hour.size>1:hour = hour[0] |
|
136 | if hour.size>1:hour = hour[0] | |
137 | if hour.size==1:hour = numpy.resize(hour,year.size) |
|
137 | if hour.size==1:hour = numpy.resize(hour,year.size) | |
138 |
|
138 | |||
139 | mins = self.mins |
|
139 | mins = self.mins | |
140 | if mins.size>1:mins = mins[0] |
|
140 | if mins.size>1:mins = mins[0] | |
141 | if mins.size==1:mins = numpy.resize(mins,year.size) |
|
141 | if mins.size==1:mins = numpy.resize(mins,year.size) | |
142 |
|
142 | |||
143 | secs = self.secs |
|
143 | secs = self.secs | |
144 | if secs.size>1:secs = secs[0] |
|
144 | if secs.size>1:secs = secs[0] | |
145 | if secs.size==1:secs = numpy.resize(secs,year.size) |
|
145 | if secs.size==1:secs = numpy.resize(secs,year.size) | |
146 |
|
146 | |||
147 | # Using time.mktime to compute seconds respect to 1970. |
|
147 | # Using time.mktime to compute seconds respect to 1970. | |
148 | secs1970 = numpy.zeros(year.size) |
|
148 | secs1970 = numpy.zeros(year.size) | |
149 | for ii in numpy.arange(year.size): |
|
149 | for ii in numpy.arange(year.size): | |
150 | secs1970[ii] = time.mktime((int(year[ii]),int(month[ii]),int(dom[ii]),\ |
|
150 | secs1970[ii] = time.mktime((int(year[ii]),int(month[ii]),int(dom[ii]),\ | |
151 | int(hour[ii]),int(mins[ii]),int(secs[ii]),0,0,0)) |
|
151 | int(hour[ii]),int(mins[ii]),int(secs[ii]),0,0,0)) | |
152 |
|
152 | |||
153 | secs1970 = numpy.int32(secs1970 - time.timezone) |
|
153 | secs1970 = numpy.int32(secs1970 - time.timezone) | |
154 |
|
154 | |||
155 | return secs1970 |
|
155 | return secs1970 | |
156 |
|
156 | |||
157 | def change2strdate(self,mode=1): |
|
157 | def change2strdate(self,mode=1): | |
158 | """ |
|
158 | """ | |
159 | change2strdate method converts a date and time of certain event to date string. The |
|
159 | change2strdate method converts a date and time of certain event to date string. The | |
160 | string format is like localtime (e.g. Fri Oct 9 15:00:19 2009). |
|
160 | string format is like localtime (e.g. Fri Oct 9 15:00:19 2009). | |
161 |
|
161 | |||
162 | Parameters |
|
162 | Parameters | |
163 | ---------- |
|
163 | ---------- | |
164 | None. |
|
164 | None. | |
165 |
|
165 | |||
166 | Return |
|
166 | Return | |
167 | ------ |
|
167 | ------ | |
168 |
|
168 | |||
169 | Modification History |
|
169 | Modification History | |
170 | -------------------- |
|
170 | -------------------- | |
171 | Created by Freddy R. Galindo, ROJ, 09 October 2009. |
|
171 | Created by Freddy R. Galindo, ROJ, 09 October 2009. | |
172 |
|
172 | |||
173 | """ |
|
173 | """ | |
174 |
|
174 | |||
175 | secs = numpy.atleast_1d(self.change2secs()) |
|
175 | secs = numpy.atleast_1d(self.change2secs()) | |
176 | strdate = [] |
|
176 | strdate = [] | |
177 | for ii in numpy.arange(numpy.size(secs)): |
|
177 | for ii in numpy.arange(numpy.size(secs)): | |
178 | secs_tmp = time.localtime(secs[ii] + time.timezone) |
|
178 | secs_tmp = time.localtime(secs[ii] + time.timezone) | |
179 | if mode==1: |
|
179 | if mode==1: | |
180 | strdate.append(time.strftime("%d-%b-%Y (%j) %H:%M:%S",secs_tmp)) |
|
180 | strdate.append(time.strftime("%d-%b-%Y (%j) %H:%M:%S",secs_tmp)) | |
181 | elif mode==2: |
|
181 | elif mode==2: | |
182 | strdate.append(time.strftime("%d-%b-%Y (%j)",secs_tmp)) |
|
182 | strdate.append(time.strftime("%d-%b-%Y (%j)",secs_tmp)) | |
183 |
|
183 | |||
184 | strdate = numpy.array(strdate) |
|
184 | strdate = numpy.array(strdate) | |
185 |
|
185 | |||
186 | return strdate |
|
186 | return strdate | |
187 |
|
187 | |||
188 |
|
188 | |||
189 | class Secs: |
|
189 | class Secs: | |
190 | """ |
|
190 | """ | |
191 | secs(secs): |
|
191 | secs(secs): | |
192 |
|
192 | |||
193 | An object represents the number of seconds respect to 1970. |
|
193 | An object represents the number of seconds respect to 1970. | |
194 |
|
194 | |||
195 | Parameters |
|
195 | Parameters | |
196 | ---------- |
|
196 | ---------- | |
197 |
|
197 | |||
198 | SECS = A scalar or array giving the number of seconds respect to 1970. |
|
198 | SECS = A scalar or array giving the number of seconds respect to 1970. | |
199 |
|
199 | |||
200 | Example: |
|
200 | Example: | |
201 | -------- |
|
201 | -------- | |
202 | secs_info = secs(1251241373) |
|
202 | secs_info = secs(1251241373) | |
203 |
|
203 | |||
204 | secs_info = secs([1251241373,1251241383,1251241393]) |
|
204 | secs_info = secs([1251241373,1251241383,1251241393]) | |
205 | """ |
|
205 | """ | |
206 | def __init__(self,secs): |
|
206 | def __init__(self,secs): | |
207 | self.secs = secs |
|
207 | self.secs = secs | |
208 |
|
208 | |||
209 | def change2julday(self): |
|
209 | def change2julday(self): | |
210 | """ |
|
210 | """ | |
211 | Convert seconds from 1970 to Julian days. |
|
211 | Convert seconds from 1970 to Julian days. | |
212 | """ |
|
212 | """ | |
213 |
|
213 | |||
214 | secs_1970 = time(1970,1,1,0,0,0).change2julday() |
|
214 | secs_1970 = time(1970,1,1,0,0,0).change2julday() | |
215 |
|
215 | |||
216 | julian = self.secs/86400.0 + secs_1970 |
|
216 | julian = self.secs/86400.0 + secs_1970 | |
217 |
|
217 | |||
218 | return julian |
|
218 | return julian | |
219 |
|
219 | |||
220 | def change2time(self): |
|
220 | def change2time(self): | |
221 | """ |
|
221 | """ | |
222 | Converts seconds from 1970 to datetime. |
|
222 | Converts seconds from 1970 to datetime. | |
223 | """ |
|
223 | """ | |
224 |
|
224 | |||
225 | secs1970 = numpy.atleast_1d(self.secs) |
|
225 | secs1970 = numpy.atleast_1d(self.secs) | |
226 |
|
226 | |||
227 | datetime = numpy.zeros((9,secs1970.size)) |
|
227 | datetime = numpy.zeros((9,secs1970.size)) | |
228 | for ii in numpy.arange(secs1970.size): |
|
228 | for ii in numpy.arange(secs1970.size): | |
229 | tuple = time.gmtime(secs1970[ii]) |
|
229 | tuple = time.gmtime(secs1970[ii]) | |
230 | datetime[0,ii] = tuple[0] |
|
230 | datetime[0,ii] = tuple[0] | |
231 | datetime[1,ii] = tuple[1] |
|
231 | datetime[1,ii] = tuple[1] | |
232 | datetime[2,ii] = tuple[2] |
|
232 | datetime[2,ii] = tuple[2] | |
233 | datetime[3,ii] = tuple[3] |
|
233 | datetime[3,ii] = tuple[3] | |
234 | datetime[4,ii] = tuple[4] |
|
234 | datetime[4,ii] = tuple[4] | |
235 | datetime[5,ii] = tuple[5] |
|
235 | datetime[5,ii] = tuple[5] | |
236 | datetime[6,ii] = tuple[6] |
|
236 | datetime[6,ii] = tuple[6] | |
237 | datetime[7,ii] = tuple[7] |
|
237 | datetime[7,ii] = tuple[7] | |
238 | datetime[8,ii] = tuple[8] |
|
238 | datetime[8,ii] = tuple[8] | |
239 |
|
239 | |||
240 | datetime = numpy.int32(datetime) |
|
240 | datetime = numpy.int32(datetime) | |
241 |
|
241 | |||
242 | return datetime |
|
242 | return datetime | |
243 |
|
243 | |||
244 |
|
244 | |||
245 | class Julian: |
|
245 | class Julian: | |
246 | """ |
|
246 | """ | |
247 | julian(julian): |
|
247 | julian(julian): | |
248 |
|
248 | |||
249 | An object represents julian days. |
|
249 | An object represents julian days. | |
250 |
|
250 | |||
251 | Parameters |
|
251 | Parameters | |
252 | ---------- |
|
252 | ---------- | |
253 |
|
253 | |||
254 | JULIAN = A scalar or array giving the julina days. |
|
254 | JULIAN = A scalar or array giving the julina days. | |
255 |
|
255 | |||
256 | Example: |
|
256 | Example: | |
257 | -------- |
|
257 | -------- | |
258 | julian_info = julian(2454740) |
|
258 | julian_info = julian(2454740) | |
259 |
|
259 | |||
260 | julian_info = julian([2454740,2454760,2454780]) |
|
260 | julian_info = julian([2454740,2454760,2454780]) | |
261 | """ |
|
261 | """ | |
262 | def __init__(self,julian): |
|
262 | def __init__(self,julian): | |
263 | self.julian = numpy.atleast_1d(julian) |
|
263 | self.julian = numpy.atleast_1d(julian) | |
264 |
|
264 | |||
265 | def change2time(self): |
|
265 | def change2time(self): | |
266 | """ |
|
266 | """ | |
267 | change2time method converts from julian day to calendar date and time. |
|
267 | change2time method converts from julian day to calendar date and time. | |
268 |
|
268 | |||
269 | Return |
|
269 | Return | |
270 | ------ |
|
270 | ------ | |
271 | year = An array giving the year of the desired julian day. |
|
271 | year = An array giving the year of the desired julian day. | |
272 | month = An array giving the month of the desired julian day. |
|
272 | month = An array giving the month of the desired julian day. | |
273 | dom = An array giving the day of the desired julian day. |
|
273 | dom = An array giving the day of the desired julian day. | |
274 | hour = An array giving the hour of the desired julian day. |
|
274 | hour = An array giving the hour of the desired julian day. | |
275 | mins = An array giving the minute of the desired julian day. |
|
275 | mins = An array giving the minute of the desired julian day. | |
276 | secs = An array giving the second of the desired julian day. |
|
276 | secs = An array giving the second of the desired julian day. | |
277 |
|
277 | |||
278 | Examples |
|
278 | Examples | |
279 | -------- |
|
279 | -------- | |
280 | >> jd = 2455119.0 |
|
280 | >> jd = 2455119.0 | |
281 | >> [yy,mo,dd,hh,mi,ss] = TimeTools.julian(jd).change2time() |
|
281 | >> [yy,mo,dd,hh,mi,ss] = TimeTools.julian(jd).change2time() | |
282 | >> print [yy,mo,dd,hh,mi,ss] |
|
282 | >> print [yy,mo,dd,hh,mi,ss] | |
283 | [2009] [10] [ 14.] [ 12.] [ 0.] [ 0.] |
|
283 | [2009] [10] [ 14.] [ 12.] [ 0.] [ 0.] | |
284 |
|
284 | |||
285 | Modification history |
|
285 | Modification history | |
286 | -------------------- |
|
286 | -------------------- | |
287 | Translated from "Numerical Recipies in C", by William H. Press, Brian P. Flannery, |
|
287 | Translated from "Numerical Recipies in C", by William H. Press, Brian P. Flannery, | |
288 | Saul A. Teukolsky, and William T. Vetterling. Cambridge University Press, 1988. |
|
288 | Saul A. Teukolsky, and William T. Vetterling. Cambridge University Press, 1988. | |
289 | Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009. |
|
289 | Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009. | |
290 | """ |
|
290 | """ | |
291 |
|
291 | |||
292 | min_julian = -1095 |
|
292 | min_julian = -1095 | |
293 | max_julian = 1827933925 |
|
293 | max_julian = 1827933925 | |
294 | if (numpy.min(self.julian) < min_julian) or (numpy.max(self.julian) > max_julian): |
|
294 | if (numpy.min(self.julian) < min_julian) or (numpy.max(self.julian) > max_julian): | |
295 | print ('Value of Julian date is out of allowed range.') |
|
295 | print ('Value of Julian date is out of allowed range.') | |
296 | return None |
|
296 | return None | |
297 |
|
297 | |||
298 | # Beginning of Gregorian calendar |
|
298 | # Beginning of Gregorian calendar | |
299 | igreg = 2299161 |
|
299 | igreg = 2299161 | |
300 | julLong = numpy.floor(self.julian + 0.5) |
|
300 | julLong = numpy.floor(self.julian + 0.5) | |
301 | minJul = numpy.min(julLong) |
|
301 | minJul = numpy.min(julLong) | |
302 |
|
302 | |||
303 | if (minJul >= igreg): |
|
303 | if (minJul >= igreg): | |
304 | # All are Gregorian |
|
304 | # All are Gregorian | |
305 | jalpha = numpy.int32(((julLong - 1867216) - 0.25)/36524.25) |
|
305 | jalpha = numpy.int32(((julLong - 1867216) - 0.25)/36524.25) | |
306 | ja = julLong + 1 + jalpha - numpy.int32(0.25*jalpha) |
|
306 | ja = julLong + 1 + jalpha - numpy.int32(0.25*jalpha) | |
307 | else: |
|
307 | else: | |
308 | ja = julLong |
|
308 | ja = julLong | |
309 | gregChange = numpy.where(julLong >= igreg) |
|
309 | gregChange = numpy.where(julLong >= igreg) | |
310 | if gregChange[0].size>0: |
|
310 | if gregChange[0].size>0: | |
311 | jalpha = numpy.int32(((julLong[gregChange]-1867216) - 0.25)/36524.25) |
|
311 | jalpha = numpy.int32(((julLong[gregChange]-1867216) - 0.25)/36524.25) | |
312 | ja[gregChange] = julLong[gregChange]+1+jalpha-numpy.int32(0.25*jalpha) |
|
312 | ja[gregChange] = julLong[gregChange]+1+jalpha-numpy.int32(0.25*jalpha) | |
313 |
|
313 | |||
314 | # clear memory. |
|
314 | # clear memory. | |
315 | jalpha = -1 |
|
315 | jalpha = -1 | |
316 |
|
316 | |||
317 | jb = ja + 1524 |
|
317 | jb = ja + 1524 | |
318 | jc = numpy.int32(6680. + ((jb-2439870)-122.1)/365.25) |
|
318 | jc = numpy.int32(6680. + ((jb-2439870)-122.1)/365.25) | |
319 | jd = numpy.int32(365.*jc + (0.25*jc)) |
|
319 | jd = numpy.int32(365.*jc + (0.25*jc)) | |
320 | je = numpy.int32((jb - jd)/30.6001) |
|
320 | je = numpy.int32((jb - jd)/30.6001) | |
321 |
|
321 | |||
322 | dom = jb - jd - numpy.int32(30.6001*je) |
|
322 | dom = jb - jd - numpy.int32(30.6001*je) | |
323 | month = je - 1 |
|
323 | month = je - 1 | |
324 | month = ((month - 1) % 12) + 1 |
|
324 | month = ((month - 1) % 12) + 1 | |
325 | month = numpy.atleast_1d(month) |
|
325 | month = numpy.atleast_1d(month) | |
326 | year = jc - 4715 |
|
326 | year = jc - 4715 | |
327 | year = year - (month > 2)*1 |
|
327 | year = year - (month > 2)*1 | |
328 | year = year - (year <= 0)*1 |
|
328 | year = year - (year <= 0)*1 | |
329 | year = numpy.atleast_1d(year) |
|
329 | year = numpy.atleast_1d(year) | |
330 |
|
330 | |||
331 | # Getting hours, minutes, seconds |
|
331 | # Getting hours, minutes, seconds | |
332 | fraction = self.julian + 0.5 - julLong |
|
332 | fraction = self.julian + 0.5 - julLong | |
333 | eps_0 = dom*0.0 + 1.0e-12 |
|
333 | eps_0 = dom*0.0 + 1.0e-12 | |
334 | eps_1 = 1.0e-12*numpy.abs(julLong) |
|
334 | eps_1 = 1.0e-12*numpy.abs(julLong) | |
335 | eps = (eps_0>eps_1)*eps_0 + (eps_0<=eps_1)*eps_1 |
|
335 | eps = (eps_0>eps_1)*eps_0 + (eps_0<=eps_1)*eps_1 | |
336 |
|
336 | |||
337 | hour_0 = dom*0 + 23 |
|
337 | hour_0 = dom*0 + 23 | |
338 | hour_2 = dom*0 + 0 |
|
338 | hour_2 = dom*0 + 0 | |
339 | hour_1 = numpy.floor(fraction*24.0 + eps) |
|
339 | hour_1 = numpy.floor(fraction*24.0 + eps) | |
340 | hour = ((hour_1>hour_0)*23) + ((hour_1<=hour_0)*hour_1) |
|
340 | hour = ((hour_1>hour_0)*23) + ((hour_1<=hour_0)*hour_1) | |
341 | hour = ((hour_1<hour_2)*0) + ((hour_1>=hour_2)*hour_1) |
|
341 | hour = ((hour_1<hour_2)*0) + ((hour_1>=hour_2)*hour_1) | |
342 |
|
342 | |||
343 | fraction = fraction - (hour/24.0) |
|
343 | fraction = fraction - (hour/24.0) | |
344 | mins_0 = dom*0 + 59 |
|
344 | mins_0 = dom*0 + 59 | |
345 | mins_2 = dom*0 + 0 |
|
345 | mins_2 = dom*0 + 0 | |
346 | mins_1 = numpy.floor(fraction*1440.0 + eps) |
|
346 | mins_1 = numpy.floor(fraction*1440.0 + eps) | |
347 | mins = ((mins_1>mins_0)*59) + ((mins_1<=mins_0)*mins_1) |
|
347 | mins = ((mins_1>mins_0)*59) + ((mins_1<=mins_0)*mins_1) | |
348 | mins = ((mins_1<mins_2)*0) + ((mins_1>=mins_2)*mins_1) |
|
348 | mins = ((mins_1<mins_2)*0) + ((mins_1>=mins_2)*mins_1) | |
349 |
|
349 | |||
350 | secs_2 = dom*0 + 0 |
|
350 | secs_2 = dom*0 + 0 | |
351 | secs_1 = (fraction - mins/1440.0)*86400.0 |
|
351 | secs_1 = (fraction - mins/1440.0)*86400.0 | |
352 | secs = ((secs_1<secs_2)*0) + ((secs_1>=secs_2)*secs_1) |
|
352 | secs = ((secs_1<secs_2)*0) + ((secs_1>=secs_2)*secs_1) | |
353 |
|
353 | |||
354 | return year,month,dom,hour,mins,secs |
|
354 | return year,month,dom,hour,mins,secs | |
355 |
|
355 | |||
356 | def change2secs(self): |
|
356 | def change2secs(self): | |
357 | """ |
|
357 | """ | |
358 | Converts from Julian days to seconds from 1970. |
|
358 | Converts from Julian days to seconds from 1970. | |
359 | """ |
|
359 | """ | |
360 |
|
360 | |||
361 | jul_1970 = Time(1970,1,1,0,0,0).change2julday() |
|
361 | jul_1970 = Time(1970,1,1,0,0,0).change2julday() | |
362 |
|
362 | |||
363 | secs = numpy.int32((self.julian - jul_1970)*86400) |
|
363 | secs = numpy.int32((self.julian - jul_1970)*86400) | |
364 |
|
364 | |||
365 | return secs |
|
365 | return secs | |
366 |
|
366 | |||
367 | def change2lst(self,longitude=-76.8667): |
|
367 | def change2lst(self,longitude=-76.8667): | |
368 | """ |
|
368 | """ | |
369 | CT2LST converts from local civil time to local mean sideral time |
|
369 | CT2LST converts from local civil time to local mean sideral time | |
370 |
|
370 | |||
371 | longitude = The longitude in degrees (east of Greenwich) of the place for which |
|
371 | longitude = The longitude in degrees (east of Greenwich) of the place for which | |
372 | the local sideral time is desired, scalar. The Greenwich mean sideral time (GMST) |
|
372 | the local sideral time is desired, scalar. The Greenwich mean sideral time (GMST) | |
373 | can be found by setting longitude=0. |
|
373 | can be found by setting longitude=0. | |
374 | """ |
|
374 | """ | |
375 |
|
375 | |||
376 | # Useful constants, see Meus, p. 84 |
|
376 | # Useful constants, see Meus, p. 84 | |
377 | c = numpy.array([280.46061837, 360.98564736629, 0.000387933, 38710000.0]) |
|
377 | c = numpy.array([280.46061837, 360.98564736629, 0.000387933, 38710000.0]) | |
378 | jd2000 = 2451545.0 |
|
378 | jd2000 = 2451545.0 | |
379 | t0 = self.julian - jd2000 |
|
379 | t0 = self.julian - jd2000 | |
380 | t = t0/36525. |
|
380 | t = t0/36525. | |
381 |
|
381 | |||
382 | # Computing GST in seconds |
|
382 | # Computing GST in seconds | |
383 | theta = c[0] + (c[1]*t0) + (t**2)*(c[2]-t/c[3]) |
|
383 | theta = c[0] + (c[1]*t0) + (t**2)*(c[2]-t/c[3]) | |
384 |
|
384 | |||
385 | # Computing LST in hours |
|
385 | # Computing LST in hours | |
386 | lst = (theta + longitude)/15.0 |
|
386 | lst = (theta + longitude)/15.0 | |
387 | neg = numpy.where(lst < 0.0) |
|
387 | neg = numpy.where(lst < 0.0) | |
388 | if neg[0].size>0:lst[neg] = 24.0 + (lst[neg] % 24) |
|
388 | if neg[0].size>0:lst[neg] = 24.0 + (lst[neg] % 24) | |
389 | lst = lst % 24.0 |
|
389 | lst = lst % 24.0 | |
390 |
|
390 | |||
391 | return lst |
|
391 | return lst | |
392 |
|
392 | |||
393 |
|
393 | |||
394 | class date2doy: |
|
394 | class date2doy: | |
395 | def __init__(self,year,month,day): |
|
395 | def __init__(self,year,month,day): | |
396 | self.year = year |
|
396 | self.year = year | |
397 | self.month = month |
|
397 | self.month = month | |
398 | self.day = day |
|
398 | self.day = day | |
399 |
|
399 | |||
400 | def change2doy(self): |
|
400 | def change2doy(self): | |
401 | if calendar.isleap(self.year) == True: |
|
401 | if calendar.isleap(self.year) == True: | |
402 | tfactor = 1 |
|
402 | tfactor = 1 | |
403 | else: |
|
403 | else: | |
404 | tfactor = 2 |
|
404 | tfactor = 2 | |
405 |
|
405 | |||
406 | day = self.day |
|
406 | day = self.day | |
407 | month = self.month |
|
407 | month = self.month | |
408 |
|
408 | |||
409 | doy = numpy.floor((275*month)/9.0) - (tfactor*numpy.floor((month+9)/12.0)) + day - 30 |
|
409 | doy = numpy.floor((275*month)/9.0) - (tfactor*numpy.floor((month+9)/12.0)) + day - 30 | |
410 |
|
410 | |||
411 | return numpy.int32(doy) |
|
411 | return numpy.int32(doy) | |
412 |
|
412 | |||
413 |
|
413 | |||
414 | class Doy2Date: |
|
414 | class Doy2Date: | |
415 | def __init__(self,year,doy): |
|
415 | def __init__(self,year,doy): | |
416 | self.year = year |
|
416 | self.year = year | |
417 | self.doy = doy |
|
417 | self.doy = doy | |
418 |
|
418 | |||
419 | def change2date(self): |
|
419 | def change2date(self): | |
420 | months = numpy.arange(12) + 1 |
|
420 | months = numpy.arange(12) + 1 | |
421 |
|
421 | |||
422 | first_dem = date2doy(self.year,months,1) |
|
422 | first_dem = date2doy(self.year,months,1) | |
423 | first_dem = first_dem.change2doy() |
|
423 | first_dem = first_dem.change2doy() | |
424 |
|
424 | |||
425 | imm = numpy.where((self.doy - first_dem) > 0) |
|
425 | imm = numpy.where((self.doy - first_dem) > 0) | |
426 |
|
426 | |||
427 | month = imm[0].size |
|
427 | month = imm[0].size | |
428 | dom = self.doy -first_dem[month - 1] + 1 |
|
428 | dom = self.doy -first_dem[month - 1] + 1 | |
429 |
|
429 | |||
430 | return month, dom |
|
430 | return month, dom |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now