[电离层建模学习笔记]开源程序M_GIM学习记录

news2024/12/21 4:24:46

[电离层建模学习笔记]开源程序M_GIM学习记录

文章目录

      • [电离层建模学习笔记]开源程序M_GIM学习记录
        • 1. 程序相关信息
        • 2. 程序学习记录
          • 2.1 采用的数据说明
          • 2.2 程序运行前
          • 2.3 程序运行结果
        • 3. 其他

1. 程序相关信息

开源程序M_GIM基于Matlab(Zhou et al., 2023),用于实现全球和区域电离层建模,可支持多系统数据,建模方式也可以在多项式和球谐函数这种之间选择。该程序在M_DCB(Jin et al., 2012)的基础上发展而来,是便捷实用的电离层建模软件。

该程序发布在GPS Toolbox上,除了源程序还附带了对应论文中的测试数据。本文记录了该程序的学习过程,该程序在运行前还有一些小的错误需要改正,在此也做一个记录,以备日后查询。

相关的文献:

[1] Zhou C, Yang L, Li B, et al. M_GIM: a MATLAB-based software for multi-system global and regional ionospheric modeling[J]. GPS Solutions, 2023, 27(1): 1-7.

[2] Jin R, Jin S, Feng G. M_DCB: Matlab code for estimating GNSS satellite and receiver differential code biases[J]. GPS solutions, 2012, 16: 541-548.

2. 程序学习记录

2.1 采用的数据说明

本文采用的数据为2023年 DOY001 中国陆态网数据,共241个测站,包含GPS和GLONASS观测数据。本次解算仅采用GPS系统的数据,后发现所有测站GPS伪距观测值仅存在C1C、C1C和C2W,即C1、C2和P2数据,在计算中拟采用C1-P2来获取P4平滑值,需要在计算P4值之前加上码偏差改正,将C1归化到P1上,接下来将介绍具体的改动。

2.2 程序运行前

本次解算利用陆态网数据对中国区域电离层进行区域建模,采用6阶4次球谐函数模型,解算仅考虑GPS数据,故用到的主要程序为:Main_nonSH.m 和./Func_nonSH/Get_nonSH_G.m,其他子程序调用情况可以在这两个文件中看到。在程序运行前,首先准备好观测值文件、sp3轨道、DCB文件分别存放在对应文件夹下,运行前需要对上述程序以下部分做对应修改:

  1. 原程序里的小错误

    (1) Get_nonSH_G.m (Line 42-50)

    ...
    if isempty(d_sat)
        G_n_s=32;
    else
        G_n_s=32-length(d_sat);%the number of satellites
        disp([doy ' PRN ',num2str(d_sat) ,' have no observations.']);
        for k=length(d_sat):-1:1  %% gps_d_sat -> d_sat
            gpsx(:,d_sat(k))=[];gpsy(:,d_sat(k))=[];gpsz(:,d_sat(k))=[];    % 没有数据的卫星坐标设为空
        end
    end
    ...
    

    (2) Get_nonSH_G.m (Line 70-75)

    ...
    if ~isempty(d_sat)
        for k=length(d_sat):-1:1
            %% GPSP4(:,k)=[] -> GPSP4(:,d_sat(k))
            GPSP4(:,d_sat(k))=[];
        end
    end
    ...
    
    
  2. 加上C1归化到P1的部分

    (1) 读取DCB文件中的C1C -> C1W:read_dcb

    line 21-23
    SDCB_REF.gps=zeros(n_d,32);
    SDCB_REF.gpsc1p1=zeros(n_d,32); % edit by He Rong 2023/06/08
    SDCB_REF.glo=zeros(n_d,24);
    
    line 32
        [GPS_DCB_rec,SDCB_REF.gps(i,:),SDCB_REF.gpsc1p1]=r_gps_dcb([i_ipath '/CAS0MGXRAP_20' num2str(sdoy) '0000_01D_01D_DCB.BSX'],Sites_Info.name(index2)); % edit by He Rong 2023/06/08
        
    line 189-221
    function [DCB_rec,DCB_sat,DCB_sat_C1P1]=r_gps_dcb(fpath,sites) % edit by He Rong 2023/06/08
    fid=fopen(fpath,'r');
    n_r=length(sites);
    DCB_rec=linspace(0,0,n_r);
    DCB_sat=linspace(0,0,32);
    DCB_sat_C1P1 = linspace(0,0,32); % edit by He Rong 2023/06/08
    
    while 1
        line=fgetl(fid);
        if ~ischar(line), break, end
        %--satellites' DCB
        if length(line)>100 && strcmpi(line(1:7),' DSB  G') && strcmpi(line(26:33),'C1W  C2W') && strcmpi(line(16:19),'    ')
            prn=str2double(line(13:14));
            DCB_sat(prn)=str2double(line(83:91));
            continue;
        end
        % satelite DCB:C1C->C1W
        if length(line)>100 && strcmpi(line(1:7),' DSB  G') && strcmpi(line(26:33),'C1C  C1W') && strcmpi(line(16:19),'    ')
            prn=str2double(line(13:14));
            DCB_sat_C1P1(prn)=str2double(line(83:91));
            continue;
        end % edit by He Rong 2023/06/08
        %--receivers' DCB
        if length(line)>100 && strcmpi(line(1:12),' DSB  G    G') && strcmpi(line(26:33),'C1W  C2W')
            index=find(strcmpi(line(16:19),sites), 1);
            if ~isempty(index)
                DCB_rec(index)=str2double(line(83:91));
            end
            continue;
        end
    end
    fclose(fid);
    end
    

    (2) 在计算P4前进行改正:Get_P4

    line 1
    function [] = Get_P4(path_obs,path_p4,path_sp3,Sites_Info,lim,sate_mark, SDCB_REF)
    % 对应外部调用也需要修改
    
    line 37-41
    % C1W位置上的其实是C1C(C1)的数据,需要将其转到P1上(加上C1C->C1W)
    % 在参与计算前,将所有测站的所有 C1W 数据都进行改正
    % SDCB_REF结构体里SDCB_REF.gpsc1p1记录所有卫星的C1P1
    % edit by He Rong 2023/06/09
    [obs] = correctC1C_C1W(SDCB_REF,obs);
    
    line 1277-1308
    function [obs] = correctC1C_C1W(SDCB_REF,obs) % edit by He Rong 2023/06/08
    %% correct the observations C1C to C1W use DCB C1C->C1W
    % INPUT: 
    %     SDCB_REF: satellites DCB for each system
    %     obs: original observation structs
    %      
    %      
    % OUTPUT:
    %      obs: updated observation structs 
    % ________ correct the GPS C1C observation (in C1W position) ONLY _________
    
    %%%% Constant defination %%%%
    V = 2.99792458E+08;             
    NS2M = (V*1.0E-9);
    
    [row, col] = size(obs.GPSC1W); % 获取C1W数据的大小
    
    for i = 1:1:col     % 逐卫星循环
        % satTmp = obs.GPSC1W(:,i); % 选取当前卫星的数据
        prn = i;
        dcb_corr = SDCB_REF.gpsc1p1(prn);
        for j = 1:1:row     % 当前卫星逐历元循环
            if obs.GPSC1W(j,prn) == 0
                continue
            end
            obs.GPSC1W(j,prn) = obs.GPSC1W(j,prn) - dcb_corr * NS2M;
        end
    end
    end
    
  3. 提升代码运行速度(可选):Main_nonSH.m

    line 25-26
    %--the cores number of computer processor
    Corenum=2; % 此处根据各人计算机而定
    
2.3 程序运行结果

程序运行需要较长时间,其间生成的观测值以mat格式保存在./OBS/regional/23001/目录下,精密轨道保存在./SP3,计算得到的P4平滑值保存在./P4/regional/GPS/23001/,最终最小二乘估计的结果保存在./M_Result/,接下来根据结果计算区域格网VTEC,并输出文件。由于本次解算仅采用GPS数据,故在原程序Plot_nonSH.m的基础上做了一些修改,命名为Plot_nonSH_ChinaRegion.m,可作为参考:

%% ==========Plot and write regional ionospheric maps=================
%% nonintergral SH model
clear all;
close all;
doy=23001;  fig=24;  K=6;  M=4;
load('sate_mark.mat');
load(['M_Result/nonSH_G',num2str(doy),'.mat']);
load('sate_mark.mat');
warning off;
addpath('Tools/m_map','Tools/m_map/private');
lat2=0;     lat1=60;    lon1=70;    lon2=140;
latlim=2.5;   lonlim=5;

% latGrid = lat1:-latlim:lat2;
% lonGrid = lon1:lonlim:lon2;

VVTEC = Get_VTEC(fig, latlim, lonlim, IONC, NN, m0, K, M, lat2, lat1, lon1, lon2);
VTEC=VVTEC;VTEC(VTEC(:,4)<0,4)=0.05;
RMS=[VTEC(:,1:3),VTEC(:,5)];
% read CODE final GIMs (codg2750.19i) as reference
disp('--------> Read CODE final GIMs as reference !');
IGSData=read_ionex(fig,'TEC');
AreaTEC=Get_areaTEC(fig,lat2,lat1,lon1,lon2,IGSData);
DIFFTEC=[VTEC(:,1:3),VTEC(:,4)-AreaTEC(1:size(VTEC,1),4)];
% 保存变量
fname=['RIM_data_China\' num2str(doy) '.mat'];
save(fname,'VTEC','RMS','IGSData','AreaTEC','DIFFTEC','-mat');

% % 加载变量
% load(['RIM_data_China\',num2str(doy),'.mat'])

% %%%% 这里统计一下VTEC误差序列的结果 %%%%%
% sess = unique(DIFFTEC(:,1));
% staRes = zeros(length(sess), 3);
% for iis = 1:1:length(sess)
%     diffTmp = [];
%     for kk = 1:1:length(DIFFTEC(:,3))
%         if DIFFTEC(kk,1) == sess(iis)
%             diffTmp(end +1, :) =  DIFFTEC(kk,:);
%         end
%     end
%     % 统计
%     biasVal = mean(diffTmp(:,4), 1);
%     stdVal = std(diffTmp(:,4), 0, 1); % std(A,flag):flag用来区分std求法,如果是0,则代表除以N-1,如果是1代表的是除以N
%     rmsVal = rms(diffTmp(:,4));
%     fprintf('Session: %2d   Bias: %6.3f  STD: %6.3f  RMS: %6.3f \n', sess(iis), biasVal, stdVal, rmsVal);
%     staRes(iis,:) = [biasVal stdVal rmsVal];
%     
% end
% biasVal = mean(staRes(:,1), 1);
% stdVal = mean(staRes(:,2), 1);
% rmsVal = mean(staRes(:,3), 1);
% fprintf('Average:Bias: %6.3f  STD: %6.3f  RMS: %6.3f \n', biasVal, stdVal, rmsVal);

Pname='2023-001-nonSH-'; 
Plot_TEC(fig,latlim,lonlim,Pname,VTEC,lat1,lat2,lon1,lon2,0,50);
Pname_D='2023-001-nonSH-D-'; 
Plot_TEC(fig,latlim,lonlim,Pname_D,DIFFTEC,lat1,lat2,lon1,lon2,-10,10);
Pname_R='2023-001-nonSH-RMS-'; 
Plot_TEC(fig,latlim,lonlim,Pname_R,RMS,lat1,lat2,lon1,lon2,0,5);

% write results to ionex files
% 由于只用了GPS数据,所以其他几种系统的sDCB和rDCB均赋值为0
C_R = zeros(23,1);
E_R = zeros(18,1);
EX_R = zeros(11,1);
R_R = zeros(28,1);
C_S = zeros(1,15);
E_S = zeros(1,24);
R_S = zeros(1,21);
Write_ionex(doy,fig,G_R,C_R,E_R,EX_R,R_R,G_S,C_S,E_S,R_S,Pname,VTEC,sate_mark,total_station,list_P4);

%% ++++++++++++++++PLOT OVER!!!+++++++++++++++++++

此处,对应的Write_ionex里面在输出每颗卫星的DCB之前,加上判断,若全为0则不输出。对应程序修改可自行完成。

以上,程序运行结束,下面贴出结果图:

以下四张图展示各时段的结果,依次为:估计得到的VTEC、与CODE作差得到的VTEC插值、估计VTEC的RMS、穿刺点分布(此为自己程序写的)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
请添加图片描述

3. 其他

2.3 贴出的图是采用Python拼接而成的图,这里推荐大家使用,特别是需要将很多子图拼在一起的情况下,采用matlab直接画的话,需要微调很久(即使有循环画子图的脚本,colorbar、子图命名等均需要花费大量时间),采用adobe AI 手动拼接的话,在很多子图的情况下也是费时费力。此处参考了

给出的程序,对子图进行拼接,这里贴出程序,以备日后查用:

import os
import math
from PIL import Image


def merge_images(image_folder, output_file, n, m):
    # 获取所有图像文件的列表
    image_files = [os.path.join(image_folder, f) for f in os.listdir(image_folder) if f.endswith('.png')]

    # 计算每个小图像的大小和大图像的大小
    image_count = len(image_files)
    if image_count == 0:
        print('No image files found in the directory:', image_folder)
        return

    # 计算小图像的大小以及大图像的大小
    img = Image.open(image_files[0])
    img_size0 = img.size[0]
    img_size1 = img.size[1]
    new_img_size0 = img_size0 * n
    new_img_size1 = img_size1 * m

    # 创建一个新的大图像
    new_img = Image.new('RGB', (new_img_size0, new_img_size1), 'white')

    # 将所有小图像粘贴到新图像的正确位置
    for i, f in enumerate(image_files):
        row = int(i / n)
        col = i % n
        img = Image.open(f)
        img = img.resize((img_size0, img_size1))
        new_img.paste(img, (col * img_size0, row * img_size1))

    # 保存大图像
    new_img.save(output_file)


# 用法示例
# 图片目录
image_folder = r'x:/xxxxx/xxxxxxxx/M_GIM/M_PLOT/nonSH/'
# 输出目录
output = r'./nonSH/'
if not os.path.exists(output):  # True/False
    os.mkdir(output)
# 输出图片名(必须指定图片名.png)
output_file = r'./nonSH/comb-nonSH.png'

n = 4  # 每行显示的图像数
m = 6  # 每列显示的图像数
merge_images(image_folder, output_file, n, m)


mage_folder = r'x:/xxxxx/xxxxxxxx/M_GIM/M_PLOT/nonSH/'
# 输出目录
output = r'./nonSH/'
if not os.path.exists(output):  # True/False
    os.mkdir(output)
# 输出图片名(必须指定图片名.png)
output_file = r'./nonSH/comb-nonSH.png'

n = 4  # 每行显示的图像数
m = 6  # 每列显示的图像数
merge_images(image_folder, output_file, n, m)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/653502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js数组高阶函数——includes()方法

js数组高阶函数——includes方法 前言数组的一般化操作创建数组获取数组长度访问&#xff08;遍历&#xff09;数组元素修改数组元素删除数组元素数组尾部添加数组尾部删除 includes&#xff08;&#xff09;方法举例说明关键点 前言 ⭐JS的数组是一种特殊的对象&#xff0c;其…

SSH通过VSCode远程访问服务器Opencv和matplotlib等无法直接显示图像问题

需求描述&#xff1a; 在VSCode中通过SSH连接服务器&#xff0c;使用cv2.imshow或plt.show()无法显示图像。 解决思路如下&#xff1a; 1、首先查看与服务器之间的网络连接问题&#xff08;百分之九十问题就是出在第一步骤&#xff0c;哈哈哈&#xff09; 在本地端打开cmd&…

「案例」95后占半壁江山的浙桂,如何在百家争鸣中快人一步

如果用一个历史时期来形容目前国内单光子雪崩二极管&#xff08;SPAD&#xff09;传感器芯片的市场格局&#xff0c;那就是——春秋。 各家IC设计公司百家争鸣&#xff0c;而浙桂半导体就是其中的“百分之一”。 浙桂半导体两大特点 一、浙桂研发SPAD传感器芯片需要召唤像元、…

C语言实现字符串的模式匹配

一.模式匹配 字符串的模式匹配算法是用来查找一个字符串中是否存在另一个指定的字符串&#xff08;即模式&#xff09;的算法。常见的模式匹配算法包括暴力匹配算法、KMP算法、Boyer-Moore算法和Rabin-Karp算法。 暴力匹配算法&#xff1a;暴力匹配算法也称为朴素匹配算法&am…

自学黑客!一般人我劝你还是算了吧

一、自学网络安全学习的误区和陷阱 1.不要试图以编程为基础的学习开始学习 我在之前的回答中&#xff0c;我都一再强调不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;而且实际向安全过渡后可用到的关键知识并不多 一…

【Java之JAR包解析】(三)除核心包 rt.jar之外的其他JAR包~

JAR包解析之其他jar包 前言:one: access-bridge-64.jar:two: charsets.jar:three: cldrdata.jar:four: deploy.jar:five: jce.jar:six: jfr.jar:seven: jfxrt.jar:eight: jfxswt.jar:nine: jsse.jar:keycap_ten: localedata.jar11、management-agent.jar12、nashorn.jar13、plu…

开发人员Git仓库提交与合并

参考&#xff1a;git 的变基(rebase)和合并(merge)具体有什么分别阿&#xff1f; - 知乎 1、Git工作流 在使用Git Flow工作模式时&#xff0c;业界普遍遵循的规则&#xff1a; 所有开发分支从develop分支拉取。所有hotfix分支从master分支拉取。所有在master分支上的提交都必…

flstudio21.0.3中文版水果软件下载

FL Studio就是国人众所熟知的水果编曲软件&#xff0c;圈内用户习惯叫它“水果”。它是一个全能音乐制作环境或数字音频工作站&#xff08;DAW&#xff09;。FL Studio可以进行编曲、剪辑、录音、混音&#xff0c;让你的电脑变成全功能录音室&#xff0c;帮助你制作出属于自己的…

轻量服务器架设网站打开速度慢,如何加速?

轻量服务器非常适合流量适中的小、中型网站&#xff0c;虽作为轻量级主机包&#xff0c;但它一般与云服务器使用同样的 CPU、内存、硬盘等底层资源。只是&#xff0c;轻量服务器的资源(可用的存储空间、RAM 和 CPU等硬件/内存容量)更低&#xff0c;虽然这些对于较中、小的网站来…

GEN回零调试

一.根据motionstudio软件检测各部件完备&#xff1b; 二.调试点位模式的CPP测试程序 其中&#xff0c;配置文件如下&#xff1a; 回零相关&#xff08;就是轴状态同步&#xff09;&#xff1a; 下面是相关代码: // 例程 7-1 点位运动 //#include "stdafx.h" #inclu…

selenium自动化的时候网址重定向问题的解决思路

一、背景 因为我们系统是用企业微信扫码登录的&#xff0c;就输入网址 management-xxx.xxx.com以后&#xff0c;url就会重定向到企业微信授权的url &#xff1a;https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect?statexxx&redirect_urimanagement-xxx.xxx.com …

如何制作数据可视化、数孪、安防、区域人流量识别+控制的项目?

制作与数据可视化、数字孪生、安防、区域人群识别和控制以及其他类似计划相关的项目需要仔细规划和执行。建议遵循以下通用框架来有效地开发这些项目&#xff1a; 定义项目目标&#xff1a;清楚地阐明项目目的和目标。确定要解决的具体问题、期望的结果以及衡量成功的关键绩效指…

vue3+ts+vite+electron打包exe

文章目录 一. 前言二. 准备写好的vue项目打包2.1 修改ts打包代码检测.这个比较烦人. 在package.json中 2.2 配置打包参数2.3 打包vue 三. 打包exe3.1 拉取electron官方demo3.2 下载打包插件3.3 在electron-quick-start项目中找到入口文件 main.js &#xff0c;修改打包的文件路…

差值结构的运动

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入有3个节点&#xff0c;训练集AB各由5张二值化的图片组成&#xff0c;让B全是0&#xff0c;让差值结构的5行分别有0&#xff0c;1&#xff0c;2&#xff0c;2&#xff0c;2个1&#xff0c;3列分别有1&#xff0c;3&#xff0…

知了堂Java V9.0重磅升级,真的很硬核!

“2023年&#xff0c;Java还值得学吗&#xff1f;” 说实话&#xff0c;Java自1995年诞生起&#xff0c;至今还难逢敌手&#xff0c;没有任何编程语言能够取代它的地位。不过随着互联网、计算机技术的发展&#xff0c;Java应用领域越来越广泛&#xff0c;因此也对掌握这门语言…

Vue全家桶(二):Vue中的axios异步通信

目录 1. Axios1.1 Axios介绍1.2 为什么使用Axios1.3 Axios API1.3 Vue使用axios向服务器请求数据1.4 Vue使用axios向服务器提交数据1.5 Vue封装网络请求 2. 使用Vue-cli解决Ajax跨域问题3. GitHub用户搜索案例4. Vue-resource 1. Axios 1.1 Axios介绍 Axios 是一个开源的可以…

flexible.js + rem 适配布局

什么是&#xff1a;flexible.js &#xff1f;&#xff1f; flexible.js 是手机淘宝团队出的移动端布局适配库不需要在写不同屏幕的媒体查询&#xff0c;因为里面js做了处理原理是把当前设备划分为10等份&#xff0c;但是不同设备下&#xff0c;比例还是一致的。要做的&#xf…

【亲测解决】import torch 出现段错误,报错信息 Segmentation fault

微信公众号&#xff1a;leetcode_algos_life import torch 出现段错误 【问题】【解决方案】 【问题】 安装pytorch-gpu版本&#xff0c;安装完成后&#xff0c;import torch发现报错直接返回&#xff0c;报错信息如下&#xff1a; Segmentation fault【解决方案】 Linux环境…

查看虚拟机网络IP和网关

查看虚拟网络编辑器和修IP地址: 查看网关&#xff1a; 查看windows:环境的中VMnet8网络配置(ipconfig指令): 查看linux的配置ifconfig: ping测试主机之间网络连通性: 基本语法 ping 目的主机&#xff08;功能描述&#xff1a;测试当前服务器是否可以连接目的主机) 应用实例 测…

一秒教你搞定前端打包上传后路由404的问题!

1、问题描述 前端实现权限管理后&#xff0c;本地路由跳转正常&#xff0c;打包上传线上出现前404找不到路由路径问题 报如下错误: 2、错误原因 打包之后根路径变化&#xff0c;前端没有将获取到的用户菜单权限中的component进行转换&#xff0c;导致上传后路径错误 3、解决…