def run(self): """ Reads data from the queue and executes self.codefile if it sees an ``ALARM`` message. Quits if it sees a ``TERM`` message. """ if self.fwaddr and self.fwport: printM('Opening socket...', sender=self.sender) socket_type = s.SOCK_DGRAM if os.name in 'nt' else s.SOCK_DGRAM | s.SO_REUSEADDR self.sock = s.socket(s.AF_INET, socket_type) n = 0 next_int = time.time() + self.interval wait_pkts = self.interval / (rs.tf / 1000) while n > 3: self.getq() n += 1 n = 0 while True: self._subloop() self.raw = rs.copy(self.raw) # necessary to avoid memory leak self.stream = self.raw.copy() self._deconvolve() if n > wait_pkts: # if the trigger is activated obstart = self.stream[0].stats.endtime - timedelta( seconds=self.interval) # obspy time self.raw = self.raw.slice( starttime=obstart ) # slice the stream to the specified length (seconds variable) self.stream = self.stream.slice( starttime=obstart ) # slice the stream to the specified length (seconds variable) # run rsam analysis if time.time() > next_int: self._rsam() self.stream = rs.copy(self.stream) # prevent mem leak self._forward_rsam() self._print_rsam() next_int = time.time() + self.interval elif n == 0: printM( 'Starting RSAM analysis with interval=%s on station=%s channel=%s forward=%s' % (self.interval, self.stn, self.cha, self.fwaddr), self.sender) elif n == wait_pkts: printM('RSAM analysis up and running normally.', self.sender) if self.testing: TEST['c_rsam'][1] = True else: pass n += 1 sys.stdout.flush()
def mainloop(self, i, u): ''' The main loop in the :py:func:`rsudp.c_plot.Plot.run`. :param int i: number of plot events without clearing the linecache :param int u: queue blocking counter :return: number of plot events without clearing the linecache and queue blocking counter :rtype: int, int ''' if i > 10: linecache.clearcache() i = 0 else: i += 1 self.stream = rs.copy( self.stream) # essential, otherwise the stream has a memory leak self.raw = rs.copy(self.raw) # and could eventually crash the machine self.deconvolve() self.update_plot() if u >= 0: # avoiding a matplotlib broadcast error self.figloop() if self.save: # save the plot if (self.save_timer > self.save[0][0]): self._eventsave() u = 0 time.sleep(0.005) # wait a ms to see if another packet will arrive sys.stdout.flush() return i, u
def run(self): """ The heart of the plotting routine. Begins by updating the queue to populate a :py:`obspy.core.stream.Stream` object, then setting up the main plot. The first time through the main loop, the plot is not drawn. After that, the plot is drawn every time all channels are updated. Any plots containing a spectrogram and more than 1 channel are drawn at most every second (1000 ms). All other plots are drawn at most every quarter second (250 ms). """ self.getq() # block until data is flowing from the consumer for i in range((self.totchns) * 2): # fill up a stream object self.getq() self.set_sps() self.deconvolve() self.setup_plot() n = 0 # number of iterations without plotting i = 0 # number of plot events without clearing the linecache u = -1 # number of blocked queue calls (must be -1 at startup) while True: # main loop while True: if self.alive == False: # break if the user has closed the plot break n += 1 self.save_timer += 1 if self.queue.qsize() > 0: self.getq() time.sleep( 0.009 ) # wait a ms to see if another packet will arrive else: u += 1 if self.getq() else 0 if n > (self.delay * RS.numchns): n = 0 break if self.alive == False: # break if the user has closed the plot printM('Exiting.', self.sender) break if i > 10: linecache.clearcache() i = 0 else: i += 1 self.stream = RS.copy(self.stream) self.raw = RS.copy(self.raw) self.deconvolve() self.update_plot() if u >= 0: # avoiding a matplotlib broadcast error self.loop() if self.save: if (self.save_timer > self.save[0][0]): self._eventsave() u = 0 time.sleep(0.005) # wait a ms to see if another packet will arrive sys.stdout.flush() return
def run(self): """ Reads data from the queue into a :class:`obspy.core.stream.Stream` object, then runs a :func:`obspy.signal.trigger.recursive_sta_lta` function to determine whether to raise an alert flag (:py:data:`rsudp.c_alert.Alert.alarm`). The producer reads this flag and uses it to notify other consumers. """ n = 0 wait_pkts = (self.lta) / (rs.tf / 1000) while n > 3: self.getq() n += 1 n = 0 while True: self._subloop() self.raw = rs.copy(self.raw) # necessary to avoid memory leak self.stream = self.raw.copy() self._deconvolve() if n > wait_pkts: # if the trigger is activated obstart = self.stream[0].stats.endtime - timedelta(seconds=self.lta) # obspy time self.raw = self.raw.slice(starttime=obstart) # slice the stream to the specified length (seconds variable) self.stream = self.stream.slice(starttime=obstart) # slice the stream to the specified length (seconds variable) # filter self._filter() # figure out if the trigger has gone off self._is_trigger() # copy the stream (necessary to avoid memory leak) self.stream = rs.copy(self.stream) # print the current STA/LTA calculation self._print_stalta() elif n == 0: printM('Starting Alert trigger with sta=%ss, lta=%ss, and threshold=%s on channel=%s' % (self.sta, self.lta, self.thresh, self.cha), self.sender) printM('Earthquake trigger warmup time of %s seconds...' % (self.lta), self.sender) elif n == wait_pkts: printM('Earthquake trigger up and running normally.', self.sender) else: pass n += 1 sys.stdout.flush()
def run(self): """ Reads packets and coordinates write operations. """ self.elapse() self.getq() self.set_sps() self.getq() printM('miniSEED output directory: %s' % (self.outdir), self.sender) if self.inv: printM( 'Writing inventory file: %s/%s.%s.00.xml' % (self.outdir, self.stream[0].stats.network, self.stream[0].stats.station), self.sender) self.inv.write('%s/%s.%s.00.xml' % (self.outdir, self.stream[0].stats.network, self.stream[0].stats.station), format='STATIONXML') printM('Beginning miniSEED output.', self.sender) wait_pkts = (self.numchns * 10) / ( rs.tf / 1000) # comes out to 10 seconds (tf is in ms) n = 0 while True: while True: if self.queue.qsize() > 0: self.getq() time.sleep( 0.01 ) # wait a few ms to see if another packet will arrive n += 1 else: self.getq() n += 1 break if n >= wait_pkts: if self.newday < UTCDateTime.now( ): # end of previous day and start of new day self.write( self.stream.slice(endtime=self.newday, nearest_sample=False)) self.stream = self.stream.slice(starttime=self.newday, nearest_sample=False) self.elapse(new=True) else: self.write() self.stream = self.stream.slice(starttime=self.last, nearest_sample=False) self.stream = rs.copy(self.stream) n = 0 self.getq() time.sleep( 0.01) # wait a few ms to see if another packet will arrive sys.stdout.flush() sys.stderr.flush()
def run(self): """ """ n = 0 wait_pkts = (self.lta) / (RS.tf / 1000) while n > 3: self.getq() n += 1 n = 0 while True: while True: if self.queue.qsize() > 0: self._getq() # get recent packets else: if self._getq( ): # is this the specified channel? if so break break self.raw = RS.copy(self.raw) self.stream = self.raw.copy() if self.deconv: self._deconvolve() if n > wait_pkts: obstart = self.stream[0].stats.endtime - timedelta( seconds=self.lta) # obspy time self.raw = self.raw.slice( starttime=obstart ) # slice the stream to the specified length (seconds variable) self.stream = self.stream.slice( starttime=obstart ) # slice the stream to the specified length (seconds variable) if self.filt: if self.filt in 'bandpass': self.stalta = recursive_sta_lta( self.stream[0].copy().filter(type=self.filt, freqmin=self.freqmin, freqmax=self.freqmax), int(self.sta * self.sps), int(self.lta * self.sps)) else: self.stalta = recursive_sta_lta( self.stream[0].copy().filter(type=self.filt, freq=self.freq), int(self.sta * self.sps), int(self.lta * self.sps)) else: self.stalta = recursive_sta_lta(self.stream[0], int(self.sta * self.sps), int(self.lta * self.sps)) if self.stalta.max() > self.thresh: if not self.exceed: print() print() self.alarm = True # raise a flag that the Producer can read and modify self.exceed = True # the state machine; this one should not be touched from the outside, otherwise bad things will happen printM( 'Trigger threshold of %s exceeded: %s' % (self.thresh, round(self.stalta.max(), 3)), self.sender) if callable(self.func): self.func(sound=self.sound, *self.args, **self.kwargs) else: printM( 'Attempting execution of custom script. If something goes wrong, you may need to kill this process manually...' ) try: exec(self.func) except Exception as e: printM('Execution failed, error: %s' % e) printM( 'Trigger will reset when STA/LTA goes below %s...' % self.reset, sender=self.sender) else: pass if self.stalta.max() > self.maxstalta: self.maxstalta = self.stalta.max() else: if self.exceed: if self.stalta[-1] < self.reset: self.exceed = False print() printM( 'Max STA/LTA ratio reached in alarm state: %s' % (round(self.maxstalta, 3)), self.sender) printM( 'Earthquake trigger reset and active again.', self.sender) self.maxstalta = 0 else: pass self.stream = RS.copy(self.stream) print('\r%s [%s] Threshold: %s; Current max STA/LTA: %.4f' % (datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'), self.sender, self.thresh, round(np.max(self.stalta[-50:]), 4)), end='', flush=True) elif n == 0: printM( 'Listening to channel %s' % (self.stream[0].stats.channel), self.sender) printM( 'Earthquake trigger warmup time of %s seconds...' % (self.lta), self.sender) elif n == wait_pkts: printM('Earthquake trigger up and running normally.', self.sender) else: pass n += 1 sys.stdout.flush()