def __call__(self, frame): if frame.type == core.G3FrameType.Housekeeping: dataok = True if 'DataOK' in frame: dataok = frame['DataOK'] self.hkblob = self.PackHKToGCP( frame['DfMuxHousekeeping'], dataok=dataok, verbose=self.verbose) # Check for new connections, send any interested # parties the same data cxs = [] while True: try: s, origin_ip = self.socket.accept() except socket.error as e: if e.errno != errno.EAGAIN and \ e.errno != errno.EWOULDBLOCK: raise break core.log_debug('Accepted connection from %s:%d' % origin_ip, unit='GCPHousekeepingTee') cxs.append(s) for s in cxs: s.setblocking(True) s.sendall(self.hkblob) s.close()
def ping(self): """ Send a watchdog ping message to the GCP pager process. This method is called by the `run` method at regular intervals whenever the `data_valid` method returns True. """ try: if not self.sim: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(self.timeout) sock.connect((self.host, self.port)) sock.send('watchdog {}'.format(self.name).encode()) resp = sock.recv(4096) if resp: core.log_debug( 'Sent watchdog ping, got response {}'.format(resp.decode()), unit=self.unit, ) sock.close() except Exception as e: core.log_error('Error sending watchdog ping: {}'.format(e), unit=self.unit) # try again in ten seconds self.last_ping = time.time() - self.interval + 10 else: core.log_info('Sent watchdog ping', unit=self.unit) self.last_ping = time.time()
def FillCoordTransRotations(frame, transform_store_key, end_coord_sys=core.MapCoordReference.Equatorial, do_bad_transform=False, bs_az_key='RawBoresightAz', bs_el_key='RawBoresightEl', bs_ra_key='OnlineBoresightRa', bs_dec_key='OnlineBoresightDec', offset_az_key='OffsetBoresightAz', offset_el_key='OffsetBoresightEl', offset_ra_key='OnlineOffsetRa', offset_dec_key='OnlineOffsetDec'): ''' Calculates the rotation quaternions that take the point (1,0,0) (so az=el=0) in local coordinates to the coordinates specified by end_coord_sys and stores them in transform_store_key. This encodes the boresight pointing and any rotations about this boresight pointing due to coordinate system changes, az/el bearing tilt, etc. If do_bad_transform: It uses one set of points to calculate this rotations: (bs_az_key, bs_el_key) (bs_ra_key, bs_dec_key) Else: It uses two sets of points to calculate this rotations: (bs_az_key, bs_el_key) (bs_ra_key, bs_dec_key) (offset_az_key, offset_el_key) (offset_ra_key, offset_dec_key) If you do a bad transform it will not properly calculate the rotation around the boresight axis. ''' if frame.type != core.G3FrameType.Scan: return if transform_store_key in frame: core.log_debug("Transform already computed, skipping") return trans = G3VectorQuat() if end_coord_sys == core.MapCoordReference.Equatorial: if do_bad_transform: core.log_debug("You are doing the old calculation for pointing") create_lazy_det_ra_dec_trans(frame[bs_ra_key], frame[bs_dec_key], trans) else: create_det_ra_dec_trans(frame[bs_az_key], frame[bs_el_key], frame[bs_ra_key], frame[bs_dec_key], frame[offset_az_key], frame[offset_el_key], frame[offset_ra_key], frame[offset_dec_key], trans) elif end_coord_sys == core.MapCoordReference.Local: create_det_az_el_trans(frame[bs_az_key], frame[bs_el_key], trans) else: core.logfatal( "To do the galactic convert the equatorial transform to galactic later " + "using convert_ra_dec_trans_to_gal") frame[transform_store_key] = trans
def __call__(self, frame): if frame.type == core.G3FrameType.Wiring: self.wmap = frame['WiringMap'] if frame.type == core.G3FrameType.Timepoint: sec = int(frame['EventHeader'].time / core.G3Units.s) # Add data from this sample to the cache for this calendar second, replacing any missing detectors with -1 if sec not in self.data: self.data[sec] = {b: [] for b in self.bololist} self.data[sec]['DataOK'] = [] d = self.data[sec] for b in self.bololist: w = self.wmap[b] try: d[b].append( frame['DfMux'][w.board_serial][w.module][w.channel]) except KeyError: d[b].append(-1) if 'DataOK' in frame: self.data[sec]['DataOK'].append(bool(frame['DataOK'])) else: self.data[sec]['DataOK'].append(True) # Toss ancient data: we keep the last second (complete) # for GCP, plus the second we are currently accumulating if len(self.data) > 2: keys = list(self.data.keys()) keys.sort() for k in keys[:-2]: del self.data[k] # Check for new connections once we have a buffer if len(self.data) == 2: try: s, origin_ip = self.socket.accept() except socket.error as e: if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK: raise return core.log_debug('Accepted connection from %s:%d' % origin_ip, unit='GCPBoloDataTee') s.setblocking(True) keys = list(self.data.keys()) keys.sort() s.sendall(self.PackForGCP(self.data[keys[0]])) s.close() # Delete data once enqueued del self.data[keys[0]]
def ping(self): # send a watchdog command to the pager server port try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(self.timeout) sock.connect((self.host, self.port)) sock.send('watchdog daq'.encode()) resp = sock.recv(4096) if resp: core.log_debug("Sent DAQ watchdog ping, got response {}".format(resp.decode()), unit='GCPWatchdog') sock.close() except Exception as e: core.log_error("Error sending watchdog ping: {}".format(e), unit='GCPWatchdog') # try again in ten seconds self.last_ping = time.time() - self.interval + 10 else: core.log_info('Sent DAQ watchdog ping', unit='GCPWatchdog') self.last_ping = time.time()
def __call__(self, frame): # Only try on timepoint frames if frame.type != core.G3FrameType.Timepoint: return if self.collect_on_start and self.first_frame: self.first_frame = False return [core.G3Frame(core.G3FrameType.Housekeeping), frame] # Check for new connections try: s, origin_ip = self.socket.accept() except socket.error as e: if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK: raise return core.log_debug('Accepted housekeeping collection signal from %s:%d' % origin_ip, unit='GCPSignalledHousekeeping') s.close() return [core.G3Frame(core.G3FrameType.Housekeeping), frame]
def FillCoordTransRotations( frame, transform_store_key="OnlineRaDecRotation", end_coord_sys=MapCoordReference.Equatorial, do_bad_transform=False, bs_az_key="RawBoresightAz", bs_el_key="RawBoresightEl", bs_ra_key="OnlineBoresightRa", bs_dec_key="OnlineBoresightDec", offset_az_key="OffsetBoresightAz", offset_el_key="OffsetBoresightEl", offset_ra_key="OnlineOffsetRa", offset_dec_key="OnlineOffsetDec", ): """ Calculates the rotation quaternions that take the point (1,0,0) (so az=el=0) in local coordinates to the coordinates specified by end_coord_sys and stores them in transform_store_key. This encodes the boresight pointing and any rotations about this boresight pointing due to coordinate system changes, az/el bearing tilt, etc. Arguments --------- transform_store_key : string The key where the output transformation quaternion will be stored. If already present in the frame, this calculation will be skipped. end_coord_sys : MapCoordReference If Local, the transformation is computed using the negative of the detector delta angle. Otherwise the detector angle is not inverted. do_bad_transform : bool If end_coord_sys is not Local and this argument is True, the offset keys are ignored and the coordinate transformation does not take into account rotation about the boresight. bs_az_key, bs_el_key : string Boresight coordinates in the local coordinate system. If end_coord_sys is Local, only these two keys are required. bs_ra_key, bs_dec_key : string Boresight coordinates in the output coordinate system. If do_bad_transform is True, only these two keys and the previous two keys are required. offset_az_key, offset_el_key, offset_ra_key, offset_dec_key : string Local and output coordinates computed at a small offset from boresight. These keys are required if do_bad_transform is False, and will be used to account for any rotation about boresight in the coordinate transformation. """ if frame.type != core.G3FrameType.Scan: return if transform_store_key in frame: core.log_debug("Transform already computed, skipping") return trans = G3VectorQuat() if end_coord_sys == MapCoordReference.Local: create_det_az_el_trans(frame[bs_az_key], frame[bs_el_key], trans) else: if do_bad_transform: core.log_debug("You are doing the old calculation for pointing") create_lazy_det_ra_dec_trans(frame[bs_ra_key], frame[bs_dec_key], trans) else: create_det_ra_dec_trans( frame[bs_az_key], frame[bs_el_key], frame[bs_ra_key], frame[bs_dec_key], frame[offset_az_key], frame[offset_el_key], frame[offset_ra_key], frame[offset_dec_key], trans, ) frame[transform_store_key] = trans
def __call__(self, frame): # If Timepoint frame of bolometer data, update timer if frame.type == core.G3FrameType.Timepoint and 'DfMux' in frame: seconds = int(frame['EventHeader'].time / core.G3Units.s) self.time_chunk = seconds - seconds % self._chunk_sec # If Timepoint frame of CHWP data, fill the buffer if frame.type == core.G3FrameType.Timepoint and 'DfMux' not in frame: # Generate dict of lists if first time within this time chunk if self.time_chunk not in self.data: self.data[self.time_chunk] = { 'chwp_encoder_quad': [], 'chwp_encoder_clock': [], 'chwp_encoder_count': [], 'chwp_irig_time': [], 'chwp_irig_clock': []} # Populate dictionary lists with encoder data if 'chwp_encoder_quad' in frame.keys(): self.data[self.time_chunk]['chwp_encoder_quad'] += ( [frame['chwp_encoder_quad']]) self.data[self.time_chunk]['chwp_encoder_clock'] += ( list(frame['chwp_encoder_clock'])) self.data[self.time_chunk]['chwp_encoder_count'] += ( list(frame['chwp_encoder_count'])) # Populate dictionary lists with IRIG data elif 'chwp_irig_time' in frame.keys(): self.data[self.time_chunk]['chwp_irig_time'].append( frame['chwp_irig_time']) self.data[self.time_chunk]['chwp_irig_clock'].append( frame['chwp_irig_clock']) # Once the buffer has something, check for new connections if len(self.data) == 2: keys = list(self.data.keys()) keys.sort() try: s, origin_ip = self.socket.accept() except socket.error as e: # Raise the exception if there is a real problem if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK: raise e # If nobody is listening, prune the buffer del self.data[keys[0]] return # If someone is listening, then send the data core.log_debug( "Accepted connection from %s:%d" % (origin_ip), unit='CHWPSlowDAQTee') s.setblocking(True) # Send the data over the socket to the slowDAQ publisher # and assert that nothing was sent back to_send = self._pack_for_slow_daq(self.data[keys[0]]) retval = s.sendall(to_send) assert retval is None # Close the socket after the data is sent s.close() # Only keep the most recent data del self.data[keys[0]] elif len(self.data) > 2: raise RuntimeError('Buffer too long!')
def PackHKToGCP(hk, dataok=True, verbose=False): if verbose: core.log_debug('gcp.GCPHousekeepingTee.PackHKToGCP(hk)', unit='GCPHousekeepingTee') buf = struct.pack('<?I', dataok, len(hk)) # See HkDataStruct in GCP for ip, board in hk.items(): # if verbose mode, print a few registers for debugging if verbose: core.log_debug("%d, %10.6f, %10.6f, %10.6f, %10.6f, %10.6f" % (ip, board.temperatures['MOTHERBOARD_TEMPERATURE_ARM'], board.temperatures['MOTHERBOARD_TEMPERATURE_FPGA'], board.temperatures['MOTHERBOARD_TEMPERATURE_FPGA_DIE'], board.temperatures['MOTHERBOARD_TEMPERATURE_PHY'], board.temperatures['MOTHERBOARD_TEMPERATURE_POWER']), unit='GCPHousekeepingTee') buf += struct.pack('<fffff', board.temperatures['MOTHERBOARD_TEMPERATURE_ARM'], board.temperatures['MOTHERBOARD_TEMPERATURE_FPGA'], board.temperatures['MOTHERBOARD_TEMPERATURE_FPGA_DIE'], board.temperatures['MOTHERBOARD_TEMPERATURE_PHY'], board.temperatures['MOTHERBOARD_TEMPERATURE_POWER']) buf += struct.pack('<fffffffff', board.voltages['MOTHERBOARD_RAIL_VADJ'], board.voltages['MOTHERBOARD_RAIL_VCC12V0'], board.voltages['MOTHERBOARD_RAIL_VCC1V0'], board.voltages['MOTHERBOARD_RAIL_VCC1V0_GTX'], board.voltages['MOTHERBOARD_RAIL_VCC1V2'], board.voltages['MOTHERBOARD_RAIL_VCC1V5'], board.voltages['MOTHERBOARD_RAIL_VCC1V8'], board.voltages['MOTHERBOARD_RAIL_VCC3V3'], board.voltages['MOTHERBOARD_RAIL_VCC5V5']) buf += struct.pack('<fffffffff', board.currents['MOTHERBOARD_RAIL_VADJ'], board.currents['MOTHERBOARD_RAIL_VCC12V0'], board.currents['MOTHERBOARD_RAIL_VCC1V0'], board.currents['MOTHERBOARD_RAIL_VCC1V0_GTX'], board.currents['MOTHERBOARD_RAIL_VCC1V2'], board.currents['MOTHERBOARD_RAIL_VCC1V5'], board.currents['MOTHERBOARD_RAIL_VCC1V8'], board.currents['MOTHERBOARD_RAIL_VCC3V3'], board.currents['MOTHERBOARD_RAIL_VCC5V5']) buf += struct.pack('255s', ('iceboard' + board.serial).encode()) for i in [1,2]: buf += struct.pack('<?', board.mezz[i].present) buf += struct.pack('<?', board.mezz[i].power) buf += struct.pack('<?', board.mezz[i].squid_controller_power) buf += struct.pack('<fff', board.mezz[i].voltages['MEZZANINE_RAIL_VADJ'], board.mezz[i].voltages['MEZZANINE_RAIL_VCC12V0'], board.mezz[i].voltages['MEZZANINE_RAIL_VCC3V3']) buf += struct.pack('<fff', board.mezz[i].currents['MEZZANINE_RAIL_VADJ'], board.mezz[i].currents['MEZZANINE_RAIL_VCC12V0'], board.mezz[i].currents['MEZZANINE_RAIL_VCC3V3']) buf += struct.pack('<fff', board.mezz[i].temperature, board.mezz[i].squid_controller_temperature, board.mezz[i].squid_heater) # Prefix with total message length buf = struct.pack('!q', len(buf)) + buf return buf