class Weather: def __init__(self): self.cal = Calibration() self.last_integration_mjd_timestamp = None self.last_requested_freq_hz = None self.last_zenith_opacity = None self.number_of_opacity_files = None self.opacity_coeffs = None self.L_BAND_ZENITH_TAU = .008 def _retrieve_opacity_coefficients(self, opacity_coefficients_filename): """Return opacities (taus) derived from a list of coeffients These coefficients are produced from Ron Madalenna's getForecastValues script Keywords: infilename -- input file name needed for project name mjd -- date for data freq -- list of frequencies for which we seek an opacity Returns: a list of opacity coefficients for the time range of the dataset """ opacity_file = open(opacity_coefficients_filename, 'r') coeffs = [] if opacity_file: for line in opacity_file: # find the most recent forecast and parse out the coefficients for # each band # coeffs[0] is the mjd timestamp # coeffs[1] are the coefficients for 2-22 GHz # coeffs[2] are the coefficients for 22-50 GHz # coeffs[3] are the coefficients for 70-116 GHz coeffs.append((float(line.split('{{')[0]), \ [float(xx) for xx in line.split('{{')[1].split('}')[0].split(' ')], \ [float(xx) for xx in line.split('{{')[2].split('}')[0].split(' ')], \ [float(xx) for xx in line.split('{{')[3].split('}')[0].split(' ')])) else: print "WARNING: Could not read coefficients for Tau in", opacity_coefficients_filename return False return coeffs def retrieve_zenith_opacity(self, integration_mjd_timestamp, freq_hz): freq_ghz = freq_hz/1e9 # if less than 2 GHz, opacity coefficients are not available if freq_ghz < 2: return self.L_BAND_ZENITH_TAU # if the frequency is the same as the last requested and # this time is within the same record (1 hr window) of the last # recorded opacity coefficients, then just reuse the last # zenith opacity value requested if self.last_requested_freq_hz and self.last_requested_freq_hz == freq_hz and \ integration_mjd_timestamp >= self.last_integration_mjd_timestamp and \ integration_mjd_timestamp < self.last_integration_mjd_timestamp + .04167: return self.last_zenith_opacity self.last_integration_mjd_timestamp = integration_mjd_timestamp self.last_requested_freq_hz = freq_hz # retrieve a list of opacity coefficients files, based on a given directory # and filename structure opacity_coefficients_filename = False opacity_files = glob.glob(\ '/users/rmaddale/Weather/ArchiveCoeffs/CoeffsOpacityFreqList_avrg_*.txt') self.number_of_opacity_files = len(opacity_files) if 0 == self.number_of_opacity_files: #doMessage(logger, msg.WARN, 'WARNING: No opacity coefficients file') print 'WARNING: No opacity coefficients file' return False # sort the list of files so they are in chronological order opacity_files.sort() # the following will become True if integration_mjd_timestamp is older than available ranges # provided in the opacity coefficients files tooearly = False # check the date of each opacity coefficients file for idx, opacity_candidate_file in enumerate(opacity_files): dates = opacity_candidate_file.split('_')[-2:] opacity_file_timestamp = [] for date in dates: opacity_file_timestamp.append(int(date.split('.')[0])) opacity_file_starttime = opacity_file_timestamp[0] opacity_file_stoptime = opacity_file_timestamp[1] # set tooearly = True when integration_mjd_timestamp is older than available ranges if idx == 0 and integration_mjd_timestamp < opacity_file_starttime: tooearly = True break if integration_mjd_timestamp >= opacity_file_starttime \ and integration_mjd_timestamp < opacity_file_stoptime: opacity_coefficients_filename = opacity_candidate_file break if not opacity_coefficients_filename: if tooearly: #doMessage(logger, msg.ERR, 'ERROR: Date is too early for opacities.') #doMessage(logger, msg.ERR, ' Try setting zenith tau at command line.') sys.exit(9) else: # if the mjd in the index file comes after the date string in all of the # opacity coefficients files, then we can assume the current opacity # coefficients file will apply. a date string is only added to the opacity # coefficients file when it is no longer the most current. opacity_coefficients_filename = \ '/users/rmaddale/Weather/ArchiveCoeffs/CoeffsOpacityFreqList_avrg.txt' # opacities coefficients filename if opacity_coefficients_filename and os.path.exists(opacity_coefficients_filename): #doMessage(logger, msg.DBG, 'Using coefficients from', opacity_coefficients_filename) self.opacity_coeffs = self._retrieve_opacity_coefficients(opacity_coefficients_filename) else: #doMessage(logger, msg.WARN, 'WARNING: No opacity coefficients file') print 'WARNING: No opacity coefficients file' return False for coeffs_line in self.opacity_coeffs: if integration_mjd_timestamp >= coeffs_line[0]: prev_time = coeffs_line[0] if (freq_ghz >= 2 and freq_ghz <= 22): prev_coeffs = coeffs_line[1] elif (freq_ghz > 22 and freq_ghz <= 50): prev_coeffs = coeffs_line[2] elif (freq_ghz > 50 and freq_ghz <= 116): prev_coeffs = coeffs_line[3] elif integration_mjd_timestamp < coeffs_line[0]: next_time = coeffs_line[0] if (freq_ghz >= 2 and freq_ghz <= 22): next_coeffs = coeffs_line[1] elif (freq_ghz > 22 and freq_ghz <= 50): next_coeffs = coeffs_line[2] elif (freq_ghz > 50 and freq_ghz <= 116): next_coeffs = coeffs_line[3] break time_corrected_coeffs = [] for coeff in zip(prev_coeffs, next_coeffs): new_coeff = self.cal.interpolate_by_time(coeff[0], coeff[1], prev_time, next_time, integration_mjd_timestamp) time_corrected_coeffs.append(new_coeff) zenith_opacity = self.cal.zenith_opacity(time_corrected_coeffs, freq_ghz) self.last_zenith_opacity = zenith_opacity return zenith_opacity
class test_Calibration: def __init__(self): self.cal = None def setup(self): self.cal = Calibration() def test_total_power(self): array1 = np.ones(10) array2 = np.ones(10) * 2 result = self.cal.total_power(array1, array2) expected_result = np.ones(10) * 1.5 np.testing.assert_equal(result, expected_result) def test_tsky(self): ambient_temp_k = 310.1 freq_hz = 18.458 tau = .05 tsky = self.cal.tsky(ambient_temp_k, freq_hz, tau) expected_result = 13.432242475061472 ntest.assert_almost_equal(tsky, expected_result) def test_tsky_correction(self): array_size = 128 tsky_sig = np.ones(array_size) * 2 tsky_ref = np.ones(array_size) spillover = .123 tsky_correction = self.cal.tsky_correction(tsky_sig, tsky_ref, spillover) expected_result = np.ones(array_size) * .123 np.testing.assert_equal(tsky_correction, expected_result) def test_aperture_efficiency(self): reference_eta_a = .71 freq_hz = 23e9 efficiency = self.cal.aperture_efficiency(reference_eta_a, freq_hz) expected_result = 0.64748265789117276 ntest.assert_almost_equal(efficiency, expected_result) def test_main_beam_efficiency(self): reference_eta_a = .7 freq_hz = 23.7e9 efficiency = self.cal.main_beam_efficiency(reference_eta_a, freq_hz) expected_result = 0.6347374630868166 ntest.assert_almost_equal(efficiency, expected_result) def test_elevation_adjusted_opacity(self): zenith_opacity = .1 elevation = 45. adjusted_opacity = self.cal.elevation_adjusted_opacity(.1, 45.) expected_result = 0.07071067811865475 ntest.assert_almost_equal(adjusted_opacity, expected_result) def test__tatm(self): freq_hz = 23e9 temp_c = 40. atmospheric_effective_temp = self.cal._tatm(freq_hz, temp_c) expected_result = 298.88517422006998 ntest.assert_almost_equal(atmospheric_effective_temp, expected_result) def test_zenith_opacity(self): opacity_coefficients = [2, 1, 0] freq_ghz = 16.79 zenith_opacity = self.cal.zenith_opacity(opacity_coefficients, freq_ghz) expected_result = 18.79 ntest.assert_equal(zenith_opacity, expected_result) def test_tsys(self): tcal = 1. cal_off = np.ones(128) cal_on = np.ones(128)*3 tsys = self.cal.tsys(tcal, cal_on, cal_off) expected = 1. ntest.assert_equal(tsys, expected) def test_antenna_temp(self): tsys = .5 sig = np.ones(128) * 2 ref = np.ones(128) antenna_temp = self.cal.antenna_temp(tsys, sig, ref) expected_result = np.ones(128) * .5 np.testing.assert_equal(antenna_temp, expected_result) def test__ta_fs_one_state(self): sigref_state = [{'cal_on': None, 'cal_off': None, 'TP': None}, {'cal_on': None, 'cal_off': None, 'TP': None}] sigref_state[0]['cal_on'] = np.ones(128) sigref_state[0]['cal_off'] = np.ones(128) sigref_state[1]['cal_on'] = np.ones(128) sigref_state[1]['cal_off'] = np.ones(128) sigid = 0 refid = 1 assert False def test_ta_fs(self): assert False def test_ta_star(self): antenna_temp = np.ones(128) beam_scaling = 1. opacity = 0 spillover = 2. ta_star = self.cal.ta_star(antenna_temp, beam_scaling, opacity, spillover) expected = np.ones(128) * .5 np.testing.assert_equal(ta_star, expected) def test_jansky(self): ta_star = np.ones(128) aperture_efficiency = .1 jansky = self.cal.jansky(ta_star, aperture_efficiency) expected = np.ones(128) / .285 np.testing.assert_almost_equal(jansky, expected) def test_interpolate_by_time(self): reference1 = 0. reference1_time = 10000. reference2 = 100. reference2_time = 20000. result_time = 15000. result_value = self.cal.interpolate_by_time(reference1, reference2, reference1_time, reference2_time, result_time) expected = 50. ntest.assert_equal(result_value, expected)
class test_Calibration: def __init__(self): self.cal = None def setup(self): self.cal = Calibration() @unittest.skip("Ignoring test per email from Joe Masters, 2017-10-26") def test_total_power(self): array1 = np.ones(10) array2 = np.ones(10) * 2 result = self.cal.total_power(array1, array2) expected_result = np.ones(10) * 1.5 np.testing.assert_equal(result, expected_result) def test_tsky(self): ambient_temp_k = 310.1 freq_hz = 18.458 tau = .05 tsky = self.cal.tsky(ambient_temp_k, freq_hz, tau) expected_result = 13.432242475061472 ntest.assert_almost_equal(tsky, expected_result) def test_tsky_correction(self): array_size = 128 tsky_sig = np.ones(array_size) * 2 tsky_ref = np.ones(array_size) spillover = .123 tsky_correction = self.cal.tsky_correction(tsky_sig, tsky_ref, spillover) expected_result = np.ones(array_size) * .123 np.testing.assert_equal(tsky_correction, expected_result) def test_aperture_efficiency(self): reference_eta_a = .71 freq_hz = 23e9 efficiency = self.cal.aperture_efficiency(reference_eta_a, freq_hz) expected_result = 0.64748265789117276 ntest.assert_almost_equal(efficiency, expected_result) def test_main_beam_efficiency(self): reference_eta_a = .7 freq_hz = 23.7e9 efficiency = self.cal.main_beam_efficiency(reference_eta_a, freq_hz) expected_result = 0.6347374630868166 ntest.assert_almost_equal(efficiency, expected_result) @unittest.skip( "This test is outdated, and should be revisited in the future.") def test_elevation_adjusted_opacity(self): zenith_opacity = .1 elevation = 45. adjusted_opacity = self.cal.elevation_adjusted_opacity(.1, 45.) expected_result = 0.07071067811865475 ntest.assert_almost_equal(adjusted_opacity, expected_result) def test__tatm(self): freq_hz = 23e9 temp_c = 40. atmospheric_effective_temp = self.cal._tatm(freq_hz, temp_c) expected_result = 298.88517422006998 ntest.assert_almost_equal(atmospheric_effective_temp, expected_result) def test_zenith_opacity(self): opacity_coefficients = [2, 1, 0] freq_ghz = 16.79 zenith_opacity = self.cal.zenith_opacity(opacity_coefficients, freq_ghz) expected_result = 18.79 ntest.assert_equal(zenith_opacity, expected_result) def test_tsys(self): tcal = 1. cal_off = np.ones(128) cal_on = np.ones(128) * 3 tsys = self.cal.tsys(tcal, cal_on, cal_off) expected = 1. ntest.assert_equal(tsys, expected) @unittest.skip("Ignoring test per email from Joe Masters, 2017-10-26") def test_antenna_temp(self): tsys = .5 sig = np.ones(128) * 2 ref = np.ones(128) antenna_temp = self.cal.antenna_temp(tsys, sig, ref) expected_result = np.ones(128) * .5 np.testing.assert_equal(antenna_temp, expected_result) @unittest.skip( "This is a stub test that we would like to expand in the future.") def test__ta_fs_one_state(self): sigref_state = [{ 'cal_on': None, 'cal_off': None, 'TP': None }, { 'cal_on': None, 'cal_off': None, 'TP': None }] sigref_state[0]['cal_on'] = np.ones(128) sigref_state[0]['cal_off'] = np.ones(128) sigref_state[1]['cal_on'] = np.ones(128) sigref_state[1]['cal_off'] = np.ones(128) sigid = 0 refid = 1 assert False @unittest.skip( "This is a stub test that we would like to expand in the future.") def test_ta_fs(self): assert False @unittest.skip("Ignoring test per email from Joe Masters, 2017-10-26") def test_ta_star(self): antenna_temp = np.ones(128) beam_scaling = 1. opacity = 0 spillover = 2. ta_star = self.cal.ta_star(antenna_temp, beam_scaling, opacity, spillover) expected = np.ones(128) * .5 np.testing.assert_equal(ta_star, expected) def test_jansky(self): ta_star = np.ones(128) aperture_efficiency = .1 jansky = self.cal.jansky(ta_star, aperture_efficiency) expected = np.ones(128) / .285 np.testing.assert_almost_equal(jansky, expected) def test_interpolate_by_time(self): reference1 = 0. reference1_time = 10000. reference2 = 100. reference2_time = 20000. result_time = 15000. result_value = self.cal.interpolate_by_time(reference1, reference2, reference1_time, reference2_time, result_time) expected = 50. ntest.assert_equal(result_value, expected)
class Weather: def __init__(self): self.cal = Calibration() self.last_integration_mjd_timestamp = None self.last_requested_freq_ghz = None self.zenith_opacity = None self.opacity_coeffs = None self.L_BAND_ZENITH_TAU = .008 self.frequency_range = None self.time_range = None self.db_time_range = None self.log = None def _opacity_database(self, timestamp): # retrieve a list of opacity coefficients files, based on a given directory # and filename structure opacity_coefficients_filename = False opacity_files = glob.glob( '/home/gbtpipeline/weather/CoeffsOpacityFreqList_avrg_*.txt') if 0 == len(opacity_files): return False, False # sort the list of files so they are in chronological order opacity_files.sort() # check the date of each opacity coefficients file for idx, opacity_candidate_file in enumerate(opacity_files): dates = opacity_candidate_file.split('_')[-2:] opacity_file_timestamp = [] for date in dates: opacity_file_timestamp.append(int(date.split('.')[0])) opacity_file_starttime = opacity_file_timestamp[0] opacity_file_stoptime = opacity_file_timestamp[1] # when timestamp is older than available ranges if idx == 0 and timestamp < opacity_file_starttime: if self.log: self.log.doMessage( 'ERR', 'ERROR: Date is too early for opacities.') self.log.doMessage( 'ERR', ' Try setting zenith tau at command line.') self.log.doMessage('ERR', timestamp, '<', opacity_file_starttime) else: print 'ERROR: Date is too early for opacities.' print ' Try setting zenith tau at command line.' print timestamp, '<', opacity_file_starttime sys.exit(9) break if (opacity_file_starttime <= timestamp < opacity_file_stoptime): opacity_coefficients_filename = opacity_candidate_file opacity_db_range = (opacity_file_starttime, opacity_file_stoptime) break # uses most recent info if not opacity_coefficients_filename: # if the mjd in the index file comes after the date string in all of the # opacity coefficients files, then we can assume the current opacity # coefficients file will apply. a date string is only added to the opacity # coefficients file when it is no longer the most current. opacity_coefficients_filename = '/home/gbtpipeline/weather/CoeffsOpacityFreqList_avrg.txt' opacity_db_range = 'LATEST' # opacities coefficients filename if opacity_coefficients_filename and os.path.exists( opacity_coefficients_filename): if self.log: self.log.doMessage('DBG', 'Using coefficients from', opacity_coefficients_filename) else: print 'Using coefficients from', opacity_coefficients_filename coeffs = self._retrieve_opacity_coefficients( opacity_coefficients_filename) return coeffs, opacity_db_range else: if self.log: self.log.doMessage('ERR', 'No opacity coefficients file') else: print 'ERROR: No opacity coefficients file' return False, False def _retrieve_opacity_coefficients(self, opacity_coefficients_filename): """Return opacities (taus) derived from a list of coeffients These coefficients are produced from Ron Madalenna's getForecastValues script Keywords: infilename -- input file name needed for project name mjd -- date for data freq -- list of frequencies for which we seek an opacity Returns: a list of opacity coefficients for the time range of the dataset """ opacity_file = open(opacity_coefficients_filename, 'r') coeffs = [] if opacity_file: for line in opacity_file: # find the most recent forecast and parse out the coefficients for # each band # coeffs[0] is the mjd timestamp # coeffs[1] are the coefficients for 2-22 GHz # coeffs[2] are the coefficients for 22-50 GHz # coeffs[3] are the coefficients for 70-116 GHz coeffs.append((float(line.split('{{')[0]), [ float(xx) for xx in line.split('{{')[1].split('}')[0].split(' ') ], [ float(xx) for xx in line.split('{{')[2].split('}')[0].split(' ') ], [ float(xx) for xx in line.split('{{')[3].split('}')[0].split(' ') ])) else: print "WARNING: Could not read coefficients for Tau in", opacity_coefficients_filename return False return coeffs def retrieve_zenith_opacity(self, integration_mjd_timestamp, freq_hz, log=None): self.log = log freq_ghz = freq_hz / 1e9 # if less than 2 GHz, opacity coefficients are not available if freq_ghz < 2: return self.L_BAND_ZENITH_TAU # if the frequency is in the same range and # the time is within the same record (1 hr window) of the last # recorded opacity coefficients, then just reuse the last # zenith opacity value requested if ((self.frequency_range and (self.frequency_range[0] <= freq_ghz <= self.frequency_range[1])) and (self.time_range and (self.time_range[0] <= integration_mjd_timestamp <= self.time_range[1]))): return self.zenith_opacity self.last_integration_mjd_timestamp = integration_mjd_timestamp self.last_requested_freq_ghz = freq_ghz # if we don't have a db time range OR # we do have a time range AND # the range is 'LATEST' AND # timestamp is not w/in the same hour as the last set of coeffs, OR # the range has values AND # our new timestamp is not in the range # THEN # get another set of coefficients from a different file if ((not self.db_time_range) or (self.db_time_range == 'LATEST' and not (self.time_range[0] <= integration_mjd_timestamp < self.time_range[1])) or (self.db_time_range and not (self.db_time_range[0] <= integration_mjd_timestamp < self.db_time_range[1]))): log.doMessage( 'DBG', '-----------------------------------------------------') log.doMessage( 'DBG', 'Time or Frequency out of range. Determine new opacity') log.doMessage( 'DBG', '-----------------------------------------------------') log.doMessage('DBG', 'opacity', self.zenith_opacity) log.doMessage('DBG', 'timestamp', integration_mjd_timestamp, 'prev.', self.last_integration_mjd_timestamp) log.doMessage('DBG', 'freq', freq_ghz, 'prev.', self.last_requested_freq_ghz) log.doMessage('DBG', 'freq range', self.frequency_range) if bool(self.frequency_range): log.doMessage( 'DBG', ' freq in range == ', bool(self.frequency_range[0] <= freq_ghz <= self.frequency_range[1])) log.doMessage('DBG', 'time range', self.time_range) if bool(self.time_range): log.doMessage( 'DBG', ' time in range ==', bool(self.time_range and (self.time_range[0] <= integration_mjd_timestamp <= self.time_range[1]))) log.doMessage('DBG', 'DB time range', self.db_time_range) if bool(self.db_time_range): log.doMessage( 'DBG', ' time in DB range ==', bool(self.db_time_range and (self.db_time_range[0] <= integration_mjd_timestamp <= self.db_time_range[1]))) self.opacity_coeffs, self.db_time_range = self._opacity_database( integration_mjd_timestamp) if (not self.opacity_coeffs) or (not self.db_time_range): return False log.doMessage('DBG', 'DB time range:', self.db_time_range) for coeffs_line in self.opacity_coeffs: if (2 <= freq_ghz <= 22): self.frequency_range = (2, 22) coefficients_index = 1 elif (22 < freq_ghz <= 50): self.frequency_range = (22, 50) coefficients_index = 2 elif (50 < freq_ghz <= 116): self.frequency_range = (50, 116) coefficients_index = 3 if integration_mjd_timestamp >= coeffs_line[0]: prev_time = coeffs_line[0] prev_coeffs = coeffs_line[coefficients_index] elif integration_mjd_timestamp < coeffs_line[0]: next_time = coeffs_line[0] next_coeffs = coeffs_line[coefficients_index] break self.time_range = (prev_time, next_time) log.doMessage('DBG', 'Coefficient entry time range:', self.time_range) time_corrected_coeffs = [] for coeff in zip(prev_coeffs, next_coeffs): new_coeff = self.cal.interpolate_by_time( coeff[0], coeff[1], prev_time, next_time, integration_mjd_timestamp) time_corrected_coeffs.append(new_coeff) self.zenith_opacity = self.cal.zenith_opacity(time_corrected_coeffs, freq_ghz) log.doMessage('DBG', 'Zenith opacity:', self.zenith_opacity) return self.zenith_opacity
class Weather: def __init__(self): self.cal = Calibration() self.last_integration_mjd_timestamp = None self.last_requested_freq_ghz = None self.zenith_opacity = None self.opacity_coeffs = None self.L_BAND_ZENITH_TAU = .008 self.frequency_range = None self.time_range = None self.db_time_range = None self.log = None def _opacity_database(self, timestamp): # retrieve a list of opacity coefficients files, based on a given directory # and filename structure opacity_coefficients_filename = False opacity_files = glob.glob('/home/gbtpipeline/weather/CoeffsOpacityFreqList_avrg_*.txt') if 0 == len(opacity_files): return False, False # sort the list of files so they are in chronological order opacity_files.sort() # check the date of each opacity coefficients file for idx, opacity_candidate_file in enumerate(opacity_files): dates = opacity_candidate_file.split('_')[-2:] opacity_file_timestamp = [] for date in dates: opacity_file_timestamp.append(int(date.split('.')[0])) opacity_file_starttime = opacity_file_timestamp[0] opacity_file_stoptime = opacity_file_timestamp[1] # when timestamp is older than available ranges if idx == 0 and timestamp < opacity_file_starttime: if self.log: self.log.doMessage('ERR', 'ERROR: Date is too early for opacities.') self.log.doMessage('ERR', ' Try setting zenith tau at command line.') self.log.doMessage('ERR', timestamp, '<', opacity_file_starttime) else: print 'ERROR: Date is too early for opacities.' print ' Try setting zenith tau at command line.' print timestamp, '<', opacity_file_starttime sys.exit(9) break if (opacity_file_starttime <= timestamp < opacity_file_stoptime): opacity_coefficients_filename = opacity_candidate_file opacity_db_range = (opacity_file_starttime, opacity_file_stoptime) break # uses most recent info if not opacity_coefficients_filename: # if the mjd in the index file comes after the date string in all of the # opacity coefficients files, then we can assume the current opacity # coefficients file will apply. a date string is only added to the opacity # coefficients file when it is no longer the most current. opacity_coefficients_filename = '/home/gbtpipeline/weather/CoeffsOpacityFreqList_avrg.txt' opacity_db_range = 'LATEST' # opacities coefficients filename if opacity_coefficients_filename and os.path.exists(opacity_coefficients_filename): if self.log: self.log.doMessage('DBG', 'Using coefficients from', opacity_coefficients_filename) else: print 'Using coefficients from', opacity_coefficients_filename coeffs = self._retrieve_opacity_coefficients(opacity_coefficients_filename) return coeffs, opacity_db_range else: if self.log: self.log.doMessage('ERR', 'No opacity coefficients file') else: print 'ERROR: No opacity coefficients file' return False, False def _retrieve_opacity_coefficients(self, opacity_coefficients_filename): """Return opacities (taus) derived from a list of coeffients These coefficients are produced from Ron Madalenna's getForecastValues script Keywords: infilename -- input file name needed for project name mjd -- date for data freq -- list of frequencies for which we seek an opacity Returns: a list of opacity coefficients for the time range of the dataset """ opacity_file = open(opacity_coefficients_filename, 'r') coeffs = [] if opacity_file: for line in opacity_file: # find the most recent forecast and parse out the coefficients for # each band # coeffs[0] is the mjd timestamp # coeffs[1] are the coefficients for 2-22 GHz # coeffs[2] are the coefficients for 22-50 GHz # coeffs[3] are the coefficients for 70-116 GHz coeffs.append((float(line.split('{{')[0]), [float(xx) for xx in line.split('{{')[1].split('}')[0].split(' ')], [float(xx) for xx in line.split('{{')[2].split('}')[0].split(' ')], [float(xx) for xx in line.split('{{')[3].split('}')[0].split(' ')])) else: print "WARNING: Could not read coefficients for Tau in", opacity_coefficients_filename return False return coeffs def retrieve_zenith_opacity(self, integration_mjd_timestamp, freq_hz, log=None): self.log = log freq_ghz = freq_hz/1e9 # if less than 2 GHz, opacity coefficients are not available if freq_ghz < 2: return self.L_BAND_ZENITH_TAU # if the frequency is in the same range and # the time is within the same record (1 hr window) of the last # recorded opacity coefficients, then just reuse the last # zenith opacity value requested if ((self.frequency_range and (self.frequency_range[0] <= freq_ghz <= self.frequency_range[1])) and (self.time_range and (self.time_range[0] <= integration_mjd_timestamp <= self.time_range[1]))): return self.zenith_opacity self.last_integration_mjd_timestamp = integration_mjd_timestamp self.last_requested_freq_ghz = freq_ghz # if we don't have a db time range OR # we do have a time range AND # the range is 'LATEST' AND # timestamp is not w/in the same hour as the last set of coeffs, OR # the range has values AND # our new timestamp is not in the range # THEN # get another set of coefficients from a different file if ((not self.db_time_range) or (self.db_time_range == 'LATEST' and not (self.time_range[0] <= integration_mjd_timestamp < self.time_range[1])) or (self.db_time_range and not (self.db_time_range[0] <= integration_mjd_timestamp < self.db_time_range[1]))): log.doMessage('DBG', '-----------------------------------------------------') log.doMessage('DBG', 'Time or Frequency out of range. Determine new opacity') log.doMessage('DBG', '-----------------------------------------------------') log.doMessage('DBG', 'opacity', self.zenith_opacity) log.doMessage('DBG', 'timestamp', integration_mjd_timestamp, 'prev.', self.last_integration_mjd_timestamp) log.doMessage('DBG', 'freq', freq_ghz, 'prev.', self.last_requested_freq_ghz) log.doMessage('DBG', 'freq range', self.frequency_range) if bool(self.frequency_range): log.doMessage('DBG', ' freq in range == ', bool(self.frequency_range[0] <= freq_ghz <= self.frequency_range[1])) log.doMessage('DBG', 'time range', self.time_range) if bool(self.time_range): log.doMessage('DBG', ' time in range ==', bool(self.time_range and (self.time_range[0] <= integration_mjd_timestamp <= self.time_range[1]))) log.doMessage('DBG', 'DB time range', self.db_time_range) if bool(self.db_time_range): log.doMessage('DBG', ' time in DB range ==', bool(self.db_time_range and (self.db_time_range[0] <= integration_mjd_timestamp <= self.db_time_range[1]))) self.opacity_coeffs, self.db_time_range = self._opacity_database(integration_mjd_timestamp) if (not self.opacity_coeffs) or (not self.db_time_range): return False log.doMessage('DBG', 'DB time range:', self.db_time_range) for coeffs_line in self.opacity_coeffs: if (2 <= freq_ghz <= 22): self.frequency_range = (2, 22) coefficients_index = 1 elif (22 < freq_ghz <= 50): self.frequency_range = (22, 50) coefficients_index = 2 elif (50 < freq_ghz <= 116): self.frequency_range = (50, 116) coefficients_index = 3 if integration_mjd_timestamp >= coeffs_line[0]: prev_time = coeffs_line[0] prev_coeffs = coeffs_line[coefficients_index] elif integration_mjd_timestamp < coeffs_line[0]: next_time = coeffs_line[0] next_coeffs = coeffs_line[coefficients_index] break self.time_range = (prev_time, next_time) log.doMessage('DBG', 'Coefficient entry time range:', self.time_range) time_corrected_coeffs = [] for coeff in zip(prev_coeffs, next_coeffs): new_coeff = self.cal.interpolate_by_time(coeff[0], coeff[1], prev_time, next_time, integration_mjd_timestamp) time_corrected_coeffs.append(new_coeff) self.zenith_opacity = self.cal.zenith_opacity(time_corrected_coeffs, freq_ghz) log.doMessage('DBG', 'Zenith opacity:', self.zenith_opacity) return self.zenith_opacity