int main(int argc, char **argv) { int infile, outfile, bufsize; size_t readbytes, thisread, nread, nwrote; off_t offsetbytes; off_t sook; double offset, length, framens; char msg[512], *buf, *bptr, *outname, *inname, *dotptr; struct mark5_stream *ms; outname = NULL; // m5slice test.m5b Mark5B-512-8-2 <offset> <length> if(argc !=5 ) { usage(argv[0]); return EXIT_FAILURE; } inname = argv[1]; offset = atof(argv[3]); // Seconds length = atof(argv[4]); // Seconds ms = new_mark5_stream_absorb(new_mark5_stream_file(inname, 0), new_mark5_format_generic_from_string(argv[2])); if(!ms) { fprintf(stderr, "Error: problem opening or decoding %s\n", inname); return EXIT_FAILURE; } framens = ms->framens; offsetbytes = (off_t)(ms->frameoffset + offset/framens*1e9*ms->framebytes); readbytes = length/framens*1e9*ms->framebytes; delete_mark5_stream(ms); infile = open(inname, OPENOPTIONS); if (infile==-1) { sprintf(msg, "Failed to open input file (%s) [%d]", inname, errno); perror(msg); return EXIT_FAILURE; } if (offsetbytes>0) { sook = lseek(infile, offsetbytes, SEEK_SET); if (sook==-1 || sook!=offsetbytes) { if (sook==-1) perror("Skiping to offset\n"); else fprintf(stderr, "Could not offset to right place in file\n"); close(infile); free(outname); return EXIT_FAILURE; } } // Create output file name if not set if (outname==NULL) { // File name contained in buffer dotptr = strrchr(inname, '.'); outname = malloc(strlen(inname)+strlen("-slice")+1); if (outname==NULL) { close(infile); free(outname); return EXIT_FAILURE; } if (dotptr==NULL) { sprintf(outname, "%s-slice", inname); } else { *dotptr = 0; ++dotptr; sprintf(outname, "%s-slice.%s", inname, dotptr); } } outfile = creat(outname, S_IRUSR|S_IWUSR|S_IRGRP); if (outfile == -1) { fprintf(stderr, "Error creating output file \"%s\"\n", outname); perror(NULL); close(infile); return(0); } bufsize = BUFSIZE*1024; buf = malloc(bufsize); while (readbytes>0) { if (readbytes>bufsize) thisread = bufsize; else thisread = readbytes; nread = read(infile, buf, thisread); if (nread==0) { printf("EOF detected before full slice read\n"); close(infile); close(outfile); free(buf); free(outname); return EXIT_SUCCESS; } else if (nread==-1) { perror("Error reading file"); close(outfile); close(infile); free(outname); free(buf); return EXIT_FAILURE; } readbytes -= nread; bptr = buf; while (nread>0) { nwrote = write(outfile, bptr, nread); if (nwrote==-1 || nwrote==0) { if (nwrote==-1) perror("Error writing outfile"); else fprintf(stderr, "Error writing outfile"); close(outfile); close(infile); free(buf); free(outname); return EXIT_FAILURE; } nread -= nwrote; } } close(infile); close(outfile); free(outname); return EXIT_SUCCESS; }
static int timeaverage(const char *filename, const char *formatname, double tint, double time, const char *outfile, long long offset) { struct mark5_stream *ms; double **data=0, *avif; double complex **cdata=0; int i, status=0, nused; int nif; uint64_t totalsamples, nint, samplesDone, navg; FILE *out; int docomplex = 0; //total = unpacked = 0; ms = new_mark5_stream(new_mark5_stream_file(filename, offset), new_mark5_format_generic_from_string(formatname)); if(!ms) { printf("Error: problem opening %s\n", filename); return EXIT_FAILURE; } mark5_stream_print(ms); if (ms->complex_decode != 0) { printf("Complex decode\n"); docomplex = 1; } out = fopen(outfile, "w"); if(!out) { fprintf(stderr, "Error: cannot open %s for write\n", outfile); delete_mark5_stream(ms); return EXIT_FAILURE; } //R = nbin*freq/ms->samprate; nif = ms->nchan; totalsamples = (ms->samprate * time); // Total number of samples to process nint = (ms->samprate * tint/1000.0); // Samples per itergration printf("DEBUG: %Ld samples per integration\n", (long long)nint); printf("DEBUG: %Ld total number of samples\n", (long long)totalsamples); if (docomplex) { cdata = (complex double **)malloc(nif*sizeof(double complex*)); for(i = 0; i < nif; i++) { cdata[i] = (complex double *)malloc(ChunkSize*sizeof(complex double)); } } else { data = (double**)malloc(nif*sizeof(double*)); for(i = 0; i < nif; i++) { data[i] = (double *)malloc(ChunkSize*sizeof(double)); } } avif = (double*)calloc(nif,sizeof(double)); if (ms->ns < 0 || ms->ns > 1000000000) { fflush(stdout); fprintf(stderr, "\n***Warning*** The nano-seconds portion of the timestamp is nonsensable: %d; continuing anyway, but don't expect the time alignment to be meaningful.\n\n", ms->ns); } int iInt = 0; samplesDone = 0; navg = 0; nused = -1; while (samplesDone<totalsamples) { if(die) break; if (docomplex) { status = average_complex(ms, &nused, nint, &navg, avif, cdata); } else { status = average_real(ms, &nused, nint, &navg, avif, data); } if (status<0) { break; } if (navg>=nint) { fprintf(out, "%4d %10.6f", iInt, iInt*nint/(double)ms->samprate); iInt++; int i; for(i=0; i<nif; i++) { avif[i] /= navg; fprintf(out, " %1f", avif[i]); avif[i] = 0; } fprintf(out, "\n"); samplesDone += navg; navg = 0; } } fclose(out); for(i = 0; i < nif; i++) { if (docomplex) free(cdata[i]); else free(data[i]); } if (docomplex) free(cdata); else free(data); free(avif); delete_mark5_stream(ms); if(status >= 0) status = EXIT_SUCCESS; return status; }
DataStream *newDataStream(FILE *in) { const int NItem = 7; DataStream *ds; char buffer[NItem][MaxLineLen+1]; int i; char *v; ds = (DataStream *)calloc(1, sizeof(DataStream)); for(i = 0; i < NItem; i++) { v = fgets(buffer[i], MaxLineLen, in); if(!v) { deleteDataStream(ds); return 0; } stripEOL(buffer[i]); } ds->inputFile = strdup(buffer[0]); ds->dataFormat = strdup(buffer[1]); ds->subBand = atoi(buffer[2]); ds->offset = atoll(buffer[3]); ds->fftSize = atoi(buffer[4]); ds->startChan = atoi(buffer[5]); ds->nChan = atoi(buffer[6]); if(ds->startChan < 0 || ds->startChan > ds->fftSize/2 || (ds->nChan > 0 && (ds->startChan + ds->nChan) > ds->fftSize/2) || (ds->nChan < 0 && (ds->startChan + ds->nChan) < -1)) { printf("The start channel must be in 0 .. %d, inclusive, and\n" "the number of channels to keep must be as well:\n" "For file %s\n" "you have %d < 0 or %d > %d with %d channels to keep\n", ds->fftSize/2, ds->inputFile, ds->startChan, ds->startChan, ds->fftSize/2, ds->nChan); deleteDataStream(ds); ds = 0; return 0; } ds->ms = new_mark5_stream_absorb( new_mark5_stream_file(ds->inputFile, ds->offset), new_mark5_format_generic_from_string(ds->dataFormat) ); if(!ds->ms) { printf("problem opening %s\n", ds->inputFile); deleteDataStream(ds); ds = 0; return 0; } mark5_stream_print(ds->ms); ds->data = (double **)calloc(ds->ms->nchan, sizeof(double *)); for(i = 0; i < ds->ms->nchan; i++) { ds->data[i] = (double *)calloc(ds->fftSize+2, sizeof(double)); } ds->zdata = (fftw_complex *)calloc(ds->fftSize/2+2, sizeof(fftw_complex)); ds->spec = (fftw_complex *)calloc(abs(ds->nChan), sizeof(fftw_complex)); ds->plan = fftw_plan_dft_r2c_1d(ds->fftSize, ds->data[ds->subBand], ds->zdata, FFTW_ESTIMATE); ds->deltaF = (double)(ds->ms->samprate)/(double)(ds->fftSize); return ds; }
static int fold(const char *filename, const char *formatname, int nbin, int nint, double freq, const char *outfile, long long offset) { struct mark5_stream *ms; double **data=0, **bins=0; double complex **cdata=0; int **weight; int c, i, j, k, status; int nif, bin; long long total, unpacked; FILE *out; double R; long long sampnum; int docorrection = 1; int docomplex = 0; if(nbin < 0) { nbin = -nbin; docorrection = 0; } total = unpacked = 0; ms = new_mark5_stream( new_mark5_stream_file(filename, offset), new_mark5_format_generic_from_string(formatname) ); if(!ms) { printf("Error: problem opening %s\n", filename); return EXIT_FAILURE; } if(ms->nbit < 2) { fprintf(stderr, "Warning: 1-bit data supplied. Results will be\n"); fprintf(stderr, "useless. Proceeding anyway!\n\n"); } if(ms->nbit > 2) { fprintf(stderr, "More than 2 bits: power not being corrected!\n"); docorrection = 0; } mark5_stream_print(ms); if (ms->complex_decode != 0) { printf("Complex decode\n"); docomplex = 1; } sampnum = (long long)((double)ms->ns*(double)ms->samprate*1.0e-9 + 0.5); out = fopen(outfile, "w"); if(!out) { fprintf(stderr, "Error: cannot open %s for write\n", outfile); delete_mark5_stream(ms); return EXIT_FAILURE; } R = nbin*freq/ms->samprate; nif = ms->nchan; if (!docomplex) { data = (double **)malloc(nif*sizeof(double *)); bins = (double **)malloc(nif*sizeof(double *)); weight = (int **)malloc(nif*sizeof(int *)); for(i = 0; i < nif; i++) { data[i] = (double *)malloc(ChunkSize*sizeof(double)); bins[i] = (double *)calloc(nbin, sizeof(double)); weight[i] = (int *)calloc(nbin, sizeof(int)); } if(ms->ns < 0 || ms->ns > 1000000000) { fflush(stdout); fprintf(stderr, "\n***Warning*** The nano-seconds portion of the timestamp is nonsensable: %d; continuing anyway, but don't expect the time alignment to be meaningful.\n\n", ms->ns); sampnum = 0; } for(j = 0; j < nint; j++) { if(die) { break; } status = mark5_stream_decode_double(ms, ChunkSize, data); if(status < 0) { break; } else { total += ChunkSize; unpacked += status; } if(ms->consecutivefails > 5) { printf("Too many failures. consecutive, total fails = %d %d\n", ms->consecutivefails, ms->nvalidatefail); break; } for(k = 0; k < ChunkSize; k++) { if(data[0][k] != 0.0) { bin = ((long long)(sampnum*R)) % nbin; for(i = 0; i < nif; i++) { bins[i][bin] += data[i][k]*data[i][k]; weight[i][bin]++; } } sampnum++; } } } else { cdata = (complex double **)malloc(nif*sizeof(double complex*)); bins = (double **)malloc(nif*sizeof(double *)); weight = (int **)malloc(nif*sizeof(double *)); for(i = 0; i < nif; i++) { cdata[i] = (complex double *)malloc(ChunkSize*sizeof(complex double)); bins[i] = (double *)calloc(nbin, sizeof(double)); weight[i] = (int *)calloc(nbin, sizeof(int)); } if(ms->ns < 0 || ms->ns > 1000000000) { fflush(stdout); fprintf(stderr, "\n***Warning*** The nano-seconds portion of the timestamp is nonsensable: %d; continuing anyway, but don't expect the time alignment to be meaningful.\n\n", ms->ns); sampnum = 0; } for(j = 0; j < nint; j++) { if(die) { break; } status = mark5_stream_decode_double_complex(ms, ChunkSize, cdata); if(status < 0) { break; } else { total += ChunkSize; unpacked += status; } if(ms->consecutivefails > 5) { printf("Too many failures. consecutive, total fails = %d %d\n", ms->consecutivefails, ms->nvalidatefail); break; } for(k = 0; k < ChunkSize; k++) { if(cdata[0][k] != 0.0) { bin = ((long long)(sampnum*R)) % nbin; for(i = 0; i < nif; i++) { bins[i][bin] += creal(cdata[i][k])*creal(cdata[i][k]) + cimag(cdata[i][k])*cimag(cdata[i][k]); weight[i][bin]++; } } sampnum++; } } } fprintf(stderr, "%lld / %lld samples unpacked\n", unpacked, total); /* normalize */ for(k = 0; k < nbin; k++) { for(i = 0; i < nif; i++) { if(weight[i][k]) { bins[i][k] /= weight[i][k]; } } } /* convert the mean quantized voltage squared to nominal power */ if(docorrection) { for(k = 0; k < nbin; k++) { for(i = 0; i < nif; i++) { bins[i][k] = correct_2bit_power(bins[i][k]); } } } for(c = 0; c < nbin; c++) { fprintf(out, "%11.9f ", c/(freq*nbin)); for(i = 0; i < nif; i++) { fprintf(out, " %f", bins[i][c]); } fprintf(out, "\n"); } fclose(out); for(i = 0; i < nif; i++) { if (docomplex) free(cdata[i]); else free(data[i]); free(bins[i]); free(weight[i]); } if (docomplex) free(cdata); else free(data); free(bins); free(weight); delete_mark5_stream(ms); return EXIT_SUCCESS; }