Blame view

src/alert_manager/tasks.py 9.73 KB
5b5566ab   haribo   added celery
1
2
3
from __future__ import absolute_import

from celery.task import Task
77816f10   haribo   Workflow implemen...
4
from common.RequestBuilder import RequestBuilder
5b5566ab   haribo   added celery
5

94336356   haribo   Added starting fi...
6
from django.conf import settings
5b5566ab   haribo   added celery
7
8
from django.templatetags.static import static
import socket
94336356   haribo   Added starting fi...
9
from pyrosapp.models import *
5b5566ab   haribo   added celery
10
11

import time
94336356   haribo   Added starting fi...
12
import voeventparse
5b5566ab   haribo   added celery
13

94336356   haribo   Added starting fi...
14
15
import os
from os.path import isfile, join
77816f10   haribo   Workflow implemen...
16
import observation_manager
bb45cd4a   haribo   Date: 25/05/2016
17
import majordome.TaskManager
7a79e25b   haribo   Date: 19/05/2016
18
from decimal import Decimal
7a79e25b   haribo   Date: 19/05/2016
19

5b5566ab   haribo   added celery
20
21
22
IP = '127.0.0.1'
PORT = 31569

1b341a0f   haribo   Date: 19/07/2016
23
TIMESTAMP_JD = 2440587.500000
94336356   haribo   Added starting fi...
24
25
26
VOEVENTS_PATH = "alert_manager/events_received"


5b5566ab   haribo   added celery
27
28
29
30
class alert_listener(Task):
    '''
        Launched at server start
        Listens to VOEvents, and create appropriate request when an event is received
94336356   haribo   Added starting fi...
31
    '''
5b5566ab   haribo   added celery
32
33

    def run(self):
94336356   haribo   Added starting fi...
34
35
36
37
38
39
        '''
            Is called at the beginning of the task
            Calls the function to get the new events in the VOEVENTS_PATH directory
            For each event, calls a fonction to analyze it
        '''

2ceea892   haribo   Date: 19/07/2016
40
        print("alert listener started")
94336356   haribo   Added starting fi...
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
        if settings.SIMULATION == False:
            self.old_files = [
                f for f in os.listdir(VOEVENTS_PATH) if isfile(join(VOEVENTS_PATH, f))]
            while True:
                fresh_events = self.get_fresh_events()
                for event in fresh_events:
                    self.analyze_event(event)
                time.sleep(1)
        else:
            self.run_simulation()

    def get_fresh_events(self):
        '''
            Reads in the VOEVENTS_PATH directory to see if there are new events to analyze
            :returns : A list containing the new files to analyze
        '''

        fresh_events = []
        files = [
            f for f in os.listdir(VOEVENTS_PATH) if isfile(join(VOEVENTS_PATH, f))]

        diff = list(set(files).difference(set(self.old_files)))

        for event in diff:
7a79e25b   haribo   Date: 19/05/2016
65
            print("New file found : %s" % (event,))
94336356   haribo   Added starting fi...
66
67
68
69
            fresh_events.append(event)
        self.old_files = files
        return fresh_events

2ceea892   haribo   Date: 19/07/2016
70
    def analyze_event(self, event_file):
94336356   haribo   Added starting fi...
71
72
73
74
        '''
            Opens and parse the voevent file
            Will create the request & the alert object related
        '''
2ceea892   haribo   Date: 19/07/2016
75
76
77

        # TODO: checker si c'est bien un voevent
        with open(os.path.join(VOEVENTS_PATH, event_file), 'rb') as f:
94336356   haribo   Added starting fi...
78
            voevent = voeventparse.load(f)
2ceea892   haribo   Date: 19/07/2016
79
        request = self.create_related_request(voevent, event_file)
94336356   haribo   Added starting fi...
80

2ceea892   haribo   Date: 19/07/2016
81
    def create_related_request(self, voevent, event_file):
94336356   haribo   Added starting fi...
82
83
84
85
        '''
            Creates a request object related to the voevent received.
            For the moment, it doesn't take care of the voevent content, and hardcode the sequences etc

2ceea892   haribo   Date: 19/07/2016
86
            :param voevent: Object resulting of the VOEvent parsing with voeventparse library
94336356   haribo   Added starting fi...
87
88
89
            :returns : The request
        '''

5d61cbfe   haribo   Just adding / rem...
90
        # TODO: utiliser le VOEvent et les stratégies pour créer une requête logique
94336356   haribo   Added starting fi...
91
92
        pyros_user = PyrosUser.objects.get(user__username="haribo")
        scientific_program = ScientificProgram.objects.get(name="GRB")
2ceea892   haribo   Date: 19/07/2016
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


        alert = self.get_alert_attributes(voevent, event_file)

        if alert != None:  # à changer, juste pour test
            alert.save()

        return None  # à virer, juste pour tester le parsing de VOEvent

        if alert == None:
            pass
            # TODO: handle error (surement un simple return)

        # Ici, je crée la requete avec le strategy builder
        # Et si il n'y a pas eu de souci, j'associe ma requete à mon alerte et c'est bon


#         request_builder = RequestBuilder()
#         request_builder.start_new_request(
#             pyros_user, scientific_program, True, name=voevent_id)
#         seq1 = request_builder.add_sequence(1, 0, 10, name=voevent_id + "_1")
#         alb11 = request_builder.add_album(seq1, Device.NIR, name=voevent_id + "_11")
#         request_builder.add_plan(
#             alb11, Device.NIR_FILTER_1, 120, 5, name=voevent_id + "_111")
#         alb12 = request_builder.add_album(seq1, Device.VIS, name=voevent_id + "_12")
#         request_builder.add_plan(
#             alb12, Device.VIS_FILTER_1, 180, 1, name=voevent_id + "_121")
#         seq2 = request_builder.add_sequence(1, 0, 10, name=voevent_id + "_2")
#         alb21 = request_builder.add_album(seq2, Device.NIR, name=voevent_id + "_21")
#         request_builder.add_plan(
#             alb21, Device.NIR_FILTER_2, 60, 3, name=voevent_id + "_211")
#         return request_builder.validate_request()

    def get_alert_attributes(self, voevent, event_file):
        '''
            Parses the VOEvent to get all the required attributes
            Creates the alert object
            Handles errors (missing params, wrong params, ...)
            
            :param voevent: Object resulting of the VOEvent parsing with voeventparse library
            :returns : The alert object
        '''


        '''
            The parameters are a dictionnary with the "<What>" <Group>s as keys,
            and a dictionnary of their <Param> as values.
            The nested dictionnaries have the 'name' attribute as keys,
            and another dictionnary as values, containing {attribute : value} pairs
            The <Param>s without <Group> are in the dictionnary with 'None' as key
        '''
eecfb779   haribo   Date: 26/05/2016
144
        v_params = voeventparse.pull_params(voevent)
2ceea892   haribo   Date: 19/07/2016
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

        # Ici, je remplis l'objet alert

        alert = Alert(voevent_file=event_file)
        try:
            alert.trig_id = v_params[None]["TrigID"]["value"]
            alert.editor = v_params[None]["Packet_Type"]["value"]
            alert.soln_status = v_params[None]["Soln_Status"]["value"]
            alert.pkt_ser_num = v_params[None]["Pkt_Ser_Num"]["value"]

            tjd = Decimal(v_params[None]["Burst_TJD"]["value"])
            sod = Decimal(v_params[None]["Burst_SOD"]["value"])
            alert.burst_jd = tjd - 13370 - 1 + 2453371 + (sod / 86400)
            alert.defly_not_grb = int(alert.soln_status[0]) & 0xF0

            alert.author = voevent.Who.AuthorIVORN
1b341a0f   haribo   Date: 19/07/2016
161
162
            alert.jd_send = time.mktime(time.strptime(str(voevent.Who.Date), "%Y-%m-%dT%H:%M:%S")) / 86400 + TIMESTAMP_JD
            alert.jd_received = time.time() / 86400 + TIMESTAMP_JD
2ceea892   haribo   Date: 19/07/2016
163
164
165
166
167
168
169
170
171
172
173
174

            alert.equinox = voevent.WhereWhen.ObsDataLocation.ObservationLocation.AstroCoordSystem
            alert.burst_ra = voevent.WhereWhen.ObsDataLocation.ObservationLocation.AstroCoords.Position2D.Value2.C1
            alert.burst_dec = voevent.WhereWhen.ObsDataLocation.ObservationLocation.AstroCoords.Position2D.Value2.C2
            alert.error_radius = voevent.WhereWhen.ObsDataLocation.ObservationLocation.AstroCoords.Position2D.Error2Radius

            # TODO: faire des checks sur les valeurs récupérées ???
        except KeyError or AttributeError as e:
            print("Error while parsing VOEvent : ", e)
            return None

        return alert
94336356   haribo   Added starting fi...
175
176
177
178
179

    def run_simulation(self):
        '''
            Uses a socket to block until a message is received (simulation of a VOEvent reception)
        '''
5b5566ab   haribo   added celery
180
181
        print("run")
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
94336356   haribo   Added starting fi...
182
183
        self.server_socket.setsockopt(
            socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
5b5566ab   haribo   added celery
184
185
186
187
        self.server_socket.setblocking(True)
        self.server_socket.bind((IP, PORT))
        self.server_socket.listen(12)
        while True:
94336356   haribo   Added starting fi...
188
            # il faudra que tout ça soit dans un try ...
77816f10   haribo   Workflow implemen...
189
            print("Task en attente de signal")
5b5566ab   haribo   added celery
190
            self.server_socket.accept()
77816f10   haribo   Workflow implemen...
191
            print("signal reçu")
94336356   haribo   Added starting fi...
192
            self.alert_received_simulation()
5b5566ab   haribo   added celery
193

94336356   haribo   Added starting fi...
194
195
    def alert_received_simulation(self):
        '''
7a79e25b   haribo   Date: 19/05/2016
196
            IMPORTANT : To do simulation, settings.SIMULATION must be set True
94336356   haribo   Added starting fi...
197
198
199
            Simulates a VOEvent message by reading sequences into a file
            Creates a request with them
        '''
7a79e25b   haribo   Date: 19/05/2016
200

77816f10   haribo   Workflow implemen...
201
        # je supprime les sequences et requetes déjà existantes
9774228b   haribo   Date: 22/06/2016
202
        majordome.TaskManager.delete_pending_alert()
bb45cd4a   haribo   Date: 25/05/2016
203
204
        Plan.objects.all().delete()
        Album.objects.all().delete()
77816f10   haribo   Workflow implemen...
205
        Sequence.objects.all().delete()
bb45cd4a   haribo   Date: 25/05/2016
206
        Alert.objects.all().delete()
77816f10   haribo   Workflow implemen...
207
        Request.objects.all().delete()
bb45cd4a   haribo   Date: 25/05/2016
208
        ScheduleHasSequences.objects.all().delete()
77816f10   haribo   Workflow implemen...
209
210

        Log.objects.create(agent='Alert manager', message='Alert received')
94336356   haribo   Added starting fi...
211

77816f10   haribo   Workflow implemen...
212
213
        for file_name in os.listdir(observation_manager.tasks.IMAGES_FOLDER):
            if file_name != "empty":
94336356   haribo   Added starting fi...
214
215
                file_path = os.path.join(
                    observation_manager.tasks.IMAGES_FOLDER, file_name)
77816f10   haribo   Workflow implemen...
216
                os.unlink(file_path)
94336356   haribo   Added starting fi...
217

9774228b   haribo   Date: 22/06/2016
218
219
        print("All deleted")

7a79e25b   haribo   Date: 19/05/2016
220
        # j'ouvre le fichier des séquences de simulation, et je le lis ligne par ligne
5b5566ab   haribo   added celery
221
222
        with open("alert_manager/simulation_sequences", 'r') as sequences_file:
            sequences = sequences_file.readlines()
77816f10   haribo   Workflow implemen...
223

9774228b   haribo   Date: 22/06/2016
224
225
        print("File read")

94336356   haribo   Added starting fi...
226
227
        Log.objects.create(
            agent='Alert manager', message='Simulation sequences file read')
77816f10   haribo   Workflow implemen...
228

5b5566ab   haribo   added celery
229
        sequences = [sequence.strip('\n') for sequence in sequences]
77816f10   haribo   Workflow implemen...
230
        request_builder = RequestBuilder()
fd99569d   haribo   Date: 22/06/2016
231
        request_builder.start_new_request(PyrosUser.objects.all()[0], ScientificProgram.objects.all()[0], True, name="Simulation_request")
5b5566ab   haribo   added celery
232
        for sequence in sequences:
7a79e25b   haribo   Date: 19/05/2016
233
234
235
236
237
238
239
240
            sequence_array = sequence.split(" ")
            id_seq = sequence_array[0]
            priority = int(sequence_array[2])
            ''' transforms the duration (seconds) in days (86,400s in a day)'''
            duration = Decimal(float(sequence_array[4]) / 86400.0)
            jd1 = Decimal("%.8f" % float(sequence_array[5]))
            jd2 = Decimal("%.8f" % float(sequence_array[6]))

eecfb779   haribo   Date: 26/05/2016
241
            request_builder.add_sequence(priority, jd1, jd2, name="Simulation_" + id_seq, duration=duration)
7a79e25b   haribo   Date: 19/05/2016
242

9774228b   haribo   Date: 22/06/2016
243
        print("Parsé")
77816f10   haribo   Workflow implemen...
244
        request_builder.validate_request()
9774228b   haribo   Date: 22/06/2016
245
        print("Validé")
bb45cd4a   haribo   Date: 25/05/2016
246
        Alert.objects.create(request=request_builder.request, strategyobs=StrategyObs.objects.all()[0])
77816f10   haribo   Workflow implemen...
247
        Log.objects.create(agent='Alert manager', message='Request built')