Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelHuth committed Jan 23, 2023
1 parent 002921c commit 5b97273
Showing 1 changed file with 82 additions and 50 deletions.
132 changes: 82 additions & 50 deletions Packages/MIES/MIES_SweepFormula.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ static StrConstant SF_OP_TPFIT_RET_AMP = "amp"
static StrConstant SF_OP_TPFIT_RET_MINAMP = "minabsamp"
static StrConstant SF_OP_TPFIT_RET_FITQUALITY = "fitq"

static StrConstant SF_OP_APFREQUENCY_Y_TIME = "time"
static StrConstant SF_OP_APFREQUENCY_Y_FREQ = "freq"
static StrConstant SF_OP_APFREQUENCY_NORM = "normalize"
static StrConstant SF_OP_APFREQUENCY_NONORM = "nonormalize"

static Constant EPOCHS_TYPE_INVALID = -1
static Constant EPOCHS_TYPE_RANGE = 0
static Constant EPOCHS_TYPE_NAME = 1
Expand Down Expand Up @@ -4215,14 +4220,32 @@ End
static Function/WAVE SF_OperationApFrequency(variable jsonId, string jsonPath, string graph)

variable i, numArgs, keepX
string xUnit, xLabel

numArgs = SFH_GetNumberOfArguments(jsonID, jsonPath)
SFH_ASSERT(numArgs <=3, "ApFrequency has 3 arguments at most.")
SFH_ASSERT(numArgs <= 5, "ApFrequency has 5 arguments at most.")
SFH_ASSERT(numArgs >= 1, "ApFrequency needs at least one argument.")

WAVE/WAVE input = SFH_GetArgument(jsonID, jsonPath, graph, SF_OP_APFREQUENCY, 0)
if(numArgs == 3)

if(numArgs == 5)
WAVE/T normalize = SFH_GetArgumentSingle(jsonID, jsonPath, graph, SF_OP_APFREQUENCY, 4, checkExist=1)
SFH_ASSERT(DimSize(normalize, ROWS) == 1, "Too many input values for parameter level")
SFH_ASSERT(IsTextWave(normalize), "normalize parameter must be textual")
SFH_ASSERT(!CmpStr(normalize[0], SF_OP_APFREQUENCY_NORM) || !CmpStr(normalize[0], SF_OP_APFREQUENCY_NONORM), "Unknown normalize parameter.")
else
Make/FREE/T normalize = {SF_OP_APFREQUENCY_NONORM}
endif

if(numArgs >= 4)
WAVE/T timeFreq = SFH_GetArgumentSingle(jsonID, jsonPath, graph, SF_OP_APFREQUENCY, 3, checkExist=1)
SFH_ASSERT(DimSize(timeFreq, ROWS) == 1, "Too many input values for parameter level")
SFH_ASSERT(IsTextWave(timeFreq), "time/freq parameter must be textual")
SFH_ASSERT(!CmpStr(timeFreq[0], SF_OP_APFREQUENCY_Y_TIME) || !CmpStr(timeFreq[0], SF_OP_APFREQUENCY_Y_FREQ), "Unknown time/freq parameter.")
else
Make/FREE/T timeFreq = {SF_OP_APFREQUENCY_Y_FREQ}
endif

if(numArgs >= 3)
WAVE level = SFH_GetArgumentSingle(jsonID, jsonPath, graph, SF_OP_APFREQUENCY, 2, checkExist=1)
SFH_ASSERT(DimSize(level, ROWS) == 1, "Too many input values for parameter level")
SFH_ASSERT(IsNumericWave(level), "level parameter must be numeric")
Expand All @@ -4240,96 +4263,105 @@ static Function/WAVE SF_OperationApFrequency(variable jsonId, string jsonPath, s
endif

WAVE/WAVE output = SFH_CreateSFRefWave(graph, SF_OP_APFREQUENCY, DimSize(input, ROWS))
output = SF_OperationApFrequencyImpl(input[p], level[0], method[0])
output = SF_OperationApFrequencyImpl(input[p], level[0], method[0], timeFreq[0], normalize[0])

if(method[0] == SF_APFREQUENCY_INSTANTANEOUS_PAIR)
if(DimSize(input, ROWS))
WAVE/Z data = input[0]
if(WaveExists(data))
xUnit = WaveUnits(data, ROWS)
if(!CmpStr(xUnit, "ms"))
xLabel = "kHz"
elseif(IsEmpty(xUnit))
xLabel = "1/x"
else
xLabel = "1/" + xUnit
endif
JWN_SetStringInWaveNote(output, SF_META_XAXISLABEL, xLabel)
endif
endif
keepX = 1
JWN_SetStringInWaveNote(output, SF_META_XAXISLABEL, "ms")
endif

SFH_TransferFormulaDataWaveNoteAndMeta(input, output, SF_OP_APFREQUENCY, SF_DATATYPE_APFREQUENCY, keepX=keepX)

return SFH_GetOutputForExecutor(output, graph, SF_OP_APFREQUENCY)
End

static Function/WAVE SF_OperationApFrequencyImpl(WAVE data, variable level, variable method)
static Function/WAVE SF_OperationApFrequencyImpl(WAVE data, variable level, variable method, string yStr, string normStr)

variable numPeaks, yModeTime, normalize
variable peakTimeDiff, peakTimeFreq

yModeTime = !CmpStr(yStr, SF_OP_APFREQUENCY_Y_TIME)

variable numSets, i
WAVE peaksAt = FindLevelWrapper(data, level, FINDLEVEL_EDGE_INCREASING, FINDLEVEL_MODE_MULTI)
numPeaks = str2num(GetDimLabel(peaksAt, ROWS, 0))
Redimension/N=(1, numPeaks) peaksAt

WAVE levels = FindLevelWrapper(data, level, FINDLEVEL_EDGE_INCREASING, FINDLEVEL_MODE_MULTI)
numSets = DimSize(levels, ROWS)
Make/FREE/N=(numSets) levelPerSet = str2num(GetDimLabel(levels, ROWS, p))
WAVE/Z pairTimes = $""
normalize = numPeaks > 1 ? !CmpStr(normStr, SF_OP_APFREQUENCY_NORM) : 0

// @todo we assume that the x-axis of data has a ms scale for FULL/INSTANTANEOUS
switch(method)
case SF_APFREQUENCY_FULL:
Make/N=(numSets)/D/FREE outD = levelPerSet[p] / (DimDelta(data, ROWS) * DimSize(data, ROWS) * MILLI_TO_ONE)
// number_of_peaks / sweep_length
Make/FREE/D outD = { numPeaks / (DimDelta(data, ROWS) * DimSize(data, ROWS) * MILLI_TO_ONE) }
SetScale/P y, DimOffset(outD, ROWS), DimDelta(outD, ROWS), "Hz", outD
break
case SF_APFREQUENCY_INSTANTANEOUS:
WAVE outD = SF_ApFrequencyInstantaneous(levels, levelPerSet)
Make/FREE/D outD = { SF_ApFrequencyInstantaneous(peaksAt) }
SetScale/P y, DimOffset(outD, ROWS), DimDelta(outD, ROWS), "Hz", outD
break
case SF_APFREQUENCY_INSTANTANEOUS_PAIR:
[outD, pairTimes] = SF_ApFrequencyInstantaneousPairs(levels, levelPerSet)
WAVE/Z pairTimes = $""
[outD, pairTimes] = SF_ApFrequencyInstantaneousPairs(peaksAt, yModeTime)
if(WaveExists(outD))
JWN_SetWaveInWaveNote(outD, SF_META_XVALUES, pairTimes)
endif
break
case SF_APFREQUENCY_APCOUNT:
Make/N=(numSets)/D/FREE outD = levelPerSet[p]
Make/FREE/D outD = { numPeaks }
SetScale/P y, DimOffset(outD, ROWS), DimDelta(outD, ROWS), "peaks", outD
break
endswitch

if(normalize)
peakTimeDiff = (peaksAt[1] - peaksAt[0]) * MILLI_TO_ONE
peakTimeFreq = 1.0 / peakTimeDiff
if(yModetime)
outD /= peakTimeDiff
else
outD /= peakTimeFreq
endif
endif

return outD
End

static Function/WAVE SF_ApFrequencyInstantaneous(WAVE levels, WAVE levelPerSet)
static Function SF_ApFrequencyInstantaneous(WAVE peaksAt)

variable i
variable numSets = DimSize(levels, ROWS)
variable numPeaks

Make/N=(numSets)/D/FREE result
numPeaks = DimSize(peaksAt, COLS)

for(i = 0; i < numSets; i += 1)
if(levelPerSet[i] <= 1)
result[i] = 0
else
Make/FREE/D/N=(levelPerSet[i] - 1) distances
distances[0, levelPerSet[i] - 2] = levels[i][p + 1] - levels[i][p]
result[i] = 1.0 / (Mean(distances) * MILLI_TO_ONE)
endif
endfor
if(numPeaks <= 1)
return 0
endif

return result
Make/FREE/D/N=(numPeaks - 1) distances
distances[0, numPeaks - 2] = peaksAt[0][p + 1] - peaksAt[0][p]
return 1.0 / (mean(distances) * MILLI_TO_ONE)
End

static Function [WAVE/D result, WAVE/D pairTimes] SF_ApFrequencyInstantaneousPairs(WAVE levels, WAVE levelPerSet)
static Function [WAVE/D result, WAVE/D pairTimes] SF_ApFrequencyInstantaneousPairs(WAVE peaksAt, variable yModeTime)

SFH_ASSERT(DimSize(levels, ROWS) == 1, "Expected a single set")
variable numPeaks

if(levelPerSet[0] == 0)
numPeaks = DimSize(peaksAt, COLS)
if(numPeaks == 0)
return [$"", $""]
endif

Make/FREE/D/N=(max(levelPerSet[0] - 1, 1)) result, pairTimes
if(levelPerSet[0] == 1)
Make/FREE/D/N=(max(numPeaks - 1, 1)) result, pairTimes
if(numPeaks == 1)
result[0] = 0
pairTimes[0] = levels[0][0]
pairTimes[0] = peaksAt[0][0]
else
result = 1.0 / ((levels[0][p + 1] - levels[0][p]) * MILLI_TO_ONE)
pairTimes = levels[0][p]
pairTimes = peaksAt[0][p]
result = (peaksAt[0][p + 1] - peaksAt[0][p]) * MILLI_TO_ONE
if(yModeTime)
SetScale/P y, DimOffset(result, ROWS), DimDelta(result, ROWS), "s", result
else
result = 1.0 / result
SetScale/P y, DimOffset(result, ROWS), DimDelta(result, ROWS), "Hz", result
endif
endif

return [result, pairTimes]
Expand Down

0 comments on commit 5b97273

Please sign in to comment.