void read_PSRFITS_files(struct spectra_info *s) // Read and convert PSRFITS information from a group of files // and place the resulting info into a spectra_info structure. { int IMJD, SMJD, itmp, ii, status = 0; double OFFS, dtmp; long double MJDf; char ctmp[80], comment[120]; s->datatype = PSRFITS; s->fitsfiles = (fitsfile **)malloc(sizeof(fitsfile *) * s->num_files); s->start_subint = gen_ivect(s->num_files); s->num_subint = gen_ivect(s->num_files); s->start_spec = (long long *)malloc(sizeof(long long) * s->num_files); s->num_spec = (long long *)malloc(sizeof(long long) * s->num_files); s->num_pad = (long long *)malloc(sizeof(long long) * s->num_files); s->start_MJD = (long double *)malloc(sizeof(long double) * s->num_files); s->N = 0; s->num_beams = 1; s->get_rawblock = &get_PSRFITS_rawblock; s->offset_to_spectra = &offset_to_PSRFITS_spectra; // By default, don't flip the band. But don't change // the input value if it is aleady set to flip the band always if (s->apply_flipband==-1) s->apply_flipband = 0; // Step through the other files for (ii = 0 ; ii < s->num_files ; ii++) { // Is the file a PSRFITS file? if (!is_PSRFITS(s->filenames[ii])) { fprintf(stderr, "\nError! File '%s' does not appear to be PSRFITS!\n", s->filenames[ii]); exit(1); } // Open the PSRFITS file fits_open_file(&(s->fitsfiles[ii]), s->filenames[ii], READONLY, &status); // Is the data in search mode? fits_read_key(s->fitsfiles[ii], TSTRING, "OBS_MODE", ctmp, comment, &status); // Quick fix for Parkes DFB data (SRCH? why????)... if (strcmp("SRCH", ctmp)==0) { strncpy(ctmp, "SEARCH", 40); } if (strcmp(ctmp, "SEARCH")) { fprintf(stderr, "\nError! File '%s' does not contain SEARCH-mode data!\n", s->filenames[ii]); exit(1); } // Now get the stuff we need from the primary HDU header fits_read_key(s->fitsfiles[ii], TSTRING, "TELESCOP", ctmp, comment, &status); \ // Quick fix for MockSpec data... if (strcmp("ARECIBO 305m", ctmp)==0) { strncpy(ctmp, "Arecibo", 40); } // Quick fix for Parkes DFB data... { char newctmp[80]; // Copy ctmp first since strlower() is in-place strcpy(newctmp, ctmp); if (strcmp("parkes", strlower(remove_whitespace(newctmp)))==0) { strncpy(ctmp, "Parkes", 40); } } if (status) { printf("Error %d reading key %s\n", status, "TELESCOP"); if (ii==0) s->telescope[0]='\0'; if (status==KEY_NO_EXIST) status=0; } else { if (ii==0) strncpy(s->telescope, ctmp, 40); else if (strcmp(s->telescope, ctmp)!=0) printf("Warning!: %s values don't match for files 0 and %d!\n", "TELESCOP", ii); } get_hdr_string("OBSERVER", s->observer); get_hdr_string("SRC_NAME", s->source); get_hdr_string("FRONTEND", s->frontend); get_hdr_string("BACKEND", s->backend); get_hdr_string("PROJID", s->project_id); get_hdr_string("DATE-OBS", s->date_obs); get_hdr_string("FD_POLN", s->poln_type); get_hdr_string("RA", s->ra_str); get_hdr_string("DEC", s->dec_str); get_hdr_double("OBSFREQ", s->fctr); get_hdr_int("OBSNCHAN", s->orig_num_chan); get_hdr_double("OBSBW", s->orig_df); //get_hdr_double("CHAN_DM", s->chan_dm); get_hdr_double("BMIN", s->beam_FWHM); /* This is likely not in earlier versions of PSRFITS so */ /* treat it a bit differently */ fits_read_key(s->fitsfiles[ii], TDOUBLE, "CHAN_DM", &(s->chan_dm), comment, &status); if (status==KEY_NO_EXIST) { status = 0; s->chan_dm = 0.0; } // Don't use the macros unless you are using the struct! fits_read_key(s->fitsfiles[ii], TINT, "STT_IMJD", &IMJD, comment, &status); s->start_MJD[ii] = (long double) IMJD; fits_read_key(s->fitsfiles[ii], TINT, "STT_SMJD", &SMJD, comment, &status); fits_read_key(s->fitsfiles[ii], TDOUBLE, "STT_OFFS", &OFFS, comment, &status); s->start_MJD[ii] += ((long double) SMJD + (long double) OFFS) / SECPERDAY; // Are we tracking? fits_read_key(s->fitsfiles[ii], TSTRING, "TRK_MODE", ctmp, comment, &status); itmp = (strcmp("TRACK", ctmp)==0) ? 1 : 0; if (ii==0) s->tracking = itmp; else if (s->tracking != itmp) printf("Warning!: TRK_MODE values don't match for files 0 and %d!\n", ii); // Now switch to the SUBINT HDU header fits_movnam_hdu(s->fitsfiles[ii], BINARY_TBL, "SUBINT", 0, &status); get_hdr_double("TBIN", s->dt); get_hdr_int("NCHAN", s->num_channels); get_hdr_int("NPOL", s->num_polns); get_hdr_string("POL_TYPE", s->poln_order); fits_read_key(s->fitsfiles[ii], TINT, "NCHNOFFS", &itmp, comment, &status); if (itmp > 0) printf("Warning!: First freq channel is not 0 in file %d!\n", ii); get_hdr_int("NSBLK", s->spectra_per_subint); get_hdr_int("NBITS", s->bits_per_sample); fits_read_key(s->fitsfiles[ii], TINT, "NAXIS2", &(s->num_subint[ii]), comment, &status); fits_read_key(s->fitsfiles[ii], TINT, "NSUBOFFS", &(s->start_subint[ii]), comment, &status); s->time_per_subint = s->dt * s->spectra_per_subint; /* This is likely not in earlier versions of PSRFITS so */ /* treat it a bit differently */ fits_read_key(s->fitsfiles[ii], TFLOAT, "ZERO_OFF", &(s->zero_offset), comment, &status); if (status==KEY_NO_EXIST) { status = 0; s->zero_offset = 0.0; } s->zero_offset = fabs(s->zero_offset); // Get the time offset column info and the offset for the 1st row { double offs_sub; int colnum, anynull, numrows; // Identify the OFFS_SUB column number fits_get_colnum(s->fitsfiles[ii], 0, "OFFS_SUB", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the OFFS_SUB column!\n"); status = 0; // Reset status } else { if (ii==0) { s->offs_sub_col = colnum; } else if (colnum != s->offs_sub_col) { printf("Warning!: OFFS_SUB column changes between files!\n"); } } // Read the OFFS_SUB column value for the 1st row fits_read_col(s->fitsfiles[ii], TDOUBLE, s->offs_sub_col, 1L, 1L, 1L, 0, &offs_sub, &anynull, &status); numrows = (int)((offs_sub - 0.5 * s->time_per_subint) / s->time_per_subint + 1e-7); // Check to see if any rows have been deleted or are missing if (numrows > s->start_subint[ii]) { printf("Warning: NSUBOFFS reports %d previous rows\n" " but OFFS_SUB implies %d. Using OFFS_SUB.\n" " Will likely be able to correct for this.\n", s->start_subint[ii], numrows); } s->start_subint[ii] = numrows; } // This is the MJD offset based on the starting subint number MJDf = (s->time_per_subint * s->start_subint[ii]) / SECPERDAY; // The start_MJD values should always be correct s->start_MJD[ii] += MJDf; // Compute the starting spectra from the times MJDf = s->start_MJD[ii] - s->start_MJD[0]; if (MJDf < 0.0) { fprintf(stderr, "Error!: File %d seems to be from before file 0!\n", ii); exit(1); } s->start_spec[ii] = (long long)(MJDf * SECPERDAY / s->dt + 0.5); // Now pull stuff from the other columns { float ftmp; long repeat, width; int colnum, anynull; // Identify the data column and the data type fits_get_colnum(s->fitsfiles[ii], 0, "DATA", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the DATA column!\n"); status = 0; // Reset status } else { if (ii==0) { s->data_col = colnum; fits_get_coltype(s->fitsfiles[ii], colnum, &(s->FITS_typecode), &repeat, &width, &status); } else if (colnum != s->data_col) { printf("Warning!: DATA column changes between files!\n"); } } // Telescope azimuth fits_get_colnum(s->fitsfiles[ii], 0, "TEL_AZ", &colnum, &status); if (status==COL_NOT_FOUND) { s->azimuth = 0.0; status = 0; // Reset status } else { fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, 1L, 0, &ftmp, &anynull, &status); if (ii==0) s->azimuth = (double) ftmp; } // Telescope zenith angle fits_get_colnum(s->fitsfiles[ii], 0, "TEL_ZEN", &colnum, &status); if (status==COL_NOT_FOUND) { s->zenith_ang = 0.0; status = 0; // Reset status } else { fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, 1L, 0, &ftmp, &anynull, &status); if (ii==0) s->zenith_ang = (double) ftmp; } // Observing frequencies fits_get_colnum(s->fitsfiles[ii], 0, "DAT_FREQ", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the channel freq column!\n"); status = 0; // Reset status } else { int jj; float *freqs = (float *)malloc(sizeof(float) * s->num_channels); fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, s->num_channels, 0, freqs, &anynull, &status); if (ii==0) { s->df = freqs[1]-freqs[0]; s->lo_freq = freqs[0]; s->hi_freq = freqs[s->num_channels-1]; // Now check that the channel spacing is the same throughout for (jj = 0 ; jj < s->num_channels - 1 ; jj++) { ftmp = freqs[jj+1] - freqs[jj]; if (fabs(ftmp - s->df) > 1e-7) printf("Warning!: Channel spacing changes in file %d!\n", ii); } } else { ftmp = fabs(s->df-(freqs[1]-freqs[0])); if (ftmp > 1e-7) printf("Warning!: Channel spacing changes between files!\n"); ftmp = fabs(s->lo_freq-freqs[0]); if (ftmp > 1e-7) printf("Warning!: Low channel changes between files!\n"); ftmp = fabs(s->hi_freq-freqs[s->num_channels-1]); if (ftmp > 1e-7) printf("Warning!: High channel changes between files!\n"); } free(freqs); } // Data weights fits_get_colnum(s->fitsfiles[ii], 0, "DAT_WTS", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the channel weights!\n"); status = 0; // Reset status } else { if (s->apply_weight < 0) { // Use the data to decide int jj; if (ii==0) { s->dat_wts_col = colnum; } else if (colnum != s->dat_wts_col) { printf("Warning!: DAT_WTS column changes between files!\n"); } float *fvec = (float *)malloc(sizeof(float) * s->num_channels); fits_read_col(s->fitsfiles[ii], TFLOAT, s->dat_wts_col, 1L, 1L, s->num_channels, 0, fvec, &anynull, &status); for (jj = 0 ; jj < s->num_channels ; jj++) { // If the weights are not 1, apply them if (fvec[jj] != 1.0) { s->apply_weight = 1; break; } } free(fvec); } if (s->apply_weight < 0) s->apply_weight = 0; // not needed } // Data offsets fits_get_colnum(s->fitsfiles[ii], 0, "DAT_OFFS", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the channel offsets!\n"); status = 0; // Reset status } else { if (s->apply_offset < 0) { // Use the data to decide int jj; if (ii==0) { s->dat_offs_col = colnum; } else if (colnum != s->dat_offs_col) { printf("Warning!: DAT_OFFS column changes between files!\n"); } float *fvec = (float *)malloc(sizeof(float) * s->num_channels * s->num_polns); fits_read_col(s->fitsfiles[ii], TFLOAT, s->dat_offs_col, 1L, 1L, s->num_channels * s->num_polns, 0, fvec, &anynull, &status); for (jj = 0 ; jj < s->num_channels * s->num_polns ; jj++) { // If the offsets are not 0, apply them if (fvec[jj] != 0.0) { s->apply_offset = 1; break; } } free(fvec); } if (s->apply_offset < 0) s->apply_offset = 0; // not needed } // Data scalings fits_get_colnum(s->fitsfiles[ii], 0, "DAT_SCL", &colnum, &status); if (status==COL_NOT_FOUND) { printf("Warning!: Can't find the channel scalings!\n"); status = 0; // Reset status } else { if (s->apply_scale < 0) { // Use the data to decide int jj; if (ii==0) { s->dat_scl_col = colnum; } else if (colnum != s->dat_scl_col) { printf("Warning!: DAT_SCL column changes between files!\n"); } float *fvec = (float *)malloc(sizeof(float) * s->num_channels * s->num_polns); fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, s->num_channels * s->num_polns, 0, fvec, &anynull, &status); for (jj = 0 ; jj < s->num_channels * s->num_polns ; jj++) { // If the scales are not 1, apply them if (fvec[jj] != 1.0) { s->apply_scale = 1; break; } } free(fvec); } if (s->apply_scale < 0) s->apply_scale = 0; // not needed } } // Compute the samples per file and the amount of padding // that the _previous_ file has s->num_pad[ii] = 0; s->num_spec[ii] = s->spectra_per_subint * s->num_subint[ii]; if (ii > 0) { if (s->start_spec[ii] > s->N) { // Need padding s->num_pad[ii-1] = s->start_spec[ii] - s->N; s->N += s->num_pad[ii-1]; } } s->N += s->num_spec[ii]; } // Convert the position strings into degrees { int d, h, m; double sec; ra_dec_from_string(s->ra_str, &h, &m, &sec); s->ra2000 = hms2rad(h, m, sec) * RADTODEG; ra_dec_from_string(s->dec_str, &d, &m, &sec); s->dec2000 = dms2rad(d, m, sec) * RADTODEG; } // Are the polarizations summed? if ((strncmp("AA+BB", s->poln_order, 5)==0) || (strncmp("INTEN", s->poln_order, 5)==0)) s->summed_polns = 1; else s->summed_polns = 0; // Calculate some others s->T = s->N * s->dt; s->orig_df /= (double) s->orig_num_chan; s->samples_per_spectra = s->num_polns * s->num_channels; // Note: the following is the number of bytes that will be in // the returned array from CFITSIO. // CFITSIO turns bits into bytes when FITS_typecode=1 // and we turn 2-bits or 4-bits into bytes if bits_per_sample < 8 if (s->bits_per_sample < 8) s->bytes_per_spectra = s->samples_per_spectra; else s->bytes_per_spectra = (s->bits_per_sample * s->samples_per_spectra) / 8; s->samples_per_subint = s->samples_per_spectra * s->spectra_per_subint; s->bytes_per_subint = s->bytes_per_spectra * s->spectra_per_subint; // Flip the band? if (s->hi_freq < s->lo_freq) { float ftmp = s->hi_freq; s->hi_freq = s->lo_freq; s->lo_freq = ftmp; s->df *= -1.0; s->apply_flipband = 1; } // Compute the bandwidth s->BW = s->num_channels * s->df; // Flip the bytes for Parkes FB_1BIT data if (s->bits_per_sample==1 && strcmp(s->telescope, "Parkes")==0 && strcmp(s->backend, "FB_1BIT")==0) { printf("Flipping bit ordering since Parkes FB_1BIT data.\n"); s->flip_bytes = 1; } else { s->flip_bytes = 0; } // Allocate the buffers cdatabuffer = gen_bvect(s->bytes_per_subint); // Following is twice as big because we use it as a ringbuffer too fdatabuffer = gen_fvect(2 * s->spectra_per_subint * s->num_channels); s->padvals = gen_fvect(s->num_channels); for (ii = 0 ; ii < s->num_channels ; ii++) s->padvals[ii] = 0.0; offsets = gen_fvect(s->num_channels * s->num_polns); scales = gen_fvect(s->num_channels * s->num_polns); weights = gen_fvect(s->num_channels); // Initialize these if we won't be reading them from the file if (s->apply_offset==0) for (ii = 0 ; ii < s->num_channels * s->num_polns ; ii++) offsets[ii] = 0.0; if (s->apply_scale==0) for (ii = 0 ; ii < s->num_channels * s->num_polns ; ii++) scales[ii] = 1.0; if (s->apply_weight==0) for (ii = 0 ; ii < s->num_channels ; ii++) weights[ii] = 1.0; }
void output_fundamentals(fourierprops * props, GSList * list, accelobs * obs, infodata * idata) { double accel = 0.0, accelerr = 0.0, coherent_pow; int ii, jj, numcols = 12, numcands, *width, *error; int widths[12] = { 4, 5, 6, 8, 4, 16, 15, 15, 15, 11, 15, 20 }; int errors[12] = { 0, 0, 0, 0, 0, 1, 1, 2, 1, 2, 2, 0 }; char tmpstr[30], ctrstr[30], *notes; accelcand *cand; GSList *listptr; rzwerrs errs; static char **title; static char *titles1[] = { "", "", "Summed", "Coherent", "Num", "Period", "Frequency", "FFT 'r'", "Freq Deriv", "FFT 'z'", "Accel", "" }; static char *titles2[] = { "Cand", "Sigma", "Power", "Power", "Harm", "(ms)", "(Hz)", "(bin)", "(Hz/s)", "(bins)", "(m/s^2)", "Notes" }; numcands = g_slist_length(list); listptr = list; /* Close the old work file and open the cand file */ if (!obs->dat_input) fclose(obs->workfile); /* Why is this here? -A */ obs->workfile = chkfopen(obs->accelnm, "w"); /* Set our candidate notes to all spaces */ notes = (char *) malloc(numcands * widths[numcols - 1]); memset(notes, ' ', numcands * widths[numcols - 1]); /* Compare the candidates with the pulsar database */ if (dms2rad(idata->ra_h, idata->ra_m, idata->ra_s) != 0.0 && hms2rad(idata->dec_d, idata->dec_m, idata->dec_s) != 0.0) { for (ii = 0; ii < numcands; ii++) { comp_psr_to_cand(props + ii, idata, notes + ii * 20, 0); } } /* Compare the candidates with themselves */ compare_rzw_cands(props, numcands, notes); /* Print the header */ width = widths; title = titles1; for (ii = 0; ii < numcols - 1; ii++) { center_string(ctrstr, *title++, *width++); fprintf(obs->workfile, "%s ", ctrstr); } center_string(ctrstr, *title++, *width++); fprintf(obs->workfile, "%s\n", ctrstr); width = widths; title = titles2; for (ii = 0; ii < numcols - 1; ii++) { center_string(ctrstr, *title++, *width++); fprintf(obs->workfile, "%s ", ctrstr); } center_string(ctrstr, *title++, *width++); fprintf(obs->workfile, "%s\n", ctrstr); width = widths; for (ii = 0; ii < numcols - 1; ii++) { memset(tmpstr, '-', *width); tmpstr[*width++] = '\0'; fprintf(obs->workfile, "%s--", tmpstr); } memset(tmpstr, '-', *width++); tmpstr[widths[ii]] = '\0'; fprintf(obs->workfile, "%s\n", tmpstr); /* Print the fundamentals */ for (ii = 0; ii < numcands; ii++) { width = widths; error = errors; cand = (accelcand *) (listptr->data); calc_rzwerrs(props + ii, obs->T, &errs); { /* Calculate the coherently summed power */ double coherent_r = 0.0, coherent_i = 0.0; double phs0, phscorr, amp; rderivs harm; /* These phase calculations assume the fundamental is best */ /* Better to irfft them and check the amplitude */ phs0 = cand->derivs[0].phs; for (jj = 0; jj < cand->numharm; jj++) { harm = cand->derivs[jj]; if (obs->nph > 0.0) amp = sqrt(harm.pow / obs->nph); else amp = sqrt(harm.pow / harm.locpow); phscorr = phs0 - fmod((jj + 1.0) * phs0, TWOPI); coherent_r += amp * cos(harm.phs + phscorr); coherent_i += amp * sin(harm.phs + phscorr); } coherent_pow = coherent_r * coherent_r + coherent_i * coherent_i; } sprintf(tmpstr, "%-4d", ii + 1); center_string(ctrstr, tmpstr, *width++); error++; fprintf(obs->workfile, "%s ", ctrstr); sprintf(tmpstr, "%.2f", cand->sigma); center_string(ctrstr, tmpstr, *width++); error++; fprintf(obs->workfile, "%s ", ctrstr); sprintf(tmpstr, "%.2f", cand->power); center_string(ctrstr, tmpstr, *width++); error++; fprintf(obs->workfile, "%s ", ctrstr); sprintf(tmpstr, "%.2f", coherent_pow); center_string(ctrstr, tmpstr, *width++); error++; fprintf(obs->workfile, "%s ", ctrstr); sprintf(tmpstr, "%d", cand->numharm); center_string(ctrstr, tmpstr, *width++); error++; fprintf(obs->workfile, "%s ", ctrstr); write_val_with_err(obs->workfile, errs.p * 1000.0, errs.perr * 1000.0, *error++, *width++); write_val_with_err(obs->workfile, errs.f, errs.ferr, *error++, *width++); write_val_with_err(obs->workfile, props[ii].r, props[ii].rerr, *error++, *width++); write_val_with_err(obs->workfile, errs.fd, errs.fderr, *error++, *width++); write_val_with_err(obs->workfile, props[ii].z, props[ii].zerr, *error++, *width++); accel = props[ii].z * SOL / (obs->T * obs->T * errs.f); accelerr = props[ii].zerr * SOL / (obs->T * obs->T * errs.f); write_val_with_err(obs->workfile, accel, accelerr, *error++, *width++); fprintf(obs->workfile, " %.20s\n", notes + ii * 20); fflush(obs->workfile); listptr = listptr->next; } fprintf(obs->workfile, "\n\n"); free(notes); }
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); }
int comp_rawbin_to_cand(rawbincand * cand, infodata * idata, char *output, int full) /* Compares a binary PSR candidate defined by its props found in */ /* *cand, and *idata with all of the pulsars in the pulsar */ /* database. It returns a string (verbose if full==1) describing */ /* the results of the search in *output. */ { int ii, jj, kk; static int np; double theop, ra, dec, beam2, difft = 0.0, epoch; double bmod, pmod, orbperr, psrperr; char tmp1[80], tmp2[80], tmp3[80]; /* Read the database if needed */ if (!have_database) np = read_database(); /* Convert the beam width to radians */ beam2 = 2.0 * ARCSEC2RAD * idata->fov; /* Convert RA and DEC to radians (Use J2000) */ ra = hms2rad(idata->ra_h, idata->ra_m, idata->ra_s); dec = dms2rad(idata->dec_d, idata->dec_m, idata->dec_s); /* Calculate the time related variables */ epoch = (double) idata->mjd_i + idata->mjd_f; /* Calculate the approximate error in our value of orbital period */ orbperr = 0.5 * cand->full_T / cand->mini_N; /* Calculate the approximate error in our value of spin period */ if (cand->full_lo_r == 0.0) psrperr = cand->psr_p; else psrperr = fabs(cand->full_T / (cand->full_lo_r + 0.5 * cand->mini_N) - cand->full_T / cand->full_lo_r); /* Run through RAs in database looking for things close */ /* If find one, check the DEC as well (the angle between */ /* the sources < 2*beam diam). If find one, check its */ /* period. If this matches within 2*perr, return the */ /* number of the pulsar. If no matches, return 0. */ for (ii = 0; ii < np; ii++) { /* See if we're close in RA */ if (fabs(pulsardata[ii].ra2000 - ra) < 5.0 * beam2) { /* See if we're close in RA and DEC */ if (sphere_ang_diff(pulsardata[ii].ra2000, pulsardata[ii].dec2000, ra, dec) < 5.0 * beam2) { /* Check that the psr in the database is in a binary */ if (pulsardata[ii].orb.p != 0.0) { /* Predict the period of the pulsar at the observation MJD */ difft = SECPERDAY * (epoch - pulsardata[ii].timepoch); theop = pulsardata[ii].p + pulsardata[ii].pd * difft; /* Check the predicted period and its harmonics against the */ /* measured period. Use both pulsar and binary periods. */ for (jj = 1; jj < 41; jj++) { pmod = 1.0 / (double) jj; if (fabs(theop * pmod - cand->psr_p) < psrperr) { for (kk = 1; kk < 10; kk++) { bmod = (double) kk; if (fabs (pulsardata[ii].orb.p * bmod - cand->orb_p / SECPERDAY) < orbperr) { if (strlen(pulsardata[ii].bname) == 0) { if (jj > 1) { if (full) { sprintf(tmp1, "Possibly the %s phasemod harmonic ", num[kk]); sprintf(tmp2, "of the %s harmonic of PSR ", num[jj]); sprintf(tmp3, "J%s (p = %11.7f s, pbin = %9.4f d).\n", pulsardata[ii].jname, theop, pulsardata[ii].orb.p); sprintf(output, "%s%s%s", tmp1, tmp2, tmp3); } else { sprintf(output, "%s H J%.12s", num[kk], pulsardata[ii].jname); } } else { if (full) { sprintf(tmp1, "Possibly the %s phasemod harmonic ", num[kk]); sprintf(tmp2, "of PSR J%s (p = %11.7f s, pbin = %9.4f d).\n", pulsardata[ii].jname, theop, pulsardata[ii].orb.p); sprintf(output, "%s%s", tmp1, tmp2); } else { sprintf(output, "PSR J%.12s", pulsardata[ii].jname); } } } else { if (jj > 1) { if (full) { sprintf(tmp1, "Possibly the %s modulation harmonic ", num[kk]); sprintf(tmp2, "of the %s harmonic of PSR ", num[jj]); sprintf(tmp3, "B%s (p = %11.7f s, pbin = %9.4f d).\n", pulsardata[ii].bname, theop, pulsardata[ii].orb.p); sprintf(output, "%s%s%s", tmp1, tmp2, tmp3); } else { sprintf(output, "%s H B%s", num[kk], pulsardata[ii].bname); } } else { if (full) { sprintf(tmp1, "Possibly the %s phasemod harmonic ", num[kk]); sprintf(tmp2, "of PSR B%s (p = %11.7f s, pbin = %9.4f d).\n", pulsardata[ii].bname, theop, pulsardata[ii].orb.p); sprintf(output, "%s%s", tmp1, tmp2); } else { sprintf(output, "PSR B%s", pulsardata[ii].bname); } } } } return ii + 1; } } } } } } } /* Didn't find a match */ if (full) { sprintf(output, "I don't recognize this candidate in the pulsar database.\n"); } else { sprintf(output, " "); } return 0; }
int comp_psr_to_cand(fourierprops * cand, infodata * idata, char *output, int full) /* Compares a pulsar candidate defined by its properties found in */ /* *cand, and *idata with all of the pulsars in the pulsar */ /* database. It returns a string (verbose if full==1) describing */ /* the results of the search in *output. */ { int ii, jj; static infodata *old_idata; double theor, theoz, sidedr = 20.0; double r_criteria, z_criteria, rdiff, zdiff, difft = 0; static double T, beam2, ra, dec, epoch; char tmp1[80], tmp2[80], tmp3[80], shortout[30], psrname[20]; rzwerrs rzws; /* Read the database if needed */ if (!have_database) np = read_database(); /* If calling for the first time for a certain data set, */ /* initialize some values. */ if (idata != old_idata) { /* Convert the beam width to radians */ beam2 = 2.0 * ARCSEC2RAD * idata->fov; /* Convert RA and DEC to radians (Use J2000) */ ra = hms2rad(idata->ra_h, idata->ra_m, idata->ra_s); dec = dms2rad(idata->dec_d, idata->dec_m, idata->dec_s); T = idata->N * idata->dt; epoch = (double) idata->mjd_i + idata->mjd_f + T / (2.0 * SECPERDAY); /* Set up old_idata for next time */ old_idata = idata; } /* Calculate the measured r, z, w's and their derivatives */ calc_rzwerrs(cand, T, &rzws); /* Run through RAs in database looking for things close */ /* If find one, check the DEC as well (the angle between */ /* the sources < 2*beam diam). If find one, check its */ /* period. If this matches within 2*perr, return the */ /* number of the pulsar. If no matches, return 0. */ for (ii = 0; ii < np; ii++) { /* See if we're close in RA */ if (fabs(pulsardata[ii].ra2000 - ra) < 5 * beam2) { /* See if we're close in RA and DEC */ if (sphere_ang_diff(pulsardata[ii].ra2000, pulsardata[ii].dec2000, ra, dec) < 5 * beam2) { /* Predict the period of the pulsar at the observation MJD */ difft = SECPERDAY * (epoch - pulsardata[ii].timepoch); theor = T / (pulsardata[ii].p + pulsardata[ii].pd * difft); theoz = -pulsardata[ii].pd * theor * theor; /* Check the predicted period and its harmonics against the */ /* measured period. */ for (jj = 1; jj < 41; jj++) { /* If the psr from the database is in a */ /* binary orbit, loosen the match criteria. */ /* This accounts for Doppler variations in period. */ if (pulsardata[ii].orb.p != 0.0) { r_criteria = 0.001 * theor * jj; /* 0.1% fractional error */ z_criteria = 9999999999.0; /* Always match for binary */ strcpy(tmp1, "?"); if (full) { strcpy(tmp3, "Possibly (large error) "); } } else { r_criteria = 5.0; /* 5 bin error matching... */ z_criteria = 9999999999.0; /* Always match for binary */ /* z_criteria = 2.5 * cand->zerr; */ strcpy(tmp1, ""); if (full) { strcpy(tmp3, "Looks like "); } } if (theor * jj > 1.5 * cand->r) break; rdiff = fabs(theor * jj - cand->r); zdiff = fabs(theoz * jj - cand->z); if (rdiff < r_criteria && zdiff < z_criteria) { if (strlen(pulsardata[ii].bname) == 0) sprintf(psrname, "J%s", pulsardata[ii].jname); else sprintf(psrname, "B%s", pulsardata[ii].bname); if (jj == 1) { if (full) { sprintf(tmp1, "the fundamental of "); sprintf(tmp2, "PSR %s. (predicted p = %11.7f s).\n", psrname, T / theor); sprintf(output, "%s%s\n %s", tmp3, tmp1, tmp2); } else { sprintf(shortout, "PSR %s%s", psrname, tmp1); strncpy(output, shortout, 20); } } else { if (full) { sprintf(tmp1, "the %s harmonic of ", num[jj]); sprintf(tmp2, "PSR %s. (predicted p = %11.7f s).\n", psrname, T / theor); sprintf(output, "%s%s\n %s", tmp3, tmp1, tmp2); } else { sprintf(shortout, "%s H %s%s", num[jj], psrname, tmp1); strncpy(output, shortout, 20); } } return ii + 1; } else if (rdiff < sidedr) { if (strlen(pulsardata[ii].bname) == 0) sprintf(psrname, "J%s", pulsardata[ii].jname); else sprintf(psrname, "B%s", pulsardata[ii].bname); if (full) { sprintf(tmp1, "a sidelobe of the %s harmonic of ", num[jj]); sprintf(tmp2, "PSR %s. (predicted p = %11.7f s).\n", psrname, T / theor); sprintf(output, "%s%s\n %s", tmp3, tmp1, tmp2); } else { sprintf(shortout, "SL H%d %s", jj, psrname); strncpy(output, shortout, 20); } return ii + 1; } } } } } /* Didn't find a match */ if (full) { sprintf(output, "I don't recognize this candidate in the pulsar database.\n"); } else { strncpy(output, " ", 20); } return 0; }
int get_psr_from_parfile(char *parfilenm, double epoch, psrparams * psr) /* Converts info from a "par" file to the "current" epoch. */ /* Returned values go in *psr. The name of the parfile is */ /* in *parfilenm. epoch is the time in question in MJD. */ /* The int returned is 1 if successful, 0 otherwise. */ { FILE *parfile; int binary = 0; double orbdifft = 0.0, difft = 0.0, f = 0.0, fd = 0.0; double eps1 = 0.0, eps2 = 0.0, eps1d = 0.0, eps2d = 0.0, ed = 0.0, xd = 0.0; char line[80], *keyword, *value; psr->f = psr->fd = psr->fdd = psr->p = psr->pd = psr->pdd = psr->dm = 0.0; psr->orb.p = psr->orb.pd = psr->orb.x = psr->orb.e = 0.0; psr->orb.w = psr->orb.wd = psr->orb.t = 0.0; parfile = chkfopen(parfilenm, "r"); while (fgets(line, 80, parfile)) { keyword = strtok(line, " \t\n"); if (keyword != NULL) { if (strncmp("PSR", keyword, 80) == 0 || strncmp("PSRJ", keyword, 80) == 0) { strncpy(psr->jname, strtok(NULL, " \t\n"), 20); if (psr->jname[0] == 'J' || psr->jname[0] == 'B') { int ii = 0; do { ii++; psr->jname[ii - 1] = psr->jname[ii]; } while (psr->jname[ii] != '\0'); } if (DEBUGOUT) printf("The pulsar is '%s'\n", psr->jname); } else if (strncmp("RAJ", keyword, 80) == 0 || strncmp("RA", keyword, 80) == 0) { int h, m; double s; ra_dec_from_string(strtok(NULL, " \t\n"), &h, &m, &s); psr->ra2000 = hms2rad(h, m, s); if (DEBUGOUT) printf("The RA is %d %d %f (%f)\n", h, m, s, psr->ra2000); } else if (strncmp("DECJ", keyword, 80) == 0 || strncmp("DEC", keyword, 80) == 0) { int d, m; double s; ra_dec_from_string(strtok(NULL, " \t\n"), &d, &m, &s); psr->dec2000 = dms2rad(d, m, s); if (DEBUGOUT) printf("The DEC is %d %d %f (%f)\n", d, m, s, psr->dec2000); } else if (strncmp("F0", keyword, 80) == 0 || strncmp("F", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); f = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf("The freq is %.15g\n", f); } else if (strncmp("P0", keyword, 80) == 0 || strncmp("P", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); f = 1.0 / strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf("The period is %.15g\n", 1.0 / f); } else if (strncmp("F1", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); fd = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf("The f-dot is %.15g\n", fd); } else if (strncmp("P1", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); fd = -strtod(fortran_double_convert(value), &value) * f * f; if (DEBUGOUT) printf("The p-dot is %.15g\n", -fd / (f * f)); } else if (strncmp("F2", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->fdd = strtod(fortran_double_convert(value), &value); psr->pdd = (2.0 * (fd * fd) / f - psr->fdd) / (f * f); if (DEBUGOUT) printf("The f-dotdot is %.15g\n", psr->fdd); } else if (strncmp("PEPOCH", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->timepoch = strtod(fortran_double_convert(value), &value); difft = (epoch - psr->timepoch) * SECPERDAY; if (DEBUGOUT) printf("The PEPOCH is %.15g\n", psr->timepoch); } else if (strncmp("DM", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->dm = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf("The DM is %.15g\n", psr->dm); } else if (strncmp("BINARY", keyword, 80) == 0) { binary = 1; value = strtok(NULL, " \t\n"); if (DEBUGOUT) printf("This is a binary PSR ('%s')...\n", value); } else if (strncmp("PB", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->orb.p = strtod(fortran_double_convert(value), &value) * SECPERDAY; if (DEBUGOUT) printf(" P_orb = %.15g\n", psr->orb.p); } else if (strncmp("PBDOT", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->orb.pd = strtod(fortran_double_convert(value), &value) * 1.0E-12; if (DEBUGOUT) printf(" P_orb-dot = %.15g\n", psr->orb.pd); } else if (strncmp("OM", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->orb.w = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf(" w_orb = %.15g\n", psr->orb.w); } else if (strncmp("OMDOT", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->orb.wd = strtod(fortran_double_convert(value), &value) / SECPERJULYR; if (DEBUGOUT) printf(" w_orb-dot = %.15g\n", psr->orb.wd); } else if (strncmp("A1", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->orb.x = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf(" x_orb = %.15g\n", psr->orb.x); } else if (strncmp("XDOT", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); xd = strtod(fortran_double_convert(value), &value) * 1.0E-12; if (DEBUGOUT) printf(" x_orb-dot = %.15g\n", xd); } else if (strncmp("E", keyword, 80) == 0 || strncmp("ECC", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->orb.e = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf(" e_orb = %.15g\n", psr->orb.e); } else if (strncmp("EDOT", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); ed = strtod(fortran_double_convert(value), &value) * 1.0E-12; if (DEBUGOUT) printf(" e_orb-dot = %.15g\n", ed); } else if (strncmp("T0", keyword, 80) == 0 || strncmp("TASC", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); psr->orb.t = strtod(fortran_double_convert(value), &value); /* TEMPO bases the orbital params on T0, not PEPOCH */ orbdifft = (epoch - psr->orb.t) * SECPERDAY; if (DEBUGOUT) printf(" T_orb = %.15g\n", psr->orb.t); } else if (strncmp("EPS1", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); eps1 = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf(" EPS1 = %.15g\n", eps1); } else if (strncmp("EPS2", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); eps2 = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf(" EPS2 = %.15g\n", eps2); } else if (strncmp("EPS1DOT", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); eps1d = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf(" EPS1DOT = %.15g\n", eps1d); } else if (strncmp("EPS2DOT", keyword, 80) == 0) { value = strtok(NULL, " \t\n"); eps2d = strtod(fortran_double_convert(value), &value); if (DEBUGOUT) printf(" EPS2DOT = %.15g\n", eps2d); } else if (strncmp("OM2DOT", keyword, 80) == 0 || strncmp("X2DOT", keyword, 80) == 0 || strncmp("F3", keyword, 80) == 0 || strncmp("F4", keyword, 80) == 0 || strncmp("F5", keyword, 80) == 0) { printf(" readpar: Warning! '%s' is currently unused!\n", keyword); } } } /* Update the spin parameters */ psr->f = f + fd * difft + 0.5 * psr->fdd * difft * difft; psr->fd = fd + psr->fdd * difft; psr->p = 1.0 / psr->f; psr->pd = -psr->fd * psr->p * psr->p; psr->pdd = (2.0 * (fd * fd) / f - psr->fdd) / (f * f); if (binary) { psr->orb.p += psr->orb.pd * orbdifft; psr->orb.w += psr->orb.wd * orbdifft; psr->orb.x += xd * orbdifft; psr->orb.e += ed * orbdifft; eps1 += eps1d * orbdifft; eps2 += eps1d * orbdifft; if (eps1 != 0.0 || eps2 != 0.0) { /* Convert Laplace-Lagrange params to e and w */ /* Warning! This is presently untested! */ psr->orb.e = sqrt(eps1 * eps1 + eps2 * eps2); psr->orb.w = atan2(eps1, eps2); psr->orb.t += psr->orb.p / SECPERDAY * (psr->orb.w / TWOPI); psr->orb.w *= RADTODEG; } /* psr->orb.t is in seconds, _not_ MJD. It represents the */ /* time in sec _since_ the last periastron passage, _not_ */ /* when the next periastron will occur.... */ psr->orb.t = fmod((epoch - psr->orb.t) * SECPERDAY, psr->orb.p); if (psr->orb.t < 0.0) psr->orb.t += psr->orb.p; psr->orb.w = fmod(psr->orb.w, 360.0); } fclose(parfile); return 1; }