def test_dd2sec(self): self.assertEqual(dd2sec(1), 3600) self.assertEqual(dd2sec(-1), -3600) self.assertEqual(dd2sec(hp2dec(0.0001)), 1) self.assertEqual(dd2sec(hp2dec(-0.0001)), -1) self.assertEqual(dd2sec(hp2dec(0.00001)), 0.1) self.assertEqual(dd2sec(dec_ex4), 189) self.assertEqual(dd2sec(-dec_ex4), -189) self.assertEqual(dd2sec(dec_ex2), 45270) self.assertEqual(dd2sec(-dec_ex2), -45270)
def dnaout_va(obslist, same_stdev=True, stdev=1, pointing_err=0.001): dnaobs = [] if same_stdev: for observation in obslist: # Format Line line = ('V ' + observation.from_id.ljust(20) + observation.to_id.ljust(20) + ''.ljust(34) + str(observation.va_obs.degree).rjust(3) + ' ' + str(observation.va_obs.minute).rjust(2, '0') + ' ' + ('{:.3f}'.format(observation.va_obs.second).rjust(6, '0')).ljust(8) + ('{:.4f}'.format(stdev)).ljust(8) # add standard deviation + ('{:.3f}'.format(observation.inst_height)).ljust(7) # add intrument height + ('{:.3f}'.format(observation.target_height))) dnaobs.append(line) else: for observation in obslist: # Calc Standard Deviation (in seconds) based on pointing error (in metres) # and angular standard deviation (in seconds) if observation.sd_obs == 0: stdev_pt = stdev else: pointing_err_pt = dd2sec(degrees(atan(pointing_err / observation.sd_obs))) stdev_pt = str(sqrt((pointing_err_pt ** 2) + (stdev ** 2))) # Format Line line = ('V ' + observation.from_id.ljust(20) + observation.to_id.ljust(20) + ''.ljust(34) + str(observation.va_obs.degree).rjust(3) + ' ' + str(observation.va_obs.minute).rjust(2, '0') + ' ' + str(('{:.3f}'.format(observation.va_obs.second).rjust(6, '0')).ljust(8)) + stdev_pt[0:5].ljust(8) # add standard deviation + ('{:.3f}'.format(observation.inst_height)).ljust(7) # add intrument height + ('{:.3f}'.format(observation.target_height))) dnaobs.append(line) return dnaobs
def dnaout_dirset(obslist, same_stdev=True, stdev=1, pointing_err=0.001): # Test for Single Observation if len(obslist) < 2: return [] fromlist = [] for ob in obslist: fromlist.append(ob.from_id) fromlist = list(set(fromlist)) if len(fromlist) != 1: raise ValueError('Direction Set requires obs with same from_id') else: pass dnaobs = [] if same_stdev: # create first line using obslist[0] line1 = ('D ' + obslist[0].from_id.ljust(20) + obslist[0].to_id.ljust(20) + str(len(obslist)-1).ljust(20) + str(obslist[0].hz_obs.degree).rjust(17) + ' ' + str('%02d' % obslist[0].hz_obs.minute) + ' ' + str('{:.3f}'.format(obslist[0].hz_obs.second).rjust(6, '0').ljust(8)) + ('{:.4f}'.format(stdev))) # add standard deviation dnaobs.append(line1) # create other lines using range(1:) for num in range(1, len(obslist)): line = ('D ' + ''.ljust(40) + obslist[num].to_id.ljust(20) + str(obslist[num].hz_obs.degree).rjust(17) + ' ' + str('%02d' % obslist[num].hz_obs.minute) + ' ' + str('{:.3f}'.format(obslist[num].hz_obs.second).rjust(6, '0').ljust(8)) + ('{:.4f}'.format(stdev))) # add standard deviation dnaobs.append(line) else: # calc stdev for first ob if obslist[0].sd_obs == 0: stdev_pt = stdev else: pointing_err_pt = dd2sec(degrees(atan(pointing_err / obslist[0].sd_obs))) stdev_pt = str(sqrt((pointing_err_pt ** 2) + (stdev ** 2))) # create first line using obslist[0] line1 = ('D ' + obslist[0].from_id.ljust(20) + obslist[0].to_id.ljust(20) + str(len(obslist)-1).ljust(20) + str(obslist[0].hz_obs.degree).rjust(17) + ' ' + str('%02d' % obslist[0].hz_obs.minute) + ' ' + str('{:.3f}'.format(obslist[0].hz_obs.second).rjust(6, '0').ljust(8)) + stdev_pt[0:5]) # add standard deviation dnaobs.append(line1) # create other lines using range(1:) for num in range(1, len(obslist)): if obslist[num].sd_obs == 0: # keep stdev_pt = stdev else: pointing_err_pt = dd2sec(degrees(atan(pointing_err / obslist[num].sd_obs))) stdev_pt = str(sqrt((pointing_err_pt ** 2) + (stdev ** 2))) line = ('D ' + ''.ljust(40) + obslist[num].to_id.ljust(20) + str(obslist[num].hz_obs.degree).rjust(17) + ' ' + str('%02d' % obslist[num].hz_obs.minute) + ' ' + str('{:.3f}'.format(obslist[num].hz_obs.second).rjust(6, '0').ljust(8)) + stdev_pt[0:5]) # add standard deviation dnaobs.append(line) return dnaobs
def reducesetup(obslist, strict=False, zerodist=False, meanmulti=False): """ Takes a list of Observations from one setup and means together FL, FR pairs of Observations. :param obslist: List of Observations (i.e. from one InstSetup) :param strict: If True, all single-face Obs are ignored. If False, all single-face Obs are included and converted to Face Left :param zerodist: If True, Obs with Slope Distance of Zero are included. If False, these are ignored :param meanmulti: If True, multiple rounds of observations are reduced to a single FL-sense Observation :return: a reduced list of Observations """ # Remove obs with sd_obs == 0 if not zerodist: for ob in obslist: if ob.sd_obs == 0: obslist.remove(ob) # Group obs numbers by to_id uniqueto = [] for ob in obslist: uniqueto.append(ob.to_id) uniqueto = list(set(uniqueto)) # Sort Obs by to_id and face meanedobs = [] for unique_id in uniqueto: fl_list = [] fr_list = [] for ob in obslist: if ob.to_id == unique_id and ob.face == 'FL': fl_list.append(ob) elif ob.to_id == unique_id and ob.face == 'FR': fr_list.append(ob) elif ob.to_id != unique_id and (ob.face == 'FL' or ob.face == 'FR'): pass else: raise ValueError('Invalid Face') obsdict = {unique_id: {'FL': fl_list, 'FR': fr_list}} # Group Obs into FL, FR pairs and mean (Remove all non-paired obs) if strict: for key in obsdict: pairedlist = list(zip(obsdict[key]['FL'], obsdict[key]['FR'])) for pair in pairedlist: meanob = meanfaces(pair[0], pair[1]) meanedobs.append(meanob) # Group Obs into FL, FR pairs and mean (Keep all non-paired obs) elif not strict: for key in obsdict: pairedlist = list(itertools.zip_longest(obsdict[key]['FL'], obsdict[key]['FR'], fillvalue=None)) for pair in pairedlist: meanob = meanfaces(pair[0], pair[1]) meanedobs.append(meanob) # Mean multiple repeated measurements into a single FL observation if meanmulti: multiob = [] to_ids = set([i.to_id for i in meanedobs]) for id in to_ids: matchedobs = [] for ob in meanedobs: if ob.to_id == id: matchedobs.append(ob) ob1 = matchedobs[0] repeat_hz = [ob.hz_obs.dec() for ob in matchedobs] repeat_hz = sorted(repeat_hz) repeat_va = [ob.va_obs.dec() for ob in matchedobs] repeat_sd = [ob.sd_obs for ob in matchedobs] # Finds where Horizontal Obseravtions are either side of 360, converts those on 360 side to negative hz_diff = [j - i for i, j in zip(repeat_hz[:-1], repeat_hz[1:])] bigjump = 1e100 for num, i in enumerate(hz_diff): if i > 180: bigjump = num for num, ob in enumerate(repeat_hz): if num > bigjump: repeat_hz[num] = repeat_hz[num] - 360 # Mean Repeated Observations mean_hz = mean(repeat_hz) if mean_hz < 0: mean_hz += 360 mean_va = mean(repeat_va) mean_sd = mean(repeat_sd) # Compute Standard Deviations for Observations if len(repeat_hz) > 2: hz_stdev = stdev(repeat_hz) else: hz_stdev = 0.0 if len(repeat_va) > 2: va_stdev = stdev(repeat_va) else: va_stdev = 0.0 if len(repeat_sd) > 2: sd_stdev = stdev(repeat_sd) else: sd_stdev = 0.0 # Compute number of rounds of observations completed sum_rounds = 0 for ob in matchedobs: sum_rounds += ob.rounds # Output Meaned Observation multiob.append(Observation(ob1.from_id, id, ob1.inst_height, ob1.target_height, ob1.face, sum_rounds, dec2dms(mean_hz), dd2sec(hz_stdev), dec2dms(mean_va), dd2sec(va_stdev), mean_sd, sd_stdev)) meanedobs = multiob # Order list of meaned obs sorted_meanedobs = sorted(meanedobs, key=operator.attrgetter('hz_obs')) return sorted_meanedobs