/* ---------------------------------------------------------------- PWS16SVR written by R. Baines 2/90. based on FORTRAN code by L. Granroth. This module contains the Begin, Command, Data and End functions for internal data processing of raw data read from file. Begin - opens communication. Command - instructs server on what data is req'd and how to process it. Data - returns one channel of data. End - closes communication. Since there is alot of code, the Command function has been broken down into several functions to make it more readable and to reduce repititous code segments. ---------------------------------------------------------------- */ /* Includes */ #include #include #include #include #include #include #include #include #include "pwstruct.h" #include "pwsglobl.h" #include "proto.h" /* Macros for this module */ #define sfail 411077030.0 #define big 10.0e30 #define iseed 1313137L #define dat_length 454 /* Internal Global Vars - some used in PWS16SRB */ int ibin, mode, ichan = 0, numbin, maxbin, jstat, idatmin[NUM_CHAN], idatmax[NUM_CHAN], jsc, itype=1, kyr, kdoy, ndays, kyear, kleap, kountwait, index, lyr, ldoy, lhr; boolean pw_found = FALSE, fg_found = FALSE, data_found = FALSE, cmd_pw, found; float span, binwidth, offset, cal[NUM_CHAN+1][256], tonl[8] = { 2.0, 1.0, -1.0, -2.0, -3.0, 1.0, 2.0, 1.0 }, bw[NUM_CHAN][2] = { { 2.99, 2.16 }, { 3.77, 3.58 }, { 7.50, 4.50 }, { 10.6, 10.7 }, { 13.3, 13.8 }, { 29.8, 28.8 }, { 59.5, 39.8 }, { 106., 75.9 }, { 133., 75.9 }, { 211., 151. }, { 298., 324. }, { 421., 513. }, { 943., 832. }, { 2110, 1260 }, { 4210, 2400 }, { 5950, 3800 } }; FILE *fileunit, *datunit; char filename[LLEN]; double tbeg, tend, tyme=0; cd_type cd[64]; /* Internal Function Prototypes */ void process_data(int, int*, float*, float*, float*); void pw_set(int, int); void pw_range(int, int, int, long, float); void pw_get(float *); int getcd(void); void cd_read(void *, size_t, size_t, FILE *); void cd_read_rest(size_t, size_t); int doy_to_md (int); int leap_doy_to_md (int); /* External Function Prototype for reading compressed raw data files */ int LZOPEN(char *); int LZREAD(void *, int *); int LZCLOSE(void); /*--------------------------------------------------------------------- pws16_server_begin by R. Baines 2/90. to initialize server connections for the PWS16PC program. ---------------------------------------------------------------------*/ void pws16_server_begin(void) { /* Set Initial Values for cmd, Zmin and Zmax */ printf ("\nPWS16C version %s\n",VERSION); cmd_reset(); puts ("\nEnter plot parameters (or help)"); } /*--------------------------------------------------------------------- pws16_server_command written by R. Baines Nonzero is returned after a successfully transmitted request and acknowledgment, otherwise zero is returned. NOTE: ALL processing is done in the LOOP here. ---------------------------------------------------------------------*/ int pws16_server_command (void) { float data[NUM_CHAN], sum[NUM_CHAN], peak[NUM_CHAN]; int num[NUM_CHAN], ichan, numsend; if (Cmd.survey) error(2); if (Cmd.length < 0) error(3); printf("000 Out Of %3d", Cmd.numbin); jstat = 2; cmd_pw = !Cmd.fgonly; pw_found = pw_found && Cmd.replot; fg_found = fg_found && Cmd.replot; data_found = pw_found || fg_found; span = (float) Cmd.span; if ((Cmd.numbin < 1) || (Cmd.numbin > 900)) numbin = 900; else numbin = Cmd.numbin; maxbin = numbin - 1; binwidth = span / (float) numbin; if (cmd_pw && !pw_found) { pw_set(Cmd.units, Cmd.spacecraft); pw_range(Cmd.year, Cmd.day, Cmd.hour, Cmd.minute, span); pw_get(data); pw_found = jstat == 1; if (pw_found) { data_found = TRUE; ibin = 0; for (ichan=0; ichan= Cmd.nchan) { exit_graph(); return(FALSE); } Dat.position = Cmd.chan[Iteration/2]-1; Dat.datmin = idatmin[Dat.position]; Dat.datmax = idatmax[Dat.position]; if (Cmd.peaks && ISODD(Iteration)) { Dat.flag = PEAKS; for (i=0; i<900; i++) Dat.data[i] = ipks[Dat.position][i]; } else { for (i=0; i<900; i++) Dat.data[i] = iavg[Dat.position][i]; Dat.flag = AVERAGES; } Dat.position++; Iteration += (Cmd.peaks) ? 1 : 2; return(TRUE); } /* pws16_server_data */ /*--------------------------------------------------------------------- pws16_server_end written by R. Baines 2/90 does nothing. ---------------------------------------------------------------------*/ void pws16_server_end (void) { return; } /* pws16_server_end */ /* ------------------------------------------------------------------ process_data written by R. Baines 3/90 this is a segment of code extracted from pws16_server_command to make the code more readable and reduce repititous code. ------------------------------------------------------------------ */ void process_data(int jbin, int num[], float peak[], float sum[], float data[]) { int ichan, j; float l; static float tcyc[32] = { 4, 4, 9.6, 38.4, 76.8, 96, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; if (jbin != ibin) { for (ichan=0; ichan 0) { if (Cmd.units == 1) { iavg[ichan][ibin] = NINT(sum[ichan] / (float) num[ichan]); ipks[ichan][ibin] = peak[ichan]; } else { iavg[ichan][ibin] = NINT(log10(sum[ichan] / (float) num[ichan])* 1000.0); ipks[ichan][ibin] = NINT(log10(peak[ichan]) * 1000.0); } if (ipks[ichan][ibin] > idatmax[ichan]) idatmax[ichan] = ipks[ichan][ibin]; if (iavg[ichan][ibin] < idatmin[ichan]) idatmin[ichan] = iavg[ichan][ibin]; } else /* num[ichan] <= 0 */ { iavg[ichan][ibin] = 0; ipks[ichan][ibin] = 0; } if (data[ichan] > 0.0) { peak[ichan] = data[ichan]; sum[ichan] = data[ichan]; num[ichan] = 1; } else { peak[ichan] = 0.0; sum[ichan] = 0.0; num[ichan] = 0; } } /* for */ /* Fill In iavg and ipks with values - fills in gap */ if (jbin > ibin+1) { l = ibin + NINT(tcyc[mode]/binwidth); if (l > jbin-1) l = jbin-1; for (j=ibin+1; j<=l; j++) for (ichan=0; ichan 0.0) { if (data[ichan] > peak[ichan]) peak[ichan] = data[ichan]; sum[ichan] += data[ichan]; num[ichan]++; } } /* ---------------------------------------------------------- pw_set written by R. Baines 2/90 reads in calibration tables and initializes them based upon the units used in the data request. ---------------------------------------------------------- */ void pw_set(int iset, int isc) { int j, ichan; int dummy; FILE *fileunit; /* returns if data to be seen has already been processed */ if ((iset == itype) && (isc == jsc)) return; strcpy(filename, Cal_Path); if (isc == 2) strcat(filename,"vg2pwscl.tab"); else strcat(filename,"vg1pwscl.tab"); itype = iset; jsc = isc; /* create calibration table */ setmem (cal[0],256, -99); if (!(fileunit = fopen(filename, "r"))) error(9); for (ichan = 0; ichan < 256; ichan++) fscanf (fileunit, "%d,%E,%E,%E,%E,%E,%E,%E,%E,%E,%E,%E,%E,%E,%E,%E,%E", &dummy, &cal[1][ichan], &cal[2][ichan], &cal[3][ichan], &cal[4][ichan], &cal[5][ichan], &cal[6][ichan], &cal[7][ichan], &cal[8][ichan], &cal[9][ichan], &cal[10][ichan], &cal[11][ichan], &cal[12][ichan], &cal[13][ichan], &cal[14][ichan], &cal[15][ichan], &cal[16][ichan]); fclose (fileunit); /* for (j=1; j 1) && (itype < 8)) { if (itype == 3) for (j=1; j tend) { cd_read_rest(sizeof(cd_type), 64); if (Compress) { LZCLOSE(); Compress = FALSE; } else fclose(datunit); jstat = 2; offset = -1; return; } offset = tyme - tbeg; mode = (int) cd[index].mode; /* read in data from cd */ if (cd[index].ef) { if (itype == 1) for (ichan=0; ichan 64) { index = 0; cd_read(cd, sizeof(cd_type), 64, datunit); } if ((cd[index].org.ef.time == 0.0) && (cd[index].org.ef.mfds == 0)) if (!getcd()) { jstat=2; return; } tyme = cd[index].org.ef.time; } else { /* Fix the upper 8 channels on voyager 2 */ /* note: this approx. correction is good only for part of '78 and later */ if ((jsc == 2) && (tyme >= sfail)) for (ichan=8; ichan 0) { if (cd[index].data[ichan] < 64) cd[index].data[ichan] = 64; if (cd[index].data[ichan] <= 72) cd[index].data[ichan] = tonl[ichan-8] - 530.4 + 8.6 * (float) cd[index].data[ichan]; else cd[index].data[ichan] = tonl[ichan-8] + 20.113 + 0.99 * (float) cd[index].data[ichan]; } } if (itype == 1) for (ichan=0; ichan= 64) { index = 0; cd_read(&cd[0], sizeof(cd_type), 64, datunit); } if ((cd[index].org.ef.time == 0.0) && (cd[index].org.ef.mfds == 0)) if (!getcd()) { jstat=2; return; } tyme = (double) (cd[index].org.cd.millisec / 1000.0) + (double) cd[index].org.cd.second + (cd[index].org.cd.hour -24) * (double) HOUR_SEC + kleap * (double) DAY_SEC + kyear * (double) YEAR_SEC; } } /* ------------------------------------------------------------ getcd written by R. Baines 2/90 gets a segment of raw data in cd format from a data file(s). data files may be in compressed format. ------------------------------------------------------------ */ int getcd(void) { char filename[LLEN], name[13]; /* Search for first file in range */ if (datunit) if (Compress) { LZCLOSE(); Compress = FALSE; } else fclose(datunit); datunit = NULL; while (!datunit) { ndays = (kyr % 4 == 0) ? LEAP_YEAR_DAYS : YEAR_DAYS; sprintf(name, "pws%0d%.3d.", kyr, kdoy); strcpy(filename, Data_Path[Cmd.spacecraft-1]); strcat(filename, name); strcat(filename, Extension); /* Attempt to open raw data file */ datunit = fopen(filename, "rb"); /* if unsuccesful and we have a extension for compressed files then attempt to open COMPRESSED raw data file. */ if (!datunit) { strcpy(filename, Data_Path[Cmd.spacecraft-1]); strcat(filename, name); strcat(filename, ZExtension); if (LZOPEN(filename)) Compress = TRUE; } if (!datunit) { ndays = (kyr % 4 == 0) ? LEAP_YEAR_DAYS : YEAR_DAYS; sprintf(name, "pw%0d%0d%.3d.", Cmd.spacecraft, kyr, kdoy); strcpy(filename, Data_Path[Cmd.spacecraft-1]); strcat(filename, name); strcat(filename, Extension); datunit = fopen(filename, "rb"); } if (!datunit) { strcpy(filename, Data_Path[Cmd.spacecraft-1]); strcat(filename, name); strcat(filename, ZExtension); if (LZOPEN(filename)) Compress = TRUE; } if (!datunit) { ndays = (kyr % 4 == 0) ? LEAP_YEAR_DAYS : YEAR_DAYS; if (ndays == YEAR_DAYS) sprintf(name, "T%0d%.4d.", kyr, doy_to_md (kdoy)); else sprintf(name, "T%0d%.4d.", kyr, leap_doy_to_md (kdoy)); strcpy(filename, Data_Path[Cmd.spacecraft-1]); strcat(filename, name); strcat(filename, Extension); datunit = fopen(filename, "rb"); } if (!datunit) { strcpy(filename, Data_Path[Cmd.spacecraft-1]); strcat(filename, name); strcat(filename, ZExtension); if (LZOPEN(filename)) Compress = TRUE; } kdoy++; if (datunit) break; if (kdoy > ndays) { kdoy = 1; kyr++; } if ((kyr >= lyr) && (kdoy > ldoy)) return(FALSE); } tyme = 0.0; kyear = kyr-65; kleap = kyear/4; kountwait = 0; /* find first physical record */ if (datunit) { while (tyme < tbeg) { cd_read(cd, sizeof(cd_type), 64, datunit); index = 63; while ((cd[index].org.ef.time == 0.0) && (cd[index].org.ef.mfds == 0)) index -=1; if (index < 0) error(4); if (cd[index].ef) tyme = cd[index].org.ef.time; else tyme = (double) ((float) cd[index].org.cd.millisec / 1000 + (float) cd[index].org.cd.second) + (double) ((float)(cd[index].org.cd.hour -24) * HOUR_SEC + (double) (kleap * DAY_SEC)) + (double) ((double) kyear * YEAR_DAYS * DAY_SEC); } /* find logical record */ tyme = 0.0; index = 0; while (tyme < tbeg) { if (cd[index].ef) tyme = cd[index].org.ef.time; else tyme = (double) ((float) cd[index].org.cd.millisec / 1000 + (float) cd[index].org.cd.second) + (double) ((float)(cd[index].org.cd.hour -24) * HOUR_SEC + (float) (kleap * DAY_SEC)) + (double) (kyear * YEAR_DAYS * DAY_SEC); index += 1; } } else tyme = tend; return(TRUE); } /* ---------------------------------------------------------- cd_read written by R. Baines 2/90 actually do physical read of raw data or pass reading to the compress module to decompress data from a compressed data file. ---------------------------------------------------------- */ void cd_read(void *ptr, size_t size, size_t n, FILE *stream) { const int len = size * n; cd_type buf[64]; if (Compress) LZREAD(&buf, &len); else fread(buf, size, n, stream); memcpy(ptr, buf, len); } /* ---------------------------------------------------------- cd_read_rest written by R. Baines 2/90 read rest of compressed data file to handle any problems that may occur if we leave it unfinished. ---------------------------------------------------------- */ void cd_read_rest(size_t size, size_t n) { const int len = size * n; cd_type buf[64]; while(LZREAD(&buf, &len) == len); } int doy_to_md (int l_doy) { int md; if ((l_doy >= 1) && (l_doy <=31)) md = 100 + l_doy; else if ((l_doy >= 32) && (l_doy <= 59)) md = 200 + (l_doy - 31); else if ((l_doy >= 60) && (l_doy <= 90)) md = 300 + (l_doy - 59); else if ((l_doy >= 91) && (l_doy <= 120)) md = 400 + (l_doy - 90); else if ((l_doy >= 121) && (l_doy <= 151)) md = 500 + (l_doy - 120); else if ((l_doy >= 152) && (l_doy <= 181)) md = 600 + (l_doy - 151); else if ((l_doy >= 182) && (l_doy <= 212)) md = 700 + (l_doy - 181); else if ((l_doy >= 213) && (l_doy <= 243)) md = 800 + (l_doy - 212); else if ((l_doy >= 244) && (l_doy <= 273)) md = 900 + (l_doy - 243); else if ((l_doy >= 274) && (l_doy <= 304)) md = 1000 + (l_doy - 273); else if ((l_doy >= 305) && (l_doy <= 334)) md = 1100 + (l_doy - 304); else if ((l_doy >= 335) && (l_doy <= 365)) md = 1200 + (l_doy - 334); else md = 101; return (md); } int leap_doy_to_md (int l_doy) { int md; if ((l_doy >= 1) && (l_doy <=31)) md = 100 + l_doy; else if ((l_doy >= 32) && (l_doy <= 60)) md = 200 + (l_doy - 31); else if ((l_doy >= 61) && (l_doy <= 91)) md = 300 + (l_doy - 60); else if ((l_doy >= 92) && (l_doy <= 121)) md = 400 + (l_doy - 91); else if ((l_doy >= 122) && (l_doy <= 152)) md = 500 + (l_doy - 121); else if ((l_doy >= 153) && (l_doy <= 182)) md = 600 + (l_doy - 152); else if ((l_doy >= 183) && (l_doy <= 213)) md = 700 + (l_doy - 182); else if ((l_doy >= 214) && (l_doy <= 244)) md = 800 + (l_doy - 213); else if ((l_doy >= 245) && (l_doy <= 274)) md = 900 + (l_doy - 244); else if ((l_doy >= 275) && (l_doy <= 305)) md = 1000 + (l_doy - 274); else if ((l_doy >= 306) && (l_doy <= 335)) md = 1100 + (l_doy - 305); else if ((l_doy >= 336) && (l_doy <= 366)) md = 1200 + (l_doy - 335); else md = 101; return (md); }