GSList *search_ffdotpows(ffdotpows * ffdot, int numharm, accelobs * obs, GSList * cands) { int ii, jj; float powcut; long long numindep; powcut = obs->powcut[twon_to_index(numharm)]; numindep = obs->numindep[twon_to_index(numharm)]; for (ii = 0; ii < ffdot->numzs; ii++) { for (jj = 0; jj < ffdot->numrs; jj++) { if (ffdot->powers[ii][jj] > powcut) { float pow, sig; double rr, zz; int added = 0; pow = ffdot->powers[ii][jj]; sig = candidate_sigma(pow, numharm, numindep); rr = (ffdot->rlo + jj * (double) ACCEL_DR) / (double) numharm; zz = (ffdot->zlo + ii * (double) ACCEL_DZ) / (double) numharm; cands = insert_new_accelcand(cands, pow, sig, numharm, rr, zz, &added); if (added && !obs->dat_input) fprintf(obs->workfile, "%-7.2f %-7.4f %-2d %-14.4f %-14.9f %-10.4f\n", pow, sig, numharm, rr, rr / obs->T, zz); } } } return cands; }
void output_harmonics(GSList * list, accelobs * obs, infodata * idata) { int ii, jj, numcols = 13, numcands; int widths[13] = { 5, 4, 5, 15, 11, 18, 13, 12, 9, 12, 10, 10, 20 }; int errors[13] = { 0, 0, 0, 2, 0, 2, 0, 2, 0, 2, 2, 2, 0 }; char tmpstr[30], ctrstr[30], notes[21], *command; accelcand *cand; GSList *listptr; fourierprops props; rzwerrs errs; static char *titles1[] = { "", "", "", "Power /", "Raw", "FFT 'r'", "Pred 'r'", "FFT 'z'", "Pred 'z'", "Phase", "Centroid", "Purity", "" }; static char *titles2[] = { "Cand", "Harm", "Sigma", "Loc Pow", "Power", "(bin)", "(bin)", "(bins)", "(bins)", "(rad)", "(0-1)", "<p> = 1", "Notes" }; numcands = g_slist_length(list); listptr = list; /* Print the header */ for (ii = 0; ii < numcols - 1; ii++) { center_string(ctrstr, titles1[ii], widths[ii]); fprintf(obs->workfile, "%s ", ctrstr); } center_string(ctrstr, titles1[ii], widths[ii]); fprintf(obs->workfile, "%s\n", ctrstr); for (ii = 0; ii < numcols - 1; ii++) { if (obs->nph > 0.0 && ii == 3) /* HAAACK!!! */ center_string(ctrstr, "NumPhot", widths[ii]); else center_string(ctrstr, titles2[ii], widths[ii]); fprintf(obs->workfile, "%s ", ctrstr); } center_string(ctrstr, titles2[ii], widths[ii]); fprintf(obs->workfile, "%s\n", ctrstr); for (ii = 0; ii < numcols - 1; ii++) { memset(tmpstr, '-', widths[ii]); tmpstr[widths[ii]] = '\0'; fprintf(obs->workfile, "%s--", tmpstr); } memset(tmpstr, '-', widths[ii]); tmpstr[widths[ii]] = '\0'; fprintf(obs->workfile, "%s\n", tmpstr); /* Print the fundamentals */ for (ii = 0; ii < numcands; ii++) { cand = (accelcand *) (listptr->data); for (jj = 0; jj < cand->numharm; jj++) { if (obs->nph > 0.0) { double tmp_locpow; tmp_locpow = cand->derivs[jj].locpow; cand->derivs[jj].locpow = obs->nph; calc_props(cand->derivs[jj], cand->hirs[jj], cand->hizs[jj], 0.0, &props); cand->derivs[jj].locpow = tmp_locpow; } else { calc_props(cand->derivs[jj], cand->hirs[jj], cand->hizs[jj], 0.0, &props); } calc_rzwerrs(&props, obs->T, &errs); comp_psr_to_cand(&props, idata, notes, 0); if (jj == 0) sprintf(tmpstr, " %-4d", ii + 1); else sprintf(tmpstr, " "); center_string(ctrstr, tmpstr, widths[0]); fprintf(obs->workfile, "%s ", ctrstr); sprintf(tmpstr, "%-4d", jj + 1); center_string(ctrstr, tmpstr, widths[1]); fprintf(obs->workfile, "%s ", ctrstr); sprintf(tmpstr, "%.2f", candidate_sigma(props.pow, 1, 1)); center_string(ctrstr, tmpstr, widths[2]); fprintf(obs->workfile, "%s ", ctrstr); write_val_with_err(obs->workfile, props.pow, props.powerr, errors[3], widths[3]); sprintf(tmpstr, "%.3g", props.rawpow); center_string(ctrstr, tmpstr, widths[4]); fprintf(obs->workfile, "%s ", ctrstr); write_val_with_err(obs->workfile, props.r, props.rerr, errors[5], widths[5]); sprintf(tmpstr, "%.2f", cand->r * (jj + 1)); center_string(ctrstr, tmpstr, widths[6]); fprintf(obs->workfile, "%s ", ctrstr); write_val_with_err(obs->workfile, props.z, props.zerr, errors[7], widths[7]); sprintf(tmpstr, "%.2f", cand->z * (jj + 1)); center_string(ctrstr, tmpstr, widths[8]); fprintf(obs->workfile, "%s ", ctrstr); write_val_with_err(obs->workfile, props.phs, props.phserr, errors[9], widths[9]); write_val_with_err(obs->workfile, props.cen, props.cenerr, errors[10], widths[10]); write_val_with_err(obs->workfile, props.pur, props.purerr, errors[11], widths[11]); fprintf(obs->workfile, " %.20s\n", notes); fflush(obs->workfile); } listptr = listptr->next; } fprintf(obs->workfile, "\n\n"); fclose(obs->workfile); command = malloc(strlen(obs->rootfilenm) + strlen(obs->accelnm) + 20); sprintf(command, "cat %s.inf >> %s", obs->rootfilenm, obs->accelnm); system(command); free(command); }
// FIXME: this shouldn't be a #define, or it shouldn't be here void optimize_accelcand(accelcand * cand, accelobs * obs) { int ii; int *r_offset; fcomplex **data; double r, z; cand->pows = gen_dvect(cand->numharm); cand->hirs = gen_dvect(cand->numharm); cand->hizs = gen_dvect(cand->numharm); r_offset = (int*) malloc(sizeof(int)*cand->numharm); data = (fcomplex**) malloc(sizeof(fcomplex*)*cand->numharm); cand->derivs = (rderivs *) malloc(sizeof(rderivs) * cand->numharm); if (obs->use_harmonic_polishing) { if (obs->mmap_file || obs->dat_input) { for(ii=0;ii<cand->numharm;ii++) { r_offset[ii]=obs->lobin; data[ii] = obs->fft; } max_rz_arr_harmonics(data, cand->numharm, r_offset, obs->numbins, cand->r-obs->lobin, cand->z, &r, &z, cand->derivs, cand->pows); } else { max_rz_file_harmonics(obs->fftfile, cand->numharm, obs->lobin, cand->r-obs->lobin, cand->z, &r, &z, cand->derivs, cand->pows); } for(ii=0;ii<cand->numharm;ii++) { cand->hirs[ii]=(r+obs->lobin)*(ii+1); cand->hizs[ii]=z*(ii+1); } } else { for (ii = 0; ii < cand->numharm; ii++) { if (obs->mmap_file || obs->dat_input) cand->pows[ii] = max_rz_arr(obs->fft, obs->numbins, cand->r * (ii + 1) - obs->lobin, cand->z * (ii + 1), &(cand->hirs[ii]), &(cand->hizs[ii]), &(cand->derivs[ii])); else cand->pows[ii] = max_rz_file(obs->fftfile, cand->r * (ii + 1) - obs->lobin, cand->z * (ii + 1), &(cand->hirs[ii]), &(cand->hizs[ii]), &(cand->derivs[ii])); cand->hirs[ii] += obs->lobin; } } free(r_offset); free(data); cand->sigma = candidate_sigma(cand->power, cand->numharm, obs->numindep[twon_to_index(cand->numharm)]); }
void search_minifft(fcomplex * minifft, int numminifft, double min_orb_p, double max_orb_p, rawbincand * cands, int numcands, int numharmsum, int numbetween, double numfullfft, double timefullfft, double lorfullfft, presto_interptype interptype, presto_checkaliased checkaliased) /* This routine searches a short FFT (usually produced using the */ /* MiniFFT binary search method) and returns a candidte vector */ /* containing information about the best binary candidates found. */ /* The routine uses either interbinning or interpolation as well */ /* as harmonic summing during the search. */ /* Arguments: */ /* 'minifft' is the FFT to search (complex valued) */ /* 'numminifft' is the number of complex points in 'minifft' */ /* 'min_orb_p' is the minimum orbital period (s) to search */ /* 'max_orb_p' is the maximum orbital period (s) to search */ /* 'cands' is a pre-allocated vector of rawbincand type in which */ /* the sorted (in decreasing sigma) candidates are returned */ /* 'numcands' is the length of the 'cands' vector */ /* 'numharmsum' the number of harmonics to sum during the search */ /* 'numbetween' the points to interpolate per bin */ /* 'numfullfft' the number of points in the original long FFT */ /* 'timefullfft' the duration of the original time series (s) */ /* 'lorfullfft' the 1st bin of the long FFT that was miniFFT'd */ /* 'interptype' is either INTERBIN or INTERPOLATE. */ /* INTERBIN = (interbinning) is fast but less sensitive. */ /* NOTE: INTERBINNING is conducted by this routine! */ /* INTERPOLATE = (Fourier interpolation) is slower but more */ /* sensitive. */ /* NOTE: The interpolation is assumed to ALREADY have been */ /* completed by the calling function! The easiest */ /* way is by zero-padding to 2*numminifft and FFTing. */ /* If you use this method, make sure numminifft is the*/ /* original length rather than the interpolated */ /* length and also make sure numbetween is correct. */ /* 'checkaliased' is either CHECK_ALIASED or NO_CHECK_ALIASED. */ /* NO_CHECK_ALIASED = harmonic summing does not include */ /* aliased freqs making it faster but less sensitive. */ /* CHECK_ALIASED = harmonic summing includes aliased freqs */ /* making it slower but more sensitive. */ { int ii, jj, fftlen, offset, numtosearch = 0, lobin, hibin, numspread = 0; float powargr, powargi, *fullpows = NULL, *sumpows; double twobypi, minpow, minsig, dr, numindep; fcomplex *spread; /* Override the value of numbetween if interbinning */ if (interptype == INTERBIN) numbetween = 2; /* Prep some other values we will need */ dr = 1.0 / (double) numbetween; twobypi = 2.0 / PI; fftlen = numminifft * numbetween; for (ii = 0; ii < numcands; ii++) { cands[ii].mini_sigma = 0.0; cands[ii].mini_power = 0.0; } lobin = ceil(2 * numminifft * min_orb_p / timefullfft); if (lobin <= 0) lobin = 1; hibin = floor(2 * numminifft * max_orb_p / timefullfft); if (hibin >= 2 * numminifft) hibin = 2 * numminifft - 1; lobin *= numbetween; hibin *= numbetween; /* Spread and interpolate the fft */ numtosearch = (checkaliased == CHECK_ALIASED) ? 2 * fftlen : fftlen; numspread = numminifft * numbetween + 1; if (interptype == INTERPOLATE) { /* INTERPOLATE */ spread = minifft; } else { /* INTERBIN */ spread = gen_cvect(numspread); spread_with_pad(minifft, numminifft, spread, numspread, numbetween, 0); for (ii = 1; ii < fftlen; ii += 2) { spread[ii].r = twobypi * (spread[ii - 1].r - spread[ii + 1].r); spread[ii].i = twobypi * (spread[ii - 1].i - spread[ii + 1].i); } } spread[0].r = spread[fftlen].r = 1.0; spread[0].i = spread[fftlen].i = 0.0; fullpows = gen_fvect(numtosearch); fullpows[0] = 1.0; if (checkaliased == CHECK_ALIASED) fullpows[fftlen] = 1.0; /* used to be nyquist^2 */ /* The following wraps the data around the Nyquist freq such that */ /* we consider aliased frequencies as well (If CHECK_ALIASED). */ if (checkaliased == CHECK_ALIASED) for (ii = 1, jj = numtosearch - 1; ii < fftlen; ii++, jj--) fullpows[ii] = fullpows[jj] = POWER(spread[ii].r, spread[ii].i); else for (ii = 1; ii < numtosearch; ii++) fullpows[ii] = POWER(spread[ii].r, spread[ii].i); if (interptype == INTERBIN) vect_free(spread); /* Search the raw powers */ numindep = hibin - lobin + 1.0; minpow = power_for_sigma(MINRETURNSIG, 1, numindep); for (ii = lobin; ii < hibin; ii++) { if (fullpows[ii] > minpow) { cands[numcands - 1].mini_r = dr * (double) ii; cands[numcands - 1].mini_power = fullpows[ii]; cands[numcands - 1].mini_numsum = 1.0; cands[numcands - 1].mini_sigma = candidate_sigma(fullpows[ii], 1, numindep); minsig = percolate_rawbincands(cands, numcands); if (cands[numcands - 1].mini_power > minpow) minpow = cands[numcands - 1].mini_power; } } /* If needed, sum and search the harmonics */ if (numharmsum > 1) { sumpows = gen_fvect(numtosearch); memcpy(sumpows, fullpows, sizeof(float) * numtosearch); for (ii = 2; ii <= numharmsum; ii++) { offset = ii / 2; numindep = (hibin - lobin + 1.0) / (double) ii; if (cands[numcands - 1].mini_sigma < MINRETURNSIG) minsig = MINRETURNSIG; else minsig = cands[numcands - 1].mini_sigma; minpow = power_for_sigma(minsig, ii, numindep); for (jj = lobin * ii; jj < hibin; jj++) { sumpows[jj] += fullpows[(jj + offset) / ii]; if (sumpows[jj] > minpow) { cands[numcands - 1].mini_r = (dr * (double) jj) / ii; cands[numcands - 1].mini_power = sumpows[jj]; cands[numcands - 1].mini_numsum = (double) ii; cands[numcands - 1].mini_sigma = candidate_sigma(sumpows[jj], ii, numindep); minsig = percolate_rawbincands(cands, numcands); if (minsig > MINRETURNSIG) minpow = power_for_sigma(minsig, ii, numindep); } } } vect_free(sumpows); } vect_free(fullpows); /* Add the rest of the rawbincand data to the candidate array */ for (ii = 0; ii < numcands; ii++) { cands[ii].full_N = numfullfft; cands[ii].full_T = timefullfft; cands[ii].full_lo_r = lorfullfft; cands[ii].mini_N = 2 * numminifft; /* # of real points */ cands[ii].psr_p = timefullfft / (lorfullfft + numminifft); cands[ii].orb_p = timefullfft * cands[ii].mini_r / cands[ii].mini_N; } }
fftcand *search_fft(fcomplex * fft, int numfft, int lobin, int hibin, int numharmsum, int numbetween, presto_interptype interptype, float norm, float sigmacutoff, int *numcands, float *powavg, float *powvar, float *powmax) /* This routine searches a short FFT of 'numfft' complex freqs */ /* and returns a candidate vector of fftcand structures containing */ /* information about the best candidates found. */ /* The routine uses either interbinning or interpolation as well */ /* as harmonic summing during the search. */ /* The number of candidates returned is either 'numcands' if != 0, */ /* or is determined automatically by 'sigmacutoff' -- which */ /* takes into account the number of bins searched. */ /* The returned vector is sorted in order of decreasing power. */ /* Arguments: */ /* 'fft' is the FFT to search (complex valued) */ /* 'numfft' is the number of complex points in 'fft' */ /* 'lobin' is the lowest Fourier freq to search */ /* 'hibin' is the highest Fourier freq to search */ /* 'numharmsum' the number of harmonics to sum during the search */ /* 'numbetween' the points to interpolate per bin */ /* 'interptype' is either INTERBIN or INTERPOLATE. */ /* INTERBIN = (interbinning) is fast but less sensitive. */ /* NOTE: INTERBINNING is conducted by this routine! */ /* INTERPOLATE = (Fourier interpolation) is slower but more */ /* sensitive. */ /* NOTE: The interpolation is assumed to ALREADY have been */ /* completed by the calling function! The easiest */ /* way is by zero-padding to 2*numfft and FFTing. */ /* If you use this method, make sure numfft is the */ /* original length rather than the interpolated */ /* length and also make sure numbetween is correct. */ /* 'norm' is the normalization constant to multiply each power by */ /* 'sigmacutoff' if the number of candidates will be determined */ /* automatically, is the minimum Gaussian significance of */ /* candidates to keep -- taking into account the number of */ /* bins searched */ /* 'numcands' if !0, is the number of candates to return. */ /* if 0, is a return value giving the number of candidates. */ /* 'powavg' is a return value giving the average power level */ /* 'powvar' is a return value giving the power level variance */ /* 'powmax' is a return value giving the maximum power */ { int ii, jj, offset, numtosearch, dynamic = 0; int numspread = 0, nc = 0, startnc = 10; float powargr, powargi, *fullpows = NULL, *sumpows, ftmp; double twobypi, minpow = 0.0, tmpminsig = 0.0, dr, davg, dvar; fftcand *cands, newcand; fcomplex *spread; /* Override the value of numbetween if interbinning */ if (interptype == INTERBIN) numbetween = 2; norm = 1.0 / norm; *powmax = 0.0; /* Decide if we will manage the number of candidates */ if (*numcands > 0) startnc = *numcands; else { dynamic = 1; minpow = power_for_sigma(sigmacutoff, 1, hibin - lobin); } cands = (fftcand *) malloc(startnc * sizeof(fftcand)); for (ii = 0; ii < startnc; ii++) cands[ii].sig = 0.0; /* Prep some other values we will need */ dr = 1.0 / (double) numbetween; twobypi = 2.0 / PI; numtosearch = numfft * numbetween; /* Spread and interpolate the fft */ numspread = numfft * numbetween + 1; if (interptype == INTERPOLATE) { /* INTERPOLATE */ spread = fft; } else { /* INTERBIN */ spread = gen_cvect(numspread); spread_with_pad(fft, numfft, spread, numspread, numbetween, 0); for (ii = 1; ii < numtosearch; ii += 2) { spread[ii].r = twobypi * (spread[ii - 1].r - spread[ii + 1].r); spread[ii].i = twobypi * (spread[ii - 1].i - spread[ii + 1].i); } } spread[0].r = spread[numtosearch].r = 1.0; spread[0].i = spread[numtosearch].i = 0.0; /* First generate the original powers in order to */ /* calculate the statistics. Yes, this is inefficient... */ fullpows = gen_fvect(numtosearch); for (ii = lobin, jj = 0; ii < hibin; ii++, jj++) { ftmp = POWER(fft[ii].r, fft[ii].i) * norm; fullpows[jj] = ftmp; if (ftmp > *powmax) *powmax = ftmp; } avg_var(fullpows, hibin - lobin, &davg, &dvar); *powavg = davg; *powvar = dvar; fullpows[0] = 1.0; for (ii = 1; ii < numtosearch; ii++) fullpows[ii] = POWER(spread[ii].r, spread[ii].i) * norm; if (interptype == INTERBIN) vect_free(spread); /* Search the raw powers */ for (ii = lobin * numbetween; ii < hibin * numbetween; ii++) { if (fullpows[ii] > minpow) { newcand.r = dr * (double) ii; newcand.p = fullpows[ii]; newcand.sig = candidate_sigma(fullpows[ii], 1, hibin - lobin); newcand.nsum = 1; cands[startnc - 1] = newcand; tmpminsig = percolate_fftcands(cands, startnc); if (dynamic) { nc++; if (nc == startnc) { startnc *= 2; cands = (fftcand *) realloc(cands, startnc * sizeof(fftcand)); for (jj = nc; jj < startnc; jj++) cands[jj].sig = 0.0; } } else { minpow = cands[startnc - 1].p; if (nc < startnc) nc++; } } } /* If needed, sum and search the harmonics */ if (numharmsum > 1) { sumpows = gen_fvect(numtosearch); memcpy(sumpows, fullpows, sizeof(float) * numtosearch); for (ii = 2; ii <= numharmsum; ii++) { offset = ii / 2; if (dynamic) minpow = power_for_sigma(sigmacutoff, ii, hibin - lobin); else minpow = power_for_sigma(tmpminsig, ii, hibin - lobin); for (jj = lobin * numbetween; jj < numtosearch; jj++) { sumpows[jj] += fullpows[(jj + offset) / ii]; if (sumpows[jj] > minpow) { newcand.r = dr * (double) jj; newcand.p = sumpows[jj]; newcand.sig = candidate_sigma(sumpows[jj], ii, hibin - lobin); newcand.nsum = ii; cands[startnc - 1] = newcand; tmpminsig = percolate_fftcands(cands, startnc); if (dynamic) { nc++; if (nc == startnc) { startnc *= 2; cands = (fftcand *) realloc(cands, startnc * sizeof(fftcand)); for (jj = nc; jj < startnc; jj++) cands[jj].sig = 0.0; } } else { minpow = power_for_sigma(tmpminsig, ii, hibin - lobin); if (nc < startnc) nc++; } } } } vect_free(sumpows); } vect_free(fullpows); /* Chop off the unused parts of the dynamic array */ if (dynamic) cands = (fftcand *) realloc(cands, nc * sizeof(fftcand)); *numcands = nc; return cands; }