Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelHuth committed Aug 16, 2024
1 parent 09ba5cb commit 33d4401
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 75 deletions.
1 change: 1 addition & 0 deletions Packages/MIES/MIES_Oscilloscope.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ Function SCOPE_UpdateOscilloscopeData(device, dataAcqOrTP, [chunk, fifoPos, devi
tpInput.tpLengthPoints = tpLengthPoints
tpInput.readTimeStamp = ticks * TICKS_TO_SECONDS
tpInput.activeADCs = tpChannels
tpInput.cycleId = ROVAR(GetTestpulseCycleID(device))

tpStart = trunc(fifoPosGlobal / tpLengthPoints)
tpEnd = trunc(fifoLatest / tpLengthPoints)
Expand Down
77 changes: 77 additions & 0 deletions Packages/MIES/MIES_Publish.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -645,3 +645,80 @@ Function PUB_AccessResistanceSmoke(string device, variable sweepNo, variable hea

PUB_Publish(jsonID, ANALYSIS_FUNCTION_AR)
End

threadsafe static Function PUB_AddTPResultEntry(variable jsonId, string path, variable value, string unit)

JSON_AddTreeObject(jsonID, path)
JSON_AddVariable(jsonID, path + "/value", value)
JSON_AddString(jsonID, path + "/unit", unit)
End

threadsafe Function PUB_TPResult(STRUCT TPZMQData &tpzmq)

string path
variable jsonId = JSON_New()
string adUnit = SelectString(tpzmq.clampMode == V_CLAMP_MODE, "mV", "pA")
string daUnit = SelectString(tpzmq.clampMode == V_CLAMP_MODE, "pA", "mV")

path = "properties"
JSON_AddTreeObject(jsonID, path)
JSON_AddVariable(jsonID, path + "/tp marker", tpzmq.marker)
JSON_AddString(jsonID, path + "/device", tpzmq.device)
JSON_AddVariable(jsonID, path + "/headstage", tpzmq.headstage)
JSON_AddVariable(jsonID, path + "/clamp mode", tpzmq.clampMode)

PUB_AddTPResultEntry(jsonId, path + "/time of tp acquisition", tpzmq.now, "s")
PUB_AddTPResultEntry(jsonId, path + "/clamp amplitude", tpzmq.clampAmp, daUnit)
PUB_AddTPResultEntry(jsonId, path + "/pulse duration", tpzmq.duration, "points")
PUB_AddTPResultEntry(jsonId, path + "/baseline fraction", tpzmq.baselineFrac, "ratio")
PUB_AddTPResultEntry(jsonId, path + "/tp length", tpzmq.lengthTPInPoints, "points")
PUB_AddTPResultEntry(jsonId, path + "/sample interval ADC", tpzmq.sampleIntADC, "ms")
PUB_AddTPResultEntry(jsonId, path + "/timestamp", tpzmq.timeStamp, "s")
PUB_AddTPResultEntry(jsonId, path + "/timestampUTC", tpzmq.timeStampUTC, "s")
PUB_AddTPResultEntry(jsonId, path + "/tp cycle id", tpzmq.cycleId, "1")

path = "results"
JSON_AddTreeObject(jsonID, path)
PUB_AddTPResultEntry(jsonId, path + "/average baseline steady state", tpzmq.avgBaselineSS, adUnit)
PUB_AddTPResultEntry(jsonId, path + "/average tp steady state", tpzmq.avgTPSS, adUnit)
PUB_AddTPResultEntry(jsonId, path + "/instantaneous", tpzmq.instVal, adUnit)
PUB_AddTPResultEntry(jsonId, path + "/steady state resistance", tpzmq.resistanceSS, "MΩ")
PUB_AddTPResultEntry(jsonId, path + "/instantaneous resistance", tpzmq.resistanceInst, "MΩ")

PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_NOW, releaseJSON = 0)
if(PUB_CheckPublishingTime(ZMQ_FILTER_TPRESULT_1S, 1))
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_1S, releaseJSON = 0)
endif
if(PUB_CheckPublishingTime(ZMQ_FILTER_TPRESULT_5S, 5))
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_5S, releaseJSON = 0)
endif
if(PUB_CheckPublishingTime(ZMQ_FILTER_TPRESULT_10S, 10))
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_10S, releaseJSON = 0)
endif
JSON_Release(jsonID)
End

/// @brief Updates the publishing timestamp in the TUFXOP storage and returns 1 if an update is due (0 otherwise)
threadsafe static Function PUB_CheckPublishingTime(string pubFilter, variable period)

variable curTime

TUFXOP_AcquireLock/N=(pubFilter)
TUFXOP_GetStorage/Z/Q/N=(pubFilter) lastUpdated
if(V_flag)
TUFXOP_Init/N=(pubFilter)
TUFXOP_GetStorage/Z/N=(pubFilter) lastUpdated
Make/FREE/D dTime = {DateTime}
lastUpdated[0] = dTime
endif
curTime = DateTime
WAVE lastTime = lastUpdated[0]
if(lastTime[0] + period > curTime)
lastTime[0] = curTime + period
TUFXOP_ReleaseLock/N=(pubFilter)
return 1
endif
TUFXOP_ReleaseLock/N=(pubFilter)

return 0
End
23 changes: 23 additions & 0 deletions Packages/MIES/MIES_Structures.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,29 @@ Structure TPAnalysisInput
variable activeADCs
variable timeStamp
variable timeStampUTC
variable cycleId
EndStructure

/// @brief Helper structure for TP data transfer to zeromq
Structure TPZMQData
variable marker
string device
variable headstage
variable now
variable clampMode
variable clampAmp
variable duration
variable baselineFrac
variable lengthTPInPoints
variable sampleIntADC
variable timeStamp
variable timeStampUTC
variable cycleId
variable avgBaselineSS
variable avgTPSS
variable instVal
variable resistanceSS
variable resistanceInst
EndStructure

/// @brief Helper structure for GetPlotArea()
Expand Down
160 changes: 85 additions & 75 deletions Packages/MIES/MIES_TestPulse.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -106,45 +106,87 @@ Function TP_StoreTP(device, TPWave, tpMarker, hsList)
SetNumberInWaveNote(storedTP, NOTE_INDEX, index)
End

/// @brief Return a number of consecutive test pulses ending with the TP
/// identified by tpMarker.
///
/// The wave reference wave will have as many columns as active headstages were used.
Function/WAVE TP_GetConsecutiveTPsUptoMarker(string device, variable tpMarker, variable number)
static Function TP_GetStoredTPIndex(string device, variable tpMarker)

variable numEntries

WAVE/WAVE storedTP = GetStoredTestPulseWave(device)
numEntries = GetNumberFromWaveNote(storedTP, NOTE_INDEX)

if(numEntries == 0)
return $""
return NaN
endif

Make/FREE/N=(numEntries) matches

Multithread matches[0, numEntries - 1] = GetNumberFromWaveNote(storedTP[p], "TPMarker") == tpMarker

FindValue/V=1 matches

if(V_row == -1)
return NaN
endif

return V_row
End

Function/WAVE TP_GetStoredTP(string device, variable tpMarker, variable includeDAC)

variable tpIndex, numEntries, dimMarker

includeDAC = !!includeDAC

tpIndex = TP_GetStoredTPIndex(device, tpMarker)
if(IsNaN(tpIndex))
return $""
endif

Make/FREE/N=(number)/WAVE result
WAVE/WAVE tpStored = GetStoredTestPulseWave(device)
WAVE tpADC = tpStored[tpIndex]

if(number > V_row + 1)
WAVE tpStorage = GetTPStorage(device)
numEntries = GetNumberFromWaveNote(tpStorage, NOTE_INDEX)
dimMarker = FindDimLabel(tpStorage, LAYERS, "TPMarker")
FindValue/RMD=[][0][dimMarker]/V=(tpMarker) tpStorage
ASSERT(V_row >= 0, "Inconsistent TP data")
Duplicate/FREE/RMD=[V_row][][] tpStorage, tpResults

if(includeDAC)
Make/FREE/D/N=0 tpDAC
// TP_CreateTestPulseWaveImpl(tpDAC, variable totalLength, variable pulseStart, variable pulseLength)
else
WAVE/Z tpDAC = $""
endif

Make/FREE/WAVE tpAll = {tpADC, tpDAC, tpResults}

return tpAll
End

/// @brief Return a number of consecutive test pulses ending with the TP
/// identified by tpMarker.
///
/// The wave reference wave will have as many columns as active headstages were used.
Function/WAVE TP_GetConsecutiveTPsUptoMarker(string device, variable tpMarker, variable number)

variable tpIndex, tpCycleId

tpIndex = TP_GetStoredTPIndex(device, tpMarker)
if(IsNaN(tpIndex))
return $""
endif

if(number > tpIndex + 1)
// too few TPs available
return $""
endif

result[] = storedTP[V_row - number + 1 + p]
Make/FREE/N=(number)/WAVE result

// check that they all belong to the same TP cycle
Redimension/N=(number) matches
matches[] = GetNumberFromWaveNote(result[0], "TPCycleID") == GetNumberFromWaveNote(result[p], "TPCycleID")
WAVE/WAVE storedTP = GetStoredTestPulseWave(device)
result[] = storedTP[tpIndex - number + 1 + p]

if(Sum(matches) < number)
// check that they all belong to the same TP cycle
Make/FREE/N=(number) matches
tpCycleId = GetNumberFromWaveNote(result[0], "TPCycleID")
matches[] = tpCycleId == GetNumberFromWaveNote(result[p], "TPCycleID")
if(sum(matches) < number)
return $""
endif

Expand Down Expand Up @@ -888,9 +930,11 @@ threadsafe Function/DF TP_TSAnalysis(dfrInp)
variable evalRange, refTime, refPoint, tpStartPoint
variable sampleInt, jsonId
variable avgBaselineSS, avgTPSS, instVal, evalOffsetPointsCorrected, instPoint
STRUCT TPZMQData tpzmq

DFREF dfrOut = NewFreeDataFolder()

// see TP_PrepareAnalysisDF for order
WAVE data = dfrInp:param0
NVAR/SDFR=dfrInp clampAmp = param1
NVAR/SDFR=dfrInp clampMode = param2
Expand All @@ -904,6 +948,7 @@ threadsafe Function/DF TP_TSAnalysis(dfrInp)
NVAR/SDFR=dfrInp activeADCs = param10
NVAR/SDFR=dfrInp timeStamp = param11
NVAR/SDFR=dfrInp timeStampUTC = param12
NVAR/SDFR=dfrInp cycleId = param13

#if defined(TP_ANALYSIS_DEBUGGING)
DEBUGPRINT_TS("Marker: ", var = marker)
Expand Down Expand Up @@ -1007,68 +1052,32 @@ threadsafe Function/DF TP_TSAnalysis(dfrInp)
variable/G dfrOut:timeStamp = timeStamp
variable/G dfrOut:timeStampUTC = timeStampUTC

// ZMQ publishing
jsonId = JSON_New()
JSON_AddTreeObject(jsonID, "properties")
JSON_AddVariable(jsonID, "properties/unique tp marker", marker)
JSON_AddString(jsonID, "properties/device", device)
JSON_AddVariable(jsonID, "properties/headstage", hsIndex)
JSON_AddVariable(jsonID, "properties/time of tp acquisition", now)
JSON_AddVariable(jsonID, "properties/clamp mode", clampMode)
JSON_AddVariable(jsonID, "properties/clamp amplitude", clampAmp)
JSON_AddVariable(jsonID, "properties/pulse duration in points", duration)
JSON_AddVariable(jsonID, "properties/baseline fraction", baselineFrac)
JSON_AddVariable(jsonID, "properties/length of tp in sample points", lengthTPInPoints)
JSON_AddVariable(jsonID, "properties/sample interval", sampleInt)
JSON_AddVariable(jsonID, "properties/timeStamp", timeStamp)
JSON_AddVariable(jsonID, "properties/timeStampUTC", timeStampUTC)
JSON_AddTreeObject(jsonID, "results")
JSON_AddVariable(jsonID, "results/average baseline steady state", avgBaselineSS)
JSON_AddVariable(jsonID, "results/average tp steady state", avgTPSS)
JSON_AddVariable(jsonID, "results/instantaneous", instVal)
JSON_AddVariable(jsonID, "results/steady state resistance", outData[1])
JSON_AddVariable(jsonID, "results/instantaneous resistance", outData[2])

PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_NOW, releaseJSON = 0)
if(TP_CheckPublishingTime(ZMQ_FILTER_TPRESULT_1S, 1))
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_1S, releaseJSON = 0)
endif
if(TP_CheckPublishingTime(ZMQ_FILTER_TPRESULT_5S, 5))
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_5S, releaseJSON = 0)
endif
if(TP_CheckPublishingTime(ZMQ_FILTER_TPRESULT_10S, 10))
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_10S, releaseJSON = 0)
endif
JSON_Release(jsonID)
// Serialize for ZMQ publishing
tpzmq.marker = marker
tpzmq.device = device
tpzmq.headstage = hsIndex
tpzmq.now = now
tpzmq.clampMode = clampMode
tpzmq.clampAmp = clampAmp
tpzmq.duration = duration
tpzmq.baselineFrac = baselineFrac
tpzmq.lengthTPInPoints = lengthTPInPoints
tpzmq.sampleIntADC = sampleInt
tpzmq.timeStamp = timeStamp
tpzmq.timeStampUTC = timeStampUTC
tpzmq.cycleId = cycleId

tpzmq.avgBaselineSS = avgBaselineSS
tpzmq.avgTPSS = avgTPSS
tpzmq.instVal = instVal
tpzmq.resistanceSS = outData[1]
tpzmq.resistanceInst = outData[2]

PUB_TPResult(tpzmq)

return dfrOut
End

/// @brief Updates the publishing timestamp in the TUFXOP storage and returns 1 if an update is due (0 otherwise)
threadsafe static Function TP_CheckPublishingTime(string pubFilter, variable period)

variable curTime

TUFXOP_AcquireLock/N=(pubFilter)
TUFXOP_GetStorage/Z/Q/N=(pubFilter) lastUpdated
if(V_flag)
TUFXOP_Init/N=(pubFilter)
TUFXOP_GetStorage/Z/N=(pubFilter) lastUpdated
Make/FREE/D dTime = {DateTime}
lastUpdated[0] = dTime
endif
curTime = DateTime
WAVE lastTime = lastUpdated[0]
if(lastTime[0] + period > curTime)
lastTime[0] = curTime + period
TUFXOP_ReleaseLock/N=(pubFilter)
return 1
endif
TUFXOP_ReleaseLock/N=(pubFilter)

return 0
End

/// @brief Calculates running average [box average] for all entries and all headstages
static Function TP_CalculateAverage(WAVE TPResultsBuffer, WAVE TPResults)
variable numEntries, numLayers
Expand Down Expand Up @@ -1597,6 +1606,7 @@ Function/DF TP_PrepareAnalysisDF(string device, STRUCT TPAnalysisInput &tpInput)
ASYNC_AddParam(threadDF, var = tpInput.activeADCs)
ASYNC_AddParam(threadDF, var = tpInput.timeStamp)
ASYNC_AddParam(threadDF, var = tpInput.timeStampUTC)
ASYNC_AddParam(threadDF, var = tpInput.cycleId)

return threadDF
End
Expand Down

0 comments on commit 33d4401

Please sign in to comment.