Source code for recipe_system.adcc.client.qap_specviewer.mock_primitive

#!/usr/bin/env python
"""
Mock plotSpectraForQA primitive.

This module emulates a pipeline that reproduces how the plotSpectraForQA would
behave in real time.

In practice, it creates JSON data and send it to the ADCC Server in a timed loop.
"""
import json
import time
import urllib.error
import urllib.request

import numpy as np
from scipy import ndimage

URL = "http://localhost:8777/spec_report"


[docs] def main(): """ Main function. """ np.random.seed(0) args = _parse_arguments() url = args.url n_frames = args.n_frames n_apertures = args.n_apertures sleep_between_frames = args.sleep_time data_size = 4000 snr = 10. pixel_scale = 0.1614 wavelength_min = 300. wavelength_max = 800. wavelength_units = "nm" file_index = 1 program_index = 1 while True: obj_max_weight = 1000. obj_continnum = 300. + 0.01 * np.arange(data_size) noise_level = obj_continnum / snr wavelength = np.linspace(wavelength_min, wavelength_max, data_size) dispersion = np.mean(np.diff(wavelength)) data = [create_1d_spectrum(data_size, 20, obj_max_weight) + obj_continnum * i for i in range(n_apertures)] center = np.random.randint(100, 900, size=n_apertures+1) lower = np.random.randint(-15, -1, size=n_apertures+1) upper = np.random.randint(1, 15, size=n_apertures+1) year = 2020 today = 20200131 program_id = "GX-{}C-Q-{:03d}".format(year, program_index) group_index = 1 group_id = "{:s}-{:02d}".format(program_id, group_index) for frame_index in range(n_frames): data_label = "{:s}-{:03d}".format(group_id, frame_index + 1) filename = "X{}S{:03d}_frame.fits".format(today, file_index) if frame_index == 0: stack_data_label = "{:s}-{:03d}_stack".format(group_id, frame_index + 1) stack_filename = "X{}S{:03d}_stack.fits".format(today, file_index) def aperture_generator(i): delta_center = (np.random.rand() - 0.5) * 0.9 / pixel_scale center[i] = center[i] + delta_center center[i] = np.round(center[i]) _data = data[i] _error = np.random.poisson(_data) + noise_level * (np.random.rand(_data.size) - 0.5) _aperture = ApertureModel( int(center[i]), int(lower[i]), int(upper[i]), wavelength_units, dispersion, wavelength, _data, _error) return _aperture.__dict__ def stack_aperture_generator(i): delta_center = (np.random.rand() - 0.5) * 0.9 / pixel_scale center[i] = center[i] + delta_center _data = data[i] _error = np.random.rand(_data.size) - 0.5 _error *= noise_level / (frame_index + 1) _error += np.random.poisson(_data) _aperture = ApertureModel( int(center[i]), int(lower[i]), int(upper[i]), wavelength_units, dispersion, wavelength, _data, _error) return _aperture.__dict__ n = np.random.randint(n_apertures-1, n_apertures+1) apertures = [aperture_generator(i) for i in range(n)] n = np.random.randint(n_apertures - 1, n_apertures + 1) stack_apertures = [stack_aperture_generator(i) for i in range(n)] frame = SpecPackModel( data_label=data_label, group_id=group_id, filename=filename, is_stack=False, pixel_scale=pixel_scale, program_id=program_id, stack_size=1, apertures=apertures) stack = SpecPackModel( data_label=stack_data_label, group_id=group_id, filename=stack_filename, is_stack=True, pixel_scale=pixel_scale, program_id=program_id, stack_size=frame_index + 1, apertures=stack_apertures) json_list = [frame.__dict__, stack.__dict__] json_data = json.dumps(json_list).encode("utf-8") print("\n Created JSON for single frame with: ") print(" Program ID: {}".format(program_id)) print(" Group-id: {}".format(group_id)) print(" Data-label: {}".format(data_label)) print(" Filename: {}".format(filename)) print(" Apertures: {}".format(center)) print(" Performing request...") try: post_request = urllib.request.Request(url) post_request.add_header("Content-Type", "application/json") postr = urllib.request.urlopen(post_request, json_data) postr.read() postr.close() except urllib.error.URLError: import sys print("\n Error trying to open URL: {}".format(url)) print(" Please, check that the server is running " "and run again.\n") sys.exit() print(" Done.") print(" Sleeping for {} seconds ...".format(sleep_between_frames)) time.sleep(sleep_between_frames) file_index += 1 program_index += 1 group_index += 1
def _parse_arguments(): """ Parses arguments received from the command line. Returns ------- namespace all the default and customized options parsed from the command line. """ import argparse parser = argparse.ArgumentParser( description="A script that simulates a pipeline running the " "plotSpectraForQA and posting JSON data to the " "ADCC server.") parser.add_argument( '-a', '--apertures', default=3, dest="n_apertures", help="Number of aperetures for each data", type=int, ) parser.add_argument( '-f', '--frames', default=3, dest="n_frames", help="Number of frames for each Group ID.", type=int, ) parser.add_argument( '-u', '--url', default=URL, help="URL of the ADCC server (e.g.: http://localhost:8777/spec_report)", type=str, ) parser.add_argument( '-s', '--sleep', default=10., dest="sleep_time", help="Sleep time between post requests", type=float, ) return parser.parse_args()
[docs] def create_1d_spectrum(width, n_lines, max_weight): """ Generates a 1D NDArray that simulates a random spectrum. Parameters ---------- width : int Number of array elements. n_lines : int Number of artificial lines. max_weight : float Maximum weight (or flux, or intensity) of the lines. Returns ------- sky_1d_spectrum : numpy.ndarray """ lines = np.random.randint(low=0, high=width, size=n_lines) weights = max_weight * np.random.random(size=n_lines) spectrum = np.zeros(width) spectrum[lines] = weights spectrum = ndimage.gaussian_filter1d(spectrum, 5) return spectrum
[docs] class ApertureModel: def __init__(self, center, lower, upper, wavelength_units, dispersion, wavelength, intensity, error): wavelength = np.round(wavelength, 3) intensity = np.round(intensity) error = np.round(error) self.center = center self.lower = lower self.upper = upper self.dispersion = dispersion self.wavelength_units = wavelength_units self.intensity = [[w, int(d)] for w, d in zip(wavelength, intensity)] self.stddev = [[w, int(d)] for w, d in zip(wavelength, error)]
[docs] class SpecPackModel: def __init__(self, data_label, group_id, filename, is_stack, pixel_scale, program_id, stack_size, apertures): self.data_label = data_label self.group_id = group_id self.filename = filename self.msgtype = "specjson" self.is_stack = is_stack self.pixel_scale = pixel_scale self.program_id = program_id self.stack_size = stack_size self.timestamp = time.time() self.apertures = apertures
if __name__ == '__main__': main()