def copy_sestbl_procdef_atx(self): self.frame, atx = determine_frame(self.Config.options['frames'], self.date) # copy process.defaults and sestbl. copyfile(self.GamitOpts['process_defaults'], os.path.join(self.pwd_tables, 'process.defaults')) # copyfile(self.GamitOpts['atx'], os.path.join(self.pwd_tables, 'antmod.dat')) copyfile(atx, os.path.join(self.pwd_tables, 'antmod.dat')) # change the scratch directory in the sestbl. file with open(os.path.join(self.pwd_tables, 'sestbl.'), 'w') as sestbl: with open(self.GamitOpts['sestbl']) as orig_sestbl: for line in orig_sestbl: if 'Scratch directory' in line: # empty means local directory! LA RE PU... sestbl.write('Scratch directory = \n') else: sestbl.write(line)
def __init__(self, rinexobj, otl_coeff, options, sp3types, sp3altrn, antenna_height, strict=True, apply_met=True, kinematic=False, clock_interpolation=False, hash=0, erase=True, decimate=True): assert isinstance(rinexobj, pyRinex.ReadRinex) PPPSpatialCheck.__init__(self) self.rinex = rinexobj self.epoch = rinexobj.date self.antH = antenna_height self.ppp_path = options['ppp_path'] self.ppp = options['ppp_exe'] self.options = options self.kinematic = kinematic self.ppp_version = None self.file_summary = None self.proc_parameters = None self.observation_session = None self.coordinate_estimate = None self.clock_estimates = None # DDG: do not allow clock interpolation before May 1 2001 self.clock_interpolation = clock_interpolation if rinexobj.date > Date(year=2001, month=5, day=1) else False self.frame = None self.atx = None self.x = None self.y = None self.z = None self.lat = None self.lon = None self.h = None self.sigmax = None self.sigmay = None self.sigmaz = None self.sigmaxy = None self.sigmaxz = None self.sigmayz = None self.clock_phase = None self.clock_phase_sigma = None self.phase_drift = None self.phase_drift_sigma = None self.clock_rms = None self.clock_rms_number = None self.hash = hash self.processed_obs = None self.rejected_obs = None self.orbit_type = None self.orbits1 = None self.orbits2 = None self.clocks1 = None self.clocks2 = None self.eop_file = None self.sp3altrn = sp3altrn self.sp3types = sp3types self.otl_coeff = otl_coeff self.strict = strict self.apply_met = apply_met self.erase = erase self.out = '' self.summary = '' self.pos = '' self.rootdir = os.path.join('production', 'ppp') fieldnames = ['NetworkCode', 'StationCode', 'X', 'Y', 'Z', 'Year', 'DOY', 'ReferenceFrame', 'sigmax', 'sigmay', 'sigmaz', 'sigmaxy', 'sigmaxz', 'sigmayz', 'hash'] self.record = dict.fromkeys(fieldnames) # determine the atx to use self.frame, self.atx = determine_frame(self.options['frames'], self.epoch) if os.path.isfile(self.rinex.rinex_path): # generate a unique id for this instance self.rootdir = os.path.join(self.rootdir, str(uuid.uuid4())) try: # create a production folder to analyze the rinex file if not os.path.exists(self.rootdir): os.makedirs(self.rootdir) os.makedirs(os.path.join(self.rootdir, 'orbits')) except Exception: # could not create production dir! FATAL raise try: self.get_orbits(self.sp3types) except (pySp3.pySp3Exception, pyClk.pyClkException, pyEOP.pyEOPException): if sp3altrn: self.get_orbits(self.sp3altrn) else: raise self.write_otl() self.copyfiles() self.config_session() # make a local copy of the rinex file # decimate the rinex file if the interval is < 15 sec. # DDG: only decimate when told by caller if self.rinex.interval < 15 and decimate: self.rinex.decimate(30) copyfile(self.rinex.rinex_path, os.path.join(self.rootdir, self.rinex.rinex)) else: raise pyRunPPPException('The file ' + self.rinex.rinex_path + ' could not be found. PPP was not executed.') return
def StnInfoCheck(cnn, stnlist, Config): # check that there are no inconsistencies in the station info records atx = dict() for frame in Config.options['frames']: # read all the available atx files atx[frame['name']] = parse_atx_antennas(frame['atx']) for stn in stnlist: NetworkCode = stn['NetworkCode'] StationCode = stn['StationCode'] first_obs = False try: stninfo = pyStationInfo.StationInfo( cnn, NetworkCode, StationCode) # type: pyStationInfo.StationInfo # there should not be more than one entry with 9999 999 in DateEnd empty_edata = [[record['DateEnd'], record['DateStart']] for record in stninfo.records if not record['DateEnd']] if len(empty_edata) > 1: list_empty = [ pyDate.Date(datetime=record[1]).yyyyddd() for record in empty_edata ] list_empty = ', '.join(list_empty) sys.stdout.write( '%s.%s: There is more than one station info entry with Session Stop = 9999 999 ' 'Session Start -> %s\n' % (NetworkCode, StationCode, list_empty)) # there should not be a DateStart < DateEnd of different record list_problems = [] atx_problem = False hc_problem = False for i, record in enumerate(stninfo.records): # check existence of ANTENNA in ATX # determine the reference frame using the start date frame, atx_file = determine_frame(Config.options['frames'], record['DateStart']) # check if antenna in atx, if not, produce a warning if record['AntennaCode'] not in atx[frame]: sys.stdout.write( '%s.%s: %-16s%s -> Not found in ANTEX file %s (%s) - dome not checked\n' % (NetworkCode, StationCode, record['AntennaCode'], record['RadomeCode'], os.path.basename(atx_file), frame)) atx_problem = True # check if the station info has a slant height and if the slant can be translated into a DHARP overlaps = stninfo.overlaps(record) if overlaps: for overlap in overlaps: if overlap['DateStart'].datetime( ) != record['DateStart'].datetime(): list_problems.append([ str(overlap['DateStart']), str(overlap['DateEnd']), str(record['DateStart']), str(record['DateEnd']) ]) station_list_gaps = [] if len(stninfo.records) > 1: # get gaps between stninfo records for erecord, srecord in zip(stninfo.records[0:-1], stninfo.records[1:]): sdate = srecord['DateStart'] edate = erecord['DateEnd'] # if the delta between previous and current session exceeds one second, check if any rinex falls # in that gap if (sdate.datetime() - edate.datetime()).total_seconds() > 1: count = cnn.query( 'SELECT count(*) as rcount FROM rinex_proc ' 'WHERE "NetworkCode" = \'%s\' AND "StationCode" = \'%s\' AND ' '"ObservationETime" > \'%s\' AND "ObservationSTime" < \'%s\' AND ' '"Completion" >= 0.5' % (NetworkCode, StationCode, edate.strftime(), sdate.strftime())).dictresult()[0]['rcount'] if count != 0: station_list_gaps += [[ count, [ str(erecord['DateStart']), str(erecord['DateEnd']) ], [ str(srecord['DateStart']), str(srecord['DateEnd']) ] ]] # there should not be RINEX data outside the station info window rs = cnn.query( 'SELECT min("ObservationSTime") as first_obs, max("ObservationSTime") as last_obs ' 'FROM rinex_proc WHERE "NetworkCode" = \'%s\' AND "StationCode" = \'%s\' ' 'AND "Completion" >= 0.5' % (NetworkCode, StationCode) ) # only check RINEX files with more than 12 hours of data rnxtbl = rs.dictresult() if rnxtbl[0]['first_obs'] is not None: # to avoid empty stations (no rinex data) if rnxtbl[0]['first_obs'] < stninfo.records[0][ 'DateStart'].datetime(): d1 = pyDate.Date(datetime=rnxtbl[0]['first_obs']) d2 = stninfo.records[0]['DateStart'] sys.stdout.write( '%s.%s: There is one or more RINEX observation file(s) outside the ' 'Session Start -> RINEX: %s STNINFO: %s\n' % (NetworkCode, StationCode, d1.yyyyddd(), d2.yyyyddd())) first_obs = True if rnxtbl[0]['last_obs'] > stninfo.records[-1][ 'DateEnd'].datetime(): d1 = pyDate.Date(datetime=rnxtbl[0]['last_obs']) d2 = stninfo.records[-1]['DateEnd'] sys.stdout.write( '%s.%s: There is one or more RINEX observation file(s) outside the last ' 'Session End -> RINEX: %s STNINFO: %s\n' % (NetworkCode, StationCode, d1.yyyyddd(), d2.yyyyddd())) first_obs = True if len(station_list_gaps) > 0: for gap in station_list_gaps: sys.stdout.write( '%s.%s: There is a gap with %s RINEX file(s) between ' 'the following station information records: %s -> %s :: %s -> %s\n' % (NetworkCode, StationCode, gap[0], gap[1][0], gap[1][1], gap[2][0], gap[2][1])) if len(list_problems) > 0: list_problems = [ record[0] + ' -> ' + record[1] + ' conflicts ' + record[2] + ' -> ' + record[3] for record in list_problems ] list_problems = '\n '.join(list_problems) sys.stdout.write( '%s.%s: There are conflicting recods in the station information table\n %s\n' % (NetworkCode, StationCode, list_problems)) if len(empty_edata) > 1 or len(list_problems) > 0 or first_obs or len(station_list_gaps) > 0 or \ atx_problem: # only print a partial of the station info: sys.stdout.write('\n' + stninfo.return_stninfo_short() + '\n\n') else: sys.stderr.write('%s.%s: No problems found\n' % (NetworkCode, StationCode)) sys.stdout.flush() except pyStationInfo.pyStationInfoException as e: tqdm.write(str(e))
def __init__(self, in_rinex, otl_coeff, options, sp3types, sp3altrn, antenna_height, strict=True, apply_met=True, kinematic=False, clock_interpolation=False, hash=0, erase=True, decimate=True, solve_coordinates=True, solve_troposphere=105, back_substitution=False, elev_mask=10, x=0, y=0, z=0): assert isinstance(in_rinex, pyRinex.ReadRinex) # DDG: if RINEX 3 version, convert to RINEX 2 (no PPP support) if in_rinex.rinex_version >= 3: # DDG: make a new object and convert to RINEX 3 to leave the other one untouched rinexobj = pyRinex.ReadRinex(in_rinex.NetworkCode, in_rinex.StationCode, in_rinex.origin_file, no_cleanup=in_rinex.no_cleanup, allow_multiday=in_rinex.allow_multiday) rinexobj.ConvertRinex(2) else: # file is in RINEX 2 format, use file as is rinexobj = in_rinex PPPSpatialCheck.__init__(self) self.rinex = rinexobj self.epoch = rinexobj.date self.antH = antenna_height self.ppp_path = options['ppp_path'] self.ppp = options['ppp_exe'] self.options = options self.kinematic = kinematic self.ppp_version = None self.file_summary = None self.proc_parameters = None self.observation_session = None self.coordinate_estimate = None self.clock_estimates = None # DDG: do not allow clock interpolation before May 1 2001 self.clock_interpolation = clock_interpolation if rinexobj.date > Date(year=2001, month=5, day=1) else False self.frame = None self.atx = None # DDG: now accepts solving for a fixed coordinate PPP self.solve_coordinates = solve_coordinates self.solve_troposphere = solve_troposphere self.back_substitution = back_substitution self.elev_mask = elev_mask self.x = x self.y = y self.z = z self.lat = None self.lon = None self.h = None self.sigmax = None self.sigmay = None self.sigmaz = None self.sigmaxy = None self.sigmaxz = None self.sigmayz = None self.clock_phase = None self.clock_phase_sigma = None self.phase_drift = None self.phase_drift_sigma = None self.clock_rms = None self.clock_rms_number = None self.hash = hash self.processed_obs = None self.rejected_obs = None self.orbit_type = None self.orbits1 = None self.orbits2 = None self.clocks1 = None self.clocks2 = None self.eop_file = None self.sp3altrn = sp3altrn self.sp3types = sp3types self.otl_coeff = otl_coeff self.strict = strict self.apply_met = apply_met self.erase = erase self.out = '' self.summary = '' self.pos = '' self.rootdir = os.path.join('production', 'ppp') fieldnames = ('NetworkCode', 'StationCode', 'X', 'Y', 'Z', 'Year', 'DOY', 'ReferenceFrame', 'sigmax', 'sigmay', 'sigmaz', 'sigmaxy', 'sigmaxz', 'sigmayz', 'hash') self.record = dict.fromkeys(fieldnames) # determine the atx to use self.frame, self.atx = determine_frame(self.options['frames'], self.epoch) if os.path.isfile(self.rinex.rinex_path): # generate a unique id for this instance self.rootdir = os.path.join(self.rootdir, str(uuid.uuid4())) path = os.path.join(self.rootdir, self.rinex.rinex[:-3]) self.path_sum_file = path + 'sum' self.path_pos_file = path + 'pos' self.path_ses_file = path + 'ses' self.path_res_file = path + 'res' try: # create a production folder to analyze the rinex file if not os.path.exists(self.rootdir): os.makedirs(self.rootdir) os.makedirs(os.path.join(self.rootdir, 'orbits')) except Exception: # could not create production dir! FATAL raise try: self.get_orbits(self.sp3types) except (pySp3.pySp3Exception, pyClk.pyClkException, pyEOP.pyEOPException): if sp3altrn: self.get_orbits(self.sp3altrn) else: raise self.write_otl() self.copyfiles() self.config_session() # make a local copy of the rinex file # decimate the rinex file if the interval is < 15 sec. # DDG: only decimate when told by caller if self.rinex.interval < 15 and decimate: self.rinex.decimate(30) copyfile(self.rinex.rinex_path, os.path.join(self.rootdir, self.rinex.rinex)) else: raise pyRunPPPException('The file ' + self.rinex.rinex_path + ' could not be found. PPP was not executed.')