CODE:
FrequencySearch[data_, step_, window_, test_: {"skip"}] := Module[
{
DATA, (* EQUALY SPACED SIGNAL *)
WINDOW, (* WINDOW FUNCTION *)
POINTS, (* # OF POINTS IN DATA *)
STEP, (*
POINTS SPACING *)
WINDOWFUNC, X, WINDOWDATA, FOURIER, (*
LOCALS *)
POS1, POS2, POS3,(* LOCALS *)
T1, T2, (*
PERIOD WITHOUT SIGNAL CONVOLUTION AND WITH IT *)
OMEGA1,
OMEGA2, (* SAME STAFF FOR FREQUENCY *)
TEST, (* A DEBUG FLAG *)
POSREQ, OMEGAREQ, TREQ, RUN (* LOCALS *)
},
{
(* ASSIGN INPUT TO LOCAL VARS *)
TEST = test;
STEP = step;
DATA = data;
POINTS = Length[DATA];
WINDOW = window;
(* TESTING*)
If[TEST == "Test", {
Print["STEP 1: PLOT INITIAL DATA"];
Print[ListPlot[DATA]];
}];
(* REMOVE SIGNAL AVERAGE *)
DATA = DATA - Mean[DATA];
(* TESTING*)
If[TEST == "Test", {
Print["STEP 2: REMOVE SIGNAL AVERAGE VALUE"];
Print[ListPlot[DATA]];
}];
(* APPLY WINDOW *)
If[WINDOW ==
"Hann", {WINDOWFUNC[X_] :=
0.5 (1 - Cos[2 Pi X/(POINTS - 1)]);}, {WINDOWFUNC[X_] :=
0.42 - 0.5 Cos[2 Pi X/(POINTS - 1)] +
0.08 Cos[4 Pi X/(POINTS - 1)];}];
WINDOWDATA = Table[WINDOWFUNC[X], {X, 1, POINTS}];
DATA = DATA WINDOWDATA;
(* TESTING*)
If[TEST == "Test", {
Print["STEP 3: APPLY WINDOW FUNCTION"];
Print[ListPlot[DATA]];
}];
(* FOURIER WITHOUT CONVOLUTION *)
FOURIER = Abs[Fourier[DATA]];
POS1 = Position[FOURIER, Max[FOURIER]][[1, 1]];
T1 = POINTS/(POS1 - 2 ) STEP;
OMEGA1 = (POS1 - 2)/POINTS;
(* TESTING*)
If[TEST == "Test", {
Print["STEP 4: FOURIER TRANSFORM AND LOCATE INITIAL MAXIMUM"];
Print[Show[
ListPlot[FOURIER],
Graphics[{Red, Point[{POS1, FOURIER[[POS1]]}]}],
PlotRange -> All
]];
Print["Initial position: ", POS1];
Print["Initial frequency: ", 2 Pi/T1 // N];
}];
(* OVERLAP/CONVOLUTION *)
DATA = DATA Exp[2 Pi I OMEGA1 N[Range[0, POINTS - 1]]];
(* TESTING*)
If[TEST == "Test", {
Print["STEP 5: OVERLAP (Re,Im,Abs)"];
Print[ListPlot[Re[DATA]]];
Print[ListPlot[Im[DATA]]];
Print[ListPlot[Abs[DATA]]];
}];
(* FOURIER WITH CONVOLUTION *)
FOURIER = Abs[Fourier[DATA, FourierParameters -> {0, 2/POINTS}]];
POS2 = Position[FOURIER, Max[FOURIER]][[1, 1]];
T2 = POINTS/(POS1 - 2 + 2 (POS2 - 1)/POINTS) STEP;
(* TESTING*)
If[TEST == "Test", {
Print["STEP 6: FOURIER TRANSFORM AND LOCATE NEW MAXIMUM"];
Print[Show[
ListPlot[FOURIER],
Graphics[{Red, Point[{POS2, FOURIER[[POS2]]}]}],
PlotRange -> All
]];
Print["New position: ", POS2];
Print["New frequency: ", 2 Pi/T2 // N];
}];
(* RESULTS *)
OMEGA1 = 2 Pi/T1 (* NO CONVOLUTION *);
OMEGA2 = 2 Pi /T2(* CONVOLUTION *);
{N[OMEGA1], N[OMEGA2]}
}];