- Timestamp:
- Sep 26, 2017, 7:03:10 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ohana.20170822/src/opihi/cmd.data/periodogram-fm.c
r40145 r40146 1 1 # include "data.h" 2 # define MIN_VAR 1e-8 3 int periodogram_fm (int argc, char **argv) { 4 5 int N; 2 6 3 int periodogram (int argc, char **argv) { 4 5 int i, N, Npt, Np, NP, VERBOSE; 6 opihi_flt *tv, *fv; 7 float minP, maxP, minT, maxT, dTime; 8 float mean, var, w, tau, P, Pc, Ps, Po; 9 float C, S, cs, sn, cs2, sn2, ratio; 10 Vector *time, *flux, *dflux, *power, *period; 11 12 VERBOSE = FALSE; 7 int VERBOSE = FALSE; 13 8 if ((N = get_argument (argc, argv, "-v"))) { 14 9 VERBOSE = TRUE; … … 17 12 18 13 if (argc != 8) { 19 gprint (GP_ERR, "USAGE: periodogram -fm (time) (flux) (dflux) (minP) (maxP) (period) (power)\n");14 gprint (GP_ERR, "USAGE: periodogram_fm (time) (flux) (dflux) (minP) (maxP) (period) (power)\n"); 20 15 return (FALSE); 21 16 } … … 23 18 // XXX allow dflux to be dropped? 24 19 25 if ((time = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE); 26 if ((flux = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE); 27 if ((dflux = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE); 28 minP = atof(argv[4]); 29 maxP = atof(argv[5]); 20 Vector *time, *flux, *dflux, *power, *period; 21 if ((time = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE); 22 if ((flux = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE); 23 if ((dflux = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE); 30 24 if ((period = SelectVector (argv[6], ANYVECTOR, TRUE)) == NULL) return (FALSE); 31 25 if ((power = SelectVector (argv[7], ANYVECTOR, TRUE)) == NULL) return (FALSE); 26 double minP = atof(argv[4]); 27 double maxP = atof(argv[5]); 32 28 33 29 REQUIRE_VECTOR_FLT (time, FALSE); 34 30 REQUIRE_VECTOR_FLT (flux, FALSE); 31 REQUIRE_VECTOR_FLT (dflux, FALSE); 35 32 36 /* find the max baseline, mean, and variance */ 37 minT = maxT = time[0].elements.Flt[0]; 38 Npt = time[0].Nelements; 39 tv = time[0].elements.Flt; 40 fv = flux[0].elements.Flt; 41 mean = var = 0; 42 for (i = 0; i < Npt; i++, tv++, fv++) { 33 /* find the max baseline, sum the inverse variances */ 34 double minT = time[0].elements.Flt[0]; 35 double maxT = time[0].elements.Flt[0]; 36 opihi_flt Weight = 0; 37 int Npt = time[0].Nelements; 38 39 opihi_flt *tv = time[0].elements.Flt; 40 opihi_flt *df = dflux[0].elements.Flt; 41 for (int i = 0; i < Npt; i++, tv++, df++) { 43 42 minT = MIN (minT, *tv); 44 43 maxT = MAX (maxT, *tv); 45 mean += *fv; 44 // skip points with 0.0 error? or add minimum variance? 45 Weight += 1.0 / (SQ(*df) + MIN_VAR); // MIN_VAR : added in quadrature to avoid Inf (XXX make this a user parameter?) 46 46 } 47 mean = mean / Npt;48 fv = flux[0].elements.Flt;49 for (i = 0; i < Npt; i++, fv++) {50 var += SQ(*fv - mean);51 }52 var = var / (Npt - 1);53 47 54 if (VERBOSE) gprint (GP_ERR, "mean: %f, var: %f, minT: %f, maxT: %f\n", mean, var, minT, maxT); 55 56 dTime = maxT - minT; 48 double WeightInv = 1.0 / Weight; 49 double dTime = maxT - minT; 57 50 if (dTime == 0) { 58 51 gprint (GP_ERR, "ERROR: time range is zero\n"); … … 60 53 } 61 54 62 Np = 0;63 NP = 100;55 int Np = 0; 56 int NP = 100; 64 57 ResetVector (power, OPIHI_FLT, NP); 65 58 ResetVector (period, OPIHI_FLT, NP); … … 70 63 71 64 // XXX consider choice of period or frequency step 72 P = minP;73 while (P < maxP) {74 w = 2*M_PI/P;65 double P = minP; 66 while (P <= maxP) { 67 double w = 2*M_PI/P; 75 68 76 69 /* find the period offset tau */ … … 78 71 df = dflux[0].elements.Flt; 79 72 80 cs = sn = cs2 = sn2 =0;73 double cs = 0.0, sn = 0.0, sn2 = 0.0, cs2 = 0.0; 81 74 82 for (i = 0; i < Npt; i++, tv++) { 83 opihi_flt wt = 84 cs += cos (*tv*w*2); 85 sn += sin (*tv*2*2); 75 for (int i = 0; i < Npt; i++, tv++, df++) { 76 opihi_flt wt = WeightInv / (SQ(*df) + MIN_VAR); 77 cs += wt*cos (*tv*w); 78 sn += wt*sin (*tv*w); 79 cs2 += wt*cos (*tv*w*2); 80 sn2 += wt*sin (*tv*w*2); 86 81 } 87 tau = 0.5*atan2 (sn, cs) / w; 82 double ytan = sn2 - 2*cs*sn; 83 double xtan = cs2 - (SQ(cs) - SQ(sn)); 84 double tau = 0.5*atan2 (ytan, xtan) / w; 88 85 89 86 /* find the power at this period */ 90 87 tv = time[0].elements.Flt; 91 fv = flux[0].elements.Flt; 92 cs = sn = cs2 = sn2 = 0; 93 for (i = 0; i < Npt; i++, tv++, fv++) { 94 C = cos (w*(*tv-tau)); 95 S = sin (w*(*tv-tau)); 96 // C = cos (w**tv); 97 // S = sin (w**tv); 98 cs += (*fv - mean) * C; 99 sn += (*fv - mean) * S; 100 cs2 += SQ(C); 101 sn2 += SQ(S); 88 df = dflux[0].elements.Flt; 89 opihi_flt *fv = flux[0].elements.Flt; 90 91 // YY = YY_s - Y_s*Y_s 92 // CC = CC_s - C_s*C_s 93 // SS = SS_s - S_s*S_s 94 // YC = YC_s - Y_s*C_s 95 // YS = YS_s - Y_s*S_s 96 97 double YY_s = 0.0, CC_s = 0.0, SS_s = 0.0, YC_s = 0.0, YS_s = 0.0; 98 double Y_s = 0.0, C_s = 0.0, S_s = 0.0; 99 for (int i = 0; i < Npt; i++, tv++, fv++, df++) { 100 opihi_flt wt = WeightInv / (SQ(*df) + MIN_VAR); 101 cs = cos (w*(*tv-tau)); 102 sn = sin (w*(*tv-tau)); 103 104 double wtf = *fv*wt; 105 Y_s += wtf; 106 C_s += wt*cs; 107 S_s += wt*sn; 108 109 YY_s += wtf*(*fv); 110 YC_s += wtf*cs; 111 YS_s += wtf*sn; 112 113 CC_s += wt*cs*cs; 114 SS_s += wt*sn*sn; 102 115 } 103 Pc = SQ(cs) / cs2; 104 Ps = SQ(sn) / sn2; 105 Po = (Pc + Ps) / (2*var); 116 double YY = YY_s - SQ(Y_s); 117 double YC = YC_s - Y_s*C_s; 118 double YS = YS_s - Y_s*S_s; 119 double CC = CC_s - SQ(C_s); 120 double SS = SS_s - SQ(S_s); 121 122 double Pa = SQ(YC) / CC; 123 double Pb = SQ(YS) / SS; 124 double Po = (Pa + Pb) / YY; 106 125 107 126 power[0].elements.Flt[Np] = Po; … … 114 133 } 115 134 116 ratio = 1 + 0.1*P/dTime;135 double ratio = 1 + 0.1*P/dTime; 117 136 118 137 if (VERBOSE) gprint (GP_ERR, "tau: %f, P: %f, ratio: %f, dTime: %f, nextP: %f\n", tau, P, ratio, dTime, P*ratio);
Note:
See TracChangeset
for help on using the changeset viewer.
