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; }
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; }