void TabulatedFunction_load(TabulatedFunction *func, char *fileName) { FILE *f; char line[1024]="", *c; TabulatedFunctionSample sample; int narg; DynamicArray_init(&func->samples, sizeof(TabulatedFunctionSample)); /* sprintf(fname, "%s/clock2/%s.clk", getenv("TEMPO2"), fileName); */ f = fopen(fileName, "r"); if (f==NULL) { fprintf(stderr, "Fatal Error: Unable to open file %s for reading: %s\n", fileName, strerror(errno)); exit(1); } fgets(func->header_line, 1024, f); // first line is a header line if (func->header_line[0]!='#') { fprintf(stderr, "Error parsing file %s: first line must begin with #\n", fileName); exit(1); } for (c=line; *c=='#'; c++) ; /* parse table lines */ while (fgets(line, 1024, f)!=NULL) { if (line[0]!='#') { if (sscanf(line, "%lf %lf", &sample.x, &sample.y)==2) DynamicArray_push_back(&func->samples, &sample); } } fclose(f); /* Make shortened filename and store it */ /* find last / */ for (c = fileName + strlen(fileName)-1; *c!='/' && c != fileName; c--) ; if (*c=='/') c++; strcpy(func->fileName, c); /* copy after / */ // func->fileName[strlen(func->fileName)-4] = '\0';/* wipe off .clk */ }
void initialize_ClockCorrections(int dispWarnings) { glob_t g; char pattern[1024]; char **pfname; int globRet; ClockCorrectionFunction func; DynamicArray_init(&clockCorrectionFunctions, sizeof(ClockCorrectionFunction)); DynamicArray_init(&clockCorrectionSequences, sizeof(DynamicArray)); /* load all .clk files in $TEMPO2/clock */ sprintf(pattern, "%s/clock/*.clk", getenv(TEMPO2_ENVIRON)); globRet = glob(pattern, 0, NULL, &g); if (globRet == GLOB_NOSPACE) { printf("Out of memory in clkcorr.C\n"); exit(1);} #ifdef GLOB_ABORTED else if (globRet == GLOB_ABORTED) { printf("Read error in clkcorr.C\n"); exit(1); } #endif #ifdef GLOB_NOMATCH else if (globRet == GLOB_NOMATCH) { printf("No clock correction files in $TEMPO2/clock\n"); exit(1); } #endif for (pfname = g.gl_pathv; *pfname != NULL; pfname++) { ClockCorrectionFunction_load(&func, *pfname); DynamicArray_push_back(&clockCorrectionFunctions, &func); if (dispWarnings==0) printf("Loaded clock correction %s : %s -> %s badness %.3g\n", func.table.fileName, func.clockFrom, func.clockTo, func.badness); } clockCorrections_initialized = 1; globfree(&g); }
void initialize_meteorology_table(int dispWarnings, char *path, char *extension, DynamicArray *tables, char *description) { glob_t g; char pattern[1024]; char **pfname; int globRet; MeteorologyFunction func; DynamicArray_init(tables, sizeof(MeteorologyFunction)); /* load all files in specified spot */ sprintf(pattern, "%s/%s/*.%s", getenv(TEMPO2_ENVIRON), path, extension); globRet = glob(pattern, 0, NULL, &g); if (globRet == GLOB_NOSPACE) { printf("Out of memory in tropo.C\n"); exit(1);} #ifdef GLOB_ABORTED else if (globRet == GLOB_ABORTED) { printf("Read error in tropo.C\n"); exit(1); } #endif #ifdef GLOB_NOMATCH else if (globRet == GLOB_NOMATCH) { if (dispWarnings==0) printf("No .%s files in $TEMPO2/%s\n", extension, path); return; } #endif for (pfname = g.gl_pathv; *pfname != NULL; pfname++) { MeteorologyFunction_load(&func, *pfname); DynamicArray_push_back(tables, &func); if (dispWarnings==0) printf("Loaded %s for site %s from %s\n", description, func.siteName, func.table.fileName); } }
void defineClockCorrectionSequence(char *fileList_in,int dispWarnings) { ClockCorrectionFunction *func; size_t ifunc; DynamicArray seq; char fileList[2048], *c; const char *white=" \t\r\n"; if ( clockCorrections_initialized != 1 ) initialize_ClockCorrections(dispWarnings); DynamicArray_init(&seq, sizeof(ClockCorrectionFunction *)); /* for each file name, find the function from the list of loaded ones, and add a pointer into that list to the array defining the present sequence */ strcpy(fileList, fileList_in); for (c=strtok(fileList, white); c!=NULL; c=strtok(NULL, white)) { for (ifunc=0; ifunc < clockCorrectionFunctions.nelem; ifunc++) { func = ((ClockCorrectionFunction *)clockCorrectionFunctions.data)+ifunc; if (!strcmp(func->table.fileName, c)) break; } if (ifunc == clockCorrectionFunctions.nelem) { printf( "Requested clock correction file %s not found!\n",c); exit(1); } DynamicArray_push_back(&seq, &func); } /* save the sequence in the list of sequences*/ DynamicArray_push_back(&clockCorrectionSequences, &seq); }
void load_EOP(DynamicArray *EOPsamples,char *eopcFile) { char fname[1024], line[1024], mjd_s[1024], xp_s[1024], yp_s[1024], dut1_s[1024]; int year; EOPSample newSample; FILE *f; int iline,idummy; int format=0; const char *CVS_verNum = "$Revision: 1.10 $"; if (displayCVSversion == 1) CVSdisplayVersion("eop.C","load_EOP()",CVS_verNum); // init array DynamicArray_init(EOPsamples, sizeof(EOPSample)); // open file // sprintf(fname, "%s/%s", getenv("TEMPO2"), EOPC04_FILE); sprintf(fname, "%s/%s", getenv("TEMPO2"), eopcFile); f = fopen(fname, "r"); if (!f) { fprintf(stderr, "Fatal Error: Unable to open file %s for reading: %s\n", fname, strerror(errno)); exit(1); } // parse file for (iline=1; fgets(line, 1024, f)!=NULL; iline++) { // ignore header lines, ancient history (pre-PSR), etc if (sscanf(line, "%d", &year)==1 && year > 1966 && year < 3000) { if (format==0) { // break it up, ugly fixed format fortran I/O strncpy(mjd_s, line+17, 5); mjd_s[5]='\0'; strncpy(xp_s, line+22, 9); xp_s[9]='\0'; strncpy(yp_s, line+31, 9); yp_s[9]='\0'; strncpy(dut1_s, line+40, 10); dut1_s[10]='\0'; // put into sample, in radians and seconds if (sscanf(mjd_s, "%lf", &newSample.mjd)!=1 || sscanf(xp_s, "%lf", &newSample.xp)!=1 || sscanf(yp_s, "%lf", &newSample.yp)!=1 || sscanf(dut1_s, "%lf", &newSample.dut1)!=1) { fprintf(stderr, "Error parsing line %d of %s", iline, fname); exit(1); } } else if (format==1) { if (sscanf(line,"%d %d %d %lf %lf %lf %lf",&year,&idummy,&idummy,&newSample.mjd,&newSample.xp,&newSample.yp,&newSample.dut1)!=7) { fprintf(stderr, "Error parsing line %d of %s", iline, fname); exit(1); } } newSample.xp *= M_PI/(180.0*60.0*60.0); newSample.yp *= M_PI/(180.0*60.0*60.0); DynamicArray_push_back(EOPsamples, &newSample); } else { // Check which format we are using if (strstr(line,"FORMAT(2X,I4,2X,A4,I3,2X,I5,2F9.6,F10.7,2X,F10.7,2X,2F9.6)")!=NULL) { format=0; printf("Warning: using old format for $TEMPO2/eopc04_IAU2000.62-now - should update\n"); } else if (strstr(line,"FORMAT(3(I4),I7,2(F11.6),2(F12.7),2(F11.6),2(F11.6),2(F11.7),2F12.6)")!=NULL) { format=1; logdbg("Using new format for $TEMPO2/eopc04_IAU2000.62-now"); } } } fclose(f); }
/* Function to make a clock correction sequence using Dijkstra's shortest path algorithm , see http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm */ DynamicArray *makeClockCorrectionSequence(const char *clockFrom, const char *clockTo, double mjd,int warnings) { size_t slen = 16; DynamicArray names; /* Array of clock names. Other values index this arr */ int *S; /* Clocks for which shortest path are known */ int n_known; int *Q; /* Remaining clocks */ float *d; /* Best distance to a clock */ int *edge_to_previous; /* edge to use to link to previous node */ int s, t; /* indices of clockFrom, clockTo */ size_t ifunc; int iclock; ClockCorrectionFunction *func; char *clock; int to_present, from_present; int ibest; float best; /* make a list of edges */ typedef struct { int from; int to; ClockCorrectionFunction *func; } Edge; Edge *edges; int iedge, v, nedges; int istep, nsteps; DynamicArray seq; // printf("HERE %s %s %lf %d\n",clockFrom,clockTo,mjd,warnings); DynamicArray_init(&names, slen); /* initialize list of all known clocks, and list of edges for functions that cover the requested mjd */ edges = (Edge *)malloc(sizeof(Edge)*clockCorrectionFunctions.nelem); iedge = 0; for (ifunc=0; ifunc < clockCorrectionFunctions.nelem; ifunc++) { func = ((ClockCorrectionFunction *)clockCorrectionFunctions.data)+ifunc; if (ClockCorrectionFunction_getStartMJD(func) <= mjd && ClockCorrectionFunction_getEndMJD(func) >= mjd) { /* see if to and from clocks there already */ to_present = from_present = 0; for (iclock=0; iclock < (int)names.nelem && !(to_present && from_present); iclock++) { clock = ((char *)names.data)+iclock*slen; if (!strcasecmp(clock, func->clockTo)) { to_present = 1; edges[iedge].to = iclock; } if (!strcasecmp(clock, func->clockFrom)) { from_present = 1; edges[iedge].from = iclock; // printf("%s present already\n", func->clockFrom); } /* else */ /* printf("%s != %s!\n", clock, func->clockFrom); */ } /* add to list if not already present */ if (!to_present) { DynamicArray_push_back(&names, func->clockTo); edges[iedge].to = names.nelem-1; } if (!from_present) { DynamicArray_push_back(&names, func->clockFrom); edges[iedge].from = names.nelem-1; } // printf("Add edge %d <%s> <%s> %d %d\n", iedge, func->clockTo, func->clockFrom, // edges[iedge].to, edges[iedge].from); edges[iedge].func = func; iedge++; } } nedges = iedge; /* find requested start (s) and end (t) clock in array of names */ s = t = -1; for (iclock=0; iclock < (int)names.nelem && (t < 0 || s < 0); iclock++) { clock = ((char *)names.data)+iclock*slen; if (!strcasecmp(clock, clockFrom)) s = iclock; if (!strcasecmp(clock, clockTo)) t = iclock; } if (s < 0) { char msg[1000],msg2[1000]; sprintf(msg,"no clock corrections available for clock %s for MJD", clockFrom); sprintf(msg2,"%.1f",mjd); displayMsg(1,"CLK3",msg,msg2,warnings); //logerr("no clock corrections available for clock %s -> %s for MJD %.1f",clockFrom,clockTo,mjd); // printf("EXITING 1\n"); free(edges); edges = NULL; DynamicArray_free(&names); return NULL; } if (t < 0) { char msg[1000],msg2[1000]; sprintf(msg,"no clock corrections available for clock %s for MJD", clockTo); sprintf(msg2,"%.1f",mjd); displayMsg(1,"CLK3",msg,msg2,warnings); //logerr("no clock corrections available for clock %s -> %s for MJD %.1f",clockFrom,clockTo,mjd); // printf("EXITING 2\n"); free(edges); edges = NULL; DynamicArray_free(&names); return NULL; } /* initialize S, Q, d, p */ n_known = 0; S = (int *)malloc(sizeof(int)*names.nelem); Q = (int *)malloc(sizeof(int)*names.nelem); d = (float *)malloc(sizeof(float)*names.nelem); edge_to_previous = (int *)malloc(sizeof(int)*names.nelem); for (iclock=0; iclock < (int)names.nelem; iclock++) { S[iclock] = 0; Q[iclock] = 1; d[iclock] = FLT_MAX; edge_to_previous[iclock] = -1; } d[s] = 0.0; /* main algorithm */ while (1) { /* find the member of Q with the lowest d */ best = FLT_MAX; ibest = -1; for (iclock=0; iclock < (int)names.nelem; iclock++) if (Q[iclock] && d[iclock] < best) { best = d[iclock]; ibest = iclock; } if (ibest == -1) break; Q[ibest] = 0; /* remove it from Q */ S[ibest] = 1; /* add it to S */ if (ibest == t) break; /* shortest path found */ /* for every edge connected to ibest */ /* printf("Looking for edges connected to %s d[%d] = %f\n", */ /* ((char *)names.data)+ibest*slen, ibest, best); */ for (iedge=0; iedge < nedges; iedge++) if (edges[iedge].from==ibest || edges[iedge].to==ibest) { /* set v to where the edge connects to */ if (edges[iedge].from==ibest) v = edges[iedge].to; else v = edges[iedge].from; /* use this edge if it is better */ // printf("Try %s %s badness %f\n", // edges[iedge].func->clockFrom, edges[iedge].func->clockTo, // edges[iedge].func->badness); if (d[v] > d[ibest] + edges[iedge].func->badness) { d[v] = d[ibest] + edges[iedge].func->badness; edge_to_previous[v] = iedge; /* printf(" edge %d --> %d %f\n", iedge, v, d[v]); */ } /* else */ /* printf("Reject %s %s\n", edges[iedge].func->clockFrom, edges[iedge].func->clockTo); */ } } // printf("Badness total = %f\n", best); if (ibest == -1) { char msg[1000],msg2[1000]; sprintf(msg,"no clock corrections available from %s to %s for MJD", clockFrom,clockTo); sprintf(msg2,"%.1f",mjd); //logerr("no clock corrections available for clock %s -> %s for MJD %.1f",clockFrom,clockTo,mjd); displayMsg(1,"CLK7",msg,msg2,warnings); // printf("EXITING 3\n"); free(edges); edges = NULL; DynamicArray_free(&names); return NULL; } else { /* Write out the best path in reverse order, as an edge list to "S" */ nsteps = 0; v = t; while (v != s) { S[nsteps] = edge_to_previous[v]; v = (edges[edge_to_previous[v]].to==v ? edges[edge_to_previous[v]].from : edges[edge_to_previous[v]].to); nsteps++; } /* set up the actual sequence now in the correct order */ DynamicArray_init(&seq, sizeof(ClockCorrectionFunction *)); if (warnings==0) printf("Using the following chain of clock corrections for %s -> %s\n", clockFrom, clockTo); for (istep=nsteps-1; istep >=0; istep--) { /* not any more since some functions are excluded (wrong mjd range) */ /* func = ((ClockCorrectionFunction *)clockCorrectionFunctions.data) */ /* + S[istep]; */ func = edges[S[istep]].func; DynamicArray_push_back(&seq, &func); if (warnings==0) printf("%s : %s <-> %s\n", func->table.fileName, func->clockFrom, func->clockTo); } } /* free memory */ free(edges); edges = NULL; free(edge_to_previous); edge_to_previous = NULL; free(d); d = NULL; free(Q); Q = NULL; free(S); S = NULL; DynamicArray_free(&names); // printf("END HERE\n"); return (DynamicArray *)DynamicArray_push_back(&clockCorrectionSequences, &seq); }