Skip to content

Commit

Permalink
Index signal specific data using the signal code
Browse files Browse the repository at this point in the history
Rather than the signal frequency index which is still used in the
observation structure to keep that compact.

When there are many signals the set of signals can change and when the
priorities are recomputed the frequency index can change so the
frequency index is not a reliable key for this state. This is not an
issue with just one signal, or perhaps two, but with more than NFREQ
signals there were subtle issues as the priories changed and the state
was mixed up.

There are a good few structures with just one array of data for each
signal and these have been expanded from being NFREQ+NEXOBS to MAXCODE
so that the signal code can be used as the index. This is a little
wasteful of memory but simple.
  • Loading branch information
ourairquality committed Oct 8, 2024
1 parent 38f579d commit 3aa775b
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 222 deletions.
152 changes: 84 additions & 68 deletions src/convrnx.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ typedef struct { /* stream file type */
raw_t raw; /* input receiver raw data */
rnxctr_t rnx; /* input RINEX control data */
stas_t *stas; /* station list */
uint8_t slips [MAXSAT][NFREQ+NEXOBS]; /* cycle slip flag cache */
halfc_t *halfc[MAXSAT][NFREQ+NEXOBS]; /* half-cycle ambiguity list */
uint8_t slips [MAXSAT][MAXCODE]; /* cycle slip flag cache */
halfc_t *halfc[MAXSAT][MAXCODE]; /* half-cycle ambiguity list */
FILE *fp; /* output file pointer */
} strfile_t;

Expand Down Expand Up @@ -147,7 +147,6 @@ static strfile_t *gen_strfile(int format, const char *opt)
{
strfile_t *str;
gtime_t time0={0};
int i,j;

trace(3,"init_strfile:\n");

Expand Down Expand Up @@ -200,9 +199,10 @@ static strfile_t *gen_strfile(int format, const char *opt)
}

str->stas=NULL;
for (i=0;i<MAXSAT;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
str->slips[i][j]=0;
str->halfc[i][j]=NULL;
for (int i=0;i<MAXSAT;i++)
for (int code=0;code<MAXCODE;code++) {
str->slips[i][code]=0;
str->halfc[i][code]=NULL;
}
str->fp=NULL;
return str;
Expand All @@ -212,7 +212,6 @@ static void free_strfile(strfile_t *str)
{
stas_t *sp,*sp_next;
halfc_t *hp,*hp_next;
int i,j;

trace(3,"free_strfile:\n");

Expand All @@ -229,8 +228,9 @@ static void free_strfile(strfile_t *str)
sp_next=sp->next;
free(sp);
}
for (i=0;i<MAXSAT;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
for (hp=str->halfc[i][j];hp;hp=hp_next) {
for (int i=0;i<MAXSAT;i++)
for (int code=0;code<MAXCODE;code++) {
for (hp=str->halfc[i][code];hp;hp=hp_next) {
hp_next=hp->next;
free(hp);
}
Expand Down Expand Up @@ -624,15 +624,15 @@ static void dump_stas(const strfile_t *str)
#endif
}
/* add half-cycle ambiguity list ---------------------------------------------*/
static int add_halfc(strfile_t *str, int sat, int idx, gtime_t time)
static int add_halfc(strfile_t *str, int sat, int code, gtime_t time)
{
halfc_t *p;

if (!(p=(halfc_t *)calloc(sizeof(halfc_t),1))) return 0;
p->ts=p->te=time;
p->stat=0;
p->next=str->halfc[sat-1][idx];
str->halfc[sat-1][idx]=p;
p->next=str->halfc[sat-1][code];
str->halfc[sat-1][code]=p;
return 1;
}
/* update half-cycle ambiguity -----------------------------------------------*/
Expand All @@ -643,56 +643,59 @@ static void update_halfc(strfile_t *str, obsd_t *obs)
for (i=0;i<NFREQ+NEXOBS;i++) {
if (obs->L[i]==0.0) continue;

int code = obs->code[i];
if (code == CODE_NONE) continue;

/* if no list, start list */
if (!str->halfc[sat-1][i]) {
if (!add_halfc(str,sat,i,obs->time)) continue;
if (!str->halfc[sat-1][code]) {
if (!add_halfc(str,sat,code,obs->time)) continue;
}
/* reset list if true cycle slip */
if ((obs->LLI[i]&LLI_SLIP)&&!(obs->LLI[i]&(LLI_HALFA|LLI_HALFS))) {
str->halfc[sat-1][i]->stat=0;
str->halfc[sat-1][code]->stat=0;
}
if (obs->LLI[i]&LLI_HALFC) { /* halfcyc unresolved */
/* if new list, set unresolved start epoch */
if (str->halfc[sat-1][i]->stat==0) {
str->halfc[sat-1][i]->ts=obs->time;
if (str->halfc[sat-1][code]->stat==0) {
str->halfc[sat-1][code]->ts=obs->time;
}
/* update unresolved end epoch and set status to active */
str->halfc[sat-1][i]->te=obs->time;
str->halfc[sat-1][i]->stat=1;
str->halfc[sat-1][code]->te=obs->time;
str->halfc[sat-1][code]->stat=1;
} /* else if resolved, update status */
else if (str->halfc[sat-1][i]->stat==1) {
else if (str->halfc[sat-1][code]->stat==1) {
if (obs->LLI[i]&LLI_HALFA) {
str->halfc[sat-1][i]->stat=2; /* resolved with add */
str->halfc[sat-1][code]->stat=2; /* resolved with add */
}
else if (obs->LLI[i]&LLI_HALFS) {
str->halfc[sat-1][i]->stat=3; /* resolved with subtract */
str->halfc[sat-1][code]->stat=3; /* resolved with subtract */
}
else {
str->halfc[sat-1][i]->stat=4; /* resolved with no adjust */
str->halfc[sat-1][code]->stat=4; /* resolved with no adjust */
}
/* create new list entry */
if (!add_halfc(str,sat,i,obs->time)) continue;
if (!add_halfc(str,sat,code,obs->time)) continue;
}
}
}
/* dump half-cycle ambiguity list --------------------------------------------*/
static void dump_halfc(const strfile_t *str)
{
#if 0 /* for debug */
halfc_t *p;
char s0[32],s1[32],s2[32],*stats[]={"ADD","SUB","NON"};
int i,j;

#ifdef RTK_DISABLED /* for debug */
trace(2,"# HALF-CYCLE AMBIGUITY CORRECTIONS\n");
trace(2,"# %20s %22s %4s %3s %3s\n","START","END","SAT","FRQ","COR");

for (i=0;i<MAXSAT;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
for (p=str->halfc[i][j];p;p=p->next) {
for (int i=0;i<MAXSAT;i++)
for (int code=0;code<MAXCODE;code++) {
const char *obs=code2obs(code);
for (halfc_t *p=str->halfc[i][code];p;p=p->next) {
if (p->stat<=1) continue;
char s0[8],s1[40],s2[40];
satno2id(i+1,s0);
time2str(p->ts,s1,2);
time2str(p->te,s2,2);
trace(2,"%s %s %4s %3d %3s\n",s1,s2,s0,j+1,stats[p->stat-2]);
const char *stats[]={"ADD","SUB","NON"};
trace(2,"%s %s %4s %2s %3s\n",s1,s2,s0,obs,stats[p->stat-2]);
}
}
#endif
Expand All @@ -701,15 +704,16 @@ static void dump_halfc(const strfile_t *str)
static void resolve_halfc(const strfile_t *str, obsd_t *data, int n)
{
halfc_t *p;
int i,j,sat;
int sat;

for (i=0;i<n;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
for (int i=0;i<n;i++) {
sat=data[i].sat;

for (p=str->halfc[sat-1][j];p;p=p->next) {
if (p->stat<=1) continue; /* unresolved half cycle */
if (timediff(data[i].time,p->ts)<-DTTOL||
timediff(data[i].time,p->te)> DTTOL) continue;
for (int j=0;j<NFREQ+NEXOBS;j++) {
int code = data[i].code[j];
for (p=str->halfc[sat-1][code];p;p=p->next) {
if (p->stat<=1) continue; /* unresolved half cycle */
if (timediff(data[i].time,p->ts)<-DTTOL||
timediff(data[i].time,p->te)> DTTOL) continue;

if (p->stat==2) { /* add half cycle */
data[i].L[j]+=0.5;
Expand All @@ -720,6 +724,7 @@ static void resolve_halfc(const strfile_t *str, obsd_t *data, int n)
data[i].LLI[j]&=~LLI_HALFC;
}
data[i].LLI[j]&=~(LLI_HALFA|LLI_HALFS);
}
}
}
/* scan input files ----------------------------------------------------------*/
Expand Down Expand Up @@ -756,14 +761,14 @@ static int scan_file(char **files, int nf, rnxopt_t *opt, strfile_t *str,

/* update obs-types */
for (j=0;j<NFREQ+NEXOBS;j++) {
int c=str->obs->data[i].code[j];
if (c==CODE_NONE) continue;
int cd=str->obs->data[i].code[j];
if (cd==CODE_NONE) continue;

for (k=0;k<n[l];k++) {
if (codes[l][k]==c) break;
if (codes[l][k]==cd) break;
}
if (k>=n[l]&&n[l]<32) {
codes[l][n[l]++]=c;
codes[l][n[l]++]=cd;
}
if (k<n[l]) {
if (str->obs->data[i].P[j]!=0.0) types[l][k]|=1;
Expand Down Expand Up @@ -968,21 +973,27 @@ static void outrnxevent(FILE *fp, const rnxopt_t *opt, gtime_t time, int event,
/* save cycle slips ----------------------------------------------------------*/
static void save_slips(strfile_t *str, obsd_t *data, int n)
{
int i,j;

for (i=0;i<n;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
if (data[i].LLI[j]&LLI_SLIP) str->slips[data[i].sat-1][j]=1;
for (int i=0;i<n;i++)
for (int j=0;j<NFREQ+NEXOBS;j++) {
int sat = data[i].sat;
if (sat == 0) continue;
int code = data[i].code[j];
if (code == CODE_NONE) continue;
if (data[i].LLI[j]&LLI_SLIP) str->slips[sat-1][code]=1;
}
}
/* restore cycle slips -------------------------------------------------------*/
static void rest_slips(strfile_t *str, obsd_t *data, int n)
{
int i,j;

for (i=0;i<n;i++) for (j=0;j<NFREQ+NEXOBS;j++) {
if (data[i].L[j]!=0.0&&str->slips[data[i].sat-1][j]) {
data[i].LLI[j]|=LLI_SLIP;
str->slips[data[i].sat-1][j]=0;
for (int i=0;i<n;i++)
for (int j=0;j<NFREQ+NEXOBS;j++) {
int sat = data[i].sat;
if (sat == 0) continue;
int code = data[i].code[j];
if (code == CODE_NONE) continue;
if (data[i].L[j]!=0.0&&str->slips[sat-1][code]) {
data[i].LLI[j]|=LLI_SLIP;
str->slips[sat-1][code]=0;
}
}
}
Expand Down Expand Up @@ -1022,14 +1033,19 @@ static void convobs(FILE **ofp, rnxopt_t *opt, strfile_t *str, int *n,
/* save cycle slips */
save_slips(str,str->obs->data,str->obs->n);

if (!screent_ttol(time,opt->ts,opt->te,opt->tint,opt->ttol)) return;
if (!screent_ttol(time,opt->ts,opt->te,opt->tint,opt->ttol)) {
if (str->staid!=*staid) { /* Station ID changed */
*staid=str->staid;
}
str->obs->flag = 0;
return;
}

/* restore cycle slips */
/* Restore cycle slips */
rest_slips(str,str->obs->data,str->obs->n);

if (str->staid!=*staid) { /* station ID changed */

if (*staid>=0) { /* output RINEX event */
if (str->staid!=*staid) { /* Station ID changed */
if (*staid>=0) { /* Output RINEX event */
outrnxevent(ofp[0],opt,str->time,EVENT_NEWSITE,str->stas,str->staid);
}
*staid=str->staid;
Expand Down Expand Up @@ -1256,7 +1272,7 @@ static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file,
FILE *ofp[NOUTFILE]={NULL};
strfile_t *str;
gtime_t tend[3]={{0}};
int i,j,nf,type,n[NOUTFILE+2]={0},mask[MAXEXFILE]={0},staid=-1,abort=0;
int j,nf,type,n[NOUTFILE+2]={0},mask[MAXEXFILE]={0},staid=-1,abort=0;
char path[1024],*paths[NOUTFILE],s[NOUTFILE][1024];
char *epath[MAXEXFILE]={0},*staname=*opt->staid?opt->staid:"0000";

Expand All @@ -1270,7 +1286,7 @@ static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file,
return 0;
}
/* expand wild-cards in input file */
for (i=0;i<MAXEXFILE;i++) {
for (int i=0;i<MAXEXFILE;i++) {
if (!(epath[i]=(char *)malloc(1024))) {
for (i=0;i<MAXEXFILE;i++) free(epath[i]);
return 0;
Expand All @@ -1281,7 +1297,7 @@ static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file,
return 0;
}
if (!(str=gen_strfile(format,opt->rcvopt))) {
for (i=0;i<MAXEXFILE;i++) free(epath[i]);
for (int i=0;i<MAXEXFILE;i++) free(epath[i]);
return 0;
}
if (format==STRFMT_RTCM2||format==STRFMT_RTCM3||format==STRFMT_RT17) {
Expand All @@ -1291,20 +1307,20 @@ static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file,
str->time=timeadd(opt->ts,-1.0);
}
/* set GLONASS FCN in RINEX options */
for (i=0;i<MAXPRNGLO;i++) {
for (int i=0;i<MAXPRNGLO;i++) {
str->nav->glo_fcn[i]=opt->glofcn[i]; /* FCN+8 */
}
/* scan input files */
if (!scan_file(epath,nf,opt,str,mask)) {
for (i=0;i<MAXEXFILE;i++) free(epath[i]);
for (int i=0;i<MAXEXFILE;i++) free(epath[i]);
free_strfile(str);
return 0;
}
/* set format and file in RINEX options comments */
setopt_file(format,epath,nf,mask,opt);

/* replace keywords in output file */
for (i=0;i<NOUTFILE;i++) {
for (int i=0;i<NOUTFILE;i++) {
paths[i]=s[i];
if (reppath(ofile[i],paths[i],opt->ts.time?opt->ts:str->tstart,
staname,"")<0) {
Expand All @@ -1316,13 +1332,13 @@ static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file,
}
/* open output files */
if (!openfile(ofp,paths,path,opt,str->nav)) {
for (i=0;i<MAXEXFILE;i++) free(epath[i]);
for (int i=0;i<MAXEXFILE;i++) free(epath[i]);
free_strfile(str);
return 0;
}
str->time=str->tstart;

for (i=0;i<nf&&!abort;i++) {
for (int i=0;i<nf&&!abort;i++) {
if (!mask[i]) continue;

/* open stream file */
Expand Down Expand Up @@ -1353,7 +1369,7 @@ static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file,
closefile(ofp,opt,str->nav);

/* remove empty output files */
for (i=0;i<NOUTFILE;i++) {
for (int i=0;i<NOUTFILE;i++) {
if (ofp[i]&&n[i]<=0) remove(ofile[i]);
}
showstat(sess,opt->tstart,opt->tend,n);
Expand All @@ -1362,7 +1378,7 @@ static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file,
unsetopt_file(opt);

free_strfile(str);
for (i=0;i<MAXEXFILE;i++) free(epath[i]);
for (int i=0;i<MAXEXFILE;i++) free(epath[i]);

return abort?-1:1;
}
Expand Down
Loading

0 comments on commit 3aa775b

Please sign in to comment.