diff --git a/GWalarm.kv b/GWalarm.kv index 0429b27bd51a776cf7fac3fc72ec1df0a86d6ce8..df8ea7544c5af2713b4be8f50e388d5c3a1f7fff 100644 --- a/GWalarm.kv +++ b/GWalarm.kv @@ -36,7 +36,7 @@ color:0,0,0,1 text_size:self.width,None halign:'left' - font_size:22 + font_size:dp(22) size_hint_y:0.2 HSeparator: rgba: 0,0,0,1 @@ -47,7 +47,7 @@ text_size:self.width,None height:self.texture_size[1] halign:'left' - font_size:18 + font_size:dp(18) size_hint_y:0.35 BoxLayout: padding:2,0 @@ -80,25 +80,29 @@ pos:self.pos size:self.size rows:2 - cols:3 size_hint_y:0.4 - Image: - source:'./IGR.jpg' - size_hint_x:0.15 - Label: - size_hint_x:0.7 - Button: - text:'About' - on_press:Factory.AboutPop().open() - size_hint_x:0.15 - Label: - size_hint_x:0.15 - Label: - text:'Gravitational Wave Alarm' - font_size:32 - size_hint_x:0.7 - Label: - size_hint_x:0.15 + BoxLayout: + padding:[3,3] + Image: + source:'./UofG.jpg' + size_hint_x:0.3 + Label: + size_hint_x:0.6 + Button: + text:'About' + on_press:Factory.AboutPop().open() + size_hint_x:0.15 + BoxLayout: + padding:[3,3] + Image: + source:'./IGR.jpg' + size_hint_x:0.1 + Label: + text:'Gravitational Wave Alarm' + font_size:dp(36) + size_hint_x:0.8 + Label: + size_hint_x:0.1 GridLayout: canvas.before: Color: @@ -126,12 +130,13 @@ imgsource:'./event_data/LIGO Livingston.jpg' : - text_size: root.width, None - size:self.texture_size + text_size: self.width,None + size_hint_y:None height:self.texture_size[1] + padding:10,10 halign: 'center' valign: 'middle' - font_size: 14 + font_size:dp(16) : names: @@ -162,7 +167,7 @@ size:self.texture_size halign: 'center' valign: 'middle' - font_size: 14 + font_size:dp(14) : @@ -170,7 +175,7 @@ halign:'center' color:(0,0,0,1) bg_col:self.prop[3] - font_size:14 + font_size:dp(14) canvas.before: Color: rgba: self.bg_col or [1,1,1,1] @@ -260,14 +265,17 @@ Label: text: 'Detector name' color:0,0,0,1 + halign:'center' Label: text: 'Current status' color:0,0,0,1 + halign:'center' Label: text: 'Duration \n (hours:minutes)' #size_hint_y:None - text_size:self.size + #text_size:self.size #height:self.texture_size[1] + halign:'center' color:0,0,0,1 #valign:'bottom' @@ -283,15 +291,15 @@ GridLayout: rows:3 size_hint_x:0.84 - padding:(0,30) + padding:(0,20) Label: text:'Welcome to the Detector Portal!' - font_size:30 + font_size:dp(30) color:0,0,0,1 size_hint_y:0.1 Label: text:'Tap any of the detectors on-screen to learn more.' - fontsize:20 + fontsize:22 color:0,0,0,1 size_hint_y:0.1 AsyncImage: @@ -384,7 +392,7 @@ text_size: self.width,None height:self.texture_size[1] size_hint_y:None - font_size:16 + font_size:dp(16) line_height:1.2 markup:True color:0,0,0,1 @@ -413,7 +421,7 @@ Label: text:root.detlist[0] size_hint_y: 0.15 - font_size:32 + font_size:dp(32) text_size: self.width, None halign: 'left' color:0,0,0,1 @@ -421,7 +429,7 @@ Label: text:root.detlist[1]+' ' + root.detlist[2] size_hint_y:0.05 - font_size:24 + font_size:dp(24) text_size: self.width, None halign: 'left' valign:'top' @@ -460,6 +468,37 @@ height:self.minimum_height orientation:'vertical' +: + bgcol:1,1,1,1 + keytext:'test' + cols:2 + canvas.before: + Color: + rgba: 0,0,0,1 + Line: + width: 1 + points:self.x,self.y,self.x,self.y+self.height + BoxLayout: + padding:10,10 + Label: + canvas.before: + Color: + rgba: root.bgcol + Rectangle: + pos:self.pos + size:self.size + canvas: + Color: + rgba: 0,0,0,1 + Line: + width:1 + rectangle:self.x,self.y,self.width,self.height + size_hint:1,1 + Label: + text:root.keytext + color:0,0,0,1 + font_size:dp(12) + : specialnames:['GraceID','Distance','Instruments','FAR','UpdateTime'] lookoutfor:['BBH','BNS','NSBH','MassGap','Terrestrial'] @@ -475,61 +514,33 @@ rows:5 GridLayout: cols:6 - size_hint_y:0.05 + size_hint_y:0.07 + padding:[5,0] + canvas.before: + Color: + rgba: [0.9,0.9,0.9,1] + Rectangle: + pos:self.pos + size:self.size Label: text:'Key:' color:(0,0,0,1) - canvas.before: - Color: - rgba: [0.2,0.25,0.4,1] - Rectangle: - pos:self.pos - size:self.size - Label: - text:root.lookoutfor[0] - color:(0,0,0,1) - canvas.before: - Color: - rgba: root.backcolors[0] - Rectangle: - size:self.size - pos:self.pos - Label: - text:root.lookoutfor[1] - color:(0,0,0,1) - canvas.before: - Color: - rgba: root.backcolors[1] - Rectangle: - size:self.size - pos:self.pos - Label: - text:root.lookoutfor[2] - color:(0,0,0,1) - canvas.before: - Color: - rgba: root.backcolors[2] - Rectangle: - size:self.size - pos:self.pos - Label: - text:root.lookoutfor[3] - color:(0,0,0,1) - canvas.before: - Color: - rgba: root.backcolors[3] - Rectangle: - size:self.size - pos:self.pos - Label: - text:root.lookoutfor[4] - color:(0,0,0,1) - canvas.before: - Color: - rgba: root.backcolors[4] - Rectangle: - size:self.size - pos:self.pos + + KeyLabel: + keytext:root.lookoutfor[0] + bgcol:root.backcolors[0] + KeyLabel: + keytext:root.lookoutfor[1] + bgcol:root.backcolors[1] + KeyLabel: + keytext:root.lookoutfor[2] + bgcol:root.backcolors[2] + KeyLabel: + keytext:root.lookoutfor[3] + bgcol:root.backcolors[3] + KeyLabel: + keytext:root.lookoutfor[4] + bgcol:root.backcolors[4] HSeparator: rgba:0,0,0,1 padding:2,0 @@ -583,7 +594,7 @@ BoxLayout: size_hint_y:0.08 Button: - text:'back up database' + text:'Database Hard Backup' on_press:root.stupid() Button: text:'Main Menu' @@ -636,20 +647,35 @@ size:self.size canvas.after: Color: - rgba: 0.6,0.6,0.6,1 + rgba: 0,0,0,1 Line: width:2 rectangle: self.x, self.y, self.width, self.height Label: - text:'Superevent Information' + text:'EVENT INFORMATION' + markup:True + font_size:dp(16) size_hint_y:0.1 + color:0,0,0,1 + canvas.before: + Color: + rgba: 0.95,0.95,0.95,1 + Rectangle: + pos:self.pos + size:self.size + Label: + padding:10,0 + text_size:self.width,None + height:self.texture_size[1] + font_size:dp(16) + text:'Welcome to the event information page! \n Here you can find all the interesting info for a particular gravitational wave event. \n Swipe to see where in the sky it may have come from!' Button: - size_hint:(1,0.8) + size_hint:(1,0.1) padding:10,2 text:'Open Glossary' on_press:root.gloss_open() Button: - text:'Exit Info Scrn' + text:'Back to Event History' size_hint_y:0.1 on_press:root.dismiss() GridLayout: @@ -661,7 +687,7 @@ size_hint_y:0.6 canvas.before: Color: - rgba: (0.2,0.2,0.2,1) + rgba: (0,0,0,1) Rectangle: size:self.size pos:self.pos @@ -682,7 +708,7 @@ rows: len(root.part3info) canvas.after: Color: - rgba:1,0,1,1 + rgba:0.2,0.25,0.4,1 Line: width:2 points: [self.x+self.width+1,self.y+self.height,self.x,self.y+self.height,self.x,self.y,self.x+self.width+1,self.y] @@ -710,48 +736,48 @@ size_hint:(1,0.3) canvas.before: Color: - rgba:.2,.2,.2,1 + rgba:0,0,0,1 Rectangle: pos:self.pos size:self.size GridLayout: canvas.before: Color: - rgba:1,1,1,1 + rgba:0,0,0,1 Line: width:2 rectangle:self.x,self.y,self.width,self.height rows:2 Label: text:root.part1info[0][3:]+' left?' - font_size:14 + font_size:dp(14) text_size:self.width,None height:self.texture_size[1] halign:'center' Label: text:root.rowdict[root.part1info[0]] - font_size:20 + font_size:dp(20) GridLayout: canvas.before: Color: - rgba:1,1,1,1 + rgba:0,0,0,1 Line: width:2 rectangle:self.x,self.y,self.width,self.height rows:2 Label: text:root.part1info[1][3:]+' progenitor?' - font_size:14 + font_size:dp(14) halign:'center' Label: text:root.rowdict[root.part1info[1]] - font_size:20 + font_size:dp(20) BoxLayout: size_hint:(1,0.7) canvas.after: Color: - rgba: 1,0,1,1 + rgba: 0.2,0.25,0.4,1 Line: width:2 points:[self.x-2,self.y+self.height*0.58,self.x-2,self.y+self.height,self.x+self.width,self.y+self.height,self.x+self.width,self.y,self.x-2,self.y] @@ -760,9 +786,9 @@ source:root.rowdict['GraceID']+'_pie.png' BoxLayout: Button: - text:'Exit \n Info Scrn' + text:'Back to \n Event \n History' size_hint:(0.1,0.3) - on_press:caro.index=0;root.dismiss() + on_press:root.dismiss() text_size:root.width,None halign:'center' valign:'top' @@ -780,10 +806,19 @@ AsyncImage: source:root.imsource size_hint_y:0.8 - WrapLabel: - text:root.desc + ScrollView: + do_scroll_x:False size_hint_y:0.2 - color:0,0,0,1 + canvas.before: + Color: + rgba:95/255,95/255,169/255,1 + Rectangle: + size:self.size + pos:self.pos + WrapLabel: + text:root.desc + color:1,1,1,1 + : imgsources:['test','test','test','test'] @@ -817,7 +852,7 @@ Button: on_press:root.manager.current='main' text:'main' - size_hint_y:0.1 + size_hint_y:0.08 : current_color: (0,0,0,0) @@ -839,17 +874,29 @@ valign:'top' size_hint_y:None text_size: root.width, None + height:self.texture_size[1] halign: 'justify' - font_size:12 + font_size:dp(12) line_height:1 markup:True + + viewclass: 'GlossDefLabel' + + RecycleBoxLayout: + default_size:None,dp(56) + default_size_hint:1,None + size_hint_y:None + height:self.minimum_height + orientation:'vertical' + padding:[0,20] + : on_press:self.nav() : color:0,0,0,1 - font_size:14 + font_size:dp(14) : name: None diff --git a/GWalarm.py b/GWalarm.py index 05802108971aaf0dca16a722c488877d6b6baa5d..ebbe145f22eb2100a23921e2aa3815146c3ac00f 100644 --- a/GWalarm.py +++ b/GWalarm.py @@ -31,6 +31,7 @@ from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition, SlideT from kivy.uix.scrollview import ScrollView from kivy.uix.carousel import Carousel from kivy.uix.popup import Popup +from kivy.uix.recycleview import RecycleView from kivy.uix.behaviors import ButtonBehavior, ToggleButtonBehavior from kivy.animation import Animation from kivy.lang.builder import Builder @@ -46,11 +47,24 @@ import datetime import os import re import numpy as np +from matplotlib.image import imread +from matplotlib.pyplot import imsave -#gpioimport board -#gpioimport neopixel -# -#gpiopixels = neopixel.NeoPixel(board.D18,8,auto_write=False) +'''CHECK IF ON RASPBERRY PI FOR GPIO FUNCTIONALITY''' +if os.uname()[4][:3] == 'arm': + import board + import neopixel + import RPi.GPIO as GPIO + buzzPin = 17 + neoPin = board.D18 + num_leds = 8 + pixels = neopixel.NeoPixel(neoPin,num_leds,auto_write=False) + GPIO.setmode(GPIO.BCM) + GPIO.setup(buzzPin,GPIO.OUT) + GPIO.output(buzzPin,GPIO.LOW) + +else: + pixels = None class Event(IsDescription): AlertType=StringCol(30) @@ -98,91 +112,91 @@ class MainButton(Button): app.root.current='main' elif self.name=='plots': app.root.current='plots' -class MainScreen(Screen): - def __init__(self,**kwargs): - super().__init__(**kwargs) - layout=GridLayout(cols=2,rows=2,padding=30,spacing=30,row_default_height=150) - with layout.canvas.before: - Color(.2,.2,.2,1) - self.rect=Rectangle(size=(800,600), pos=layout.pos) - - def stop(obj): - global main_flag - main_flag=1 - App.get_running_app().stop() - - self.add_widget(layout) - ids=('history','status','plots') - texts=('Event History','Detector Status','Test Plots') - [layout.add_widget(MainButton(text=texts[i],name=ids[i])) for i in range(0,len(ids))] - quitButton=Button(text='Quit') - quitButton.bind(on_press=stop) - layout.add_widget(quitButton) - - def event_waiting(): - '''New event popup handler''' - global newevent_flag - global main_flag - newevent_flag=0 - main_flag=0 - while True: - while True: - print("i'm waiting") - #check for the flag once per minute (same rate the file is polled) - if newevent_flag == 1: - newevent_flag=0 - #skip a level up to execute the rest of the loop, then back to waiting. - print('New event has been detected!!') - break - if main_flag == 1: - print('Event listener #2 closing...') - #return takes you right out of the function - return - time.sleep(5) - - #Read in the new event - if os.path.basename(os.getcwd()) != "event_data": - try: - os.chdir("./event_data") - except: - os.mkdir("./event_data") - os.chdir("./event_data") - while True: - try: - h5file = open_file("Event Database",mode="r",title="eventinfo") - break - except: - print("file in use... trying again in 5s") - time.sleep(5) - try: - h5file.root.events - except NoSuchNodeError: - time.sleep(5) - pass - - #parse the event data file for the most recent event to be loaded: that's the name - file = open("PreviousEventToRead.xml").read() - def search(line): - result = re.search('\n', - str(line)) - return result.group(1) - eventid = search(file) - for tab in h5file.list_nodes("/events"): - if str(tab.name) in eventid: - new_event_table=tab -# if tab.name == eventid: -# new_event_table = tab - namelist = new_event_table.colnames - new_event_row = new_event_table[-1] - orderedrow = [] - for key in namelist: - orderedrow.append(new_event_row[key].decode()) - pop = InfoPop(title='New Event Detected!',namelist=namelist,row=orderedrow) - pop.open() - h5file.close() - - event_waiting_thread = threading.Thread(target=event_waiting) - event_waiting_thread.start() +#class MainScreen(Screen): +# def __init__(self,**kwargs): +# super().__init__(**kwargs) +# layout=GridLayout(cols=2,rows=2,padding=30,spacing=30,row_default_height=150) +# with layout.canvas.before: +# Color(.2,.2,.2,1) +# self.rect=Rectangle(size=(800,600), pos=layout.pos) +# +# def stop(obj): +# global main_flag +# main_flag=1 +# App.get_running_app().stop() +# +# self.add_widget(layout) +# ids=('history','status','plots') +# texts=('Event History','Detector Status','Test Plots') +# [layout.add_widget(MainButton(text=texts[i],name=ids[i])) for i in range(0,len(ids))] +# quitButton=Button(text='Quit') +# quitButton.bind(on_press=stop) +# layout.add_widget(quitButton) +# +# def event_waiting(): +# '''New event popup handler''' +# global newevent_flag +# global main_flag +# newevent_flag=0 +# main_flag=0 +# while True: +# while True: +# print("i'm waiting") +# #check for the flag once per minute (same rate the file is polled) +# if newevent_flag == 1: +# newevent_flag=0 +# #skip a level up to execute the rest of the loop, then back to waiting. +# print('New event has been detected!!') +# break +# if main_flag == 1: +# print('Event listener #2 closing...') +# #return takes you right out of the function +# return +# time.sleep(5) +# +# #Read in the new event +# if os.path.basename(os.getcwd()) != "event_data": +# try: +# os.chdir("./event_data") +# except: +# os.mkdir("./event_data") +# os.chdir("./event_data") +# while True: +# try: +# h5file = open_file("Event Database",mode="r",title="eventinfo") +# break +# except: +# print("file in use... trying again in 5s") +# time.sleep(5) +# try: +# h5file.root.events +# except NoSuchNodeError: +# time.sleep(5) +# pass +# +# #parse the event data file for the most recent event to be loaded: that's the name +# file = open("PreviousEventToRead.xml").read() +# def search(line): +# result = re.search('\n', +# str(line)) +# return result.group(1) +# eventid = search(file) +# for tab in h5file.list_nodes("/events"): +# if str(tab.name) in eventid: +# new_event_table=tab +## if tab.name == eventid: +## new_event_table = tab +# namelist = new_event_table.colnames +# new_event_row = new_event_table[-1] +# orderedrow = [] +# for key in namelist: +# orderedrow.append(new_event_row[key].decode()) +# pop = InfoPop(title='New Event Detected!',namelist=namelist,row=orderedrow) +# pop.open() +# h5file.close() +# +# event_waiting_thread = threading.Thread(target=event_waiting) +# event_waiting_thread.start() class HisColLabel(ToggleButtonBehavior,Label): sorttype=ObjectProperty() @@ -376,10 +390,10 @@ class HistoryScreenv2(Screen): for child in self.ids.HisCols.children: child.names = names - t2 = threading.Thread(target=historyUpdatev2,args=(self.ids.rv,names,specialnames,lookoutfor,backcolors),daemon=True) + t2 = threading.Thread(target=historyUpdatev2,args=(self.ids.rv,names,specialnames,lookoutfor,backcolors,'Time Descending',True),daemon=True) t2.start() -def historyUpdatev2(rv,names,specialnames,lookoutfor,backcolors,sorttype='Time Descending'): +def historyUpdatev2(rv,names,specialnames,lookoutfor,backcolors,sorttype='Time Descending',led_init = False): print('begin hist update') '''An important function that is responsible for populating and repopulating the history screen.''' global flag @@ -451,19 +465,19 @@ def historyUpdatev2(rv,names,specialnames,lookoutfor,backcolors,sorttype='Time D if sort_vars != []: if 'Descending' in sorttype: try: - tables = [x for _,x in sorted(zip(sort_vars,tables),key=len[0])] + tables = [x for _,x in reversed(sorted(zip(sort_vars,tables)),key=len[0])] except TypeError: tables2=[] - sort_indexes = np.argsort(np.array(sort_vars)) + sort_indexes = reversed(np.argsort(np.array(sort_vars))) for index in sort_indexes: tables2.append(tables[index]) tables=tables2 elif 'Ascending' in sorttype: try: - tables = [x for _,x in reversed(sorted(zip(sort_vars,tables)))] + tables = [x for _,x in (sorted(zip(sort_vars,tables)))] except TypeError: tables2=[] - sort_indexes = reversed(np.argsort(np.array(sort_vars))) + sort_indexes = (np.argsort(np.array(sort_vars))) for index in sort_indexes: tables2.append(tables[index]) tables=tables2 @@ -497,14 +511,20 @@ def historyUpdatev2(rv,names,specialnames,lookoutfor,backcolors,sorttype='Time D to_add_to_data['bgcol'] = backcolors[np.argmax(stats)] new_data.append(to_add_to_data) + if i == 0: + winner = lookoutfor[np.argmax(stats)] + rv.data = new_data print('Event History Updated...') + + if pixels: + notifier(winner) h5file.close() #reset the flag first = 0 - waittime = 10 + waittime = 5 i=0 while i < waittime: if flag ==1: @@ -529,22 +549,6 @@ class InfoPop(Popup): namelist=ObjectProperty() row=ObjectProperty() def gloss_open(self): - content = GridLayout(rows=2) - content.add_widget(Glossary(size_hint_y=0.9)) - but = Button(text='Done',size_hint_y=0.1) - content.add_widget(but) - pop = Popup(title='Glossary',content=content,size_hint=(0.25,1),pos_hint={'x':0,'y':0}) - but.bind(on_press=pop.dismiss) - pop.open() - -class GlossDefLabel(Label): - nom=ObjectProperty() - desc=ObjectProperty() - - -class Glossary(ScrollView): - def __init__(self,**kwargs): - super().__init__(**kwargs) descdict = {'GraceID': 'Identifier in GraceDB', 'AlertType': 'VOEvent alert type', 'Instruments': 'List of instruments used in analysis to identify this event', 'FAR': 'False alarm rate for GW candidates with this strength or greater', @@ -560,22 +564,51 @@ class Glossary(ScrollView): 'UpdateTime': "The date & time of the most recent update to this event's parameters", 'MassGap':"Compact binary systems with at least one compact object whose mass is in the hypothetical 'mass gap' between neutron stars and black holes, defined here as 3-5 solar masses.", 'Revision':"The number of revisions (updates) made to this event's parameters"} - descripts=[] - names = [] - for key,value in descdict.items(): - names.append(key) - descripts.append(value) - namelist = sorted(names) - descs=[x for _,x in sorted(zip(names,descripts))] - layout2 = GridLayout(rows=len(descs),size_hint_y=None) - for i in range(len(namelist)): - gloss = GlossDefLabel(nom=namelist[i],desc=descs[i]) - layout2.add_widget(gloss) - self.add_widget(layout2) - self.do_scroll_x=False - self.do_scroll_y=True - layout2.height=sum([c.height for c in layout2.children])+20 + content = GridLayout(rows=2) + _glossary = Glossary(size_hint_y=0.9) + descdata=[] + sortedkeys=[] + for key in descdict: + sortedkeys.append(key) + for key in sortedkeys: + descdata.append({'nom':key,'desc':descdict[key]}) + _glossary.data = descdata + content.add_widget(_glossary) + but = Button(text='Done',size_hint_y=0.1) + content.add_widget(but) + pop = Popup(title='Glossary',content=content,size_hint=(0.25,1),pos_hint={'x':0,'y':0}) + but.bind(on_press=pop.dismiss) + pop.open() + def on_dismiss(self): + Clock.schedule_once(lambda dt: self.fin_dismiss(),0.1) + def fin_dismiss(self): + self.ids.caro.index=0 + +class GlossDefLabel(Label): + nom=ObjectProperty() + desc=ObjectProperty() + +class Glossary(RecycleView): + pass +# +#class Glossary(ScrollView): +# def __init__(self,**kwargs): +# super().__init__(**kwargs) +# descripts=[] +# names = [] +# +# namelist = sorted(names) +# descs=[x for _,x in sorted(zip(names,descripts))] +# layout2 = GridLayout(rows=len(descs),size_hint_y=None) +# for i in range(len(namelist)): +# gloss = GlossDefLabel(nom=namelist[i],desc=descs[i]) +# layout2.add_widget(gloss) +# self.add_widget(layout2) +# self.do_scroll_x=False +# self.do_scroll_y=True +# layout2.height=sum([c.height for c in layout2.children])+20 +# class EventContainer(ButtonBehavior,GridLayout): name=ObjectProperty() @@ -789,21 +822,22 @@ def statusupdate(obj): for i,elem in enumerate(data): setattr(obj,'det'+str(i+1)+'props',elem) - '''LED CONTROL (replace #gpio with "" to use)''' - #gpiofor i,stat in enumerate(stats): - #gpioif stat == 0: - #red - #gpiopixels[i] = (255,0,0) - #gpioif stat == 1: - #orange - #gpiopixels[i] = (228,119,10) - #gpioif stat == 2: - #green - #gpiopixels[i] = (17,221,17) - #gpioif stat == 3: - #yellow - #gpiopixels[i] = (0,0,0) - #gpiopixels.show() + '''LED CONTROL''' + if pixels: + for i,stat in enumerate(stats): + if stat == 0: + #red + pixels[i] = (255,0,0) + if stat == 1: + #orange + pixels[i] = (228,119,10) + if stat == 2: + #green + pixels[i] = (17,221,17) + if stat == 3: + #yellow + pixels[i] = (0,0,0) + pixels.show() waittime = 30 i = 0 @@ -831,22 +865,25 @@ def plotupdate(obj): url = "https://www.gw-openscience.org/detector_status/day/"+datestring+"/" url2 = "https://www.gw-openscience.org/detector_status/day/"+datestring+"/instrument_performance/analysis_time/" #grab the soup and parse for links + descripts + date = datetime.datetime.today() try: - date = datetime.datetime.today() sort_date = [str(date.year),str(date.month).zfill(2),str(date.day).zfill(2)] datestring = sort_date[0]+sort_date[1]+sort_date[2] url = "https://www.gw-openscience.org/detector_status/day/"+datestring+"/" url2 = "https://www.gw-openscience.org/detector_status/day/"+datestring+"/instrument_performance/analysis_time/" resp=requests.get(url) r = resp.text - if 'Not Found' in str(r): - date = datetime.datetime.today() - datetime.timedelta(days=1) - sort_date = [str(date.year),str(date.month).zfill(2),str(date.day).zfill(2)] - datestring = sort_date[0]+sort_date[1]+sort_date[2] - url = "https://www.gw-openscience.org/detector_status/day/"+datestring+"/" - url2 = "https://www.gw-openscience.org/detector_status/day/"+datestring+"/instrument_performance/analysis_time/" - resp=requests.get(url) - r = resp.text + while True: + if 'Not Found' in str(r): + date = date - datetime.timedelta(days=1) + sort_date = [str(date.year),str(date.month).zfill(2),str(date.day).zfill(2)] + datestring = sort_date[0]+sort_date[1]+sort_date[2] + url = "https://www.gw-openscience.org/detector_status/day/"+datestring+"/" + url2 = "https://www.gw-openscience.org/detector_status/day/"+datestring+"/instrument_performance/analysis_time/" + resp=requests.get(url) + r = resp.text + else: + break soup=BeautifulSoup(r,"lxml") resp2 = requests.get(url2) r2 = resp2.text @@ -873,6 +910,10 @@ def plotupdate(obj): source= 'https://www.gw-openscience.org'+str(link.get("href")) os.system("curl -0 "+ source+ ' > ' + filepath) paths.append(filepath) + + img = imread("./Detector_Plot_3.png") + cropimg = img[50:550,100:1200,:] + imsave("./Detector_Plot_3.png",cropimg,format='png') i+=1 break @@ -887,6 +928,20 @@ def plotupdate(obj): i+=5 time.sleep(5) + +def notifier(event_type): + if event_type == 'Terrestrial': + pixels[1] = (242,179,179) + elif event_type == 'NSBH': + pixels[1] = (238,242,179) + elif event_type == 'BBH': + pixels[1] = (202,214,235) + elif event_type == 'MassGap': + pixels[1] = (231,179,242) + elif event_type == 'BNS': + pixels[1] = (179,242,183) + pixels.show() + class MainScreenv2(Screen): def __init__(self,**kwargs): super().__init__(**kwargs) @@ -897,12 +952,38 @@ class MainScreenv2(Screen): global main_flag newevent_flag=0 main_flag=0 + + def buzz(times): + i=0 + while i < times: + GPIO.output(buzzPin,GPIO.HIGH) + time.sleep(0.1) + GPIO.output(buzzPin,GPIO.LOW) + time.sleep(0.05) + GPIO.output(buzzPin,GPIO.HIGH) + time.sleep(0.1) + GPIO.output(buzzPin,GPIO.LOW) + time.sleep(0.05) + GPIO.output(buzzPin,GPIO.HIGH) + time.sleep(0.1) + GPIO.output(buzzPin,GPIO.LOW) + time.sleep(0.05) + GPIO.output(buzzPin,GPIO.HIGH) + time.sleep(0.1) + GPIO.output(buzzPin,GPIO.LOW) + time.sleep(0.05) + + i+=1 + while True: while True: #check for the flag once per minute (same rate the file is polled) if newevent_flag == 1: newevent_flag=0 #skip a level up to execute the rest of the loop, then back to waiting. + if buzzPin: + buzzthread = threading.Thread(target=buzz,args=(3,)) + buzzthread.start() print('New event has been detected!!') break if main_flag == 1: @@ -947,7 +1028,16 @@ class MainScreenv2(Screen): new_event_row = new_event_table[-1] orderedrow = [] for key in namelist: - orderedrow.append(new_event_row[key].decode()) + orderedrow.append(new_event_row[key].decode()) + + if pixels: + stats = [] + lookoutfor = ['BBH','BNS','NSBH','MassGap','Terrestrial'] + for name in lookoutfor: + stats.append(float(new_event_row[name].decode().strip('%'))) + winner = lookoutfor[np.argmax(stats)] + notifier(winner) + pop = InfoPop(title='New Event Detected!',namelist=namelist,row=orderedrow) pop.open() h5file.close() @@ -972,11 +1062,11 @@ class StatusScreenv2(Screen): bios=ListProperty() def __init__(self,**kwargs): super().__init__(**kwargs) - self.bios=(['LIGO Livingston was one of two trailblazing gravitational wave detectors (the other being LIGO Hanford). The observatory uses ultra-high-vacuum technology to achieve extremely precise measurement capability. \n Forming a pair seperated by over 3000km, LIGO Hanford and Livingston observed gravitational waves for the first time in history in February, 2016.', - 'LIGO Hanford was one of two trailblazing gravitational wave detectors (the other being LIGO Livingston). The observatory uses ultra-high-vacuum technology to achieve extremely precise measurement capability. \n Forming a pair seperated by over 3000km, LIGO Hanford and Livingston observed gravitational waves for the first time in history in February, 2016.', + self.bios=(['LIGO Livingston is one of two trailblazing gravitational wave detectors (the other being LIGO Hanford). The observatory uses ultra-high-vacuum technology to achieve extremely precise measurement capability. \n Forming a pair seperated by over 3000km, LIGO Hanford and Livingston observed gravitational waves for the first time in history in February, 2016.', + 'LIGO Hanford is one of two trailblazing gravitational wave detectors (the other being LIGO Livingston). The observatory uses ultra-high-vacuum technology to achieve extremely precise measurement capability. \n Forming a pair seperated by over 3000km, LIGO Hanford and Livingston observed gravitational waves for the first time in history in February, 2016.', + 'GEO600 is a gravitational wave detector located in Hanover, Germany. Although smaller than other counterparts worldwide, the detector is still capable of extremely precise measurement, only a few orders of magnitude less sensitive than significantly larger detectors. It has been a vital proof of concept for many advanced technologies and features that will surely be seen in future gravitational wave observatories. ', "The Virgo interferometer is Europe's largest to date. Currently, Virgo is being modified and improved to its next stage, 'Advanced Virgo', which aims to improve sensitivity by a factor of 10 by installing new adaptive-optic mirror systems and additional cryotraps to prevent the entry of residual particles. \n Virgo made its first GW detection, alongside LIGO, in August 2017 - the merger of two neutron stars.", - 'GEO600 is a detector located in Hanover, Germany. Although smaller than other counterparts worldwide, the detector is still capable of extremely precise measurement, only a few orders of magnitude less sensitive than significantly larger detectors. It has been a vital proof of concept for many advanced technologies and features that will surely be seen in future gravitational wave observatories. ', - "The Kamioka Gravitational Wave Detector (KAGRA) is the world's first underground gravitational wave observatory currently under construction in the Kamioka mine, Japan, with the University of Tokyo. \n The detector will utilise cryogenic cooling to reduce the interference of thermal noise in the measuring process. It will be completed towards the end of 2019."]) + "The Kamioka Gravitational Wave Detector (KAGRA) will be the world's first underground gravitational wave observatory. It is currently under construction in the Kamioka mine, Japan, with the University of Tokyo. \n The detector will utilise cryogenic cooling to reduce the interference of thermal noise in the measuring process. It will be completed towards the end of 2019."]) t = threading.Thread(target=statusupdate,args=(self,),daemon=True) t.start() diff --git a/UofG.jpg b/UofG.jpg new file mode 100644 index 0000000000000000000000000000000000000000..780ebffc69b0c121b88cb37dffe6043f8f0e48c9 Binary files /dev/null and b/UofG.jpg differ diff --git a/__pycache__/detector_monitorv2.cpython-36.pyc b/__pycache__/detector_monitorv2.cpython-36.pyc index 51dc12db0c134d8b60bc4240bf8d4b6baf472f5f..77747c01629ccd5ff3cc5b58386187b1638b384f 100644 Binary files a/__pycache__/detector_monitorv2.cpython-36.pyc and b/__pycache__/detector_monitorv2.cpython-36.pyc differ diff --git a/__pycache__/gcn_test.cpython-36.pyc b/__pycache__/gcn_test.cpython-36.pyc index 6a359c0c2ea23eead261608a065435a99c3ca34f..5ecb6cd798e5bfa8710af99f644d95ee701be970 100644 Binary files a/__pycache__/gcn_test.cpython-36.pyc and b/__pycache__/gcn_test.cpython-36.pyc differ diff --git a/detector_monitorv2.py b/detector_monitorv2.py index 613029615497965aaee9dc0c3850791d2f86826c..60f8f9e25ca269c29e4899eeee43d2c5a9085eef 100644 --- a/detector_monitorv2.py +++ b/detector_monitorv2.py @@ -45,16 +45,16 @@ def statusdetect(): for i,row in enumerate(detrows): if statuses[i] == 0: #red - toput = [1,0,0,1] + toput = [236/255,23/255,23/255,0.7] elif statuses[i] == 1: #orange - toput=[228/255,119/255,10/255,1] + toput=[228/255,119/255,10/255,0.7] elif statuses[i] == 2: #green - toput=[0,1,0,1] + toput=[132/255,241/255,70/255,0.7] elif statuses[i] == 3: #yellow - toput=[1,1,0,1] + toput=[229/255,237/255,78/255,0.7] temp=[row[0],row[2],row[3],toput] export.append(temp) export[0],export[2] = export[2],export[0] diff --git a/event_data/Detector_Plot_0.png b/event_data/Detector_Plot_0.png index e63291c2ec4693f4c0b1b7fc691d3d82bdec885c..e5bc5ff7db1c35bef05d0be247bdb11a5ec1cf1f 100644 Binary files a/event_data/Detector_Plot_0.png and b/event_data/Detector_Plot_0.png differ diff --git a/event_data/Detector_Plot_1.png b/event_data/Detector_Plot_1.png index e59d2a7837f97cc076431964b9efac3bc0354071..5ac9ee3ed231ef46d893d80ec9a517abd6a6fc5d 100644 Binary files a/event_data/Detector_Plot_1.png and b/event_data/Detector_Plot_1.png differ diff --git a/event_data/Detector_Plot_2.png b/event_data/Detector_Plot_2.png index a4b712c24c7fa21cab54610301c75f4354f0a096..5bcbd75fe7903c5497ad7cb1ce8df229f68e6127 100644 Binary files a/event_data/Detector_Plot_2.png and b/event_data/Detector_Plot_2.png differ diff --git a/event_data/Detector_Plot_3.png b/event_data/Detector_Plot_3.png index 86d8982d61de901f2c99fcd98ca2c924b6eddd34..d075970b0cdfb5de2417b072fc611a45a07300a1 100644 Binary files a/event_data/Detector_Plot_3.png and b/event_data/Detector_Plot_3.png differ diff --git a/event_data/Event Database b/event_data/Event Database index ee66ba4d96abc82553c469d3e1c6085c7ce8fd92..9ba555904900156527f37748209ceb89cfad5409 100644 Binary files a/event_data/Event Database and b/event_data/Event Database differ diff --git a/gcn_test.py b/gcn_test.py index ceca0687cb12aea2658e9aa28a00f7fdcdc8a191..722a95104cdd0564566af77a7ecf27fa2660bd64 100644 --- a/gcn_test.py +++ b/gcn_test.py @@ -51,7 +51,7 @@ def process_gcn(payload, root): if root.attrib['role'] != 'observation': return #acknowledge - #print('I have received a notice!!') + #print('I have received a notice!') #ensure correct working directory and open the table if os.path.basename(os.getcwd()) != "event_data": @@ -142,6 +142,9 @@ def process_gcn(payload, root): descriptions={} # Print all parameters. i=0 + + print(params['GraceID']) + for key, value in params.items(): #print(key, '=', value) if key == 'FAR': diff --git a/my.ini b/my.ini index 6e0cf7a4e7dc3ccb76b1d4035fcb94d0660fd81e..538689d28bb013fe8f02b30227c9eb5141db0c6d 100644 --- a/my.ini +++ b/my.ini @@ -1,4 +1,4 @@ [Section] -periodicbackup = 1566473667.1543036 +periodicbackup = 1566565428.3119123 initialbackup = 1