long long get_WAPP_info(char *filename, FILE * files[], int numfiles, int numwapps, struct HEADERP **h, struct wappinfo *w) { int ii, wappindex; struct HEADERP *h2; struct wappinfo w2; long long N = 0; // Read the header of the first file with the yacc/lex generated tools // This sets the basic parameters of the conversion *h = head_parse(files[0]); set_wappinfo(*h, w); if (get_hdr_int(*h, "isalfa")) { w->beamnum = wapp_beamnum(filename); if (w->beamnum == -1) { printf("Warning! isalfa = 1, but beamnum is not set!\n"); exit(1); } } // Number of samples in the file w->numsamples = (chkfilelen(files[0], 1) - w->header_size) / w->bytes_per_sample; // This will be the total number of samples to convert N = w->numsamples; // Skip the ASCII and binary header chkfseek(files[0], w->header_size, SEEK_SET); // loop through all the other files and check/prep them for (ii = 1; ii < numfiles; ii++) { // Read the header with the yacc/lex generated tools h2 = head_parse(files[ii]); set_wappinfo(h2, &w2); close_parse(h2); // Number of samples in the file w2.numsamples = (chkfilelen(files[ii], 1) - w2.header_size) / w2.bytes_per_sample; // Skip the ASCII and binary header chkfseek(files[ii], w2.header_size, SEEK_SET); // Do a basic check to see if the files are similar wappindex = ii % numwapps; if (wappindex == 0) { // Same WAPP if (!compare_samewapp_files(ii, w, &w2)) exit(1); N += w2.numsamples; } else { // Different WAPPs if (!compare_diffwapp_files(ii, numwapps, wappindex, w, &w2)) exit(1); } } return N; }
int main(int argc, char *argv[]) { float minval = SMALLNUM, maxval = LARGENUM, inx = 0, iny = 0; int centern, offsetn; int zoomlevel, maxzoom = 0, minzoom, xid, psid; char *rootfilenm, inchar; datapart *lodp; dataview *dv; basicstats *statvals; if (argc == 1) { printf("\nusage: exploredat datafilename\n\n"); exit(0); } printf("\n\n"); printf(" Interactive Data Explorer\n"); printf(" by Scott M. Ransom\n"); printf(" November, 2001\n"); print_help(); { int hassuffix = 0; char *suffix; hassuffix = split_root_suffix(argv[1], &rootfilenm, &suffix); if (hassuffix) { if (strcmp(suffix, "dat") != 0) { printf ("\nInput file ('%s') must be a single PRESTO data file ('.dat')!\n\n", argv[1]); free(suffix); exit(0); } free(suffix); } else { printf("\nInput file ('%s') must be a PRESTO data file ('.dat')!\n\n", argv[1]); exit(0); } } /* Read the info file */ readinf(&idata, rootfilenm); if (idata.object) { printf("Examining %s data from '%s'.\n\n", remove_whitespace(idata.object), argv[1]); } else { printf("Examining data from '%s'.\n\n", argv[1]); } #ifdef USEMMAP mmap_file = open(argv[1], O_RDONLY); { int rt; struct stat buf; rt = fstat(mmap_file, &buf); if (rt == -1) { perror("\nError in fstat() in exploredat.c"); printf("\n"); exit(-1); } Ndat = buf.st_size / sizeof(float); } lodp = get_datapart(0, Ndat); #else { int numsamp; datfile = chkfopen(argv[1], "rb"); Ndat = chkfilelen(datfile, sizeof(float)); numsamp = (Ndat > MAXPTS) ? (int) MAXPTS : (int) Ndat; lodp = get_datapart(0, numsamp); } #endif /* Plot the initial data */ centern = 0.5 * INITIALNUMPTS; if (centern > lodp->nn) centern = lodp->nn / 2; zoomlevel = LOGMAXDISPNUM - LOGINITIALNUMPTS; minzoom = LOGMAXDISPNUM - LOGMAXPTS; maxzoom = LOGMAXDISPNUM - LOGMINDISPNUM; dv = get_dataview(centern, zoomlevel, lodp); /* Prep the XWIN device for PGPLOT */ xid = cpgopen("/XWIN"); if (xid <= 0) { free_datapart(lodp); #ifdef USEMMAP close(mmap_file); #else fclose(datfile); #endif free(dv); exit(EXIT_FAILURE); } cpgask(0); cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); do { cpgcurs(&inx, &iny, &inchar); if (DEBUGOUT) printf("You pressed '%c'\n", inchar); switch (inchar) { case ' ': /* Toggle stats and sample plotting on/off */ /* 0 = both, 1 = stats only, 2 = data only */ plotstats++; plotstats = plotstats % 3; cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; case 'M': /* Toggle between median and average */ case 'm': usemedian = (usemedian) ? 0 : 1; free(dv); dv = get_dataview(centern, zoomlevel, lodp); cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; case 'A': /* Zoom in */ case 'a': centern = inx + offsetn; case 'I': case 'i': if (DEBUGOUT) printf(" Zooming in (zoomlevel = %d)...\n", zoomlevel); if (zoomlevel < maxzoom) { zoomlevel++; free(dv); dv = get_dataview(centern, zoomlevel, lodp); cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); } else printf(" Already at maximum zoom level (%d).\n", zoomlevel); break; case 'X': /* Zoom out */ case 'x': case 'O': case 'o': if (DEBUGOUT) printf(" Zooming out (zoomlevel = %d)...\n", zoomlevel); if (zoomlevel > minzoom) { zoomlevel--; free(dv); dv = get_dataview(centern, zoomlevel, lodp); cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); } else printf(" Already at minimum zoom level (%d).\n", zoomlevel); break; case '<': /* Shift left 1 full screen */ centern -= dv->numsamps + dv->numsamps / 8; case ',': /* Shift left 1/8 screen */ if (DEBUGOUT) printf(" Shifting left...\n"); centern -= dv->numsamps / 8; { /* Should probably get the previous chunk from the datfile... */ double lowestr; lowestr = 0.5 * dv->numsamps; if (centern < lowestr) centern = lowestr; } free(dv); dv = get_dataview(centern, zoomlevel, lodp); cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; case '>': /* Shift right 1 full screen */ centern += dv->numsamps - dv->numsamps / 8; case '.': /* Shift right 1/8 screen */ centern += dv->numsamps / 8; if (DEBUGOUT) printf(" Shifting right...\n"); { /* Should probably get the next chunk from the datfile... */ double highestr; highestr = lodp->nlo + lodp->nn - 0.5 * dv->numsamps; if (centern > highestr) centern = highestr; } free(dv); dv = get_dataview(centern, zoomlevel, lodp); cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; case '+': /* Increase height of top edge */ { float dy; if (maxval > 0.5 * LARGENUM) { printf(" Auto-scaling of top edge is off.\n"); if (minval < 0.5 * SMALLNUM) dy = dv->maxval - dv->minval; else dy = dv->maxval - minval; maxval = dv->maxval + 0.1 * dy; } else { if (minval < 0.5 * SMALLNUM) dy = maxval - dv->minval; else dy = maxval - minval; maxval += 0.1 * dy; } cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; } case '_': /* Decrease height of top edge */ { float dy; if (maxval > 0.5 * LARGENUM) { printf(" Auto-scaling of top edge is off.\n"); if (minval < 0.5 * SMALLNUM) dy = dv->maxval - dv->minval; else dy = dv->maxval - minval; maxval = dv->maxval - 0.1 * dy; } else { if (minval < 0.5 * SMALLNUM) dy = maxval - dv->minval; else dy = maxval - minval; maxval -= 0.1 * dy; } cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; } case '=': /* Increase height of bottom edge */ { float dy; if (minval < 0.5 * SMALLNUM) { printf(" Auto-scaling of bottom edge is off.\n"); if (maxval > 0.5 * LARGENUM) dy = dv->maxval - dv->minval; else dy = maxval - dv->minval; minval = dv->minval + 0.1 * dy; } else { if (maxval > 0.5 * LARGENUM) dy = dv->maxval - minval; else dy = maxval - minval; minval += 0.1 * dy; } cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; } case '-': /* Decrease height of bottom edge */ { float dy; if (minval < 0.5 * SMALLNUM) { printf(" Auto-scaling of bottom edge is off.\n"); if (maxval > 0.5 * LARGENUM) dy = dv->maxval - dv->minval; else dy = maxval - dv->minval; minval = dv->minval - 0.1 * dy; } else { if (maxval > 0.5 * LARGENUM) dy = dv->maxval - minval; else dy = maxval - minval; minval -= 0.1 * dy; } cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; } case 'S': /* Auto-scale */ case 's': printf(" Auto-scaling is on.\n"); minval = SMALLNUM; maxval = LARGENUM; cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); break; case 'G': /* Goto a time */ case 'g': { char timestr[50]; double time = -1.0; while (time < 0.0) { printf (" Enter the time (s) from the beginning of the file to go to:\n"); fgets(timestr, 50, stdin); timestr[strlen(timestr) - 1] = '\0'; time = atof(timestr); } offsetn = 0.0; centern = (int) (time / idata.dt + 0.5); printf(" Moving to time %.15g (data point %d).\n", time, centern); free(dv); dv = get_dataview(centern, zoomlevel, lodp); cpgpage(); offsetn = plot_dataview(dv, minval, maxval, 1.0); } break; case '?': /* Print help screen */ print_help(); break; case 'P': /* Print the current plot */ case 'p': { int len; char filename[200]; printf(" Enter the filename to save the plot as:\n"); fgets(filename, 195, stdin); len = strlen(filename) - 1; filename[len + 0] = '/'; filename[len + 1] = 'C'; filename[len + 2] = 'P'; filename[len + 3] = 'S'; filename[len + 4] = '\0'; psid = cpgopen(filename); cpgslct(psid); cpgpap(10.25, 8.5 / 11.0); cpgiden(); offsetn = plot_dataview(dv, minval, maxval, 1.0); cpgclos(); cpgslct(xid); filename[len] = '\0'; printf(" Wrote the plot to the file '%s'.\n", filename); } break; case 'V': /* Show the basic statistics for the current dataview */ case 'v': statvals = calc_stats(dv, lodp); printf("\n Statistics:\n" " Low sample %d\n" " Number of samples %d\n" " Low time (s) %.7g\n" " Duration of samples (s) %.7g\n" " Maximum value %.7g\n" " Minimum value %.7g\n" " Average value %.7g\n" " Median value %.7g\n" " Standard Deviation %.7g\n" " Skewness %.7g\n" " Kurtosis %.7g\n\n", dv->lon, dv->numsamps, dv->lon * idata.dt, dv->numsamps * idata.dt, statvals->max, statvals->min, statvals->average, statvals->median, statvals->stdev, statvals->skewness, statvals->kurtosis); free(statvals); break; case 'Q': /* Quit */ case 'q': printf(" Quitting...\n"); free(dv); cpgclos(); break; default: printf(" Unrecognized option '%c'.\n", inchar); break; } } while (inchar != 'Q' && inchar != 'q'); free_datapart(lodp); #ifdef USEMMAP close(mmap_file); #else fclose(datfile); #endif printf("Done\n\n"); return 0; }
void create_accelobs(accelobs * obs, infodata * idata, Cmdline * cmd, int usemmap) { int ii, rootlen, input_shorts = 0; { int hassuffix = 0; char *suffix; hassuffix = split_root_suffix(cmd->argv[0], &(obs->rootfilenm), &suffix); if (hassuffix) { if (strcmp(suffix, "fft") != 0 && strcmp(suffix, "dat") != 0 && strcmp(suffix, "sdat") != 0) { printf("\nInput file ('%s') must be an '.fft' or '.[s]dat' file!\n\n", cmd->argv[0]); free(suffix); exit(0); } /* If the input file is a time series */ if (strcmp(suffix, "dat") == 0 || strcmp(suffix, "sdat") == 0) { obs->dat_input = 1; obs->mmap_file = 0; if (strcmp(suffix, "sdat") == 0) input_shorts = 1; } else { obs->dat_input = 0; } free(suffix); } else { printf("\nInput file ('%s') must be an '.fft' or '.[s]dat' file!\n\n", cmd->argv[0]); exit(0); } } if (cmd->noharmpolishP) obs->use_harmonic_polishing = 0; else obs->use_harmonic_polishing = 1; // now default /* Read the info file */ readinf(idata, obs->rootfilenm); if (idata->object) { printf("Analyzing %s data from '%s'.\n\n", remove_whitespace(idata->object), cmd->argv[0]); } else { printf("Analyzing data from '%s'.\n\n", cmd->argv[0]); } /* Prepare the input time series if required */ if (obs->dat_input) { FILE *datfile; long long filelen; float *ftmp; printf("Reading and FFTing the time series..."); fflush(NULL); datfile = chkfopen(cmd->argv[0], "rb"); /* Check the length of the file to see if we can handle it */ filelen = chkfilelen(datfile, sizeof(float)); if (input_shorts) filelen *= 2; if (filelen > 67108864) { /* Small since we need memory for the templates */ printf("\nThe input time series is too large. Use 'realfft' first.\n\n"); exit(0); } /* Read the time series into a temporary buffer */ /* Note: The padding allows us to search very short time series */ /* using correlations without having to worry about */ /* accessing data before or after the valid FFT freqs. */ if (input_shorts) { short *stmp = gen_svect(filelen); ftmp = gen_fvect(filelen+2*ACCEL_PADDING); for (ii = 0; ii < ACCEL_PADDING; ii++) { ftmp[ii] = 0.0; ftmp[ii+filelen+ACCEL_PADDING] = 0.0; } chkfread(stmp, sizeof(short), filelen, datfile); for (ii = 0; ii < filelen; ii++) ftmp[ii+ACCEL_PADDING] = (float) stmp[ii]; free(stmp); } else { ftmp = read_float_file(datfile, -ACCEL_PADDING, filelen+2*ACCEL_PADDING); } /* Now, offset the pointer so that we are pointing at the first */ /* bits of valid data. */ ftmp += ACCEL_PADDING; fclose(datfile); /* FFT it */ realfft(ftmp, filelen, -1); obs->fftfile = NULL; obs->fft = (fcomplex *) ftmp; obs->numbins = filelen / 2; printf("done.\n"); /* De-redden it */ printf("Removing red-noise..."); deredden(obs->fft, obs->numbins); printf("done.\n\n"); } /* Determine the output filenames */ rootlen = strlen(obs->rootfilenm) + 25; obs->candnm = (char *) calloc(rootlen, 1); obs->accelnm = (char *) calloc(rootlen, 1); obs->workfilenm = (char *) calloc(rootlen, 1); sprintf(obs->candnm, "%s_ACCEL_%d.cand", obs->rootfilenm, cmd->zmax); sprintf(obs->accelnm, "%s_ACCEL_%d", obs->rootfilenm, cmd->zmax); sprintf(obs->workfilenm, "%s_ACCEL_%d.txtcand", obs->rootfilenm, cmd->zmax); /* Open the FFT file if it exists appropriately */ if (!obs->dat_input) { obs->fftfile = chkfopen(cmd->argv[0], "rb"); obs->numbins = chkfilelen(obs->fftfile, sizeof(fcomplex)); if (usemmap) { fclose(obs->fftfile); obs->fftfile = NULL; printf("Memory mapping the input FFT. This may take a while...\n"); obs->mmap_file = open(cmd->argv[0], O_RDONLY); if (obs->mmap_file == -1) { perror("\nError in open() in accel_utils.c"); printf("\n"); exit(-1); } obs->fft = (fcomplex *) mmap(0, sizeof(fcomplex) * obs->numbins, PROT_READ, MAP_SHARED, obs->mmap_file, 0); if (obs->fft == MAP_FAILED) { perror("\nError in mmap() in accel_utils.c"); printf("Falling back to a non-mmaped approach\n"); obs->fftfile = chkfopen(cmd->argv[0], "rb"); obs->mmap_file = 0; } } else { obs->mmap_file = 0; } } /* Determine the other parameters */ if (cmd->zmax % ACCEL_DZ) cmd->zmax = (cmd->zmax / ACCEL_DZ + 1) * ACCEL_DZ; if (!obs->dat_input) obs->workfile = chkfopen(obs->workfilenm, "w"); obs->N = (long long) idata->N; if (cmd->photonP) { if (obs->mmap_file || obs->dat_input) { obs->nph = obs->fft[0].r; } else { obs->nph = get_numphotons(obs->fftfile); } printf("Normalizing powers using %.0f photons.\n\n", obs->nph); } else { obs->nph = 0.0; /* For short FFTs insure that we don't pick up the DC */ /* or Nyquist component as part of the interpolation */ /* for higher frequencies. */ if (cmd->locpowP) { obs->norm_type = 1; printf("Normalizing powers using local-power determination.\n\n"); } else if (cmd->medianP) { obs->norm_type = 0; printf("Normalizing powers using median-blocks.\n\n"); } else { obs->norm_type = 0; printf("Normalizing powers using median-blocks (default).\n\n"); } if (obs->dat_input) { obs->fft[0].r = 1.0; obs->fft[0].i = 1.0; } } obs->lobin = cmd->lobin; if (obs->lobin > 0) { obs->nph = 0.0; if (cmd->lobin > obs->numbins - 1) { printf("\n'lobin' is greater than the total number of\n"); printf(" frequencies in the data set. Exiting.\n\n"); exit(1); } } if (cmd->numharm != 1 && cmd->numharm != 2 && cmd->numharm != 4 && cmd->numharm != 8 && cmd->numharm != 16) { printf("\n'numharm' = %d must be a power-of-two! Exiting\n\n", cmd->numharm); exit(1); } obs->numharmstages = twon_to_index(cmd->numharm) + 1; obs->dz = ACCEL_DZ; obs->numz = cmd->zmax * 2 + 1; obs->numbetween = ACCEL_NUMBETWEEN; obs->dt = idata->dt; obs->T = idata->dt * idata->N; if (cmd->floP) { obs->rlo = floor(cmd->flo * obs->T); if (obs->rlo < obs->lobin) obs->rlo = obs->lobin; if (obs->rlo > obs->numbins - 1) { printf("\nLow frequency to search 'flo' is greater than\n"); printf(" the highest available frequency. Exiting.\n\n"); exit(1); } } else { if (cmd->rloP) obs->rlo = cmd->rlo; else obs->rlo = 1.0; if (obs->rlo < obs->lobin) obs->rlo = obs->lobin; if (obs->rlo > obs->numbins - 1) { printf("\nLow frequency to search 'rlo' is greater than\n"); printf(" the available number of points. Exiting.\n\n"); exit(1); } } obs->highestbin = obs->numbins - 1; if (cmd->fhiP) { obs->highestbin = ceil(cmd->fhi * obs->T); if (obs->highestbin > obs->numbins - 1) obs->highestbin = obs->numbins - 1; obs->rhi = obs->highestbin; if (obs->highestbin < obs->rlo) { printf("\nHigh frequency to search 'fhi' is less than\n"); printf(" the lowest frequency to search 'flo'. Exiting.\n\n"); exit(1); } } else if (cmd->rhiP) { obs->highestbin = cmd->rhi; if (obs->highestbin > obs->numbins - 1) obs->highestbin = obs->numbins - 1; obs->rhi = obs->highestbin; if (obs->highestbin < obs->rlo) { printf("\nHigh frequency to search 'rhi' is less than\n"); printf(" the lowest frequency to search 'rlo'. Exiting.\n\n"); exit(1); } } obs->dr = ACCEL_DR; obs->zhi = cmd->zmax; obs->zlo = -cmd->zmax; obs->sigma = cmd->sigma; obs->powcut = (float *) malloc(obs->numharmstages * sizeof(float)); obs->numindep = (long long *) malloc(obs->numharmstages * sizeof(long long)); for (ii = 0; ii < obs->numharmstages; ii++) { if (obs->numz == 1) obs->numindep[ii] = (obs->rhi - obs->rlo) / index_to_twon(ii); else /* The numz+1 takes care of the small amount of */ /* search we get above zmax and below zmin. */ obs->numindep[ii] = (obs->rhi - obs->rlo) * (obs->numz + 1) * (obs->dz / 6.95) / index_to_twon(ii); obs->powcut[ii] = power_for_sigma(obs->sigma, index_to_twon(ii), obs->numindep[ii]); } obs->numzap = 0; /* if (zapfile!=NULL) obs->numzap = get_birdies(cmd->zapfile, obs->T, obs->baryv, &(obs->lobins), &(obs->hibins)); else obs->numzap = 0; */ }
int main(int argc, char *argv[]) { float *data; int status, isign; unsigned long numdata; /* unsigned long next2ton; */ FILE *datafile, *scratchfile; char datafilenm[100], scratchfilenm[100], resultfilenm[100]; char command[80]; struct tms runtimes; double ttim, stim, utim, tott; tott = times(&runtimes) / (double) CLK_TCK; printf("\n\n"); printf(" Real-Valued Data FFT Program v2.0\n"); printf(" by Scott M. Ransom\n"); printf(" 8 June, 1997\n\n"); if ((argc > 1) && (argc < 7)) { /* Open and check data file. */ if (argc == 3) { sprintf(datafilenm, "%s.", argv[2]); sprintf(scratchfilenm, "%s.tmp", argv[2]); sprintf(resultfilenm, "%s.", argv[2]); } if (argc == 4) { sprintf(datafilenm, "%s/%s.", argv[3], argv[2]); sprintf(scratchfilenm, "%s/%s.tmp", argv[3], argv[2]); sprintf(resultfilenm, "%s/%s.", argv[3], argv[2]); } if (argc == 5) { sprintf(datafilenm, "%s/%s.", argv[3], argv[2]); sprintf(scratchfilenm, "%s/%s.tmp", argv[4], argv[2]); sprintf(resultfilenm, "%s/%s.", argv[3], argv[2]); } isign = atoi(argv[1]); /* Add the appropriate suffix to the filenames. */ if (isign == 1) { strcat(datafilenm, "fft"); strcat(resultfilenm, "dat"); } else { strcat(datafilenm, "dat"); strcat(resultfilenm, "fft"); } /* Check the input data set... */ printf("Checking data in \"%s\".\n", datafilenm); datafile = chkfopen(datafilenm, "rb"); /* # of real data points */ numdata = chkfilelen(datafile, sizeof(float)); /* next2ton = next2_to_n(numdata); */ /* if (numdata != next2ton) { */ /* printf("\nNumber of data pts must be an integer power of two,\n"); */ /* printf(" or data must be single precision floats.\n"); */ /* printf("Exiting.\n\n"); */ /* fclose(datafile); */ /* exit(1); */ /* } */ printf("Data OK. There are %ld points.\n\n", numdata); fclose(datafile); } else { printf("\nUsage: realfft sign datafilename [ data path] "); printf("[scratch path]\n\n"); printf(" This program calculates the FFT of a file containing\n"); printf(" a power-of-two number of floats representing\n"); printf(" real numbers. (i.e. a normal time series)\n\n"); printf(" THE INPUT FILE WILL BE OVERWRITTEN.\n\n"); printf(" \"sign\" is the sign of the exponential during the FFT. \n"); printf(" (i.e. -1 is the standard forward transform, 1 is the\n"); printf(" inverse transform times N (the number of floats))\n"); printf(" If both paths are omitted, the data is assumed to be\n"); printf(" located in the working directory, and the scratch space\n"); printf(" if needed will be located there. If only one path is\n"); printf(" given, both input and scratch files will reside there.\n\n"); printf(" Notes:\n"); printf(" - datafilename must not include \".dat\" or \".fft\"\n"); printf(" suffix. It will be added by the program.\n"); printf(" - Do not end paths in \"/\".\n"); printf(" - The scratch file is the same size as the input file.\n"); printf(" - If \"sign\"=1, the file to be transformed should end\n"); printf(" with \".fft\". Otherwise, it should end with\n"); printf(" \".dat\".\n\n"); exit(0); } /* Start the transform sequence */ if (numdata > MAXREALFFT) { /* Perform Two-Pass, Out-of-Core, FFT */ printf("Performing Out-of-Core Two-Pass FFT on data.\n\n"); printf("Result will be stored in the file \"%s\".\n", resultfilenm); /* Initialize files. */ datafile = chkfopen(datafilenm, "rb+"); scratchfile = chkfopen(scratchfilenm, "wb+"); printf("\nTransforming...\n"); /* Call Two-Pass routine */ if (isign == 1) { realfft_scratch_inv(datafile, scratchfile, numdata); } else { realfft_scratch_fwd(datafile, scratchfile, numdata); } fclose(scratchfile); sprintf(command, "rm -f %s\n", scratchfilenm); if ((status = (system(command))) == -1 || status == 127) { perror("\nSystem call (rm) failed"); printf("\n"); exit(1); } printf("Finished.\n\n"); printf("Timing summary:\n"); tott = times(&runtimes) / (double) CLK_TCK - tott; utim = runtimes.tms_utime / (double) CLK_TCK; stim = runtimes.tms_stime / (double) CLK_TCK; ttim = utim + stim; printf("CPU usage: %.3f sec total (%.3f sec user, %.3f sec system)\n", ttim, utim, stim); printf("Total time elapsed: %.3f sec.\n\n", tott); } else { /* Perform standard FFT for real functions */ printf("Performing in-core FFT for real functions on data.\n\n"); printf("FFT will be stored in the file \"%s\".\n\n", resultfilenm); /* Open the data and fft results files. */ datafile = chkfopen(datafilenm, "rb+"); /* Read data from file to data array */ printf("Reading data.\n\n"); data = gen_fvect(numdata); chkfread(data, sizeof(float), (unsigned long) numdata, datafile); chkfileseek(datafile, 0L, sizeof(char), SEEK_SET); /* Start and time the transform */ printf("Transforming...\n"); realfft(data, numdata, isign); printf("Finished.\n\n"); /* Write data from FFT array to file */ printf("Writing FFT data.\n\n"); chkfwrite(data, sizeof(float), (unsigned long) numdata, datafile); vect_free(data); /* Output the timing information */ printf("Timing summary:\n"); tott = times(&runtimes) / (double) CLK_TCK - tott; utim = runtimes.tms_utime / (double) CLK_TCK; stim = runtimes.tms_stime / (double) CLK_TCK; ttim = utim + stim; printf("CPU usage: %.3f sec total (%.3f sec user, %.3f sec system)\n", ttim, utim, stim); printf("Total time elapsed: %.3f sec.\n\n", tott); } sprintf(command, "mv %s %s\n", datafilenm, resultfilenm); if ((status = (system(command))) == -1 || status == 127) { perror("\nSystem call (mv) failed"); printf("\n"); exit(1); } fclose(datafile); /* fftw_print_max_memory_usage(); fftw_check_memory_leaks(); */ exit(0); }
multifile *fopen_multifile(int numfiles, char **filenames, char *mode, long long maxlen) /* Open a multifile for use and return the multifile structure. */ /* 'numfiles' is the number of files in the multifile. */ /* 'filenames' is an array of the names of the component files */ /* 'mode' is the method of opening the file (binary is assumed) */ /* "r" : read only, do not create (truncate) the files */ /* "r+": read+write, do not create (truncate) the files */ /* "w" : read+write, create (truncate) the files */ /* "a" : read+write, create files or open at end of files */ /* 'maxlen' is the maximum length in bytes of each file. This */ /* number is only used if a file is opened fo writing. The */ /* default value is DEFAULT_MAXLEN. If you want to use */ /* the default, simply set 'maxlen' to 0. */ { multifile *mfile; int ii, append = 0; mfile = (multifile *) malloc(sizeof(multifile)); mfile->numfiles = numfiles; mfile->currentfile = 0; mfile->currentpos = 0; mfile->length = 0; mfile->position = 0; if (maxlen > 0) mfile->maxfilelen = maxlen; else mfile->maxfilelen = DEFAULT_MAXLEN; mfile->filelens = (long long *) malloc(numfiles * sizeof(long long)); mfile->filenames = (char **) malloc(numfiles * sizeof(char *)); mfile->fileptrs = (FILE **) malloc(numfiles * sizeof(FILE *)); if (strncmp(mode, "r", 1) == 0) { if (strncmp(mode, "r+", 2) == 0) { strcpy(mfile->mode, "rb+"); } else { strcpy(mfile->mode, "rb"); } } else if (strncmp(mode, "w", 1) == 0) { if (strncmp(mode, "w+", 2) == 0) { strcpy(mfile->mode, "wb+"); } else { strcpy(mfile->mode, "wb"); } } else if (strncmp(mode, "a", 1) == 0) { if (strncmp(mode, "a+", 2) == 0) { strcpy(mfile->mode, "ab+"); } else { strcpy(mfile->mode, "ab"); } append = 1; } else { printf("\n'mode' = '%s' in open_multifile() is not valid.\n\n", mode); return NULL; } for (ii = 0; ii < numfiles; ii++) { mfile->filenames[ii] = (char *) calloc(strlen(filenames[ii]) + 1, 1); strcpy(mfile->filenames[ii], filenames[ii]); mfile->fileptrs[ii] = chkfopen(filenames[ii], mfile->mode); mfile->filelens[ii] = chkfilelen(mfile->fileptrs[ii], 1); mfile->length += mfile->filelens[ii]; } if (append) { mfile->currentfile = numfiles - 1; chkfileseek(mfile->fileptrs[mfile->currentfile], 0, 1, SEEK_END); } return mfile; }
int main(int argc, char *argv[]) /* dftfold: Does complex plane vector addition of a DFT freq */ /* Written by Scott Ransom on 31 Aug 00 based on Ransom and */ /* Eikenberry paper I (to be completed sometime...). */ { FILE *infile; char infilenm[200], outfilenm[200]; int dataperread; unsigned long N; double T, rr = 0.0, norm = 1.0; dftvector dftvec; infodata idata; Cmdline *cmd; /* Call usage() if we have no command line arguments */ if (argc == 1) { Program = argv[0]; usage(); exit(1); } /* Parse the command line using the excellent program Clig */ cmd = parseCmdline(argc, argv); #ifdef DEBUG showOptionValues(); #endif printf("\n\n"); printf(" DFT Vector Folding Routine\n"); printf(" by Scott M. Ransom\n"); printf(" 31 August, 2000\n\n"); /* Open the datafile and read the info file */ sprintf(infilenm, "%s.dat", cmd->argv[0]); infile = chkfopen(infilenm, "rb"); readinf(&idata, cmd->argv[0]); /* The number of points in datafile */ N = chkfilelen(infile, sizeof(float)); dataperread = N / cmd->numvect; /* N = cmd->numvect * dataperread; */ T = N * idata.dt; /* Calculate the Fourier frequency */ if (!cmd->rrP) { if (cmd->ffP) rr = cmd->ff; else if (cmd->ppP) rr = T / cmd->pp; else { printf("\n You must specify a frequency to fold! Exiting.\n\n"); } } else rr = cmd->rr; /* Calculate the amplitude normalization if required */ if (cmd->normP) norm = 1.0 / sqrt(cmd->norm); else if (cmd->fftnormP) { FILE *fftfile; int kern_half_width, fftdatalen, startbin; double rrfrac, rrint; char fftfilenm[200]; fcomplex *fftdata; sprintf(fftfilenm, "%s.fft", cmd->argv[0]); fftfile = chkfopen(fftfilenm, "rb"); kern_half_width = r_resp_halfwidth(HIGHACC); fftdatalen = 2 * kern_half_width + 10; rrfrac = modf(rr, &rrint); startbin = (int) rrint - fftdatalen / 2; fftdata = read_fcomplex_file(fftfile, startbin, fftdatalen); norm = 1.0 / sqrt(get_localpower3d(fftdata, fftdatalen, rrfrac + fftdatalen / 2, 0.0, 0.0)); vect_free(fftdata); fclose(fftfile); } /* Initialize the dftvector */ init_dftvector(&dftvec, dataperread, cmd->numvect, idata.dt, rr, norm, T); /* Show our folding values */ printf("\nFolding data from '%s':\n", infilenm); printf(" Folding Fourier Freq = %.5f\n", rr); printf(" Folding Freq (Hz) = %-.11f\n", rr / T); printf(" Folding Period (s) = %-.14f\n", T / rr); printf(" Points per sub-vector = %d\n", dftvec.n); printf(" Number of sub-vectors = %d\n", dftvec.numvect); printf(" Normalization constant = %g\n", norm * norm); /* Perform the actual vector addition */ { int ii, jj; float *data; double real, imag, sumreal = 0.0, sumimag = 0.0; double theta, aa, bb, cc, ss, dtmp; double powargr, powargi, phsargr, phsargi, phstmp; data = gen_fvect(dftvec.n); theta = -TWOPI * rr / (double) N; dtmp = sin(0.5 * theta); aa = -2.0 * dtmp * dtmp; bb = sin(theta); cc = 1.0; ss = 0.0; for (ii = 0; ii < dftvec.numvect; ii++) { chkfread(data, sizeof(float), dftvec.n, infile); real = 0.0; imag = 0.0; for (jj = 0; jj < dftvec.n; jj++) { real += data[jj] * cc; imag += data[jj] * ss; cc = aa * (dtmp = cc) - bb * ss + cc; ss = aa * ss + bb * dtmp + ss; } dftvec.vector[ii].r = norm * real; dftvec.vector[ii].i = norm * imag; sumreal += dftvec.vector[ii].r; sumimag += dftvec.vector[ii].i; } vect_free(data); printf("\nDone:\n"); printf(" Vector sum = %.3f + %.3fi\n", sumreal, sumimag); printf(" Total phase (deg) = %.2f\n", PHASE(sumreal, sumimag)); printf(" Total power = %.2f\n", POWER(sumreal, sumimag)); printf("\n"); } fclose(infile); /* Write the output structure */ sprintf(outfilenm, "%s_%.3f.dftvec", cmd->argv[0], rr); write_dftvector(&dftvec, outfilenm); /* Free our vector and return */ free_dftvector(&dftvec); return (0); }
int main(int argc, char *argv[]) { FILE **infiles, *outfile = NULL, *scalingfile; int filenum, argnum = 1, ii = 0, ptsperblock, numlags, numfiles; int bytes_per_read, scaling = 0, numscalings, output = 1; long long N; char *path, *filenm; char outfilenm[200], filenmbase[200], scalingnm[200], rawlags[4096]; unsigned char output_samples[2048]; float *scalings = NULL; double dt, T; SPIGOT_INFO *spigots; sigprocfb fb; infodata idata; if (argc == 1) { fprintf(stderr, "Usage: spigotSband2filterbank [-stdout] SPIGOT_files\n"); exit(0); } if (!strcmp(argv[argnum], "-stdout")) { /* Use STDOUT */ argnum++; output = 0; outfile = stdout; } else { printf ("\nConverting raw SPIGOT S-band FITs data into SIGPROC\n" "filterbank format and throwing out the bottom 200MHz...\n\n"); } /* Attempt to read a file with lag scalings in it */ sprintf(scalingnm, "%s.scaling", filenmbase); if ((scalingfile = fopen(scalingnm, "rb"))) { /* Determine the length of the file */ numscalings = (int) chkfilelen(scalingfile, sizeof(float)); /* Create the array and read 'em */ scalings = gen_fvect(numscalings); chkfread(scalings, sizeof(float), numscalings, scalingfile); scaling = 1; /* close the scaling file */ fclose(scalingfile); if (outfile != stdout) printf("Scaling the lags with the %d values found in '%s'\n\n", numscalings, scalingnm); } /* Read and convert the basic SPIGOT file information */ numfiles = argc - 1; if (outfile == stdout) numfiles--; else printf("Spigot card input file information:\n"); spigots = (SPIGOT_INFO *) malloc(sizeof(SPIGOT_INFO) * numfiles); infiles = (FILE **) malloc(sizeof(FILE *) * numfiles); for (filenum = 0; filenum < numfiles; filenum++, argnum++) { if (outfile != stdout) printf(" '%s'\n", argv[argnum]); infiles[filenum] = chkfopen(argv[argnum], "rb"); read_SPIGOT_header(argv[argnum], spigots + filenum); rewind(infiles[filenum]); } if (outfile != stdout) printf("\n"); /* The following is necessary in order to initialize all the */ /* static variables in spigot.c */ get_SPIGOT_file_info(infiles, spigots, numfiles, 0, 0, &N, &ptsperblock, &numlags, &dt, &T, &idata, output); /* Step through the SPIGOT files */ ii = 0; if (outfile == stdout) argnum = 2; else argnum = 1; for (filenum = 0; filenum < numfiles; filenum++, argnum++) { split_path_file(argv[argnum], &path, &filenm); strncpy(filenmbase, filenm, strlen(filenm) - 5); filenmbase[strlen(filenm) - 5] = '\0'; sprintf(outfilenm, "%s.fil", filenmbase); if (outfile != stdout){ printf("Reading S-band Spigot lags from '%s'\n", argv[argnum]); printf("Writing filterbank spectra to '%s'\n\n", outfilenm); outfile = chkfopen(outfilenm, "wb"); } // Update the filterbank header information for each file spigot2sigprocfb(&(spigots[filenum]), &fb, filenmbase); write_filterbank_header(&fb, outfile); chkfseek(infiles[filenum], spigots[filenum].header_len, SEEK_SET); bytes_per_read = numlags * spigots[filenum].bits_per_lag / 8; /* Loop over the samples in the file */ while (chkfread(rawlags, bytes_per_read, 1, infiles[filenum])) { if (scaling) convert_SPIGOT_point(rawlags, output_samples, SUMIFS, scalings[ii]); else convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 1.0); ii++; /* Invert the band so that the high freqs are first */ /* This is how SIGPROC stores its data. */ { int jj; unsigned char tempzz = 0.0, *loptr, *hiptr; loptr = output_samples + 0; hiptr = output_samples + numlags - 1; for (jj = 0; jj < numlags / 2; jj++, loptr++, hiptr--) { SWAP(*loptr, *hiptr); } } chkfwrite(output_samples, sizeof(unsigned char), fb.nchans, outfile); } fclose(infiles[filenum]); if (outfile != stdout) fclose(outfile); } if (outfile != stdout) fprintf(stderr, "Converted and wrote %d samples.\n\n", ii); if (scaling) vect_free(scalings); free(spigots); free(path); free(filenm); free(infiles); return 0; }
int main(int argc, char *argv[]) { /* Any variable that begins with 't' means topocentric */ /* Any variable that begins with 'b' means barycentric */ FILE **outfiles = NULL; float **outdata; double dtmp, *dms, avgdm = 0.0, dsdt = 0, maxdm; double *dispdt, tlotoa = 0.0, blotoa = 0.0, BW_ddelay = 0.0; double max = -9.9E30, min = 9.9E30, var = 0.0, avg = 0.0; double *btoa = NULL, *ttoa = NULL, avgvoverc = 0.0; char obs[3], ephem[10], rastring[50], decstring[50]; long totnumtowrite, totwrote = 0, padwrote = 0, datawrote = 0; int *idispdt, **offsets; int ii, jj, numadded = 0, numremoved = 0, padding = 0, good_inputs = 1; int numbarypts = 0, numread = 0, numtowrite = 0; int padtowrite = 0, statnum = 0; int numdiffbins = 0, *diffbins = NULL, *diffbinptr = NULL, good_padvals = 0; double local_lodm; char *datafilenm, *outpath, *outfilenm, *hostname; struct spectra_info s; infodata idata; mask obsmask; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myid); #ifdef _OPENMP omp_set_num_threads(1); // Explicitly turn off OpenMP #endif set_using_MPI(); { FILE *hostfile; char tmpname[100]; int retval; hostfile = chkfopen("/etc/hostname", "r"); retval = fscanf(hostfile, "%s\n", tmpname); if (retval==0) { printf("Warning: error reading /etc/hostname on proc %d\n", myid); } hostname = (char *) calloc(strlen(tmpname) + 1, 1); memcpy(hostname, tmpname, strlen(tmpname)); fclose(hostfile); } /* Call usage() if we have no command line arguments */ if (argc == 1) { if (myid == 0) { Program = argv[0]; usage(); } MPI_Finalize(); exit(1); } make_maskbase_struct(); make_spectra_info_struct(); /* Parse the command line using the excellent program Clig */ cmd = parseCmdline(argc, argv); spectra_info_set_defaults(&s); // If we are zeroDMing, make sure that clipping is off. if (cmd->zerodmP) cmd->noclipP = 1; s.clip_sigma = cmd->clip; if (cmd->noclipP) { cmd->clip = 0.0; s.clip_sigma = 0.0; } if (cmd->ifsP) { // 0 = default or summed, 1-4 are possible also s.use_poln = cmd->ifs + 1; } if (!cmd->numoutP) cmd->numout = LONG_MAX; #ifdef DEBUG showOptionValues(); #endif if (myid == 0) { /* Master node only */ printf("\n\n"); printf(" Parallel Pulsar Subband De-dispersion Routine\n"); printf(" by Scott M. Ransom\n\n"); s.filenames = cmd->argv; s.num_files = cmd->argc; s.clip_sigma = cmd->clip; // -1 causes the data to determine if we use weights, scales, & // offsets for PSRFITS or flip the band for any data type where // we can figure that out with the data s.apply_flipband = (cmd->invertP) ? 1 : -1; s.apply_weight = (cmd->noweightsP) ? 0 : -1; s.apply_scale = (cmd->noscalesP) ? 0 : -1; s.apply_offset = (cmd->nooffsetsP) ? 0 : -1; s.remove_zerodm = (cmd->zerodmP) ? 1 : 0; if (RAWDATA) { if (cmd->filterbankP) s.datatype = SIGPROCFB; else if (cmd->psrfitsP) s.datatype = PSRFITS; else if (cmd->pkmbP) s.datatype = SCAMP; else if (cmd->bcpmP) s.datatype = BPP; else if (cmd->wappP) s.datatype = WAPP; else if (cmd->spigotP) s.datatype = SPIGOT; } else { // Attempt to auto-identify the data identify_psrdatatype(&s, 1); if (s.datatype==SIGPROCFB) cmd->filterbankP = 1; else if (s.datatype==PSRFITS) cmd->psrfitsP = 1; else if (s.datatype==SCAMP) cmd->pkmbP = 1; else if (s.datatype==BPP) cmd->bcpmP = 1; else if (s.datatype==WAPP) cmd->wappP = 1; else if (s.datatype==SPIGOT) cmd->spigotP = 1; else if (s.datatype==SUBBAND) insubs = 1; else { printf("\nError: Unable to identify input data files. Please specify type.\n\n"); good_inputs = 0; } } // So far we can only handle PSRFITS, filterbank, and subbands if (s.datatype!=PSRFITS && s.datatype!=SIGPROCFB && s.datatype!=SUBBAND) good_inputs = 0; // For subbanded data if (!RAWDATA) s.files = (FILE **)malloc(sizeof(FILE *) * s.num_files); if (good_inputs && (RAWDATA || insubs)) { char description[40]; psrdatatype_description(description, s.datatype); if (s.num_files > 1) printf("Reading %s data from %d files:\n", description, s.num_files); else printf("Reading %s data from 1 file:\n", description); for (ii = 0; ii < s.num_files; ii++) { printf(" '%s'\n", cmd->argv[ii]); if (insubs) s.files[ii] = chkfopen(s.filenames[ii], "rb"); } printf("\n"); if (RAWDATA) { read_rawdata_files(&s); print_spectra_info_summary(&s); spectra_info_to_inf(&s, &idata); } else { // insubs char *root, *suffix; cmd->nsub = s.num_files; s.N = chkfilelen(s.files[0], sizeof(short)); s.start_subint = gen_ivect(1); s.num_subint = gen_ivect(1); s.start_MJD = (long double *)malloc(sizeof(long double)); s.start_spec = (long long *)malloc(sizeof(long long)); s.num_spec = (long long *)malloc(sizeof(long long)); s.num_pad = (long long *)malloc(sizeof(long long)); s.start_spec[0] = 0L; s.start_subint[0] = 0; s.num_spec[0] = s.N; s.num_subint[0] = s.N / SUBSBLOCKLEN; s.num_pad[0] = 0L; s.padvals = gen_fvect(s.num_files); for (ii = 0 ; ii < ii ; ii++) s.padvals[ii] = 0.0; if (split_root_suffix(s.filenames[0], &root, &suffix) == 0) { printf("\nError: The input filename (%s) must have a suffix!\n\n", s.filenames[0]); exit(1); } if (strncmp(suffix, "sub", 3) == 0) { char *tmpname; tmpname = calloc(strlen(root) + 10, 1); sprintf(tmpname, "%s.sub", root); readinf(&idata, tmpname); free(tmpname); strncpy(s.telescope, idata.telescope, 40); strncpy(s.backend, idata.instrument, 40); strncpy(s.observer, idata.observer, 40); strncpy(s.source, idata.object, 40); s.ra2000 = hms2rad(idata.ra_h, idata.ra_m, idata.ra_s) * RADTODEG; s.dec2000 = dms2rad(idata.dec_d, idata.dec_m, idata.dec_s) * RADTODEG; ra_dec_to_string(s.ra_str, idata.ra_h, idata.ra_m, idata.ra_s); ra_dec_to_string(s.dec_str, idata.dec_d, idata.dec_m, idata.dec_s); s.num_channels = idata.num_chan; s.start_MJD[0] = idata.mjd_i + idata.mjd_f; s.dt = idata.dt; s.T = s.N * s.dt; s.lo_freq = idata.freq; s.df = idata.chan_wid; s.hi_freq = s.lo_freq + (s.num_channels - 1.0) * s.df; s.BW = s.num_channels * s.df; s.fctr = s.lo_freq - 0.5 * s.df + 0.5 * s.BW; s.beam_FWHM = idata.fov / 3600.0; s.spectra_per_subint = SUBSBLOCKLEN; print_spectra_info_summary(&s); } else { printf("\nThe input files (%s) must be subbands! (i.e. *.sub##)\n\n", cmd->argv[0]); MPI_Finalize(); exit(1); } free(root); free(suffix); } } } // If we don't have good input data, exit MPI_Bcast(&good_inputs, 1, MPI_INT, 0, MPI_COMM_WORLD); if (!good_inputs) { MPI_Finalize(); exit(1); } MPI_Bcast(&insubs, 1, MPI_INT, 0, MPI_COMM_WORLD); if (insubs) cmd->nsub = cmd->argc; /* Determine the output file names and open them */ local_numdms = cmd->numdms / (numprocs - 1); dms = gen_dvect(local_numdms); if (cmd->numdms % (numprocs - 1)) { if (myid == 0) printf ("\nThe number of DMs must be divisible by (the number of processors - 1).\n\n"); MPI_Finalize(); exit(1); } local_lodm = cmd->lodm + (myid - 1) * local_numdms * cmd->dmstep; split_path_file(cmd->outfile, &outpath, &outfilenm); datafilenm = (char *) calloc(strlen(outfilenm) + 20, 1); if (myid > 0) { if (chdir(outpath) == -1) { printf("\nProcess %d on %s cannot chdir() to '%s'. Exiting.\n\n", myid, hostname, outpath); MPI_Finalize(); exit(1); } outfiles = (FILE **) malloc(local_numdms * sizeof(FILE *)); for (ii = 0; ii < local_numdms; ii++) { dms[ii] = local_lodm + ii * cmd->dmstep; avgdm += dms[ii]; sprintf(datafilenm, "%s_DM%.2f.dat", outfilenm, dms[ii]); outfiles[ii] = chkfopen(datafilenm, "wb"); } avgdm /= local_numdms; } // Broadcast the raw data information broadcast_spectra_info(&s, myid); if (myid > 0) { spectra_info_to_inf(&s, &idata); if (s.datatype==SIGPROCFB) cmd->filterbankP = 1; else if (s.datatype==PSRFITS) cmd->psrfitsP = 1; else if (s.datatype==SCAMP) cmd->pkmbP = 1; else if (s.datatype==BPP) cmd->bcpmP = 1; else if (s.datatype==WAPP) cmd->wappP = 1; else if (s.datatype==SPIGOT) cmd->spigotP = 1; else if (s.datatype==SUBBAND) insubs = 1; } s.filenames = cmd->argv; /* Read an input mask if wanted */ if (myid > 0) { int numpad = s.num_channels; if (insubs) numpad = s.num_files; s.padvals = gen_fvect(numpad); for (ii = 0 ; ii < numpad ; ii++) s.padvals[ii] = 0.0; } if (cmd->maskfileP) { if (myid == 0) { read_mask(cmd->maskfile, &obsmask); printf("Read mask information from '%s'\n\n", cmd->maskfile); good_padvals = determine_padvals(cmd->maskfile, &obsmask, s.padvals); } broadcast_mask(&obsmask, myid); MPI_Bcast(&good_padvals, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(s.padvals, obsmask.numchan, MPI_FLOAT, 0, MPI_COMM_WORLD); } else { obsmask.numchan = obsmask.numint = 0; MPI_Bcast(&good_padvals, 1, MPI_INT, 0, MPI_COMM_WORLD); } // The number of topo to bary time points to generate with TEMPO numbarypts = (int) (s.T * 1.1 / TDT + 5.5) + 1; // Identify the TEMPO observatory code { char *outscope = (char *) calloc(40, sizeof(char)); telescope_to_tempocode(idata.telescope, outscope, obs); free(outscope); } // Broadcast or calculate a few extra important values if (insubs) avgdm = idata.dm; idata.dm = avgdm; dsdt = cmd->downsamp * idata.dt; maxdm = cmd->lodm + cmd->numdms * cmd->dmstep; BW_ddelay = delay_from_dm(maxdm, idata.freq) - delay_from_dm(maxdm, idata.freq + (idata.num_chan-1) * idata.chan_wid); blocksperread = ((int) (BW_ddelay / idata.dt) / s.spectra_per_subint + 1); worklen = s.spectra_per_subint * blocksperread; if (cmd->nsub > s.num_channels) { printf ("Warning: The number of requested subbands (%d) is larger than the number of channels (%d).\n", cmd->nsub, s.num_channels); printf(" Re-setting the number of subbands to %d.\n\n", s.num_channels); cmd->nsub = s.num_channels; } if (s.spectra_per_subint % cmd->downsamp) { if (myid == 0) { printf ("\nError: The downsample factor (%d) must be a factor of the\n", cmd->downsamp); printf(" blocklength (%d). Exiting.\n\n", s.spectra_per_subint); } MPI_Finalize(); exit(1); } tlotoa = idata.mjd_i + idata.mjd_f; /* Topocentric epoch */ if (cmd->numoutP) totnumtowrite = cmd->numout; else totnumtowrite = (long) idata.N / cmd->downsamp; if (cmd->nobaryP) { /* Main loop if we are not barycentering... */ /* Dispersion delays (in bins). The high freq gets no delay */ /* All other delays are positive fractions of bin length (dt) */ dispdt = subband_search_delays(s.num_channels, cmd->nsub, avgdm, idata.freq, idata.chan_wid, 0.0); idispdt = gen_ivect(s.num_channels); for (ii = 0; ii < s.num_channels; ii++) idispdt[ii] = NEAREST_LONG(dispdt[ii] / idata.dt); vect_free(dispdt); /* The subband dispersion delays (see note above) */ offsets = gen_imatrix(local_numdms, cmd->nsub); for (ii = 0; ii < local_numdms; ii++) { double *subdispdt; subdispdt = subband_delays(s.num_channels, cmd->nsub, dms[ii], idata.freq, idata.chan_wid, 0.0); dtmp = subdispdt[cmd->nsub - 1]; for (jj = 0; jj < cmd->nsub; jj++) offsets[ii][jj] = NEAREST_LONG((subdispdt[jj] - dtmp) / dsdt); vect_free(subdispdt); } /* Allocate our data array and start getting data */ if (myid == 0) { printf("De-dispersing using %d subbands.\n", cmd->nsub); if (cmd->downsamp > 1) printf("Downsampling by a factor of %d (new dt = %.10g)\n", cmd->downsamp, dsdt); printf("\n"); } /* Print the nodes and the DMs they are handling */ print_dms(hostname, myid, numprocs, local_numdms, dms); outdata = gen_fmatrix(local_numdms, worklen / cmd->downsamp); numread = get_data(outdata, blocksperread, &s, &obsmask, idispdt, offsets, &padding); while (numread == worklen) { numread /= cmd->downsamp; if (myid == 0) print_percent_complete(totwrote, totnumtowrite); /* Write the latest chunk of data, but don't */ /* write more than cmd->numout points. */ numtowrite = numread; if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout) numtowrite = cmd->numout - totwrote; if (myid > 0) { write_data(outfiles, local_numdms, outdata, 0, numtowrite); /* Update the statistics */ if (!padding) { for (ii = 0; ii < numtowrite; ii++) update_stats(statnum + ii, outdata[0][ii], &min, &max, &avg, &var); statnum += numtowrite; } } totwrote += numtowrite; /* Stop if we have written out all the data we need to */ if (cmd->numoutP && (totwrote == cmd->numout)) break; numread = get_data(outdata, blocksperread, &s, &obsmask, idispdt, offsets, &padding); } datawrote = totwrote; } else { /* Main loop if we are barycentering... */ /* What ephemeris will we use? (Default is DE405) */ strcpy(ephem, "DE405"); /* Define the RA and DEC of the observation */ ra_dec_to_string(rastring, idata.ra_h, idata.ra_m, idata.ra_s); ra_dec_to_string(decstring, idata.dec_d, idata.dec_m, idata.dec_s); /* Allocate some arrays */ btoa = gen_dvect(numbarypts); ttoa = gen_dvect(numbarypts); for (ii = 0; ii < numbarypts; ii++) ttoa[ii] = tlotoa + TDT * ii / SECPERDAY; /* Call TEMPO for the barycentering */ if (myid == 0) { double maxvoverc = -1.0, minvoverc = 1.0, *voverc = NULL; printf("\nGenerating barycentric corrections...\n"); voverc = gen_dvect(numbarypts); barycenter(ttoa, btoa, voverc, numbarypts, rastring, decstring, obs, ephem); for (ii = 0; ii < numbarypts; ii++) { if (voverc[ii] > maxvoverc) maxvoverc = voverc[ii]; if (voverc[ii] < minvoverc) minvoverc = voverc[ii]; avgvoverc += voverc[ii]; } avgvoverc /= numbarypts; vect_free(voverc); printf(" Average topocentric velocity (c) = %.7g\n", avgvoverc); printf(" Maximum topocentric velocity (c) = %.7g\n", maxvoverc); printf(" Minimum topocentric velocity (c) = %.7g\n\n", minvoverc); printf("De-dispersing using %d subbands.\n", cmd->nsub); if (cmd->downsamp > 1) { printf(" Downsample = %d\n", cmd->downsamp); printf(" New sample dt = %.10g\n", dsdt); } printf("\n"); } /* Print the nodes and the DMs they are handling */ print_dms(hostname, myid, numprocs, local_numdms, dms); MPI_Bcast(btoa, numbarypts, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Bcast(&avgvoverc, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); blotoa = btoa[0]; /* Dispersion delays (in bins). The high freq gets no delay */ /* All other delays are positive fractions of bin length (dt) */ dispdt = subband_search_delays(s.num_channels, cmd->nsub, avgdm, idata.freq, idata.chan_wid, avgvoverc); idispdt = gen_ivect(s.num_channels); for (ii = 0; ii < s.num_channels; ii++) idispdt[ii] = NEAREST_LONG(dispdt[ii] / idata.dt); vect_free(dispdt); /* The subband dispersion delays (see note above) */ offsets = gen_imatrix(local_numdms, cmd->nsub); for (ii = 0; ii < local_numdms; ii++) { double *subdispdt; subdispdt = subband_delays(s.num_channels, cmd->nsub, dms[ii], idata.freq, idata.chan_wid, avgvoverc); dtmp = subdispdt[cmd->nsub - 1]; for (jj = 0; jj < cmd->nsub; jj++) offsets[ii][jj] = NEAREST_LONG((subdispdt[jj] - dtmp) / dsdt); vect_free(subdispdt); } /* Convert the bary TOAs to differences from the topo TOAs in */ /* units of bin length (dt) rounded to the nearest integer. */ dtmp = (btoa[0] - ttoa[0]); for (ii = 0; ii < numbarypts; ii++) btoa[ii] = ((btoa[ii] - ttoa[ii]) - dtmp) * SECPERDAY / dsdt; /* Find the points where we need to add or remove bins */ { int oldbin = 0, currentbin; double lobin, hibin, calcpt; numdiffbins = abs(NEAREST_LONG(btoa[numbarypts - 1])) + 1; diffbins = gen_ivect(numdiffbins); diffbinptr = diffbins; for (ii = 1; ii < numbarypts; ii++) { currentbin = NEAREST_LONG(btoa[ii]); if (currentbin != oldbin) { if (currentbin > 0) { calcpt = oldbin + 0.5; lobin = (ii - 1) * TDT / dsdt; hibin = ii * TDT / dsdt; } else { calcpt = oldbin - 0.5; lobin = -((ii - 1) * TDT / dsdt); hibin = -(ii * TDT / dsdt); } while (fabs(calcpt) < fabs(btoa[ii])) { /* Negative bin number means remove that bin */ /* Positive bin number means add a bin there */ *diffbinptr = NEAREST_LONG(LININTERP (calcpt, btoa[ii - 1], btoa[ii], lobin, hibin)); diffbinptr++; calcpt = (currentbin > 0) ? calcpt + 1.0 : calcpt - 1.0; } oldbin = currentbin; } } *diffbinptr = cmd->numout; /* Used as a marker */ } diffbinptr = diffbins; /* Now perform the barycentering */ outdata = gen_fmatrix(local_numdms, worklen / cmd->downsamp); numread = get_data(outdata, blocksperread, &s, &obsmask, idispdt, offsets, &padding); while (numread == worklen) { /* Loop to read and write the data */ int numwritten = 0; double block_avg, block_var; numread /= cmd->downsamp; /* Determine the approximate local average */ avg_var(outdata[0], numread, &block_avg, &block_var); if (myid == 0) print_percent_complete(totwrote, totnumtowrite); /* Simply write the data if we don't have to add or */ /* remove any bins from this batch. */ /* OR write the amount of data up to cmd->numout or */ /* the next bin that will be added or removed. */ numtowrite = abs(*diffbinptr) - datawrote; if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout) numtowrite = cmd->numout - totwrote; if (numtowrite > numread) numtowrite = numread; if (myid > 0) { write_data(outfiles, local_numdms, outdata, 0, numtowrite); /* Update the statistics */ if (!padding) { for (ii = 0; ii < numtowrite; ii++) update_stats(statnum + ii, outdata[0][ii], &min, &max, &avg, &var); statnum += numtowrite; } } datawrote += numtowrite; totwrote += numtowrite; numwritten += numtowrite; if ((datawrote == abs(*diffbinptr)) && (numwritten != numread) && (totwrote < cmd->numout)) { /* Add/remove a bin */ int skip, nextdiffbin; skip = numtowrite; /* Write the rest of the data after adding/removing a bin */ do { if (*diffbinptr > 0) { /* Add a bin */ if (myid > 0) write_padding(outfiles, local_numdms, block_avg, 1); numadded++; totwrote++; } else { /* Remove a bin */ numremoved++; datawrote++; numwritten++; skip++; } diffbinptr++; /* Write the part after the diffbin */ numtowrite = numread - numwritten; if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout) numtowrite = cmd->numout - totwrote; nextdiffbin = abs(*diffbinptr) - datawrote; if (numtowrite > nextdiffbin) numtowrite = nextdiffbin; if (myid > 0) { write_data(outfiles, local_numdms, outdata, skip, numtowrite); /* Update the statistics and counters */ if (!padding) { for (ii = 0; ii < numtowrite; ii++) update_stats(statnum + ii, outdata[0][skip + ii], &min, &max, &avg, &var); statnum += numtowrite; } } numwritten += numtowrite; datawrote += numtowrite; totwrote += numtowrite; skip += numtowrite; /* Stop if we have written out all the data we need to */ if (cmd->numoutP && (totwrote == cmd->numout)) break; } while (numwritten < numread); } /* Stop if we have written out all the data we need to */ if (cmd->numoutP && (totwrote == cmd->numout)) break; numread = get_data(outdata, blocksperread, &s, &obsmask, idispdt, offsets, &padding); } } if (myid > 0) { /* Calculate the amount of padding we need */ if (cmd->numoutP && (cmd->numout > totwrote)) padwrote = padtowrite = cmd->numout - totwrote; /* Write the new info file for the output data */ idata.dt = dsdt; update_infodata(&idata, totwrote, padtowrite, diffbins, numdiffbins, cmd->downsamp); for (ii = 0; ii < local_numdms; ii++) { idata.dm = dms[ii]; if (!cmd->nobaryP) { double baryepoch, barydispdt, baryhifreq; baryhifreq = idata.freq + (s.num_channels - 1) * idata.chan_wid; barydispdt = delay_from_dm(dms[ii], doppler(baryhifreq, avgvoverc)); baryepoch = blotoa - (barydispdt / SECPERDAY); idata.bary = 1; idata.mjd_i = (int) floor(baryepoch); idata.mjd_f = baryepoch - idata.mjd_i; } sprintf(idata.name, "%s_DM%.2f", outfilenm, dms[ii]); writeinf(&idata); } /* Set the padded points equal to the average data point */ if (idata.numonoff >= 1) { int index, startpad, endpad; for (ii = 0; ii < local_numdms; ii++) { fclose(outfiles[ii]); sprintf(datafilenm, "%s_DM%.2f.dat", outfilenm, dms[ii]); outfiles[ii] = chkfopen(datafilenm, "rb+"); } for (ii = 0; ii < idata.numonoff; ii++) { index = 2 * ii; startpad = idata.onoff[index + 1]; if (ii == idata.numonoff - 1) endpad = idata.N - 1; else endpad = idata.onoff[index + 2]; for (jj = 0; jj < local_numdms; jj++) chkfseek(outfiles[jj], (startpad + 1) * sizeof(float), SEEK_SET); padtowrite = endpad - startpad; write_padding(outfiles, local_numdms, avg, padtowrite); } } } /* Print simple stats and results */ var /= (datawrote - 1); if (myid == 0) print_percent_complete(1, 1); if (myid == 1) { printf("\n\nDone.\n\nSimple statistics of the output data:\n"); printf(" Data points written: %ld\n", totwrote); if (padwrote) printf(" Padding points written: %ld\n", padwrote); if (!cmd->nobaryP) { if (numadded) printf(" Bins added for barycentering: %d\n", numadded); if (numremoved) printf(" Bins removed for barycentering: %d\n", numremoved); } printf(" Maximum value of data: %.2f\n", max); printf(" Minimum value of data: %.2f\n", min); printf(" Data average value: %.2f\n", avg); printf(" Data standard deviation: %.2f\n", sqrt(var)); printf("\n"); } /* Close the files and cleanup */ if (cmd->maskfileP) free_mask(obsmask); if (myid > 0) { for (ii = 0; ii < local_numdms; ii++) fclose(outfiles[ii]); free(outfiles); } vect_free(outdata[0]); vect_free(outdata); vect_free(dms); free(hostname); vect_free(idispdt); vect_free(offsets[0]); vect_free(offsets); free(datafilenm); free(outfilenm); free(outpath); if (!cmd->nobaryP) { vect_free(btoa); vect_free(ttoa); vect_free(diffbins); } MPI_Finalize(); return (0); }
void get_BPP_file_info(FILE * files[], int numfiles, float clipsig, long long *N, int *ptsperblock, int *numchan, double *dt, double *T, infodata * idata, int output) /* Read basic information into static variables and make padding */ /* calculations for a set of BPP rawfiles that you want to patch */ /* together. N, numchan, dt, and T are return values and include all */ /* the files with the required padding. If output is true, prints */ /* a table showing a summary of the values. */ { int ii, newscan = 0; char rawhdr[BPP_HEADER_SIZE]; double last_file_epoch = 0.0; BPP_SEARCH_HEADER *header; if (numfiles > MAXPATCHFILES) { printf("\nThe number of input files (%d) is greater than \n", numfiles); printf(" MAXPATCHFILES=%d. Exiting.\n\n", MAXPATCHFILES); exit(0); } chkfread(rawhdr, BPP_HEADER_SIZE, 1, files[0]); header = (BPP_SEARCH_HEADER *) rawhdr; calc_BPP_chans(header); BPP_hdr_to_inf(header, &idata_st[0]); BPP_hdr_to_inf(header, idata); /* Are we going to clip the data? */ if (clipsig > 0.0) clip_sigma_st = clipsig; *numchan = numchan_st = idata_st[0].num_chan; *ptsperblock = ptsperblk_st; if (both_IFs_present) { printf(" (Note: Both IFs are present.)\n"); numifs_st = 2; } else numifs_st = 1; /* The following is the number of bytes in the _raw_ data */ bytesperpt_st = (numchan_st * numifs_st * 4) / 8; bytesperblk_st = ptsperblk_st * bytesperpt_st; filedatalen_st[0] = chkfilelen(files[0], 1) - BPP_HEADER_SIZE; numblks_st[0] = filedatalen_st[0] / bytesperblk_st; splitbytes_st[0] = filedatalen_st[0] % bytesperblk_st; if (splitbytes_st[0]) { splitbytes_st[0] = bytesperblk_st - filedatalen_st[0] % bytesperblk_st; if (numfiles > 1) { printf (" File %2d has a non-integer number of complete blocks and/or samples!\n" "\tApplying work-around. (bytes split = %d)\n", 1, splitbytes_st[0]); numblks_st[0]++; /* This makes a memory leak as it is never freed (although the OS */ /* does free it when the program exits -- which is usually when */ /* we want it freed anyways...) */ splitbytes_buffer[0] = (unsigned char *) malloc(splitbytes_st[0]); } } numpts_st[0] = numblks_st[0] * ptsperblk_st; N_st = numpts_st[0]; dt_st = *dt = idata_st[0].dt; times_st[0] = numpts_st[0] * dt_st; mjds_st[0] = idata_st[0].mjd_i + idata_st[0].mjd_f; last_file_epoch = mjds_st[0]; elapsed_st[0] = 0.0; startblk_st[0] = 1; endblk_st[0] = (double) numpts_st[0] / ptsperblk_st; padpts_st[0] = padpts_st[numfiles - 1] = 0; for (ii = 1; ii < numfiles; ii++) { chkfread(rawhdr, BPP_HEADER_SIZE, 1, files[ii]); header = (BPP_SEARCH_HEADER *) rawhdr; calc_BPP_chans(header); BPP_hdr_to_inf(header, &idata_st[ii]); if (idata_st[ii].num_chan != numchan_st) { printf("Number of channels (file %d) is not the same!\n\n", ii + 1); } if (idata_st[ii].dt != dt_st) { printf("Sample time (file %d) is not the same!\n\n", ii + 1); } /* If the MJDs are equal, then this is a continuation */ /* of the same scan. In that case, calculate the _real_ */ /* duration of the previous file and add it to the */ /* previous files MJD to get the current MJD. */ mjds_st[ii] = idata_st[ii].mjd_i + idata_st[ii].mjd_f; if (fabs(mjds_st[ii] - last_file_epoch) * SECPERDAY > 1.0e-5) newscan = 1; else newscan = 0; last_file_epoch = mjds_st[ii]; filedatalen_st[ii] = chkfilelen(files[ii], 1) - BPP_HEADER_SIZE; if (splitbytes_st[ii - 1]) { if (newscan) { /* Fill the buffer with padding */ //memset(splitbytes_buffer[ii - 1], (padval << 4) + padval, memset(splitbytes_buffer[ii - 1], (8 << 4) + 8, splitbytes_st[ii - 1]); } else { /* Fill the buffer with the data from the missing block part */ chkfread(splitbytes_buffer[ii - 1], splitbytes_st[ii - 1], 1, files[ii]); filedatalen_st[ii] -= splitbytes_st[ii - 1]; } } numblks_st[ii] = filedatalen_st[ii] / bytesperblk_st; splitbytes_st[ii] = filedatalen_st[ii] % bytesperblk_st; if (splitbytes_st[ii]) { splitbytes_st[ii] = bytesperblk_st - filedatalen_st[ii] % bytesperblk_st; printf (" File %2d has a non-integer number of complete blocks and/or samples!\n" "\tApplying work-around. (bytes split = %d)\n", ii + 1, splitbytes_st[ii]); if (numfiles > ii + 1) { numblks_st[ii]++; /* This makes a memory leak as it is never freed (although the OS */ /* does free it when the program exits -- which is usually when */ /* we want it freed anyways...) */ splitbytes_buffer[ii] = (unsigned char *) malloc(splitbytes_st[ii]); } } numpts_st[ii] = numblks_st[ii] * ptsperblk_st; times_st[ii] = numpts_st[ii] * dt_st; if (newscan) { elapsed_st[ii] = mjd_sec_diff(idata_st[ii].mjd_i, idata_st[ii].mjd_f, idata_st[ii - 1].mjd_i, idata_st[ii - 1].mjd_f); } else { elapsed_st[ii] = times_st[ii - 1]; idata_st[ii].mjd_f = idata_st[ii - 1].mjd_f + elapsed_st[ii] / SECPERDAY; idata_st[ii].mjd_i = idata_st[ii - 1].mjd_i; if (idata_st[ii].mjd_f >= 1.0) { idata_st[ii].mjd_f -= 1.0; idata_st[ii].mjd_i++; } mjds_st[ii] = idata_st[ii].mjd_i + idata_st[ii].mjd_f; } padpts_st[ii - 1] = (long long) ((elapsed_st[ii] - times_st[ii - 1]) / dt_st + 0.5); elapsed_st[ii] += elapsed_st[ii - 1]; N_st += numpts_st[ii] + padpts_st[ii - 1]; startblk_st[ii] = (double) (N_st - numpts_st[ii]) / ptsperblk_st + 1; endblk_st[ii] = (double) (N_st) / ptsperblk_st; } padpts_st[numfiles - 1] = ((long long) ceil(endblk_st[numfiles - 1]) * ptsperblk_st - N_st); N_st += padpts_st[numfiles - 1]; *N = N_st; *T = T_st = N_st * dt_st; currentfile = currentblock = 0; #if 0 { double *freq; int *nibble; for (ii = 0; ii < 96; ii++) { gen_channel_mapping(header, &nibble, &freq, NULL); chan_index2[ii] = nibble[ii]; chan_freqs2[ii] = freq[ii] / 1000000.0; } for (ii = 0; ii < numchan_st; ii++) { printf("%3d %3d %3d %10.3f %3d %10.3f\n", ii, chan_mapping[ii], chan_index[ii], chan_freqs[chan_index[ii]], chan_index2[ii], chan_freqs2[ii]); } } #endif if (output) { printf(" Number of files = %d\n", numfiles); printf(" Points/block = %d\n", ptsperblk_st); printf(" Num of channels = %d\n", numchan_st); printf(" Total points (N) = %lld\n", N_st); printf(" Sample time (dt) = %-14.14g\n", dt_st); printf(" Total time (s) = %-14.14g\n\n", T_st); printf ("File Start Block Last Block Points Elapsed (s) Time (s) MJD Padding\n"); printf ("---- ------------ ------------ ---------- -------------- -------------- ------------------ ----------\n"); for (ii = 0; ii < numfiles; ii++) printf ("%2d %12.11g %12.11g %10lld %14.13g %14.13g %17.12f %10lld\n", ii + 1, startblk_st[ii], endblk_st[ii], numpts_st[ii], elapsed_st[ii], times_st[ii], mjds_st[ii], padpts_st[ii]); printf("\n"); } }
int main(int argc, char *argv[]) { FILE *fftfile, *candfile = NULL, *psfile = NULL; char filenm[100], candnm[100], psfilenm[120]; float locpow, norm, powargr, powargi; float *powr, *spreadpow, *minizoompow, *freqs; fcomplex *data, *minifft, *minizoom, *spread; fcomplex *resp, *kernel; double T, dr, ftobinp; int ii, nbins, ncands, candnum, lofreq = 0, nzoom, numsumpow = 1; int numbetween, numkern, kern_half_width; binaryprops binprops; infodata idata; if (argc < 3 || argc > 6) { usage(); exit(1); } printf("\n\n"); printf(" Binary Candidate Display Routine\n"); printf(" by Scott M. Ransom\n\n"); /* Initialize the filenames: */ sprintf(filenm, "%s.fft", argv[1]); sprintf(candnm, "%s_bin.cand", argv[1]); /* Read the info file */ readinf(&idata, argv[1]); if (idata.object) { printf("Plotting a %s candidate from '%s'.\n", idata.object, filenm); } else { printf("Plotting a candidate from '%s'.\n", filenm); } T = idata.N * idata.dt; /* Open the FFT file and get its length */ fftfile = chkfopen(filenm, "rb"); nbins = chkfilelen(fftfile, sizeof(fcomplex)); /* Open the candidate file and get its length */ candfile = chkfopen(candnm, "rb"); ncands = chkfilelen(candfile, sizeof(binaryprops)); /* The candidate number to examine */ candnum = atoi(argv[2]); /* Check that candnum is in range */ if ((candnum < 1) || (candnum > ncands)) { printf("\nThe candidate number is out of range.\n\n"); exit(1); } /* The lowest freq present in the FFT file */ if (argc >= 4) { lofreq = atoi(argv[3]); if ((lofreq < 0) || (lofreq > nbins - 1)) { printf("\n'lofreq' is out of range.\n\n"); exit(1); } } /* Is the original FFT a sum of other FFTs with the amplitudes added */ /* in quadrature? (i.e. an incoherent sum) */ if (argc >= 5) { numsumpow = atoi(argv[4]); if (numsumpow < 1) { printf("\nNumber of summed powers must be at least one.\n\n"); exit(1); } } /* Initialize PGPLOT using Postscript if requested */ if ((argc == 6) && (!strcmp(argv[5], "ps"))) { sprintf(psfilenm, "%s_bin_cand_%d.ps", argv[1], candnum); cpgstart_ps(psfilenm, "landscape"); } else { cpgstart_x("landscape"); } /* Read the binary candidate */ chkfileseek(candfile, (long) (candnum - 1), sizeof(binaryprops), SEEK_SET); chkfread(&binprops, sizeof(binaryprops), 1, candfile); fclose(candfile); /* Output the binary candidate */ print_bin_candidate(&binprops, 2); /* Allocate some memory */ powr = gen_fvect(binprops.nfftbins); minifft = gen_cvect(binprops.nfftbins / 2); spread = gen_cvect(binprops.nfftbins); spreadpow = gen_fvect(binprops.nfftbins); nzoom = 2 * ZOOMFACT * ZOOMNEIGHBORS; minizoom = gen_cvect(nzoom); minizoompow = gen_fvect(nzoom); /* Allocate and initialize our interpolation kernel */ numbetween = 2; kern_half_width = r_resp_halfwidth(LOWACC); numkern = 2 * numbetween * kern_half_width; resp = gen_r_response(0.0, numbetween, numkern); kernel = gen_cvect(binprops.nfftbins); place_complex_kernel(resp, numkern, kernel, binprops.nfftbins); COMPLEXFFT(kernel, binprops.nfftbins, -1); /* Read the data from the FFT file */ data = read_fcomplex_file(fftfile, binprops.lowbin - lofreq, binprops.nfftbins); /* Turn the Fourier amplitudes into powers */ for (ii = 0; ii < binprops.nfftbins; ii++) powr[ii] = POWER(data[ii].r, data[ii].i); /* Chop the powers that are way above the median level */ prune_powers(powr, binprops.nfftbins, numsumpow); /* Perform the minifft */ memcpy((float *) minifft, powr, sizeof(float) * binprops.nfftbins); realfft((float *) minifft, binprops.nfftbins, -1); /* Calculate the normalization constant */ norm = sqrt((double) binprops.nfftbins * (double) numsumpow) / minifft[0].r; locpow = minifft[0].r / binprops.nfftbins; /* Divide the original power spectrum by the local power level */ for (ii = 0; ii < binprops.nfftbins; ii++) powr[ii] /= locpow; /* Now normalize the miniFFT */ minifft[0].r = 1.0; minifft[0].i = 1.0; for (ii = 1; ii < binprops.nfftbins / 2; ii++) { minifft[ii].r *= norm; minifft[ii].i *= norm; } /* Interpolate the minifft and convert to power spectrum */ corr_complex(minifft, binprops.nfftbins / 2, RAW, kernel, binprops.nfftbins, FFT, spread, binprops.nfftbins, kern_half_width, numbetween, kern_half_width, CORR); for (ii = 0; ii < binprops.nfftbins; ii++) spreadpow[ii] = POWER(spread[ii].r, spread[ii].i); /* Plot the initial data set */ freqs = gen_freqs(binprops.nfftbins, binprops.lowbin / T, 1.0 / T); xyline(binprops.nfftbins, freqs, powr, "Pulsar Frequency (hz)", "Power / Local Power", 1); vect_free(freqs); printf("The initial data set (with high power outliers removed):\n\n"); /* Plot the miniFFT */ freqs = gen_freqs(binprops.nfftbins, 0.0, T / (2 * binprops.nfftbins)); xyline(binprops.nfftbins, freqs, spreadpow, "Binary Period (sec)", "Normalized Power", 1); vect_free(freqs); printf("The miniFFT:\n\n"); /* Interpolate and plot the actual candidate peak */ ftobinp = T / binprops.nfftbins; freqs = gen_freqs(nzoom, (binprops.rdetect - ZOOMNEIGHBORS) * ftobinp, ftobinp / (double) ZOOMFACT); for (ii = 0; ii < nzoom; ii++) { dr = -ZOOMNEIGHBORS + (double) ii / ZOOMFACT; rz_interp(minifft, binprops.nfftbins / 2, binprops.rdetect + dr, 0.0, kern_half_width, &minizoom[ii]); minizoompow[ii] = POWER(minizoom[ii].r, minizoom[ii].i); } xyline(nzoom, freqs, minizoompow, "Binary Period (sec)", "Normalized Power", 1); vect_free(freqs); printf("The candidate itself:\n\n"); printf("Done.\n\n"); /* Cleanup */ cpgend(); vect_free(data); vect_free(powr); vect_free(resp); vect_free(kernel); vect_free(minifft); vect_free(spread); vect_free(spreadpow); vect_free(minizoom); vect_free(minizoompow); fclose(fftfile); if ((argc == 6) && (!strcmp(argv[5], "ps"))) { fclose(psfile); } return (0); }
int main(int argc, char *argv[]) { FILE *fftfile; double flook, dt, nph, t, maxz, pwr, hipow = 0.0; double zlo = -30.0, zhi = 30.0, dr, dz = 2.0; double hir = 0.0, hiz = 0.0, newhir, newhiz; fcomplex **ffdotplane, *data; float powargr, powargi; int startbin, numdata, nextbin, nr, nz, numkern; int i, j, realpsr, kernel_half_width, numbetween = 4; int n, corrsize = 1024; char filenm[80], compare[200]; rderivs derivs; fourierprops props; infodata idata; struct tms runtimes; double ttim, utim, stim, tott; tott = times(&runtimes) / (double) CLK_TCK; if (argc != 3) { printf("\nUsage: 'quicklook filename fftfreq dt'\n\n"); printf(" 'filename' = a string containing the FFT file's name.\n"); printf(" (do not include the '.fft' suffix)\n"); printf(" 'fftfreq' = the central fourier frequency to examine.\n"); printf(" Quicklook will search a region of the f-fdot plane\n"); printf(" of a file containing a long, single precision FFT\n"); printf(" using the Correlation method (i.e. Ransom and \n"); printf(" Eikenberry, 1997, unpublished as of yet).\n"); printf(" The search uses a spacing of 0.5 frequency bins in\n"); printf(" the fourier frequency (r) direction, and 2 'bins' in\n"); printf(" the fdot (z) direction. The routine will output\n"); printf(" statistics for the best candidate in the region.\n\n"); printf(" The routine was written as a quick but useful hack\n"); printf(" to show the power of the Correlation method, and the\n"); printf(" forthcoming power of Scott Ransom's Pulsar Finder\n"); printf(" Software.\n"); printf(" 2 March 2001\n\n"); exit(0); } printf("\n\n"); printf(" Quick-Look Pulsation Search\n"); printf(" With database lookup.\n"); printf(" by Scott M. Ransom\n"); printf(" 2 March, 2001\n\n"); /* Initialize our data: */ sprintf(filenm, "%s.fft", argv[1]); readinf(&idata, argv[1]); flook = atof(argv[2]); dt = idata.dt; dr = 1.0 / (double) numbetween; fftfile = chkfopen(filenm, "r"); nph = get_numphotons(fftfile); n = chkfilelen(fftfile, sizeof(float)); t = n * dt; nz = (int) ((zhi - zlo) / dz) + 1; /* Determine our starting frequency and get the data */ maxz = (fabs(zlo) < fabs(zhi)) ? zhi : zlo; kernel_half_width = z_resp_halfwidth(maxz, HIGHACC); numkern = 2 * numbetween * kernel_half_width; while (numkern > 2 * corrsize) corrsize *= 2; startbin = (int) (flook) - corrsize / (2 * numbetween); numdata = corrsize / numbetween; data = read_fcomplex_file(fftfile, startbin, numdata); /* Do the f-fdot plane correlations: */ ffdotplane = corr_rz_plane(data, numdata, numbetween, kernel_half_width, zlo, zhi, nz, corrsize, LOWACC, &nextbin); nr = corrsize - 2 * kernel_half_width * numbetween; /* Search the resulting data set: */ for (i = 0; i < nz; i++) { for (j = 0; j < nr; j++) { pwr = POWER(ffdotplane[i][j].r, ffdotplane[i][j].i); if (pwr > hipow) { hir = j * dr + kernel_half_width; hiz = i * dz + zlo; hipow = pwr; } } } /* Maximize the best candidate: */ hipow = max_rz_arr(data, numdata, hir, hiz, &newhir, &newhiz, &derivs); newhir += startbin; calc_props(derivs, newhir, newhiz, 0.0, &props); printf("Searched %d pts ", nz * nr); printf("(r: %.1f to %.1f, ", (double) startbin + kernel_half_width, (double) startbin + kernel_half_width + dr * (nr - 1)); printf("z: %.1f to %.1f)\n\n", zlo, zhi); printf("Timing summary:\n"); tott = times(&runtimes) / (double) CLK_TCK - tott; utim = runtimes.tms_utime / (double) CLK_TCK; stim = runtimes.tms_stime / (double) CLK_TCK; ttim = utim + stim; printf(" CPU time: %.3f sec (User: %.3f sec, System: %.3f sec)\n", ttim, utim, stim); printf(" Total time: %.3f sec\n\n", tott); printf("The best candidate is:\n"); print_candidate(&props, dt, n, nph, 2); realpsr = comp_psr_to_cand(&props, &idata, compare, 1); printf("%s\n", compare); fclose(fftfile); /* Cleanup and exit */ free(ffdotplane[0]); free(ffdotplane); free(data); exit(0); }
double *read_events(FILE * infile, int bin, int days, int *numevents, double MJD0, double Ttot, double startfrac, double endfrac, double offset) /* This routine reads a set of events from the open file 'infile'. */ /* It returns a double precision vector of events in seconds from the */ /* first event. If 'bin' is true the routine treats the data as */ /* binary double precision (otherwise text). If 'days' is 1 then the */ /* data is assumed to be in days since the 'inf' EPOCH (0 is sec from */ /* EPOCH in 'inf'). If 'days' is 2, the data are assumed to be MJDs. */ /* The number of events read is placed in 'numevents', and the raw */ /* event is placed in 'firstevent'. MJD0 is the time to use for the */ /* reference time. Ttot is the duration of the observation. 'start' */ /* and 'end' are define the fraction of the observation that we are */ /* interested in. 'offset' is a time offset to apply to the events. */ { int N = 0, nn = 0, goodN = 0; double *ts, *goodts, dtmp, lotime, hitime; char line[80], *sptr=NULL; if (bin) { N = chkfilelen(infile, sizeof(double)); } else { /* Read the input file once to count events */ while (1) { sptr = fgets(line, 80, infile); if (!feof(infile) && sptr != NULL && sptr[0] != '\n') { if (line[0] != '#' && sscanf(line, "%lf", &dtmp) == 1) N++; } else { break; } } } /* Allocate the event arrays */ ts = (double *) malloc(N * sizeof(double)); /* Rewind and read the events for real */ rewind(infile); if (bin) { chkfread(ts, sizeof(double), N, infile); } else { while (1) { sptr = fgets(line, 80, infile); if (!feof(infile) && sptr != NULL && sptr[0] != '\n') { if (line[0] != '#' && sscanf(line, "%lf", &ts[nn]) == 1) nn++; } else { break; } } } /* Sort the events */ qsort(ts, N, sizeof(double), compare_doubles); /* If there is no offset specified and the data are non-MJD */ /* days or seconds, then set the offset to be the first event */ if (offset == 0.0 && days < 2) offset = -ts[0]; /* Convert all the events to MJD */ if (days == 0) { /* Events are in seconds since MJD0 */ for (nn = 0; nn < N; nn++) ts[nn] = MJD0 + (ts[nn] + offset) / SECPERDAY; } else if (days == 1) { /* Events are in days since MJD0 */ for (nn = 0; nn < N; nn++) ts[nn] = MJD0 + (ts[nn] + offset); } else if (days == 2 && offset != 0.0) { /* Events are in MJD with an offset */ for (nn = 0; nn < N; nn++) ts[nn] += offset; } /* Count how many events are within our range and only keep them */ lotime = MJD0 + startfrac * Ttot / SECPERDAY; hitime = MJD0 + endfrac * Ttot / SECPERDAY; for (nn = 0; nn < N; nn++) if (ts[nn] >= lotime && ts[nn] < hitime) goodN++; if (goodN != N) { goodts = (double *) malloc(goodN * sizeof(double)); goodN = 0; for (nn = 0; nn < N; nn++) { if (ts[nn] >= lotime && ts[nn] < hitime) { goodts[goodN] = ts[nn]; goodN++; } } free(ts); ts = goodts; N = goodN; } else { goodts = ts; } *numevents = N; /* Convert the events to seconds from MJD0 */ for (nn = 0; nn < N; nn++) goodts[nn] = (goodts[nn] - MJD0) * SECPERDAY; return goodts; }
int main(int argc, char *argv[]) { float maxpow = 0.0, inx = 0.0, iny = 0.0; double centerr, offsetf; int zoomlevel, maxzoom, minzoom, xid, psid; char *rootfilenm, inchar; fftpart *lofp; fftview *fv; if (argc == 1) { printf("\nusage: explorefft fftfilename\n\n"); exit(0); } printf("\n\n"); printf(" Interactive FFT Explorer\n"); printf(" by Scott M. Ransom\n"); printf(" October, 2001\n"); print_help(); { int hassuffix = 0; char *suffix; hassuffix = split_root_suffix(argv[1], &rootfilenm, &suffix); if (hassuffix) { if (strcmp(suffix, "fft") != 0) { printf("\nInput file ('%s') must be a FFT file ('.fft')!\n\n", argv[1]); free(suffix); exit(0); } free(suffix); } else { printf("\nInput file ('%s') must be a FFT file ('.fft')!\n\n", argv[1]); exit(0); } } /* Read the info file */ readinf(&idata, rootfilenm); if (strlen(remove_whitespace(idata.object)) > 0) { printf("Examining %s data from '%s'.\n\n", remove_whitespace(idata.object), argv[1]); } else { printf("Examining data from '%s'.\n\n", argv[1]); } N = idata.N; T = idata.dt * idata.N; #ifdef USEMMAP printf("Memory mapping the input FFT. This may take a while...\n"); mmap_file = open(argv[1], O_RDONLY); { int rt; struct stat buf; rt = fstat(mmap_file, &buf); if (rt == -1) { perror("\nError in fstat() in explorefft.c"); printf("\n"); exit(-1); } Nfft = buf.st_size / sizeof(fcomplex); } lofp = get_fftpart(0, Nfft); #else { int numamps; fftfile = chkfopen(argv[1], "rb"); Nfft = chkfilelen(fftfile, sizeof(fcomplex)); numamps = (Nfft > MAXBINS) ? (int) MAXBINS : (int) Nfft; lofp = get_fftpart(0, numamps); } #endif /* Plot the initial data */ { int initnumbins = INITIALNUMBINS; if (initnumbins > Nfft) { initnumbins = next2_to_n(Nfft) / 2; zoomlevel = LOGDISPLAYNUM - (int) (log(initnumbins) / log(2.0)); minzoom = zoomlevel; } else { zoomlevel = LOGDISPLAYNUM - LOGINITIALNUMBINS; minzoom = LOGDISPLAYNUM - LOGMAXBINS; } maxzoom = LOGDISPLAYNUM - LOGMINBINS; centerr = initnumbins / 2; } fv = get_fftview(centerr, zoomlevel, lofp); /* Prep the XWIN device for PGPLOT */ xid = cpgopen("/XWIN"); if (xid <= 0) { free(fv); #ifdef USEMMAP close(mmap_file); #else fclose(fftfile); #endif free_fftpart(lofp); exit(EXIT_FAILURE); } cpgscr(15, 0.4, 0.4, 0.4); cpgask(0); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); do { cpgcurs(&inx, &iny, &inchar); if (DEBUGOUT) printf("You pressed '%c'\n", inchar); switch (inchar) { case 'A': /* Zoom in */ case 'a': centerr = (inx + offsetf) * T; case 'I': case 'i': if (DEBUGOUT) printf(" Zooming in (zoomlevel = %d)...\n", zoomlevel); if (zoomlevel < maxzoom) { zoomlevel++; free(fv); fv = get_fftview(centerr, zoomlevel, lofp); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); } else printf(" Already at maximum zoom level (%d).\n", zoomlevel); break; case 'X': /* Zoom out */ case 'x': case 'O': case 'o': if (DEBUGOUT) printf(" Zooming out (zoomlevel = %d)...\n", zoomlevel); if (zoomlevel > minzoom) { zoomlevel--; free(fv); fv = get_fftview(centerr, zoomlevel, lofp); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); } else printf(" Already at minimum zoom level (%d).\n", zoomlevel); break; case '<': /* Shift left 1 full screen */ centerr -= fv->numbins + fv->numbins / 8; case ',': /* Shift left 1/8 screen */ if (DEBUGOUT) printf(" Shifting left...\n"); centerr -= fv->numbins / 8; { /* Should probably get the previous chunk from the fftfile... */ double lowestr; lowestr = 0.5 * fv->numbins; if (centerr < lowestr) centerr = lowestr; } free(fv); fv = get_fftview(centerr, zoomlevel, lofp); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); break; case '>': /* Shift right 1 full screen */ centerr += fv->numbins - fv->numbins / 8; case '.': /* Shift right 1/8 screen */ if (DEBUGOUT) printf(" Shifting right...\n"); centerr += fv->numbins / 8; { /* Should probably get the next chunk from the fftfile... */ double highestr; highestr = lofp->rlo + lofp->numamps - 0.5 * fv->numbins; if (centerr > highestr) centerr = highestr; } free(fv); fv = get_fftview(centerr, zoomlevel, lofp); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); break; case '+': /* Increase height of powers */ case '=': if (maxpow == 0.0) { printf(" Auto-scaling is off.\n"); maxpow = 1.1 * fv->maxpow; } maxpow = 3.0 / 4.0 * maxpow; cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); break; case '-': /* Decrease height of powers */ case '_': if (maxpow == 0.0) { printf(" Auto-scaling is off.\n"); maxpow = 1.1 * fv->maxpow; } maxpow = 4.0 / 3.0 * maxpow; cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); break; case 'S': /* Auto-scale */ case 's': if (maxpow == 0.0) break; else { printf(" Auto-scaling is on.\n"); maxpow = 0.0; cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); break; } case 'G': /* Goto a frequency */ case 'g': { char freqstr[50]; double freq = -1.0; while (freq < 0.0) { printf(" Enter the frequency (Hz) to go to:\n"); fgets(freqstr, 50, stdin); freqstr[strlen(freqstr) - 1] = '\0'; freq = atof(freqstr); } offsetf = 0.0; centerr = freq * T; printf(" Moving to frequency %.15g.\n", freq); free(fv); fv = get_fftview(centerr, zoomlevel, lofp); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, centerr, 2); } break; case 'H': /* Show harmonics */ case 'h': { double retval; retval = harmonic_loop(xid, centerr, zoomlevel, lofp); if (retval > 0.0) { offsetf = 0.0; centerr = retval; free(fv); fv = get_fftview(centerr, zoomlevel, lofp); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, centerr, 2); } } break; case '?': /* Print help screen */ print_help(); break; case 'D': /* Show details about a selected point */ case 'd': { double newr; printf(" Searching for peak near freq = %.7g Hz...\n", (inx + offsetf)); newr = find_peak(inx + offsetf, fv, lofp); centerr = newr; free(fv); fv = get_fftview(centerr, zoomlevel, lofp); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, centerr, 2); } break; case 'L': /* Load a zaplist */ case 'l': { int ii, len; char filename[200]; double *lobins, *hibins; printf(" Enter the filename containing the zaplist to load:\n"); fgets(filename, 199, stdin); len = strlen(filename) - 1; filename[len] = '\0'; numzaplist = get_birdies(filename, T, 0.0, &lobins, &hibins); lenzaplist = numzaplist + 20; /* Allow some room to add more */ if (lenzaplist) free(zaplist); zaplist = (bird *) malloc(sizeof(bird) * lenzaplist); for (ii = 0; ii < numzaplist; ii++) { zaplist[ii].lobin = lobins[ii]; zaplist[ii].hibin = hibins[ii]; } vect_free(lobins); vect_free(hibins); printf("\n"); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); } break; case 'Z': /* Add a birdie to a zaplist */ case 'z': { int badchoice = 2; float lox, hix, loy, hiy; double rs[2]; char choice; if (numzaplist + 1 > lenzaplist) { lenzaplist += 10; zaplist = (bird *) realloc(zaplist, sizeof(bird) * lenzaplist); } cpgqwin(&lox, &hix, &loy, &hiy); printf(" Click the left mouse button on the first frequency limit.\n"); while (badchoice) { cpgcurs(&inx, &iny, &choice); if (choice == 'A' || choice == 'a') { rs[2 - badchoice] = ((double) inx + offsetf) * T; cpgsave(); cpgsci(7); cpgmove(inx, 0.0); cpgdraw(inx, hiy); cpgunsa(); badchoice--; if (badchoice == 1) printf (" Click the left mouse button on the second frequency limit.\n"); } else { printf(" Option not recognized.\n"); } }; if (rs[1] > rs[0]) { zaplist[numzaplist].lobin = rs[0]; zaplist[numzaplist].hibin = rs[1]; } else { zaplist[numzaplist].lobin = rs[1]; zaplist[numzaplist].hibin = rs[0]; } printf(" The new birdie has: f_avg = %.15g f_width = %.15g\n\n", 0.5 * (zaplist[numzaplist].hibin + zaplist[numzaplist].lobin) / T, (zaplist[numzaplist].hibin - zaplist[numzaplist].lobin) / T); numzaplist++; qsort(zaplist, numzaplist, sizeof(bird), compare_birds); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); } break; case 'P': /* Print the current plot */ case 'p': { int len; char filename[200]; printf(" Enter the filename to save the plot as:\n"); fgets(filename, 196, stdin); len = strlen(filename) - 1; filename[len + 0] = '/'; filename[len + 1] = 'P'; filename[len + 2] = 'S'; filename[len + 3] = '\0'; psid = cpgopen(filename); cpgslct(psid); cpgpap(10.25, 8.5 / 11.0); cpgiden(); cpgscr(15, 0.8, 0.8, 0.8); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); cpgclos(); cpgslct(xid); cpgscr(15, 0.4, 0.4, 0.4); filename[len] = '\0'; printf(" Wrote the plot to the file '%s'.\n", filename); } break; case 'N': /* Changing power normalization */ case 'n': { float inx2 = 0.0, iny2 = 0.0; char choice; unsigned char badchoice = 1; printf(" Specify the type of power normalization:\n" " m,M : Median values determined locally\n" " d,D : DC frequency amplitude\n" " r,R : Raw powers (i.e. no normalization)\n" " u,U : User specified interval (the average powers)\n"); while (badchoice) { cpgcurs(&inx2, &iny2, &choice); switch (choice) { case 'M': case 'm': norm_const = 0.0; maxpow = 0.0; badchoice = 0; printf (" Using local median normalization. Autoscaling is on.\n"); break; case 'D': case 'd': norm_const = 1.0 / r0; maxpow = 0.0; badchoice = 0; printf (" Using DC frequency (%f) normalization. Autoscaling is on.\n", r0); break; case 'R': case 'r': norm_const = 1.0; maxpow = 0.0; badchoice = 0; printf (" Using raw powers (i.e. no normalization). Autoscaling is on.\n"); break; case 'U': case 'u': { char choice2; float xx = inx, yy = iny; int lor, hir, numr; double avg, var; printf (" Use the left mouse button to select a left and right boundary\n" " of a region to calculate the average power.\n"); do { cpgcurs(&xx, &yy, &choice2); } while (choice2 != 'A' && choice2 != 'a'); lor = (int) ((xx + offsetf) * T); cpgsci(7); cpgmove(xx, 0.0); cpgdraw(xx, 10.0 * fv->maxpow); do { cpgcurs(&xx, &yy, &choice2); } while (choice2 != 'A' && choice2 != 'a'); hir = (int) ((xx + offsetf) * T); cpgmove(xx, 0.0); cpgdraw(xx, 10.0 * fv->maxpow); cpgsci(1); if (lor > hir) { int tempr; tempr = hir; hir = lor; lor = tempr; } numr = hir - lor + 1; avg_var(lofp->rawpowers + lor - lofp->rlo, numr, &avg, &var); printf(" Selection has: average = %.5g\n" " std dev = %.5g\n", avg, sqrt(var)); norm_const = 1.0 / avg; maxpow = 0.0; badchoice = 0; printf (" Using %.5g as the normalization constant. Autoscaling is on.\n", avg); break; } default: printf(" Unrecognized choice '%c'.\n", choice); break; } } free(fv); fv = get_fftview(centerr, zoomlevel, lofp); cpgpage(); offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0); } break; case 'Q': /* Quit */ case 'q': printf(" Quitting...\n"); free(fv); cpgclos(); break; default: printf(" Unrecognized option '%c'.\n", inchar); break; } } while (inchar != 'Q' && inchar != 'q'); free_fftpart(lofp); #ifdef USEMMAP close(mmap_file); #else fclose(fftfile); #endif if (lenzaplist) free(zaplist); printf("Done\n\n"); return 0; }
int main(int argc, char *argv[]) { FILE *fftfile, *candfile; float powargr, powargi, *powers = NULL, *minifft; float norm, numchunks, *powers_pos; int nbins, newncand, nfftsizes, fftlen, halffftlen, binsleft; int numtoread, filepos = 0, loopct = 0, powers_offset, ncand2; int ii, ct, newper = 0, oldper = 0, numsumpow = 1; double T, totnumsearched = 0.0, minsig = 0.0, min_orb_p, max_orb_p; char *rootfilenm, *notes; fcomplex *data = NULL; rawbincand tmplist[MININCANDS], *list; infodata idata; struct tms runtimes; double ttim, utim, stim, tott; Cmdline *cmd; fftwf_plan fftplan; /* Prep the timer */ tott = times(&runtimes) / (double) CLK_TCK; /* Call usage() if we have no command line arguments */ if (argc == 1) { Program = argv[0]; printf("\n"); usage(); exit(1); } /* Parse the command line using the excellent program Clig */ cmd = parseCmdline(argc, argv); #ifdef DEBUG showOptionValues(); #endif printf("\n\n"); printf(" Phase Modulation Pulsar Search Routine\n"); printf(" by Scott M. Ransom\n\n"); { int hassuffix = 0; char *suffix; hassuffix = split_root_suffix(cmd->argv[0], &rootfilenm, &suffix); if (hassuffix) { if (strcmp(suffix, "fft") != 0) { printf("\nInput file ('%s') must be a FFT file ('.fft')!\n\n", cmd->argv[0]); free(suffix); exit(0); } free(suffix); } else { printf("\nInput file ('%s') must be a FFT file ('.fft')!\n\n", cmd->argv[0]); exit(0); } } /* Read the info file */ readinf(&idata, rootfilenm); T = idata.N * idata.dt; if (strlen(remove_whitespace(idata.object)) > 0) { printf("Analyzing '%s' data from '%s'.\n\n", remove_whitespace(idata.object), cmd->argv[0]); } else { printf("Analyzing data from '%s'.\n\n", cmd->argv[0]); } min_orb_p = MINORBP; if (cmd->noaliasP) max_orb_p = T / 2.0; else max_orb_p = T / 1.2; /* open the FFT file and get its length */ fftfile = chkfopen(cmd->argv[0], "rb"); nbins = chkfilelen(fftfile, sizeof(fcomplex)); /* Check that cmd->maxfft is an acceptable power of 2 */ ct = 4; ii = 1; while (ct < MAXREALFFT || ii) { if (ct == cmd->maxfft) ii = 0; ct <<= 1; } if (ii) { printf("\n'maxfft' is out of range or not a power-of-2.\n\n"); exit(1); } /* Check that cmd->minfft is an acceptable power of 2 */ ct = 4; ii = 1; while (ct < MAXREALFFT || ii) { if (ct == cmd->minfft) ii = 0; ct <<= 1; } if (ii) { printf("\n'minfft' is out of range or not a power-of-2.\n\n"); exit(1); } /* Low and high Fourier freqs to check */ if (cmd->floP) { cmd->rlo = floor(cmd->flo * T); if (cmd->rlo < cmd->lobin) cmd->rlo = cmd->lobin; if (cmd->rlo > cmd->lobin + nbins - 1) { printf("\nLow frequency to search 'flo' is greater than\n"); printf(" the highest available frequency. Exiting.\n\n"); exit(1); } } else { cmd->rlo = 1.0; if (cmd->rlo < cmd->lobin) cmd->rlo = cmd->lobin; if (cmd->rlo > cmd->lobin + nbins - 1) { printf("\nLow frequency to search 'rlo' is greater than\n"); printf(" the available number of points. Exiting.\n\n"); exit(1); } } if (cmd->fhiP) { cmd->rhi = ceil(cmd->fhi * T); if (cmd->rhi > cmd->lobin + nbins - 1) cmd->rhi = cmd->lobin + nbins - 1; if (cmd->rhi < cmd->rlo) { printf("\nHigh frequency to search 'fhi' is less than\n"); printf(" the lowest frequency to search 'flo'. Exiting.\n\n"); exit(1); } } else if (cmd->rhiP) { if (cmd->rhi > cmd->lobin + nbins - 1) cmd->rhi = cmd->lobin + nbins - 1; if (cmd->rhi < cmd->rlo) { printf("\nHigh frequency to search 'rhi' is less than\n"); printf(" the lowest frequency to search 'rlo'. Exiting.\n\n"); exit(1); } } /* Determine how many different mini-fft sizes we will use */ nfftsizes = 1; ii = cmd->maxfft; while (ii > cmd->minfft) { ii >>= 1; nfftsizes++; } /* Allocate some memory and prep some variables. */ /* For numtoread, the 6 just lets us read extra data at once */ numtoread = 6 * cmd->maxfft; if (cmd->stack == 0) powers = gen_fvect(numtoread); minifft = (float *) fftwf_malloc(sizeof(float) * (cmd->maxfft * cmd->numbetween + 2)); ncand2 = 2 * cmd->ncand; list = (rawbincand *) malloc(sizeof(rawbincand) * ncand2); for (ii = 0; ii < ncand2; ii++) list[ii].mini_sigma = 0.0; for (ii = 0; ii < MININCANDS; ii++) tmplist[ii].mini_sigma = 0.0; filepos = cmd->rlo - cmd->lobin; numchunks = (float) (cmd->rhi - cmd->rlo) / numtoread; printf("Searching...\n"); printf(" Amount complete = %3d%%", 0); fflush(stdout); /* Prep FFTW */ read_wisdom(); /* Loop through fftfile */ while ((filepos + cmd->lobin) < cmd->rhi) { /* Calculate percentage complete */ newper = (int) (loopct / numchunks * 100.0); if (newper > oldper) { newper = (newper > 99) ? 100 : newper; printf("\r Amount complete = %3d%%", newper); oldper = newper; fflush(stdout); } /* Adjust our search parameters if close to end of zone to search */ binsleft = cmd->rhi - (filepos + cmd->lobin); if (binsleft < cmd->minfft) break; if (binsleft < numtoread) { /* Change numtoread */ numtoread = cmd->maxfft; while (binsleft < numtoread) { cmd->maxfft /= 2; numtoread = cmd->maxfft; } } fftlen = cmd->maxfft; /* Read from fftfile */ if (cmd->stack == 0) { data = read_fcomplex_file(fftfile, filepos, numtoread); for (ii = 0; ii < numtoread; ii++) powers[ii] = POWER(data[ii].r, data[ii].i); numsumpow = 1; } else { powers = read_float_file(fftfile, filepos, numtoread); numsumpow = cmd->stack; } if (filepos == 0) powers[0] = 1.0; /* Chop the powers that are way above the median level */ prune_powers(powers, numtoread, numsumpow); /* Loop through the different small FFT sizes */ while (fftlen >= cmd->minfft) { halffftlen = fftlen / 2; powers_pos = powers; powers_offset = 0; /* Create the appropriate FFT plan */ fftplan = fftwf_plan_dft_r2c_1d(cmd->interbinP ? fftlen : 2 * fftlen, minifft, (fftwf_complex *) minifft, FFTW_PATIENT); /* Perform miniffts at each section of the powers array */ while ((numtoread - powers_offset) > (int) ((1.0 - cmd->overlap) * cmd->maxfft + DBLCORRECT)) { /* Copy the proper amount and portion of powers into minifft */ memcpy(minifft, powers_pos, fftlen * sizeof(float)); /* For Fourier interpolation use a zeropadded FFT */ if (cmd->numbetween > 1 && !cmd->interbinP) { for (ii = fftlen; ii < cmd->numbetween * fftlen; ii++) minifft[ii] = 0.0; } /* Perform the minifft */ fftwf_execute(fftplan); /* Normalize and search the miniFFT */ norm = sqrt(fftlen * numsumpow) / minifft[0]; for (ii = 0; ii < (cmd->interbinP ? fftlen + 1 : 2 * fftlen + 1); ii++) minifft[ii] *= norm; search_minifft((fcomplex *) minifft, halffftlen, min_orb_p, max_orb_p, tmplist, MININCANDS, cmd->harmsum, cmd->numbetween, idata.N, T, (double) (powers_offset + filepos + cmd->lobin), cmd->interbinP ? INTERBIN : INTERPOLATE, cmd->noaliasP ? NO_CHECK_ALIASED : CHECK_ALIASED); /* Check if the new cands should go into the master cand list */ for (ii = 0; ii < MININCANDS; ii++) { if (tmplist[ii].mini_sigma > minsig) { /* Check to see if another candidate with these properties */ /* is already in the list. */ if (not_already_there_rawbin(tmplist[ii], list, ncand2)) { list[ncand2 - 1] = tmplist[ii]; minsig = percolate_rawbincands(list, ncand2); } } else { break; } /* Mini-fft search for loop */ } totnumsearched += fftlen; powers_pos += (int) (cmd->overlap * fftlen); powers_offset = powers_pos - powers; /* Position of mini-fft in data set while loop */ } fftwf_destroy_plan(fftplan); fftlen >>= 1; /* Size of mini-fft while loop */ } if (cmd->stack == 0) vect_free(data); else vect_free(powers); filepos += (numtoread - (int) ((1.0 - cmd->overlap) * cmd->maxfft)); loopct++; /* File position while loop */ } /* Print the final percentage update */ printf("\r Amount complete = %3d%%\n\n", 100); /* Print the number of frequencies searched */ printf("Searched %.0f pts (including interbins).\n\n", totnumsearched); printf("Timing summary:\n"); tott = times(&runtimes) / (double) CLK_TCK - tott; utim = runtimes.tms_utime / (double) CLK_TCK; stim = runtimes.tms_stime / (double) CLK_TCK; ttim = utim + stim; printf(" CPU time: %.3f sec (User: %.3f sec, System: %.3f sec)\n", ttim, utim, stim); printf(" Total time: %.3f sec\n\n", tott); printf("Writing result files and cleaning up.\n"); /* Count how many candidates we actually have */ ii = 0; while (ii < ncand2 && list[ii].mini_sigma != 0) ii++; newncand = (ii > cmd->ncand) ? cmd->ncand : ii; /* Set our candidate notes to all spaces */ notes = malloc(sizeof(char) * newncand * 18 + 1); for (ii = 0; ii < newncand; ii++) strncpy(notes + ii * 18, " ", 18); /* Check the database for possible known PSR detections */ if (idata.ra_h && idata.dec_d) { for (ii = 0; ii < newncand; ii++) { comp_rawbin_to_cand(&list[ii], &idata, notes + ii * 18, 0); } } /* Compare the candidates with each other */ compare_rawbin_cands(list, newncand, notes); /* Send the candidates to the text file */ file_rawbin_candidates(list, notes, newncand, cmd->harmsum, rootfilenm); /* Write the binary candidate file */ { char *candnm; candnm = (char *) calloc(strlen(rootfilenm) + 15, sizeof(char)); sprintf(candnm, "%s_bin%d.cand", rootfilenm, cmd->harmsum); candfile = chkfopen(candnm, "wb"); chkfwrite(list, sizeof(rawbincand), (unsigned long) newncand, candfile); fclose(candfile); free(candnm); } /* Free our arrays and close our files */ if (cmd->stack == 0) vect_free(powers); free(list); fftwf_free(minifft); free(notes); free(rootfilenm); fclose(fftfile); printf("Done.\n\n"); return (0); }
int main(int argc, char *argv[]) { FILE **infiles, *outfile = NULL, *scalingfile, *zerolagfile = NULL; int filenum, ptsperblock, numlags, numfiles, outnumlags; int bytes_per_read, scaling = 0, numscalings, firstfile, firstspec; int write_data = 1, update_posn = 0; long long N, numconverted = 0, numwritten = 0; char *path, *filenm, rawlags[4096]; char outfilenm[200], filenmbase[200], zerolagnm[200], scalingnm[200]; unsigned char output_samples[2048]; float *scalings = NULL, lags[2048], tmp_floats[2048]; double dt, T, time_offset; SPIGOT_INFO *spigots; sigprocfb fb; infodata idata; Cmdline *cmd; /* Call usage() if we have no command line arguments */ if (argc == 1) { Program = argv[0]; usage(); exit(0); } /* Parse the command line using the excellent program Clig */ cmd = parseCmdline(argc, argv); // showOptionValues(); numfiles = cmd->argc; /* If requesting that we skip values or only write */ /* a specific number of values, require an output file name */ if ((cmd->skip > 0) || cmd->numoutP){ if (!cmd->outfileP && !cmd->stdoutP) { fprintf(stderr, "\nspigot2filterbank ERROR: You need to specify an output\n" " filename (or -stdout) when using the -skip and/or \n" " -numout options!\n\n"); exit(1); } } /* Give an error if specifying stdout and an output file */ if (cmd->stdoutP && cmd->outfileP){ fprintf(stderr, "\nspigot2filterbank ERROR: You cannot specify both an output\n" " file and that the data should go to STDOUT!\n\n"); exit(1); } if (!cmd->stdoutP) printf("\nConverting SPIGOT FITs lags into SIGPROC filterbank format...\n\n"); /* Determine the filename base from the first spigot file */ split_path_file(cmd->argv[0], &path, &filenm); strncpy(filenmbase, filenm, strlen(filenm) - 5); filenmbase[strlen(filenm) - 5] = '\0'; free(path); free(filenm); /* Open a file to store the zerolags */ if (cmd->zerolagsP) { if (cmd->outfileP) { sprintf(zerolagnm, "%s.zerolags", cmd->outfile); } else { sprintf(zerolagnm, "%s.zerolags", filenmbase); } zerolagfile = chkfopen(zerolagnm, "wb"); } /* Attempt to read a file with lag scalings in it */ sprintf(scalingnm, "%s.scaling", filenmbase); if ((scalingfile = fopen(scalingnm, "rb"))) { /* Determine the length of the file */ numscalings = (int) chkfilelen(scalingfile, sizeof(float)); /* Create the array and read 'em */ scalings = gen_fvect(numscalings); chkfread(scalings, sizeof(float), numscalings, scalingfile); scaling = 1; /* close the scaling file */ fclose(scalingfile); if (!cmd->stdoutP) printf("Scaling the lags with the %d values found in '%s'\n\n", numscalings, scalingnm); } /* Read and convert the basic SPIGOT file information */ if (!cmd->stdoutP) printf("Spigot card input file information:\n"); spigots = (SPIGOT_INFO *) malloc(sizeof(SPIGOT_INFO) * numfiles); infiles = (FILE **) malloc(sizeof(FILE *) * numfiles); for (filenum = 0; filenum < numfiles; filenum++) { if (!cmd->stdoutP) printf(" '%s'\n", cmd->argv[filenum]); infiles[filenum] = chkfopen(cmd->argv[filenum], "rb"); read_SPIGOT_header(cmd->argv[filenum], spigots + filenum); rewind(infiles[filenum]); } if (!cmd->stdoutP) printf("\n"); /* The following is necessary in order to initialize all the */ /* static variables in spigot.c */ get_SPIGOT_file_info(infiles, spigots, numfiles, 0, 0, &N, &ptsperblock, &numlags, &dt, &T, &idata, !cmd->stdoutP); /* Compute the first file required */ firstfile = cmd->skip / spigots[0].samples_per_file; firstspec = cmd->skip % spigots[0].samples_per_file; if (!cmd->numoutP) { cmd->numout = (N - cmd->skip) / cmd->downsamp; } bytes_per_read = numlags * spigots[0].bits_per_lag / 8; outnumlags = numlags - cmd->lokill - cmd->hikill; /* Step through the SPIGOT files */ filenum = firstfile; while (numwritten < cmd->numout){ split_path_file(cmd->argv[filenum], &path, &filenm); strncpy(filenmbase, filenm, strlen(filenm) - 5); filenmbase[strlen(filenm) - 5] = '\0'; if (cmd->outfileP) { if (filenum==firstfile) { sprintf(outfilenm, "%s", cmd->outfile); outfile = chkfopen(outfilenm, "wb"); } } else { sprintf(outfilenm, "%s.fil", filenmbase); if (cmd->stdoutP) { outfile = stdout; } else { outfile = chkfopen(outfilenm, "wb"); } } if (!cmd->stdoutP) { if (filenum==firstfile) printf("Reading Spigot lags from '%s' (starting at sample %d)\n", cmd->argv[filenum], firstspec); else printf("Reading Spigot lags from '%s'\n", cmd->argv[filenum]); printf("Writing filterbank spectra to '%s'\n\n", outfilenm); } /* Update the filterbank header information for each file */ if (!spigots[filenum].tracking) { if (cmd->outfileP || cmd->stdoutP) { time_offset = 0.5 * cmd->numout * \ spigots[filenum].dt_us * 1e-6 * cmd->downsamp; } else { // Just normal files time_offset = 0.5 * spigots[filenum].file_duration; } update_posn = 1; } else { update_posn = 0; time_offset = 0.0; } /* Adjust the Spigot start time for the skip */ spigots[filenum].elapsed_time += cmd->skip * spigots[filenum].dt_us * 1e-6; /* Determine the SIGPROC header */ spigot2sigprocfb(&(spigots[filenum]), &fb, filenmbase, cmd->lokill, cmd->hikill, cmd->downsamp, update_posn, time_offset); /* Correct the structure if we are using floats */ if (cmd->floatsP) fb.nbits = 32; /* Write a filterbank header if we have not been told not to. */ /* Don't write it, though, if using stdio or a specified output */ /* file and the input file is not the first. */ if (!cmd->nohdrP) { if ((!cmd->stdoutP && !cmd->outfileP) || ((cmd->stdoutP || cmd->outfileP) && filenum==firstfile)) { write_filterbank_header(&fb, outfile); } } /* Go to the correct autocorrelation in the correct first FITs file */ chkfseek(infiles[filenum], spigots[filenum].header_len + bytes_per_read*firstspec, SEEK_SET); /* Loop over the samples in the file */ while ((numwritten < cmd->numout) && (chkfread(rawlags, bytes_per_read, 1, infiles[filenum]))) { if (cmd->zerolagsP) { /* Correct the lags so we can write the zerolag */ get_calibrated_lags(rawlags, lags); chkfwrite(lags, sizeof(float), 1, zerolagfile); } if (scaling) { convert_SPIGOT_point(rawlags, output_samples, SUMIFS, scalings[cmd->skip+numconverted]); } else { convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 1.0); } /* If downsampling, average the current spectra */ if (cmd->downsamp > 1) { int ii; if (numconverted % cmd->downsamp == 0) { write_data = 0; /* Zero the array used for averaging */ for (ii = 0; ii < outnumlags; ii++) tmp_floats[ii] = 0.0; } else { /* Add the current data to the array used for averaging */ for (ii = 0; ii < outnumlags; ii++) tmp_floats[ii] += (float) output_samples[ii+cmd->lokill]; /* If that was the last sample to be added, average them */ /* and put them back into output_samples */ if (numconverted % cmd->downsamp == (cmd->downsamp-1)) { write_data = 1; for (ii = 0; ii < outnumlags; ii++) { tmp_floats[ii] /= (float) cmd->downsamp; output_samples[ii+cmd->lokill] = \ (unsigned char)(tmp_floats[ii]+0.5); } } } } numconverted++; if (write_data) { int ii; /* Invert the band so that the high freqs are first */ /* This is how SIGPROC stores its data. */ if (cmd->floatsP) { float tempzz = 0.0, *loptr, *hiptr; loptr = tmp_floats; // killed channels are already gone hiptr = tmp_floats + outnumlags - 1; for (ii = 0; ii < outnumlags / 2; ii++, loptr++, hiptr--) { SWAP(*loptr, *hiptr); } } else { unsigned char tempzz = 0.0, *loptr, *hiptr; loptr = output_samples + cmd->lokill; hiptr = output_samples + cmd->lokill + outnumlags - 1; for (ii = 0; ii < outnumlags / 2; ii++, loptr++, hiptr--) { SWAP(*loptr, *hiptr); } } /* Now actually write the data */ if (cmd->floatsP) { /* Copy the bytes to floats */ for (ii = 0; ii < outnumlags; ii++) tmp_floats[ii] = (float) output_samples[ii+cmd->lokill]; chkfwrite(tmp_floats, sizeof(float), fb.nchans, outfile); } else { chkfwrite(output_samples+cmd->lokill, sizeof(unsigned char), fb.nchans, outfile); } numwritten++; } } if ((!cmd->stdoutP) && (!cmd->outfileP)) fclose(outfile); fclose(infiles[filenum]); firstspec = 0; filenum++; free(path); free(filenm); } if ((!cmd->stdoutP) && (cmd->outfileP)) fclose(outfile); if (cmd->zerolagsP) fclose(zerolagfile); if (!cmd->stdoutP) fprintf(stderr, "Converted %lld samples and wrote %lld.\n\n", numconverted, numwritten); if (scaling) free(scalings); free(spigots); free(infiles); return 0; }