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); }
char *make_polycos(char *parfilenm, infodata * idata, char *polycofilenm) { FILE *tmpfile; int tracklen; double T, fmid = 0.0, epoch; char *command, *psrname, scopechar; char *pcpathnm, *pcfilenm; psrparams psr; /* Get the path and name of the output polycofilenm */ split_path_file(polycofilenm, &pcpathnm, &pcfilenm); /* Read the parfile */ epoch = idata->mjd_i + idata->mjd_f; T = (idata->dt * idata->N) / SECPERDAY; if (!get_psr_from_parfile(parfilenm, epoch, &psr)) { fprintf(stderr, "\nError: Cannot read parfile '%s' in make_polycos()\n\n", parfilenm); exit(-1); } /* Generate temp directory */ char tmpdir[] = "/tmp/polycoXXXXXX"; if (mkdtemp(tmpdir) == NULL) { fprintf(stderr, "\nError: Cannot generate temp dir '%s' in make_polycos()\n\n", tmpdir); exit(-1); } /* Copy the parfile to the temp directory */ command = (char *) calloc(strlen(parfilenm) + strlen(tmpdir) + strlen(pcfilenm) + strlen(pcpathnm) + 200, 1); sprintf(command, "cp %s %s/pulsar.par", parfilenm, tmpdir); if (system(command) != 0) { fprintf(stderr, "\nError: Cannot copy parfile '%s' to tmpdir '%s' in make_polycos()\n\n", parfilenm, tmpdir); exit(-1); } /* change to temp dir */ char *origdir = getcwd(NULL, 0); chdir(tmpdir); /* Write tz.in */ if (strcmp(idata->telescope, "GBT") == 0) { scopechar = '1'; tracklen = 12; } else if (strcmp(idata->telescope, "Arecibo") == 0) { scopechar = '3'; tracklen = 3; } else if (strcmp(idata->telescope, "VLA") == 0) { scopechar = '6'; tracklen = 6; } else if (strcmp(idata->telescope, "Parkes") == 0) { scopechar = '7'; tracklen = 12; } else if (strcmp(idata->telescope, "Jodrell") == 0) { scopechar = '8'; tracklen = 12; } else if ((strcmp(idata->telescope, "GB43m") == 0) || (strcmp(idata->telescope, "GB 140FT") == 0) || (strcmp(idata->telescope, "NRAO20") == 0)) { scopechar = 'a'; tracklen = 12; } else if (strcmp(idata->telescope, "Nancay") == 0) { scopechar = 'f'; tracklen = 4; } else if (strcmp(idata->telescope, "Effelsberg") == 0) { scopechar = 'g'; tracklen = 12; } else if (strcmp(idata->telescope, "LOFAR") == 0) { scopechar = 't'; tracklen = 12; } else if (strcmp(idata->telescope, "WSRT") == 0) { scopechar = 'i'; tracklen = 12; } else if (strcmp(idata->telescope, "GMRT") == 0) { scopechar = 'r'; tracklen = 12; } else if (strcmp(idata->telescope, "LWA") == 0) { scopechar = 'x'; tracklen = 12; } else if (strcmp(idata->telescope, "SRT") == 0) { scopechar = 'z'; tracklen = 12; } else if (strcmp(idata->telescope, "Geocenter") == 0) { scopechar = 'o'; tracklen = 12; } else { /* Barycenter */ printf("Defaulting to barycenter for polyco generation...\n"); scopechar = '@'; tracklen = 12; } /* For optical, X-ray, or gamma-ray data */ if (scopechar != '@' && scopechar != 'o') { fmid = idata->freq + (idata->num_chan / 2 - 0.5) * idata->chan_wid; } else { fmid = 0.0; } printf("Generating polycos for PSR %s.\n", psr.jname); tmpfile = chkfopen("tz.in", "w"); fprintf(tmpfile, "%c %d 60 12 430\n\n\n%s 60 12 %d %.5f\n", scopechar, tracklen, psr.jname, tracklen, fmid); fclose(tmpfile); //sprintf(command, "echo %d %d | tempo -z -f %s > /dev/null", sprintf(command, "echo %d %d | tempo -z -f pulsar.par > /dev/null", idata->mjd_i - 1, (int) ceil(epoch + T)); if (system(command) != 0) { fprintf(stderr, "\nError: Problem running TEMPO in '%s' for make_polycos()\n\n", tmpdir); exit(-1); } else { sprintf(command, "cp polyco.dat %s/%s", pcpathnm, pcfilenm); if (system(command) != 0) { fprintf(stderr, "\nError: Cannot copy polyco.dat in '%s' to '%s' make_polycos()\n\n", tmpdir, polycofilenm); exit(-1); } remove("polyco.dat"); remove("pulsar.par"); remove("tempo.lis"); remove("tz.in"); remove("tz.tmp"); } chdir(origdir); free(origdir); free(pcpathnm); free(pcfilenm); free(command); remove(tmpdir); psrname = (char *) calloc(strlen(psr.jname) + 1, sizeof(char)); strcpy(psrname, psr.jname); return psrname; }
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; }
void init_subbanding(struct psrfits *pfi, struct psrfits *pfo, struct subband_info *si, Cmdline *cmd) { int ii, jj, kk, cindex; double lofreq, dtmp; // If -nsub is not set, do no subbanding if (!cmd->nsubP) cmd->nsub = pfi->hdr.nchan; // Don't change the number of output bits unless we explicitly ask to if (!cmd->outbitsP) cmd->outbits = pfi->hdr.nbits; si->nsub = cmd->nsub; si->nchan = pfi->hdr.nchan; si->npol = pfi->hdr.npol; si->numunsigned = si->npol; if (si->npol==4) { if (strncmp(pfi->hdr.poln_order, "AABBCRCI", 8)==0) si->numunsigned = 2; if (strncmp(pfi->hdr.poln_order, "IQUV", 4)==0) si->numunsigned = 1; } si->chan_per_sub = si->nchan / si->nsub; si->bufwid = si->nchan * si->npol; // Freq * polns si->buflen = pfi->hdr.nsblk; // Number of spectra in each row // Check the downsampling factor in time if (si->buflen % cmd->dstime) { fprintf(stderr, "Error!: %d spectra per row is not evenly divisible by -dstime of %d!\n", si->buflen, cmd->dstime); exit(1); } // Check the downsampling factor in frequency if (si->nchan % si->nsub) { fprintf(stderr, "Error! %d channels is not evenly divisible by %d subbands!\n", si->nchan, si->nsub); exit(1); } si->dm = cmd->dm; si->sub_df = pfi->hdr.df * si->chan_per_sub; si->sub_freqs = (float *)malloc(sizeof(float) * si->nsub); si->chan_delays = (double *)malloc(sizeof(double) * si->nchan); si->sub_delays = (double *)malloc(sizeof(double) * si->nsub); si->idelays = (int *)malloc(sizeof(int) * si->nchan); si->weights = (float *)malloc(sizeof(float) * si->nsub); si->offsets = (float *)malloc(sizeof(float) * si->nsub * si->npol); si->scales = (float *)malloc(sizeof(float) * si->nsub * si->npol); si->chan_avgs = (float *)malloc(sizeof(float) * si->bufwid); si->chan_stds = (float *)malloc(sizeof(float) * si->bufwid); /* Alloc data buffers for the input PSRFITS file */ pfi->sub.dat_freqs = (float *)malloc(sizeof(float) * pfi->hdr.nchan); pfi->sub.dat_weights = (float *)malloc(sizeof(float) * pfi->hdr.nchan); pfi->sub.dat_offsets = (float *)malloc(sizeof(float) * pfi->hdr.nchan * pfi->hdr.npol); pfi->sub.dat_scales = (float *)malloc(sizeof(float) * pfi->hdr.nchan * pfi->hdr.npol); pfi->sub.rawdata = (unsigned char *)malloc(pfi->sub.bytes_per_subint); if (pfi->hdr.nbits!=8) { pfi->sub.data = (unsigned char *)malloc(pfi->sub.bytes_per_subint * (8 / pfi->hdr.nbits)); } else { pfi->sub.data = pfi->sub.rawdata; } // Read the first row of data psrfits_read_subint(pfi); if (si->userwgts) // Always overwrite if using user weights memcpy(pfi->sub.dat_weights, si->userwgts, pfi->hdr.nchan * sizeof(float)); // Reset the read counters since we'll re-read pfi->rownum--; pfi->tot_rows--; pfi->N -= pfi->hdr.nsblk; // Compute the subband properties, DM delays and offsets lofreq = pfi->sub.dat_freqs[0] - pfi->hdr.df * 0.5; for (ii = 0, cindex = 0 ; ii < si->nsub ; ii++) { dtmp = lofreq + ((double)ii + 0.5) * si->sub_df; si->sub_freqs[ii] = dtmp; si->sub_delays[ii] = delay_from_dm(si->dm, dtmp); // Determine the dispersion delays and convert them // to offsets in units of sample times for (jj = 0 ; jj < si->chan_per_sub ; jj++, cindex++) { si->chan_delays[cindex] = delay_from_dm(si->dm, pfi->sub.dat_freqs[cindex]); si->chan_delays[cindex] -= si->sub_delays[ii]; si->idelays[cindex] = (int)rint(si->chan_delays[cindex] / pfi->hdr.dt); } } // Now determine the earliest and latest delays si->max_early = si->max_late = 0; for (ii = 0 ; ii < si->nchan ; ii++) { if (si->idelays[ii] < si->max_early) si->max_early = si->idelays[ii]; if (si->idelays[ii] > si->max_late) si->max_late = si->idelays[ii]; } si->max_overlap = abs(si->max_early) + si->max_late; // This buffer will hold the float-converted input data, plus the bits // of data from the previous and next blocks si->fbuffer = (float *)calloc((si->buflen + 2 * si->max_overlap) * si->bufwid, sizeof(float)); // The input data will be stored directly in the buffer space // So the following is really just an offset into the bigger buffer pfi->sub.fdata = si->fbuffer + si->max_overlap * si->bufwid; // Now start setting values for the output arrays *pfo = *pfi; // We are changing the number of bits in the data if (pfi->hdr.nbits != cmd->outbits) pfo->hdr.nbits = cmd->outbits; // Determine the length of the outputfiles to use if (cmd->filetimeP) { pfo->rows_per_file = 10 * \ (int) rint(0.1 * (cmd->filetime / pfi->sub.tsubint)); } else if (cmd->filelenP) { long long filelen; int bytes_per_subint; filelen = cmd->filelen * (1L<<30); // In GB bytes_per_subint = (pfo->hdr.nbits * pfo->hdr.nchan * pfo->hdr.npol * pfo->hdr.nsblk) / \ (8 * si->chan_per_sub * cmd->dstime * (cmd->onlyIP ? 4 : 1)); pfo->rows_per_file = filelen / bytes_per_subint; pfo->sub.bytes_per_subint = bytes_per_subint; } else { // By default, keep the filesize roughly constant pfo->rows_per_file = pfi->rows_per_file * si->chan_per_sub * cmd->dstime * (cmd->onlyIP ? 4 : 1) * pfi->hdr.nbits / pfo->hdr.nbits; } pfo->filenum = 0; // This causes the output files to be created pfo->filename[0] = '\0'; pfo->rownum = 1; pfo->tot_rows = 0; pfo->N = 0; // Set the "orig" values to those of the input file pfo->hdr.orig_nchan = pfi->hdr.nchan; pfo->hdr.orig_df = pfi->hdr.df; { char *inpath, *infile; split_path_file(pfi->basefilename, &inpath, &infile); sprintf(pfo->basefilename, "%s_subs", infile); free(inpath); free(infile); } // Reset different params pfo->sub.dat_freqs = si->sub_freqs; pfo->sub.dat_weights = si->weights; pfo->sub.dat_offsets = si->offsets; pfo->sub.dat_scales = si->scales; pfo->hdr.ds_freq_fact = si->chan_per_sub; pfo->hdr.ds_time_fact = cmd->dstime; pfo->hdr.onlyI = cmd->onlyIP; pfo->hdr.chan_dm = si->dm; pfo->sub.rawdata = (unsigned char *)malloc(si->nsub * si->npol * si->buflen); if (pfo->hdr.nbits!=8) { pfo->sub.data = (unsigned char *)malloc(si->nsub * si->npol * si->buflen * (8 / pfo->hdr.nbits)); } else { pfo->sub.data = pfo->sub.rawdata; } si->outfbuffer = (float *)calloc(si->nsub * si->npol * si->buflen, sizeof(float)); pfo->sub.fdata = si->outfbuffer; // Now re-read the first row (i.e. for "real" this time) get_current_row(pfi, si); // Set the new weights properly new_weights(pfi, pfo); // Now fill the first part of si->fbuffer with the chan_avgs so that // it acts like a previously read block (or row) fill_chans_with_avgs(si->max_overlap, si->bufwid, si->fbuffer, si->chan_avgs); }
int client_mode(char* server, char mode, char* filename) { DEBUG("除錯模式啟動\n"); /* 建立客戶端 socket */ if ((client_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror("socket() 呼叫失敗"); exit(EXIT_FAILURE); } /* 設定客戶端 socket */ bzero(&server_address, sizeof (struct sockaddr_in)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr(server); server_address.sin_port = htons(PORT); len = sizeof (server_address); /* 與伺服器建立連線 */ if ((result = connect(client_sockfd, (struct sockaddr *) &server_address, len)) < 0) { perror("connect() 呼叫失敗"); close(client_sockfd); exit(EXIT_FAILURE); } else { printf("連線中...\n"); } FD_ZERO(&readfds); FD_SET(client_sockfd, &readfds); /* 開始傳送接收資料 */ bzero(bytebuf, 1); bzero(buf, BUFF_LEN); bzero(tmp, BUFF_LEN); /* 通知伺服器目前的模式 (Download/Upload) */ if (send(client_sockfd, &mode, sizeof (char), 0)) { DEBUG("mode 訊息已送出\n"); } if (mode == 'D') { /* 下載模式 */ /* 要求伺服器提供使用者指定的檔案 */ /* 傳送檔案名稱給伺服器 */ if (send(client_sockfd, filename, BUFF_LEN, 0)) { DEBUG("Filename 訊息已送出\n"); } /* 處理檔案路徑 */ /* malloc two buffs */ char* _path = malloc(BUFF_LEN); char*_fname = malloc(BUFF_LEN); split_path_file(&_path, &_fname, filename); strcpy(filename, _fname); chdir("./downloads"); DEBUG("File name: %s\n", filename); /* 接收檔案大小 */ if (recv(client_sockfd, &nread, sizeof (int), 0)) { DEBUG("Filesize 訊息已接收\n"); printf("檔案大小為 %d bytes\n", nread); } if (nread <= 0) { printf("伺服器上沒有這個檔案喔\n"); close(client_sockfd); exit(EXIT_FAILURE); } fp = fopen(filename, "wb, ccs=UTF-8"); /* 顯示進度 */ for (i = 0, cread = 1, per = 0; i < nread; i = i + 1, cread = cread + 1) { bzero(bytebuf, sizeof (wchar_t*)); st = recv(client_sockfd, bytebuf, 1, 0); per = ((float) cread / (float) nread) * 100; j = i % DOT_LEN; if (i == nread - 1) { j = DOT_LEN - 1; } /* 處理取得的資料 */ fwrite(bytebuf, 1, 1, fp); cls(); printf("\r進度:%3d %c %8s 正在下載 \"%s\" %d / %d bytes\n", per, '%', dot[j], filename, cread, nread); usleep(250); /* 避免 CPU 佔用過高與畫面閃爍 */ } fclose(fp); printf("傳輸完成\n"); chdir(".."); } if (mode == 'U') { /* 上傳模式 */ /* 處理檔案路徑 */ /* malloc two buffs */ char* _path = malloc(BUFF_LEN); char*_fname = malloc(BUFF_LEN); split_path_file(&_path, &_fname, filename); strcpy(filename, _fname); chdir(_path); DEBUG("File name: %s\n", filename); fp = fopen(filename, "rb, ccs=UTF-8"); if (!fp) { printf("找不到 %s%s\n", _path, filename); close(fd); close(client_sockfd); exit(EXIT_FAILURE); } /* 開始傳送資料 */ /* 取得檔案大小 */ fseek(fp, 0L, SEEK_END); nread = ftell(fp); fseek(fp, 0L, SEEK_SET); DEBUG("File size: %d\n", nread); /* 傳送檔案名稱與檔案大小給對方 */ if (send(client_sockfd, filename, BUFF_LEN, 0)) { DEBUG("Filename 訊息已送出\n"); } if (send(client_sockfd, &nread, sizeof (int), 0)) { DEBUG("Filesize 訊息已送出\n"); } for (i = 0, cread = 1, per = 0; i < nread; i = i + 1, cread = cread + 1) { bzero(bytebuf, sizeof (wchar_t*)); if (!feof(fp)) { st = fread(bytebuf, 1, 1, fp); } st = send(client_sockfd, bytebuf, 1, 0); per = ((float) cread / (float) nread) * 100; j = i % DOT_LEN; if (i == nread - 1) { j = DOT_LEN - 1; } cls(); printf("\r進度:%3d %c %8s 正在上傳 \"%s\" %d / %d bytes\n", per, '%', dot[j], filename, cread, nread); usleep(250); /* 避免 CPU 佔用過高與畫面閃爍 */ } fclose(fp); printf("傳輸完成\n"); chdir(".."); } /* 關閉 socket */ close(client_sockfd); exit(EXIT_SUCCESS); return EXIT_SUCCESS; }
/* Given a GString containing MMD source, and optional base directory, substitute transclusion references in the source Pass the path to the current folder if available -- should be a full path. Keep track of what we're parsing to prevent recursion using stack. */ void transclude_source(GString *source, char *basedir, char *stack, int output_format, GString *manifest) { char *base = NULL; char *path = NULL; char *start; char *stop; char *temp; int curchar; size_t pos; char real[1000]; FILE *input; long offset; if (basedir == NULL) { base = strdup(""); } else { base = strdup(basedir); } GString *folder = NULL; GString *filename = NULL; GString *filebuffer = NULL; GString *stackstring = NULL; path = strdup(base); /* Look for override folder inside document */ if (has_metadata(source->str, 0x000000)) { char *meta = extract_metadata_value(source->str, 0x000000, "transcludebase"); if (meta != NULL) path = path_from_dir_base(base, meta); } if (path == NULL) { /* We have nowhere to look, so nothing to do */ free(path); free(base); return; } folder = g_string_new(path); /* Ensure that folder ends in "/" */ /* TODO: adjust for windows */ if (!(folder->str[strlen(folder->str)-1] == '/') ) { g_string_append_c(folder, '/'); } /* fprintf(stderr, "Transclude using '%s'\n", folder->str); */ /* Iterate through {{foo.txt}} and substitute contents of file without metadata */ start = strstr(source->str,"{{"); while (start != NULL) { stop = strstr(start,"}}"); if (stop == NULL) break; /* Check that we found something reasonable -- we cap at 1000 characters */ if (stop - start < 1000) { strncpy(real,start+2,stop-start-2); real[stop-start-2] = '\0'; if (is_separator(real[0])) { filename = g_string_new(real); } else { filename = g_string_new(folder->str); g_string_append_printf(filename, "%s",real); } if (strcmp(filename->str,"./TOC") == 0) { pos = stop - source->str; start = strstr(source->str + pos,"{{"); g_string_free(filename, true); continue; } /* Adjust for wildcard extensions */ /* But not if output_format == 0 */ if (output_format && strncmp(&filename->str[strlen(filename->str) - 2],".*",2) == 0) { g_string_erase(filename, strlen(filename->str) - 2, 2); if (output_format == TEXT_FORMAT) { g_string_append(filename,".txt"); } else if (output_format == HTML_FORMAT) { g_string_append(filename,".html"); } else if (output_format == LATEX_FORMAT) { g_string_append(filename,".tex"); } else if (output_format == BEAMER_FORMAT) { g_string_append(filename,".tex"); } else if (output_format == MEMOIR_FORMAT) { g_string_append(filename,".tex"); } else if (output_format == ODF_FORMAT) { g_string_append(filename,".fodt"); } else if (output_format == OPML_FORMAT) { g_string_append(filename,".opml"); } else if (output_format == LYX_FORMAT) { g_string_append(filename,".lyx"); } else if (output_format == RTF_FORMAT) { g_string_append(filename,".rtf"); } else { /* default extension -- in this case we only have 1 */ g_string_append(filename,".txt"); } } pos = stop - source->str; /* Add to the manifest (if not already included) */ if (manifest != NULL) { temp = strstr(manifest->str,filename->str); offset = temp - manifest->str; if ((temp != NULL) && ((temp == manifest->str) || ((manifest->str)[offset - 1] == '\n')) && (temp[strlen(filename->str)] == '\n') ){ /* Already on manifest, so don't add again */ } else { g_string_append_printf(manifest,"%s\n",filename->str); } } /* Don't reparse ourselves */ if (stack != NULL) { temp = strstr(stack,filename->str); if ((temp != NULL) && (temp[strlen(filename->str)] == '\n')){ start = strstr(source->str + pos,"{{"); g_string_free(filename, true); continue; } } /* Read file */ #if defined(__WIN32) int wchars_num = MultiByteToWideChar(CP_UTF8, 0, filename->str, -1, NULL, 0); wchar_t wstr[wchars_num]; MultiByteToWideChar(CP_UTF8, 0, filename->str, -1, wstr, wchars_num); if ((input = _wfopen(wstr, L"r")) != NULL ) { #else if ((input = fopen(filename->str, "r")) != NULL ) { #endif filebuffer = g_string_new(""); while ((curchar = fgetc(input)) != EOF) g_string_append_c(filebuffer, curchar); fclose(input); pos = start - source->str; g_string_erase(source, pos, 2 + stop - start); /* Update stack list */ stackstring = g_string_new(stack); g_string_append_printf(stackstring,"%s\n",filename->str); /* Recursively transclude files */ /* We want to reset the base directory if we enter a subdirectory */ char * new_dir; char * file_only; split_path_file(&new_dir, &file_only, filename->str); /* transclude_source(filebuffer, folder->str, stackstring->str, output_format, manifest); */ transclude_source(filebuffer, new_dir, stackstring->str, output_format, manifest); free(new_dir); free(file_only); temp = source_without_metadata(filebuffer->str, 0x000000); g_string_insert(source, pos, temp); pos += strlen(temp); g_string_free(filebuffer, true); g_string_free(stackstring, true); } else { /* fprintf(stderr, "error opening file: %s\n", filename->str); */ } g_string_free(filename, true); } else { /* Our "match" was > 1000 characters long */ pos = stop - source->str; } start = strstr(source->str + pos,"{{"); } g_string_free(folder, true); free(path); free(base); } /* Allow for a footer to specify files to be appended to the end of the text, and then transcluded. Useful for appending a list of footnotes, citations, abbreviations, etc. to each separate file, but not including multiple copies when processing the master file. */ void append_mmd_footer(GString *source) { /* Look for mmd_footer metadata */ if (has_metadata(source->str, 0x000000)) { char *meta = extract_metadata_value(source->str, 0x000000, "mmdfooter"); if (meta != NULL) g_string_append_printf(source, "\n\n{{%s}}\n", meta); } } void prepend_mmd_header(GString *source) { /* Same thing, but to be inserted after metadata and before content */ if (has_metadata(source->str, 0x000000)) { char *meta = extract_metadata_value(source->str, 0x000000, "mmdheader"); if (meta != NULL) { char *content = strstr(source->str, "\n\n"); if (content != NULL) { size_t pos = content - source->str; g_string_insert_printf(source, pos, "\n\n{{%s}}", meta); } else { g_string_append_printf(source, "\n\n{{%s}}\n", meta); } } } }
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; }