def setUpCalcSiteModelPostFit(models,site_residuals, info, zen_grid, az_grid, cpus) : nZen = int(90.0/zen_grid) + 1 nAz = int(360./az_grid) print("nAz",nAz) #numParamsPerSite = nZen * nAz nModels = info['numModels'] #tSite = numParamsPerSite*params['numModels'] #numParams = tSat + tSite prefit = np.zeros(nModels) prefit_sums = np.zeros((nModels,nAz,nZen)) prefit_res = np.zeros((nModels,nAz,nZen)) postfit = np.zeros(nModels) postfit_sums = np.zeros((nModels,nAz,nZen)) postfit_res = np.zeros((nModels,nAz,nZen)) numObs = np.zeros(nModels) numObs_sums = np.zeros((nModels,nAz,nZen)) change = info['changes'] print("Changes for site",info['site'],change) # keep track of how may observations are in each bin #SiteFreq = np.zeros((nModels,nAz,nZen)) #Models = np.zeros((nModels,nAz,nZen)) #model_stdev = np.zeros((int(params['numModels']),nAz,nZen)) # create a new model everythime there has been a change of antenna for m in range(0,nModels): print(info['site'],"----> creating model",m+1,"of",info['numModels']) # start_yyyy and start_ddd should always be defind, however stop_dd may be absent #ie no changes have ocured since the last setup minVal_dt = gt.ydhms2dt(change['start_yyyy'][m],change['start_ddd'][m],0,0,0) if np.size(change['stop_ddd']) > m : maxVal_dt = gt.ydhms2dt(change['stop_yyyy'][m],change['stop_ddd'][m],23,59,59) print("Min:",minVal_dt,"Max:",maxVal_dt,m,np.size(change['stop_ddd'])) criterion = ( ( site_residuals[:,0] >= calendar.timegm(minVal_dt.utctimetuple()) ) & ( site_residuals[:,0] < calendar.timegm(maxVal_dt.utctimetuple()) ) ) else: criterion = ( site_residuals[:,0] >= calendar.timegm(minVal_dt.utctimetuple()) ) maxVal_dt = gt.unix2dt(site_residuals[-1,0]) # get the residuals for this model time period mind = np.array(np.where(criterion))[0] model_residuals = site_residuals[mind,:] diff_dt = maxVal_dt - minVal_dt numDays = diff_dt.days + 1 print("Have a total of",numDays,"days",np.shape(models)) prefit[m], prefit_sums[m,:,:], prefit_res[m,:,:], postfit[m], postfit_sums[m,:,:], postfit_res[m,:,:],numObs[m],numObs_sums[m,:,:] = setUpPostFitTasks(models,model_residuals,args.cpu,zen_grid,az_grid,params,numDays,minVal_dt) print("FINISHED Post fit RUN for model",m) return prefit, prefit_sums, prefit_res, postfit, postfit_sums, postfit_res,numObs,numObs_sums
def processAzSlice(model_residuals,svs,args,params,numDays,minVal_dt,az) : tSat = np.size(svs) * (int(14./args.nadir_grid) + 2) tSite = int(90./args.zen) + 1 numParams = tSat + tSite Neq = np.zeros((numParams,numParams)) AtWb = np.zeros(numParams) SiteFreq = np.zeros(tSite) # set up a lookup dictionary lookup_svs = {} lctr = 0 for sv in svs: lookup_svs[str(sv)] = lctr lctr+=1 site_geocentric_distance = np.linalg.norm(params['sitepos']) for d in range(0,numDays): minDTO = minVal_dt + dt.timedelta(days = d) maxDTO = minVal_dt + dt.timedelta(days = d+1) #print(d,"Stacking residuals on:",minDTO,maxDTO) criterion = ( ( model_residuals[:,0] >= calendar.timegm(minDTO.utctimetuple()) ) & ( model_residuals[:,0] < calendar.timegm(maxDTO.utctimetuple()) ) ) tind = np.array(np.where(criterion))[0] # if there are less than 300 obs, then skip to the next day if np.size(tind) < 300: continue #print("rejecting any residuals greater than 100mm",np.shape(site_residuals)) tdata = res.reject_absVal(model_residuals[tind,:],100.) #print("rejecting any residuals greater than 5 sigma",np.shape(tdata)) data = res.reject_outliers_elevation(tdata,5,0.5) #print("finished outlier detection",np.shape(data)) del tdata # determine the elevation dependent weighting a,b = res.gamitWeight(data) if(az - args.az/2. < 0) : criterion = (data[:,1] < (az + args.az/2.)) | (data[:,1] > (360. - args.az/2.) ) else: criterion = (data[:,1] < (az + args.az/2.)) & (data[:,1] > (az - args.az/2.) ) azind = np.array(np.where(criterion))[0] #print("Size of data before azimuth search",np.size(data)) data = data[azind,:] #print("Size of data after azimuth search",np.size(data)) # parse the broadcast navigation file for this day to get an accurate # nadir angle yy = minDTO.strftime("%y") doy = minDTO.strftime("%j") navfile = args.brdc_dir + 'brdc'+ doy +'0.'+ yy +'n' #print("Will read in the broadcast navigation file:",navfile) nav = rnxN.parseFile(navfile) # Get the total number of observations for this site numd = np.shape(data)[0] #print("Have:",numd,"observations") for i in range(0,numd): # work out the svn number svndto = gt.unix2dt(data[i,0]) svn = svnav.findSV_DTO(svdat,data[i,4],svndto) svn_search = 'G{:03d}'.format(svn) #print("Looking for:",svn_search,lookup_svs) ctr = lookup_svs[str(svn_search)] #print("Position is CTR:",ctr,data[i,4]) try: # get the satellite position svnpos = rnxN.satpos(data[i,4],svndto,nav) #print("SVNPOS:",svnpos[0]) satnorm = np.linalg.norm(svnpos[0]) #print("NORM:",np.linalg.norm(svnpos[0])) except: print("Error calculation satelite position for",svndto,data[i,:]) continue # work out the nadir angle nadir = NADIR.calcNadirAngle(data[i,2],site_geocentric_distance,satnorm) #print("Ele {:.2f} Old: {:.2f} New:{:.2f}".format(data[i,2],oldnadir,nadir)) #print("Ele {:.2f} New:{:.2f}".format(data[i,2],nadir)) w = a**2 + b**2/np.sin(np.radians(90.-data[i,2]))**2 w = 1./w # Work out the indices for the satellite parameters niz = int(np.floor(nadir/args.nadir_grid)) iz = int((numParamsPerSat * ctr) + niz) pco_iz = numParamsPerSat * (ctr+1) - 1 # work out the location of site parameters nsiz = int(np.floor(data[i,2]/args.zen)) #aiz = int(np.floor(data[i,1]/args.az)) #siz = int( tSat + (m*numParamsPerSite) + (aiz * nZen) + nsiz) siz = int( tSat + nsiz) # check that the indices are not overlapping if iz+1 >= pco_iz or iz >= pco_iz: #print("WARNING in indices iz+1 = pco_iz skipping obs",nadir,iz,pco_iz) continue #NadirFreq[ctr,niz] = NadirFreq[ctr,niz] +1 SiteFreq[nsiz] = SiteFreq[nsiz] +1 # # R = SITE_PCV_ERR + SAT_PCV_ERR + SAT_PCO_ERR * cos(nadir) # # dR/dSITE_PCV_ERR = 1 # dR/dSAT_PCV_ERR = 1 # dR/dSAT_PCO_ERR = cos(nadir) # # nice partial derivative tool: # http://www.symbolab.com/solver/partial-derivative-calculator # # Nadir partials.. Apart_1 = (1.-(nadir-niz*args.nadir_grid)/args.nadir_grid) Apart_2 = (nadir-niz*args.nadir_grid)/args.nadir_grid # # PCO partial ... Apart_3 = np.cos(np.radians(nadir)) # Site partials Apart_4 = (1.-(data[i,2]-nsiz*args.zen)/args.zen) Apart_5 = (data[i,2]-nsiz*args.zen)/args.zen #print("Finished forming Design matrix") #print("Starting AtWb",np.shape(AtWb),iz,pco_iz,siz) AtWb[iz] = AtWb[iz] + Apart_1 * data[i,3] * w AtWb[iz+1] = AtWb[iz+1] + Apart_2 * data[i,3] * w AtWb[pco_iz] = AtWb[pco_iz] + Apart_3 * data[i,3] * w AtWb[siz] = AtWb[siz] + Apart_4 * data[i,3] * w AtWb[siz+1] = AtWb[siz+1] + Apart_5 * data[i,3] * w #print("Finished forming b vector") Neq[iz,iz] = Neq[iz,iz] + (Apart_1 * Apart_1 * w) Neq[iz,iz+1] = Neq[iz,iz+1] + (Apart_1 * Apart_2 * w) Neq[iz,pco_iz] = Neq[iz,pco_iz] + (Apart_1 * Apart_3 * w) Neq[iz,siz] = Neq[iz,siz] + (Apart_1 * Apart_4 * w) Neq[iz,siz+1] = Neq[iz,siz+1] + (Apart_1 * Apart_5 * w) Neq[iz+1,iz] = Neq[iz+1,iz] + (Apart_2 * Apart_1 * w) Neq[iz+1,iz+1] = Neq[iz+1,iz+1] + (Apart_2 * Apart_2 * w) Neq[iz+1,pco_iz] = Neq[iz+1,pco_iz] + (Apart_2 * Apart_3 * w) Neq[iz+1,siz] = Neq[iz+1,siz] + (Apart_2 * Apart_4 * w) Neq[iz+1,siz+1] = Neq[iz+1,siz+1] + (Apart_2 * Apart_5 * w) #print("Finished NEQ Nadir estimates") Neq[pco_iz,iz] = Neq[pco_iz,iz] + (Apart_3 * Apart_1 * w) Neq[pco_iz,iz+1] = Neq[pco_iz,iz+1] + (Apart_3 * Apart_2 * w) Neq[pco_iz,pco_iz] = Neq[pco_iz,pco_iz] + (Apart_3 * Apart_3 * w) Neq[pco_iz,siz] = Neq[pco_iz,siz] + (Apart_3 * Apart_4 * w) Neq[pco_iz,siz+1] = Neq[pco_iz,siz+1] + (Apart_3 * Apart_5 * w) #print("Finished NEQ PCO estimates") Neq[siz,iz] = Neq[siz,iz] + (Apart_4 * Apart_1 * w) Neq[siz,iz+1] = Neq[siz,iz+1] + (Apart_4 * Apart_2 * w) Neq[siz,pco_iz] = Neq[siz,pco_iz] + (Apart_4 * Apart_3 * w) Neq[siz,siz] = Neq[siz,siz] + (Apart_4 * Apart_4 * w) Neq[siz,siz+1] = Neq[siz,siz+1] + (Apart_4 * Apart_5 * w) Neq[siz+1,iz] = Neq[siz+1,iz] + (Apart_5 * Apart_1 * w) Neq[siz+1,iz+1] = Neq[siz+1,iz+1] + (Apart_5 * Apart_2 * w) Neq[siz+1,pco_iz] = Neq[siz+1,pco_iz] + (Apart_5 * Apart_3 * w) Neq[siz+1,siz] = Neq[siz+1,siz] + (Apart_5 * Apart_4 * w) Neq[siz+1,siz+1] = Neq[siz+1,siz+1] + (Apart_5 * Apart_5 * w) #print("Finished NEQ Site estimates") if siz == pco_iz: print("ERROR in indices siz = pco_iz") # Add the parameter constraints to the Neq #Neq = np.add(Neq,C_inv) C_inv = formConstraints(args,tSat,tSite,1,numParams) Neq = np.add(Neq,C_inv) #print("Inverting") Cov = np.linalg.pinv(Neq) Sol = np.dot(Cov,AtWb) stdev = np.sqrt(np.diag(Cov)) return Sol, stdev, SiteFreq, az
def solveSiteModel(site_residuals, svs, params, apr, nadSpacing=0.1, zenSpacing=0.5, azSpacing=0.5, brdc_dir="./"): """ Create a model for the satellites and sites at the same time. PWL piece-wise-linear interpolation fit of phase residuals -construct a PWL fit for each azimuth bin, and then paste them all together to get the full model -inversion is done within each bin site_residuals = the one-way L3 post-fit, ambiguity fixed phase residuals svs = an array of satellite SVN numbers that are spacebourne/operating for the period of this residual stack params = meta data about the solution bein attempted ['site'] = 4 char site id ['changes'] = dictionary of when model changes need to be applied apr = satellite apriori data """ #prechi = 0 #NUMD = 0 # add one to make sure we have a linspace which includes 0.0 and 14.0 # add another parameter for the zenith PCO estimate numNADS = int(14.0/nadSpacing) + 1 PCOEstimates = 1 numSVS = np.size(svs) numParamsPerSat = numNADS + PCOEstimates tSat = numParamsPerSat * numSVS nZen = int(90.0/zenSpacing) + 1 nAz = int(360./azSpacing) print("nAz",nAz) numParamsPerSite = nZen * nAz tSite = numParamsPerSite*params['numModels'] numParams = tSat + tSite print("------------------------------------------------") print("Processing Site: ",params['site']) print("------------------------------------------------") print("Sat Params:----------------",numParamsPerSat) print("Number of Sats:------------",np.size(svs)) print("Total satellite parameters:-------------",tSat) print("Site Params:---------------",numParamsPerSite) print("Number of Models:----------",params['numModels']) print("Total Site Params:----------------------",tSite) print("------------------------------------------------") print("Total Params:---------------------------",numParams) print("------------------------------------------------") # Creating matrices #Neq = np.zeros((numParams,numParams)) #AtWb = np.zeros(numParams) change = params['changes'] print("Changes for site",params['site'],change) # keep track of how may observations are in each bin #NadirFreq = np.zeros((numSVS,numNADS)) SiteFreq = np.zeros((int(params['numModels']),nAz,nZen)) Models = np.zeros((int(params['numModels']),nAz,nZen)) model_stdev = np.zeros((int(params['numModels']),nAz,nZen)) # create a new model everythime there has been a change of antenna for m in range(0,int(params['numModels'])): print(params['site'],"----> creating model",m+1,"of",params['numModels']) # start_yyyy and start_ddd should always be defind, however stop_dd may be absent #ie no changes have ocured since the last setup minVal_dt = gt.ydhms2dt(change['start_yyyy'][m],change['start_ddd'][m],0,0,0) if np.size(change['stop_ddd']) > m : maxVal_dt = gt.ydhms2dt(change['stop_yyyy'][m],change['stop_ddd'][m],23,59,59) print("Min:",minVal_dt,"Max:",maxVal_dt,m,np.size(change['stop_ddd'])) criterion = ( ( site_residuals[:,0] >= calendar.timegm(minVal_dt.utctimetuple()) ) & ( site_residuals[:,0] < calendar.timegm(maxVal_dt.utctimetuple()) ) ) else: criterion = ( site_residuals[:,0] >= calendar.timegm(minVal_dt.utctimetuple()) ) maxVal_dt = gt.unix2dt(site_residuals[-1,0]) # get the residuals for this model time period mind = np.array(np.where(criterion))[0] model_residuals = site_residuals[mind,:] diff_dt = maxVal_dt - minVal_dt numDays = diff_dt.days + 1 print("Have a total of",numDays,"days") Models[m,:,:], model_stdev[m,:,:],SiteFreq[m,:,:] = setUpAzTasks(model_residuals,svs,args,params,numDays,minVal_dt,nAz) print("FINISHED AZ RUN for model",m) print("Normal finish of pwl") return Models, model_stdev, SiteFreq
for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + ax.get_xticklabels() + ax.get_yticklabels()): item.set_fontsize(8) plt.tight_layout() plt.show() # Calculate the block median zz = np.linspace(0,90,181) if args.consolidatedFile : cdata = parseConsolidated(args.consolidatedFile) if args.daily: dt_start = gt.unix2dt(cdata[0,0]) startDTO = dt_start res_start = int(dt_start.strftime("%Y") + dt_start.strftime("%j")) dt_stop = gt.unix2dt(cdata[-1,0]) res_stop = int(dt_stop.strftime("%Y") + dt_stop.strftime("%j")) total_time = dt_stop - dt_start days = total_time.days + 1 print("Residuals start from:",res_start," and end at ",res_stop,"total_time:",total_time,"in days:",total_time.days) eleMedians = np.zeros((days,181)) d = 0 while d < days: minDTO = startDTO + dt.timedelta(days = d) maxDTO = startDTO + dt.timedelta(days = d+1)
#=================================================================== # Work out the time scale of observations, and number of parameters # that will be solved for. #=================================================================== if args.syyyy and args.eyyyy: dt_start = dt.datetime(int(args.syyyy),01,01) + dt.timedelta(days=int(args.sdoy)-1) dt_stop = dt.datetime(int(args.eyyyy),01,01) + dt.timedelta(days=int(args.edoy)-1) else: print("") print("Warning:") print("\tusing:",args.resfile,"to work out the time period to determine how many satellites were operating.") print("") dt_start = gt.unix2dt(site_residuals[0,0]) res_start = int(dt_start.strftime("%Y") + dt_start.strftime("%j")-1) dt_stop = gt.unix2dt(site_residuals[-1,0]) res_stop = int(dt_stop.strftime("%Y") + dt_stop.strftime("%j")-1) print("\tResiduals run from:",res_start,"to:",res_stop) filename = os.path.basename(args.resfile) siteID = filename[0:4] sdata = gsf.parseSite(args.station_file,siteID.upper()) changes = gsf.determineESMChanges(dt_start,dt_stop,sdata) sitepos = gapr.getStationPos(args.apr_file,siteID) numModels = np.size(changes['ind']) + 1 info = {} info['filename'] = args.resfile info['basename'] = filename
def setUpCalcSiteModelPostFit(models, site_residuals, info, zen_grid, az_grid, cpus): nZen = int(90.0 / zen_grid) + 1 nAz = int(360. / az_grid) print("nAz", nAz) #numParamsPerSite = nZen * nAz nModels = info['numModels'] #tSite = numParamsPerSite*params['numModels'] #numParams = tSat + tSite prefit = np.zeros(nModels) prefit_sums = np.zeros((nModels, nAz, nZen)) prefit_res = np.zeros((nModels, nAz, nZen)) postfit = np.zeros(nModels) postfit_sums = np.zeros((nModels, nAz, nZen)) postfit_res = np.zeros((nModels, nAz, nZen)) numObs = np.zeros(nModels) numObs_sums = np.zeros((nModels, nAz, nZen)) change = info['changes'] print("Changes for site", info['site'], change) # keep track of how may observations are in each bin #SiteFreq = np.zeros((nModels,nAz,nZen)) #Models = np.zeros((nModels,nAz,nZen)) #model_stdev = np.zeros((int(params['numModels']),nAz,nZen)) # create a new model everythime there has been a change of antenna for m in range(0, nModels): print(info['site'], "----> creating model", m + 1, "of", info['numModels']) # start_yyyy and start_ddd should always be defind, however stop_dd may be absent #ie no changes have ocured since the last setup minVal_dt = gt.ydhms2dt(change['start_yyyy'][m], change['start_ddd'][m], 0, 0, 0) if np.size(change['stop_ddd']) > m: maxVal_dt = gt.ydhms2dt(change['stop_yyyy'][m], change['stop_ddd'][m], 23, 59, 59) print("Min:", minVal_dt, "Max:", maxVal_dt, m, np.size(change['stop_ddd'])) criterion = ((site_residuals[:, 0] >= calendar.timegm( minVal_dt.utctimetuple())) & (site_residuals[:, 0] < calendar.timegm( maxVal_dt.utctimetuple()))) else: criterion = (site_residuals[:, 0] >= calendar.timegm( minVal_dt.utctimetuple())) maxVal_dt = gt.unix2dt(site_residuals[-1, 0]) # get the residuals for this model time period mind = np.array(np.where(criterion))[0] model_residuals = site_residuals[mind, :] diff_dt = maxVal_dt - minVal_dt numDays = diff_dt.days + 1 print("Have a total of", numDays, "days", np.shape(models)) prefit[m], prefit_sums[m, :, :], prefit_res[ m, :, :], postfit[m], postfit_sums[m, :, :], postfit_res[ m, :, :], numObs[m], numObs_sums[m, :, :] = setUpPostFitTasks( models, model_residuals, args.cpu, zen_grid, az_grid, params, numDays, minVal_dt) print("FINISHED Post fit RUN for model", m) return prefit, prefit_sums, prefit_res, postfit, postfit_sums, postfit_res, numObs, numObs_sums
def solveSiteModel(site_residuals, svs, params, apr, nadSpacing=0.1, zenSpacing=0.5, azSpacing=0.5, brdc_dir="./"): """ Create a model for the satellites and sites at the same time. PWL piece-wise-linear interpolation fit of phase residuals -construct a PWL fit for each azimuth bin, and then paste them all together to get the full model -inversion is done within each bin site_residuals = the one-way L3 post-fit, ambiguity fixed phase residuals svs = an array of satellite SVN numbers that are spacebourne/operating for the period of this residual stack params = meta data about the solution bein attempted ['site'] = 4 char site id ['changes'] = dictionary of when model changes need to be applied apr = satellite apriori data """ #prechi = 0 #NUMD = 0 # add one to make sure we have a linspace which includes 0.0 and 14.0 # add another parameter for the zenith PCO estimate numNADS = int(14.0 / nadSpacing) + 1 PCOEstimates = 1 numSVS = np.size(svs) numParamsPerSat = numNADS + PCOEstimates tSat = numParamsPerSat * numSVS nZen = int(90.0 / zenSpacing) + 1 nAz = int(360. / azSpacing) print("nAz", nAz) numParamsPerSite = nZen * nAz tSite = numParamsPerSite * params['numModels'] numParams = tSat + tSite print("------------------------------------------------") print("Processing Site: ", params['site']) print("------------------------------------------------") print("Sat Params:----------------", numParamsPerSat) print("Number of Sats:------------", np.size(svs)) print("Total satellite parameters:-------------", tSat) print("Site Params:---------------", numParamsPerSite) print("Number of Models:----------", params['numModels']) print("Total Site Params:----------------------", tSite) print("------------------------------------------------") print("Total Params:---------------------------", numParams) print("------------------------------------------------") # Creating matrices #Neq = np.zeros((numParams,numParams)) #AtWb = np.zeros(numParams) change = params['changes'] print("Changes for site", params['site'], change) # keep track of how may observations are in each bin #NadirFreq = np.zeros((numSVS,numNADS)) SiteFreq = np.zeros((int(params['numModels']), nAz, nZen)) Models = np.zeros((int(params['numModels']), nAz, nZen)) model_stdev = np.zeros((int(params['numModels']), nAz, nZen)) # create a new model everythime there has been a change of antenna for m in range(0, int(params['numModels'])): print(params['site'], "----> creating model", m + 1, "of", params['numModels']) # start_yyyy and start_ddd should always be defind, however stop_dd may be absent #ie no changes have ocured since the last setup minVal_dt = gt.ydhms2dt(change['start_yyyy'][m], change['start_ddd'][m], 0, 0, 0) if np.size(change['stop_ddd']) > m: maxVal_dt = gt.ydhms2dt(change['stop_yyyy'][m], change['stop_ddd'][m], 23, 59, 59) print("Min:", minVal_dt, "Max:", maxVal_dt, m, np.size(change['stop_ddd'])) criterion = ((site_residuals[:, 0] >= calendar.timegm( minVal_dt.utctimetuple())) & (site_residuals[:, 0] < calendar.timegm( maxVal_dt.utctimetuple()))) else: criterion = (site_residuals[:, 0] >= calendar.timegm( minVal_dt.utctimetuple())) maxVal_dt = gt.unix2dt(site_residuals[-1, 0]) # get the residuals for this model time period mind = np.array(np.where(criterion))[0] model_residuals = site_residuals[mind, :] diff_dt = maxVal_dt - minVal_dt numDays = diff_dt.days + 1 print("Have a total of", numDays, "days") Models[m, :, :], model_stdev[m, :, :], SiteFreq[ m, :, :] = setUpAzTasks(model_residuals, svs, args, params, numDays, minVal_dt, nAz) print("FINISHED AZ RUN for model", m) print("Normal finish of pwl") return Models, model_stdev, SiteFreq
def processAzSlice(model_residuals, svs, args, params, numDays, minVal_dt, az): tSat = np.size(svs) * (int(14. / args.nadir_grid) + 2) tSite = int(90. / args.zen) + 1 numParams = tSat + tSite Neq = np.zeros((numParams, numParams)) AtWb = np.zeros(numParams) SiteFreq = np.zeros(tSite) # set up a lookup dictionary lookup_svs = {} lctr = 0 for sv in svs: lookup_svs[str(sv)] = lctr lctr += 1 site_geocentric_distance = np.linalg.norm(params['sitepos']) for d in range(0, numDays): minDTO = minVal_dt + dt.timedelta(days=d) maxDTO = minVal_dt + dt.timedelta(days=d + 1) #print(d,"Stacking residuals on:",minDTO,maxDTO) criterion = ( (model_residuals[:, 0] >= calendar.timegm(minDTO.utctimetuple())) & (model_residuals[:, 0] < calendar.timegm(maxDTO.utctimetuple()))) tind = np.array(np.where(criterion))[0] # if there are less than 300 obs, then skip to the next day if np.size(tind) < 300: continue #print("rejecting any residuals greater than 100mm",np.shape(site_residuals)) tdata = res.reject_absVal(model_residuals[tind, :], 100.) #print("rejecting any residuals greater than 5 sigma",np.shape(tdata)) data = res.reject_outliers_elevation(tdata, 5, 0.5) #print("finished outlier detection",np.shape(data)) del tdata # determine the elevation dependent weighting a, b = res.gamitWeight(data) if (az - args.az / 2. < 0): criterion = (data[:, 1] < (az + args.az / 2.)) | (data[:, 1] > (360. - args.az / 2.)) else: criterion = (data[:, 1] < (az + args.az / 2.)) & (data[:, 1] > (az - args.az / 2.)) azind = np.array(np.where(criterion))[0] #print("Size of data before azimuth search",np.size(data)) data = data[azind, :] #print("Size of data after azimuth search",np.size(data)) # parse the broadcast navigation file for this day to get an accurate # nadir angle yy = minDTO.strftime("%y") doy = minDTO.strftime("%j") navfile = args.brdc_dir + 'brdc' + doy + '0.' + yy + 'n' #print("Will read in the broadcast navigation file:",navfile) nav = rnxN.parseFile(navfile) # Get the total number of observations for this site numd = np.shape(data)[0] #print("Have:",numd,"observations") for i in range(0, numd): # work out the svn number svndto = gt.unix2dt(data[i, 0]) svn = svnav.findSV_DTO(svdat, data[i, 4], svndto) svn_search = 'G{:03d}'.format(svn) #print("Looking for:",svn_search,lookup_svs) ctr = lookup_svs[str(svn_search)] #print("Position is CTR:",ctr,data[i,4]) try: # get the satellite position svnpos = rnxN.satpos(data[i, 4], svndto, nav) #print("SVNPOS:",svnpos[0]) satnorm = np.linalg.norm(svnpos[0]) #print("NORM:",np.linalg.norm(svnpos[0])) except: print("Error calculation satelite position for", svndto, data[i, :]) continue # work out the nadir angle nadir = NADIR.calcNadirAngle(data[i, 2], site_geocentric_distance, satnorm) #print("Ele {:.2f} Old: {:.2f} New:{:.2f}".format(data[i,2],oldnadir,nadir)) #print("Ele {:.2f} New:{:.2f}".format(data[i,2],nadir)) w = a**2 + b**2 / np.sin(np.radians(90. - data[i, 2]))**2 w = 1. / w # Work out the indices for the satellite parameters niz = int(np.floor(nadir / args.nadir_grid)) iz = int((numParamsPerSat * ctr) + niz) pco_iz = numParamsPerSat * (ctr + 1) - 1 # work out the location of site parameters nsiz = int(np.floor(data[i, 2] / args.zen)) #aiz = int(np.floor(data[i,1]/args.az)) #siz = int( tSat + (m*numParamsPerSite) + (aiz * nZen) + nsiz) siz = int(tSat + nsiz) # check that the indices are not overlapping if iz + 1 >= pco_iz or iz >= pco_iz: #print("WARNING in indices iz+1 = pco_iz skipping obs",nadir,iz,pco_iz) continue #NadirFreq[ctr,niz] = NadirFreq[ctr,niz] +1 SiteFreq[nsiz] = SiteFreq[nsiz] + 1 # # R = SITE_PCV_ERR + SAT_PCV_ERR + SAT_PCO_ERR * cos(nadir) # # dR/dSITE_PCV_ERR = 1 # dR/dSAT_PCV_ERR = 1 # dR/dSAT_PCO_ERR = cos(nadir) # # nice partial derivative tool: # http://www.symbolab.com/solver/partial-derivative-calculator # # Nadir partials.. Apart_1 = (1. - (nadir - niz * args.nadir_grid) / args.nadir_grid) Apart_2 = (nadir - niz * args.nadir_grid) / args.nadir_grid # # PCO partial ... Apart_3 = np.cos(np.radians(nadir)) # Site partials Apart_4 = (1. - (data[i, 2] - nsiz * args.zen) / args.zen) Apart_5 = (data[i, 2] - nsiz * args.zen) / args.zen #print("Finished forming Design matrix") #print("Starting AtWb",np.shape(AtWb),iz,pco_iz,siz) AtWb[iz] = AtWb[iz] + Apart_1 * data[i, 3] * w AtWb[iz + 1] = AtWb[iz + 1] + Apart_2 * data[i, 3] * w AtWb[pco_iz] = AtWb[pco_iz] + Apart_3 * data[i, 3] * w AtWb[siz] = AtWb[siz] + Apart_4 * data[i, 3] * w AtWb[siz + 1] = AtWb[siz + 1] + Apart_5 * data[i, 3] * w #print("Finished forming b vector") Neq[iz, iz] = Neq[iz, iz] + (Apart_1 * Apart_1 * w) Neq[iz, iz + 1] = Neq[iz, iz + 1] + (Apart_1 * Apart_2 * w) Neq[iz, pco_iz] = Neq[iz, pco_iz] + (Apart_1 * Apart_3 * w) Neq[iz, siz] = Neq[iz, siz] + (Apart_1 * Apart_4 * w) Neq[iz, siz + 1] = Neq[iz, siz + 1] + (Apart_1 * Apart_5 * w) Neq[iz + 1, iz] = Neq[iz + 1, iz] + (Apart_2 * Apart_1 * w) Neq[iz + 1, iz + 1] = Neq[iz + 1, iz + 1] + (Apart_2 * Apart_2 * w) Neq[iz + 1, pco_iz] = Neq[iz + 1, pco_iz] + (Apart_2 * Apart_3 * w) Neq[iz + 1, siz] = Neq[iz + 1, siz] + (Apart_2 * Apart_4 * w) Neq[iz + 1, siz + 1] = Neq[iz + 1, siz + 1] + (Apart_2 * Apart_5 * w) #print("Finished NEQ Nadir estimates") Neq[pco_iz, iz] = Neq[pco_iz, iz] + (Apart_3 * Apart_1 * w) Neq[pco_iz, iz + 1] = Neq[pco_iz, iz + 1] + (Apart_3 * Apart_2 * w) Neq[pco_iz, pco_iz] = Neq[pco_iz, pco_iz] + (Apart_3 * Apart_3 * w) Neq[pco_iz, siz] = Neq[pco_iz, siz] + (Apart_3 * Apart_4 * w) Neq[pco_iz, siz + 1] = Neq[pco_iz, siz + 1] + (Apart_3 * Apart_5 * w) #print("Finished NEQ PCO estimates") Neq[siz, iz] = Neq[siz, iz] + (Apart_4 * Apart_1 * w) Neq[siz, iz + 1] = Neq[siz, iz + 1] + (Apart_4 * Apart_2 * w) Neq[siz, pco_iz] = Neq[siz, pco_iz] + (Apart_4 * Apart_3 * w) Neq[siz, siz] = Neq[siz, siz] + (Apart_4 * Apart_4 * w) Neq[siz, siz + 1] = Neq[siz, siz + 1] + (Apart_4 * Apart_5 * w) Neq[siz + 1, iz] = Neq[siz + 1, iz] + (Apart_5 * Apart_1 * w) Neq[siz + 1, iz + 1] = Neq[siz + 1, iz + 1] + (Apart_5 * Apart_2 * w) Neq[siz + 1, pco_iz] = Neq[siz + 1, pco_iz] + (Apart_5 * Apart_3 * w) Neq[siz + 1, siz] = Neq[siz + 1, siz] + (Apart_5 * Apart_4 * w) Neq[siz + 1, siz + 1] = Neq[siz + 1, siz + 1] + (Apart_5 * Apart_5 * w) #print("Finished NEQ Site estimates") if siz == pco_iz: print("ERROR in indices siz = pco_iz") # Add the parameter constraints to the Neq #Neq = np.add(Neq,C_inv) C_inv = formConstraints(args, tSat, tSite, 1, numParams) Neq = np.add(Neq, C_inv) #print("Inverting") Cov = np.linalg.pinv(Neq) Sol = np.dot(Cov, AtWb) stdev = np.sqrt(np.diag(Cov)) return Sol, stdev, SiteFreq, az
if args.syyyy and args.eyyyy: dt_start = dt.datetime(int(args.syyyy), 01, 01) + dt.timedelta(days=int(args.sdoy) - 1) dt_stop = dt.datetime(int(args.eyyyy), 01, 01) + dt.timedelta(days=int(args.edoy) - 1) else: print("") print("Warning:") print( "\tusing:", args.resfile, "to work out the time period to determine how many satellites were operating." ) print("") dt_start = gt.unix2dt(site_residuals[0, 0]) res_start = int( dt_start.strftime("%Y") + dt_start.strftime("%j") - 1) dt_stop = gt.unix2dt(site_residuals[-1, 0]) res_stop = int(dt_stop.strftime("%Y") + dt_stop.strftime("%j") - 1) print("\tResiduals run from:", res_start, "to:", res_stop) filename = os.path.basename(args.resfile) siteID = filename[0:4] sdata = gsf.parseSite(args.station_file, siteID.upper()) changes = gsf.determineESMChanges(dt_start, dt_stop, sdata) sitepos = gapr.getStationPos(args.apr_file, siteID) numModels = np.size(changes['ind']) + 1 info = {} info['filename'] = args.resfile
for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + ax.get_xticklabels() + ax.get_yticklabels()): item.set_fontsize(8) plt.tight_layout() plt.show() # Calculate the block median zz = np.linspace(0, 90, 181) if args.consolidatedFile: cdata = parseConsolidated(args.consolidatedFile) if args.daily: dt_start = gt.unix2dt(cdata[0, 0]) startDTO = dt_start res_start = int(dt_start.strftime("%Y") + dt_start.strftime("%j")) dt_stop = gt.unix2dt(cdata[-1, 0]) res_stop = int(dt_stop.strftime("%Y") + dt_stop.strftime("%j")) total_time = dt_stop - dt_start days = total_time.days + 1 print("Residuals start from:", res_start, " and end at ", res_stop, "total_time:", total_time, "in days:", total_time.days) eleMedians = np.zeros((days, 181)) d = 0 while d < days: minDTO = startDTO + dt.timedelta(days=d)