def parse_summary(self): self.summary = ''.join(self.out) self.ppp_version = re.findall(r'.*Version\s+(\d.\d+)\/', self.summary) if len(self.ppp_version) == 0: self.ppp_version = re.findall(r'.*CSRS-PPP ver.\s+(\d.\d+)\/', self.summary)[0] else: self.ppp_version = self.ppp_version[0] self.file_summary = self.get_text(self.summary, 'SECTION 1.', 'SECTION 2.') self.proc_parameters = self.get_text(self.summary, 'SECTION 2. ', ' SECTION 3. ') self.observation_session = self.get_text(self.summary, '3.2 Observation Session', '3.3 Coordinate estimates') self.coordinate_estimate = self.get_text(self.summary, '3.3 Coordinate estimates', '3.4 Coordinate differences ITRF') self.clock_estimates = self.get_text(self.summary, '3.5 Receiver clock estimates', '3.6 Observation rejection table') if self.strict and not self.check_phase_center(self.proc_parameters): raise pyRunPPPException( 'Error while running PPP: could not find the antenna and radome in antex file. ' 'Check RINEX header for formatting issues in the ANT # / TYPE field. RINEX header follows:\n' + ''.join( self.rinex.get_header())) if self.strict and not self.check_otl(self.proc_parameters): raise pyRunPPPException( 'Error while running PPP: could not find the OTL coefficients. ' 'Check RINEX header for formatting issues in the APPROX ANT POSITION field. If APR is too far from OTL ' 'coordinates (declared in the HARPOS or BLQ format) NRCAN will reject the coefficients. ' 'OTL coefficients record follows:\n' + self.otl_coeff) if not self.check_eop(self.file_summary): raise pyRunPPPExceptionEOPError('EOP returned NaN in Pole XYZ.') # parse rejected and accepted observations self.processed_obs, self.rejected_obs = self.get_pr_observations(self.observation_session, self.kinematic) if self.processed_obs == 0: raise pyRunPPPExceptionZeroProcEpochs('PPP returned zero processed epochs') # if self.strict and (self.processed_obs == 0 or self.rejected_obs > 0.95 * self.processed_obs): # raise pyRunPPPExceptionTooFewAcceptedObs('The processed observations (' + str(self.processed_obs) + # ') is zero or more than 95% of the observations were rejected (' + # str(self.rejected_obs) + ')') # FRAME now comes from the startup process, where the function Utils.determine_frame is called # self.frame = self.get_frame(self.coordinate_estimate) self.x, self.y, self.z = self.get_xyz(self.coordinate_estimate) self.lat, self.lon, self.h = ecef2lla([self.x, self.y, self.z]) self.sigmax, self.sigmay, self.sigmaz, \ self.sigmaxy, self.sigmaxz, self.sigmayz = self.get_sigmas(self.coordinate_estimate, self.kinematic) self.clock_phase, self.clock_phase_sigma, \ self.phase_drift, self.phase_drift_sigma, \ self.clock_rms, self.clock_rms_number = self.get_clock(self.clock_estimates, self.kinematic) # not implemented in PPP: apply NE offset if is NOT zero if self.rinex.antOffsetN != 0.0 or self.rinex.antOffsetE != 0.0: dx, dy, dz = lg2ct(numpy.array(self.rinex.antOffsetN), numpy.array(self.rinex.antOffsetE), numpy.array([0]), self.lat, self.lon) # reduce coordinates self.x -= dx[0] self.y -= dy[0] self.z -= dz[0] self.lat, self.lon, self.h = ecef2lla([self.x, self.y, self.z])
def CheckSpatialCoherence(cnn, stnlist, start_date, end_date): for stn in stnlist: NetworkCode = stn['NetworkCode'] StationCode = stn['StationCode'] rs = cnn.query( 'SELECT * FROM ppp_soln WHERE "NetworkCode" = \'%s\' AND "StationCode" = \'%s\' AND ' '"Year" || \' \' || "DOY" BETWEEN \'%s\' AND \'%s\'' % (NetworkCode, StationCode, start_date.yyyy() + ' ' + start_date.ddd(), end_date.yyyy() + ' ' + end_date.ddd())) ppp = rs.dictresult() if rs.ntuples() > 0: tqdm.write( '\nChecking spatial coherence of PPP solutions for %s.%s...' % (NetworkCode, StationCode), sys.stderr) for soln in tqdm(ppp): year = soln['Year'] doy = soln['DOY'] date = pyDate.Date(year=year, doy=doy) # calculate lla of solution lat, lon, h = ecef2lla( [float(soln['X']), float(soln['Y']), float(soln['Z'])]) SpatialCheck = pyPPP.PPPSpatialCheck(lat, lon, h) Result, match, closest_stn = SpatialCheck.verify_spatial_coherence( cnn, StationCode) if Result: if len(closest_stn) == 0: if match[0]['NetworkCode'] != NetworkCode and match[0][ 'StationCode'] != StationCode: # problem! we found a station but does not agree with the declared solution name tqdm.write( 'Warning! Solution for %s.%s %s is a match for %s.%s ' '(only this candidate was found).\n' % (NetworkCode, StationCode, date.yyyyddd(), match[0]['NetworkCode'], match[0]['StationCode'])) else: closest_stn = closest_stn[0] tqdm.write( 'Wanrning! Solution for %s.%s %s was found to be closer to %s.%s. ' 'Distance to %s.%s: %.3f m. Distance to %s.%s: %.3f m' % (NetworkCode, StationCode, date.yyyyddd(), closest_stn['NetworkCode'], closest_stn['StationCode'], closest_stn['NetworkCode'], closest_stn['StationCode'], closest_stn['distance'], match[0]['NetworkCode'], match[0]['StationCode'], match[0]['distance'])) else: if len(match) == 1: tqdm.write( 'Wanrning! Solution for %s.%s %s does not match its station code. Best match: %s.%s' % (NetworkCode, StationCode, date.yyyyddd(), match[0]['NetworkCode'], match[0]['StationCode'])) elif len(match) > 1: # No name match but there are candidates for the station matches = ', '.join([ '%s.%s: %.3f m' % (m['NetworkCode'], m['StationCode'], m['distance']) for m in match ]) tqdm.write( 'Wanrning! Solution for %s.%s %s does not match its station code. ' 'Cantidates and distances found: %s' % (NetworkCode, StationCode, date.yyyyddd(), matches)) else: tqdm.write( 'Wanrning! PPP for %s.%s %s had no match within 100 m. ' 'Closest station is %s.%s (%3.f km, %s.%s %s PPP solution is: %.8f %.8f)' % (NetworkCode, StationCode, date.yyyyddd(), closest_stn[0]['NetworkCode'], closest_stn[0]['StationCode'], numpy.divide(float(closest_stn[0]['distance']), 1000), NetworkCode, StationCode, date.yyyyddd(), lat[0], lon[0])) else: tqdm.write( '\nNo PPP solutions found for %s.%s...' % (NetworkCode, StationCode), sys.stderr)