diff --git a/Makefile.linux b/Makefile.linux index a055656..091453c 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -37,10 +37,19 @@ rfplot: rfplot.o rftime.o rfio.o rftrace.o sgdp4.o satutl.o deep.o ferror.o rftl rffft: rffft.o rffft_internal.o rftime.o $(CC) -o rffft rffft.o rffft_internal.o rftime.o -lfftw3f -lm -lsox -tests/tests: tests/tests.o tests/tests_rffft_internal.o tests/tests_rftles.o rffft_internal.o rftles.o satutl.o ferror.o +tests/tests: tests/tests.o tests/tests_rffft_internal.o tests/tests_rfio.o tests/tests_rftles.o rffft_internal.o rfio.o rftime.o rftles.o satutl.o ferror.o zscale.o $(CC) -Wall -o $@ $^ -lcmocka -lm -tests: tests/tests +tests/random: + dd if=/dev/random of=tests/random bs=12288000 count=4 + +tests/bins: rffft tests/random + mkdir -p tests/bin/ + ./rffft -i tests/random -p tests/bin/ -o t10_n120_32 -f 2250000000 -s 1024 -T 2016-09-28T00:20:00 -t 10 -n 120 + ./rffft -i tests/random -p tests/bin/ -o t15_n90_8 -f 2250000000 -s 1024 -T 2016-09-28T00:20:00 -t 15 -n 90 -b + touch tests/bins + +tests: tests/tests tests/bins ./tests/tests .PHONY: clean install uninstall tests diff --git a/Makefile.osx b/Makefile.osx index f1fde31..cf5ceb1 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -51,10 +51,19 @@ rfplot: rfplot.o rftime.o rfio.o rftrace.o sgdp4.o satutl.o deep.o ferror.o vers rffft: rffft.o rffft_internal.o rftime.o $(CC) -o rffft rffft.o rffft_internal.o rftime.o -lfftw3f -lm -lsox $(LFLAGS) -tests/tests: tests/tests.o tests/tests_rffft_internal.o tests/tests_rftles.o rffft_internal.o rftles.o satutl.o ferror.o +tests/tests: tests/tests.o tests/tests_rffft_internal.o tests/tests_rfio.o tests/tests_rftles.o rffft_internal.o rfio.o rftime.o rftles.o satutl.o ferror.o zscale.o $(CC) -Wall -o $@ $^ -lcmocka -lm -tests: tests/tests +tests/random: + dd if=/dev/random of=tests/random bs=12288000 count=4 + +tests/bins: rffft tests/random + mkdir -p tests/bin/ + ./rffft -i tests/random -p tests/bin/ -o t10_n120_32 -f 2250000000 -s 1024 -T 2016-09-28T00:20:00 -t 10 -n 120 + ./rffft -i tests/random -p tests/bin/ -o t15_n90_8 -f 2250000000 -s 1024 -T 2016-09-28T00:20:00 -t 15 -n 90 -b + touch tests/bins + +tests: tests/tests tests/bins ./tests/tests .PHONY: clean install uninstall tests diff --git a/makefile b/makefile index 36bf046..d2b418b 100644 --- a/makefile +++ b/makefile @@ -40,10 +40,19 @@ rfplot: rfplot.o rftime.o rfio.o rftrace.o sgdp4.o satutl.o deep.o ferror.o vers rffft: rffft.o rffft_internal.o rftime.o $(CC) -o rffft rffft.o rffft_internal.o rftime.o -lfftw3f -lm -lsox -tests/tests: tests/tests.o tests/tests_rffft_internal.o tests/tests_rftles.o rffft_internal.o rftles.o satutl.o ferror.o +tests/tests: tests/tests.o tests/tests_rffft_internal.o tests/tests_rfio.o tests/tests_rftles.o rffft_internal.o rfio.o rftime.o rftles.o satutl.o ferror.o zscale.o $(CC) -Wall -o $@ $^ -lcmocka -lm -tests: tests/tests +tests/random: + dd if=/dev/random of=tests/random bs=12288000 count=4 + +tests/bins: rffft tests/random + mkdir -p tests/bin/ + ./rffft -i tests/random -p tests/bin/ -o t10_n120_32 -f 2250000000 -s 1024 -T 2016-09-28T00:20:00 -t 10 -n 120 + ./rffft -i tests/random -p tests/bin/ -o t15_n90_8 -f 2250000000 -s 1024 -T 2016-09-28T00:20:00 -t 15 -n 90 -b + touch tests/bins + +tests: tests/tests tests/bins ./tests/tests .PHONY: clean install uninstall tests diff --git a/rffit.c b/rffit.c index 30104f5..00a62fa 100644 --- a/rffit.c +++ b/rffit.c @@ -188,7 +188,7 @@ int identify_satellite_from_doppler(tle_array_t *tle_array, double rmsmax) } if (rmsname) { - printf("%05d: %.3f kHz %.6f MHz | %s\n", orb.satno, tle->name, rms, d.ffit/1000.0, tle->name); + printf("%05d: %.3f kHz %.6f MHz | %s\n", orb.satno, rms, d.ffit/1000.0, tle->name); } else { printf("%05d: %.3f kHz %.6f MHz\n", orb.satno, rms, d.ffit/1000.0); } diff --git a/rfio.c b/rfio.c index 3b75583..8496838 100644 --- a/rfio.c +++ b/rfio.c @@ -1,14 +1,174 @@ +#define _XOPEN_SOURCE +#include "rfio.h" +#include "rftime.h" +#include "zscale.h" +#include +#include #include #include #include +#include #include -#include "rftime.h" -#include "rfio.h" -#include "zscale.h" + + +// Get the first and last bin number matching the prefix. There is no +// guarantee that the range is continous and there is no missing bin in +// the range. +int get_bin_range(char *prefix, int *first_bin, int *last_bin) { + DIR *dp; + struct dirent *ep; + + // Both, dirname and basename, don't handle static strings and can modifiy + // their argument. So make a copy and use a pointer to the result. + char dir[256]; + char base[256]; + strncpy(dir, prefix, 256); + strncpy(base, prefix, 256); + char *dir_p = dirname(dir); + char *base_p = strcat(basename(base), "_"); + + dp = opendir(dir); + + if (dp == NULL) { + printf("Unable to open %s directory\n", dir_p); + return -1; + } + + while ((ep = readdir(dp)) != NULL) { + if (strncmp(base_p, ep->d_name, strlen(base_p)) == 0) { + int i = strtol(ep->d_name + strlen(base_p), NULL, 10); + + if ((*first_bin < 0) || (i < *first_bin)) { + *first_bin = i; + } + if ((*last_bin < 0) || (i > *last_bin)) { + *last_bin = i; + } + } + } + + closedir(dp); + + return 0; +} + +// +// If estimated bin == initial_bin, return +// If estimated bin == previous bin, return higher bin (in between) + +int get_bin_from_time(char *prefix, int initial_bin, int previous_bin, + int first_bin, int last_bin, time_t target, + int *number_subints_per_file) { + int status; + char filename[128], header[256], nfd[32]; + FILE *file; + int nch; + double freq; + double samp_rate; + float length; + struct tm mjd_tm = {0}; + time_t mjd; + + sprintf(filename, "%s_%06i.bin", prefix, initial_bin); + + file = fopen(filename, "r"); + + if (file == NULL) { + return -1; + } + + status = fread(header, sizeof(char), 256, file); + + fclose(file); + + status = + sscanf(header, + "HEADER\nUTC_START %s\nFREQ %lf Hz\nBW %lf " + "Hz\nLENGTH %f s\nNCHAN %d\nNSUB %d\n", + nfd, &freq, &samp_rate, &length, &nch, number_subints_per_file); + + strptime(nfd, "%Y-%m-%dT%T", &mjd_tm); + mjd = mktime(&mjd_tm); + + int estimated_bin = + floor(initial_bin + + difftime(target, mjd) / (length * *number_subints_per_file)); + + // Clip to file range + if (estimated_bin < first_bin) { + estimated_bin = first_bin; + } + + if (estimated_bin > last_bin) { + estimated_bin = last_bin; + } + + if (estimated_bin == initial_bin) { + return estimated_bin; + } else if (estimated_bin == previous_bin) { + // Prevent infinite ing poin + // Return higher as the target is in the gap between + return estimated_bin > initial_bin ? estimated_bin : initial_bin; + } + + return get_bin_from_time(prefix, estimated_bin, initial_bin, first_bin, + last_bin, target, number_subints_per_file); +} + +int get_subs_from_datestrings(char *prefix, char *start, char *end, + int *start_bin, int *num_integrations) { + int k, status; + char filename[128], header[256], nfd[32]; + FILE *file; + int number_subints_per_file; + int nch; + double freq; + double samp_rate; + float length; + int first_bin = -1; + int last_bin = -1; + + // Get avaiable file range to constrain search + get_bin_range(prefix, &first_bin, &last_bin); + + if (start != NULL) { + struct tm tm = {0}; + time_t t; + strptime(start, "%Y-%m-%dT%T", &tm); + t = mktime(&tm); + + int s = get_bin_from_time(prefix, first_bin, first_bin, first_bin, last_bin, + t, &number_subints_per_file); + + if (s < 0) { + return -1; + } + + *start_bin = s; + } + + if (end != NULL) { + struct tm tm = {0}; + time_t t; + strptime(end, "%Y-%m-%dT%T", &tm); + t = mktime(&tm); + + int s = get_bin_from_time(prefix, first_bin, first_bin, first_bin, last_bin, + t, &number_subints_per_file); + + if (s < *start_bin) { + return -1; + } + + *num_integrations = (s - *start_bin + 1) * number_subints_per_file; + } + + return 0; +} struct spectrogram read_spectrogram(char *prefix,int isub,int nsub,double f0,double df0,int nbin,double foff) { - int i,j,k,l,flag=0,status,msub,ibin,nadd,nbits=-32; + int i,j,k,l,status,msub,ibin,nadd,nbits=-32; char filename[128],header[256],nfd[32]; FILE *file; struct spectrogram s; @@ -18,11 +178,10 @@ struct spectrogram read_spectrogram(char *prefix,int isub,int nsub,double f0,dou double freq,samp_rate; float length; int nchan,dummy; - float s1,s2; // Open first file to get number of channels sprintf(filename,"%s_%06d.bin",prefix,isub); - + // Open file file=fopen(filename,"r"); if (file==NULL) { @@ -40,17 +199,17 @@ struct spectrogram read_spectrogram(char *prefix,int isub,int nsub,double f0,dou nbits=8; } s.freq+=foff; - + // Close file fclose(file); // Compute plotting channel if (f0>0.0 && df0>0.0) { s.nchan=(int) (df0/s.samp_rate*(float) nch); - + j0=(int) ((f0-0.5*df0-s.freq+0.5*s.samp_rate)*(float) nch/s.samp_rate); j1=(int) ((f0+0.5*df0-s.freq+0.5*s.samp_rate)*(float) nch/s.samp_rate); - + if (j0<0 || j1>nch) { fprintf(stderr,"Requested frequency range out of limits\n"); s.nsub=0; @@ -71,9 +230,9 @@ struct spectrogram read_spectrogram(char *prefix,int isub,int nsub,double f0,dou s.nsub=nsub/nbin; s.msub=msub; s.isub=isub; - + printf("Allocating %.2f MB of memory\n",(4* (float) s.nchan * (float) s.nsub)/(1024 * 1024)); - + // Allocate s.z=(float *) malloc(sizeof(float)*s.nchan*s.nsub); s.zavg=(float *) malloc(sizeof(float)*s.nsub); @@ -128,9 +287,9 @@ struct spectrogram read_spectrogram(char *prefix,int isub,int nsub,double f0,dou } if (status==0) break; - + // Copy - for (j=0;j + struct spectrogram { int nsub,nchan,msub,isub; double *mjd; @@ -9,7 +12,15 @@ struct spectrogram { float zmin,zmax; char nfd0[32]; }; + +int get_bin_range(char *prefix, int *first_bin, int *last_bin); +int get_bin_from_time(char *prefix, int initial_bin, int previous_bin, + int first_bin, int last_bin, time_t target, + int *number_subints_per_file); +int get_subs_from_datestrings(char *prefix, char *start, char *end, + int *start_bin, int *num_integrations); struct spectrogram read_spectrogram(char *prefix,int isub,int nsub,double f0,double df0,int nbin,double foff); void write_spectrogram(struct spectrogram s,char *prefix); void free_spectrogram(struct spectrogram s); -#endif + +#endif // RFIO_H diff --git a/rfplot.c b/rfplot.c index 209e43a..48cbfe7 100644 --- a/rfplot.c +++ b/rfplot.c @@ -82,6 +82,8 @@ int main(int argc,char *argv[]) double foff=0.0,mjdgrid=0.0; int jj0,jj1; int show_names = 0; + char * start_time = NULL; + char * end_time = NULL; // Get site env=getenv("ST_COSPAR"); @@ -106,7 +108,7 @@ int main(int argc,char *argv[]) // Read arguments if (argc>1) { - while ((arg=getopt(argc,argv,"p:f:w:s:l:b:z:hc:C:gm:o:S:W:F:n"))!=-1) { + while ((arg=getopt(argc,argv,"p:f:w:s:l:b:z:hc:C:gm:o:S:W:F:nT:E:"))!=-1) { switch (arg) { case 'p': @@ -180,6 +182,14 @@ int main(int argc,char *argv[]) show_names = 1; break; + case 'T': + start_time = optarg; + break; + + case 'E': + end_time = optarg; + break; + default: usage(); return 0; @@ -190,6 +200,16 @@ int main(int argc,char *argv[]) return 0; } + if (start_time || end_time) { + status = get_subs_from_datestrings(path, start_time, end_time, &isub, &nsub); + + if (status != 0) { + printf("Failed to read files or requested period out of bin range\n"); + + return -1; + } + } + // Read data s=read_spectrogram(path,isub,nsub,f0,df0,nbin,foff); @@ -1043,6 +1063,10 @@ void usage(void) printf("-C Site ID\n"); printf("-c TLE catalog\n"); printf("-F List with frequencies [$ST_DATADIR/data/frequencies.txt]\n"); + printf("-T