Skip to content

Commit 33d4401

Browse files
committed
changes
1 parent 09ba5cb commit 33d4401

File tree

4 files changed

+186
-75
lines changed

4 files changed

+186
-75
lines changed

Packages/MIES/MIES_Oscilloscope.ipf

+1
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ Function SCOPE_UpdateOscilloscopeData(device, dataAcqOrTP, [chunk, fifoPos, devi
553553
tpInput.tpLengthPoints = tpLengthPoints
554554
tpInput.readTimeStamp = ticks * TICKS_TO_SECONDS
555555
tpInput.activeADCs = tpChannels
556+
tpInput.cycleId = ROVAR(GetTestpulseCycleID(device))
556557

557558
tpStart = trunc(fifoPosGlobal / tpLengthPoints)
558559
tpEnd = trunc(fifoLatest / tpLengthPoints)

Packages/MIES/MIES_Publish.ipf

+77
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,80 @@ Function PUB_AccessResistanceSmoke(string device, variable sweepNo, variable hea
645645

646646
PUB_Publish(jsonID, ANALYSIS_FUNCTION_AR)
647647
End
648+
649+
threadsafe static Function PUB_AddTPResultEntry(variable jsonId, string path, variable value, string unit)
650+
651+
JSON_AddTreeObject(jsonID, path)
652+
JSON_AddVariable(jsonID, path + "/value", value)
653+
JSON_AddString(jsonID, path + "/unit", unit)
654+
End
655+
656+
threadsafe Function PUB_TPResult(STRUCT TPZMQData &tpzmq)
657+
658+
string path
659+
variable jsonId = JSON_New()
660+
string adUnit = SelectString(tpzmq.clampMode == V_CLAMP_MODE, "mV", "pA")
661+
string daUnit = SelectString(tpzmq.clampMode == V_CLAMP_MODE, "pA", "mV")
662+
663+
path = "properties"
664+
JSON_AddTreeObject(jsonID, path)
665+
JSON_AddVariable(jsonID, path + "/tp marker", tpzmq.marker)
666+
JSON_AddString(jsonID, path + "/device", tpzmq.device)
667+
JSON_AddVariable(jsonID, path + "/headstage", tpzmq.headstage)
668+
JSON_AddVariable(jsonID, path + "/clamp mode", tpzmq.clampMode)
669+
670+
PUB_AddTPResultEntry(jsonId, path + "/time of tp acquisition", tpzmq.now, "s")
671+
PUB_AddTPResultEntry(jsonId, path + "/clamp amplitude", tpzmq.clampAmp, daUnit)
672+
PUB_AddTPResultEntry(jsonId, path + "/pulse duration", tpzmq.duration, "points")
673+
PUB_AddTPResultEntry(jsonId, path + "/baseline fraction", tpzmq.baselineFrac, "ratio")
674+
PUB_AddTPResultEntry(jsonId, path + "/tp length", tpzmq.lengthTPInPoints, "points")
675+
PUB_AddTPResultEntry(jsonId, path + "/sample interval ADC", tpzmq.sampleIntADC, "ms")
676+
PUB_AddTPResultEntry(jsonId, path + "/timestamp", tpzmq.timeStamp, "s")
677+
PUB_AddTPResultEntry(jsonId, path + "/timestampUTC", tpzmq.timeStampUTC, "s")
678+
PUB_AddTPResultEntry(jsonId, path + "/tp cycle id", tpzmq.cycleId, "1")
679+
680+
path = "results"
681+
JSON_AddTreeObject(jsonID, path)
682+
PUB_AddTPResultEntry(jsonId, path + "/average baseline steady state", tpzmq.avgBaselineSS, adUnit)
683+
PUB_AddTPResultEntry(jsonId, path + "/average tp steady state", tpzmq.avgTPSS, adUnit)
684+
PUB_AddTPResultEntry(jsonId, path + "/instantaneous", tpzmq.instVal, adUnit)
685+
PUB_AddTPResultEntry(jsonId, path + "/steady state resistance", tpzmq.resistanceSS, "MΩ")
686+
PUB_AddTPResultEntry(jsonId, path + "/instantaneous resistance", tpzmq.resistanceInst, "MΩ")
687+
688+
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_NOW, releaseJSON = 0)
689+
if(PUB_CheckPublishingTime(ZMQ_FILTER_TPRESULT_1S, 1))
690+
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_1S, releaseJSON = 0)
691+
endif
692+
if(PUB_CheckPublishingTime(ZMQ_FILTER_TPRESULT_5S, 5))
693+
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_5S, releaseJSON = 0)
694+
endif
695+
if(PUB_CheckPublishingTime(ZMQ_FILTER_TPRESULT_10S, 10))
696+
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_10S, releaseJSON = 0)
697+
endif
698+
JSON_Release(jsonID)
699+
End
700+
701+
/// @brief Updates the publishing timestamp in the TUFXOP storage and returns 1 if an update is due (0 otherwise)
702+
threadsafe static Function PUB_CheckPublishingTime(string pubFilter, variable period)
703+
704+
variable curTime
705+
706+
TUFXOP_AcquireLock/N=(pubFilter)
707+
TUFXOP_GetStorage/Z/Q/N=(pubFilter) lastUpdated
708+
if(V_flag)
709+
TUFXOP_Init/N=(pubFilter)
710+
TUFXOP_GetStorage/Z/N=(pubFilter) lastUpdated
711+
Make/FREE/D dTime = {DateTime}
712+
lastUpdated[0] = dTime
713+
endif
714+
curTime = DateTime
715+
WAVE lastTime = lastUpdated[0]
716+
if(lastTime[0] + period > curTime)
717+
lastTime[0] = curTime + period
718+
TUFXOP_ReleaseLock/N=(pubFilter)
719+
return 1
720+
endif
721+
TUFXOP_ReleaseLock/N=(pubFilter)
722+
723+
return 0
724+
End

Packages/MIES/MIES_Structures.ipf

+23
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,29 @@ Structure TPAnalysisInput
316316
variable activeADCs
317317
variable timeStamp
318318
variable timeStampUTC
319+
variable cycleId
320+
EndStructure
321+
322+
/// @brief Helper structure for TP data transfer to zeromq
323+
Structure TPZMQData
324+
variable marker
325+
string device
326+
variable headstage
327+
variable now
328+
variable clampMode
329+
variable clampAmp
330+
variable duration
331+
variable baselineFrac
332+
variable lengthTPInPoints
333+
variable sampleIntADC
334+
variable timeStamp
335+
variable timeStampUTC
336+
variable cycleId
337+
variable avgBaselineSS
338+
variable avgTPSS
339+
variable instVal
340+
variable resistanceSS
341+
variable resistanceInst
319342
EndStructure
320343

321344
/// @brief Helper structure for GetPlotArea()

Packages/MIES/MIES_TestPulse.ipf

+85-75
Original file line numberDiff line numberDiff line change
@@ -106,45 +106,87 @@ Function TP_StoreTP(device, TPWave, tpMarker, hsList)
106106
SetNumberInWaveNote(storedTP, NOTE_INDEX, index)
107107
End
108108

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

115111
variable numEntries
116112

117113
WAVE/WAVE storedTP = GetStoredTestPulseWave(device)
118114
numEntries = GetNumberFromWaveNote(storedTP, NOTE_INDEX)
119-
120115
if(numEntries == 0)
121-
return $""
116+
return NaN
122117
endif
123118

124119
Make/FREE/N=(numEntries) matches
125-
126120
Multithread matches[0, numEntries - 1] = GetNumberFromWaveNote(storedTP[p], "TPMarker") == tpMarker
127-
128121
FindValue/V=1 matches
129-
130122
if(V_row == -1)
123+
return NaN
124+
endif
125+
126+
return V_row
127+
End
128+
129+
Function/WAVE TP_GetStoredTP(string device, variable tpMarker, variable includeDAC)
130+
131+
variable tpIndex, numEntries, dimMarker
132+
133+
includeDAC = !!includeDAC
134+
135+
tpIndex = TP_GetStoredTPIndex(device, tpMarker)
136+
if(IsNaN(tpIndex))
131137
return $""
132138
endif
133139

134-
Make/FREE/N=(number)/WAVE result
140+
WAVE/WAVE tpStored = GetStoredTestPulseWave(device)
141+
WAVE tpADC = tpStored[tpIndex]
135142

136-
if(number > V_row + 1)
143+
WAVE tpStorage = GetTPStorage(device)
144+
numEntries = GetNumberFromWaveNote(tpStorage, NOTE_INDEX)
145+
dimMarker = FindDimLabel(tpStorage, LAYERS, "TPMarker")
146+
FindValue/RMD=[][0][dimMarker]/V=(tpMarker) tpStorage
147+
ASSERT(V_row >= 0, "Inconsistent TP data")
148+
Duplicate/FREE/RMD=[V_row][][] tpStorage, tpResults
149+
150+
if(includeDAC)
151+
Make/FREE/D/N=0 tpDAC
152+
// TP_CreateTestPulseWaveImpl(tpDAC, variable totalLength, variable pulseStart, variable pulseLength)
153+
else
154+
WAVE/Z tpDAC = $""
155+
endif
156+
157+
Make/FREE/WAVE tpAll = {tpADC, tpDAC, tpResults}
158+
159+
return tpAll
160+
End
161+
162+
/// @brief Return a number of consecutive test pulses ending with the TP
163+
/// identified by tpMarker.
164+
///
165+
/// The wave reference wave will have as many columns as active headstages were used.
166+
Function/WAVE TP_GetConsecutiveTPsUptoMarker(string device, variable tpMarker, variable number)
167+
168+
variable tpIndex, tpCycleId
169+
170+
tpIndex = TP_GetStoredTPIndex(device, tpMarker)
171+
if(IsNaN(tpIndex))
172+
return $""
173+
endif
174+
175+
if(number > tpIndex + 1)
137176
// too few TPs available
138177
return $""
139178
endif
140179

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

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

147-
if(Sum(matches) < number)
185+
// check that they all belong to the same TP cycle
186+
Make/FREE/N=(number) matches
187+
tpCycleId = GetNumberFromWaveNote(result[0], "TPCycleID")
188+
matches[] = tpCycleId == GetNumberFromWaveNote(result[p], "TPCycleID")
189+
if(sum(matches) < number)
148190
return $""
149191
endif
150192

@@ -888,9 +930,11 @@ threadsafe Function/DF TP_TSAnalysis(dfrInp)
888930
variable evalRange, refTime, refPoint, tpStartPoint
889931
variable sampleInt, jsonId
890932
variable avgBaselineSS, avgTPSS, instVal, evalOffsetPointsCorrected, instPoint
933+
STRUCT TPZMQData tpzmq
891934

892935
DFREF dfrOut = NewFreeDataFolder()
893936

937+
// see TP_PrepareAnalysisDF for order
894938
WAVE data = dfrInp:param0
895939
NVAR/SDFR=dfrInp clampAmp = param1
896940
NVAR/SDFR=dfrInp clampMode = param2
@@ -904,6 +948,7 @@ threadsafe Function/DF TP_TSAnalysis(dfrInp)
904948
NVAR/SDFR=dfrInp activeADCs = param10
905949
NVAR/SDFR=dfrInp timeStamp = param11
906950
NVAR/SDFR=dfrInp timeStampUTC = param12
951+
NVAR/SDFR=dfrInp cycleId = param13
907952

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

1010-
// ZMQ publishing
1011-
jsonId = JSON_New()
1012-
JSON_AddTreeObject(jsonID, "properties")
1013-
JSON_AddVariable(jsonID, "properties/unique tp marker", marker)
1014-
JSON_AddString(jsonID, "properties/device", device)
1015-
JSON_AddVariable(jsonID, "properties/headstage", hsIndex)
1016-
JSON_AddVariable(jsonID, "properties/time of tp acquisition", now)
1017-
JSON_AddVariable(jsonID, "properties/clamp mode", clampMode)
1018-
JSON_AddVariable(jsonID, "properties/clamp amplitude", clampAmp)
1019-
JSON_AddVariable(jsonID, "properties/pulse duration in points", duration)
1020-
JSON_AddVariable(jsonID, "properties/baseline fraction", baselineFrac)
1021-
JSON_AddVariable(jsonID, "properties/length of tp in sample points", lengthTPInPoints)
1022-
JSON_AddVariable(jsonID, "properties/sample interval", sampleInt)
1023-
JSON_AddVariable(jsonID, "properties/timeStamp", timeStamp)
1024-
JSON_AddVariable(jsonID, "properties/timeStampUTC", timeStampUTC)
1025-
JSON_AddTreeObject(jsonID, "results")
1026-
JSON_AddVariable(jsonID, "results/average baseline steady state", avgBaselineSS)
1027-
JSON_AddVariable(jsonID, "results/average tp steady state", avgTPSS)
1028-
JSON_AddVariable(jsonID, "results/instantaneous", instVal)
1029-
JSON_AddVariable(jsonID, "results/steady state resistance", outData[1])
1030-
JSON_AddVariable(jsonID, "results/instantaneous resistance", outData[2])
1031-
1032-
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_NOW, releaseJSON = 0)
1033-
if(TP_CheckPublishingTime(ZMQ_FILTER_TPRESULT_1S, 1))
1034-
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_1S, releaseJSON = 0)
1035-
endif
1036-
if(TP_CheckPublishingTime(ZMQ_FILTER_TPRESULT_5S, 5))
1037-
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_5S, releaseJSON = 0)
1038-
endif
1039-
if(TP_CheckPublishingTime(ZMQ_FILTER_TPRESULT_10S, 10))
1040-
PUB_Publish(jsonID, ZMQ_FILTER_TPRESULT_10S, releaseJSON = 0)
1041-
endif
1042-
JSON_Release(jsonID)
1055+
// Serialize for ZMQ publishing
1056+
tpzmq.marker = marker
1057+
tpzmq.device = device
1058+
tpzmq.headstage = hsIndex
1059+
tpzmq.now = now
1060+
tpzmq.clampMode = clampMode
1061+
tpzmq.clampAmp = clampAmp
1062+
tpzmq.duration = duration
1063+
tpzmq.baselineFrac = baselineFrac
1064+
tpzmq.lengthTPInPoints = lengthTPInPoints
1065+
tpzmq.sampleIntADC = sampleInt
1066+
tpzmq.timeStamp = timeStamp
1067+
tpzmq.timeStampUTC = timeStampUTC
1068+
tpzmq.cycleId = cycleId
1069+
1070+
tpzmq.avgBaselineSS = avgBaselineSS
1071+
tpzmq.avgTPSS = avgTPSS
1072+
tpzmq.instVal = instVal
1073+
tpzmq.resistanceSS = outData[1]
1074+
tpzmq.resistanceInst = outData[2]
1075+
1076+
PUB_TPResult(tpzmq)
10431077

10441078
return dfrOut
10451079
End
10461080

1047-
/// @brief Updates the publishing timestamp in the TUFXOP storage and returns 1 if an update is due (0 otherwise)
1048-
threadsafe static Function TP_CheckPublishingTime(string pubFilter, variable period)
1049-
1050-
variable curTime
1051-
1052-
TUFXOP_AcquireLock/N=(pubFilter)
1053-
TUFXOP_GetStorage/Z/Q/N=(pubFilter) lastUpdated
1054-
if(V_flag)
1055-
TUFXOP_Init/N=(pubFilter)
1056-
TUFXOP_GetStorage/Z/N=(pubFilter) lastUpdated
1057-
Make/FREE/D dTime = {DateTime}
1058-
lastUpdated[0] = dTime
1059-
endif
1060-
curTime = DateTime
1061-
WAVE lastTime = lastUpdated[0]
1062-
if(lastTime[0] + period > curTime)
1063-
lastTime[0] = curTime + period
1064-
TUFXOP_ReleaseLock/N=(pubFilter)
1065-
return 1
1066-
endif
1067-
TUFXOP_ReleaseLock/N=(pubFilter)
1068-
1069-
return 0
1070-
End
1071-
10721081
/// @brief Calculates running average [box average] for all entries and all headstages
10731082
static Function TP_CalculateAverage(WAVE TPResultsBuffer, WAVE TPResults)
10741083
variable numEntries, numLayers
@@ -1597,6 +1606,7 @@ Function/DF TP_PrepareAnalysisDF(string device, STRUCT TPAnalysisInput &tpInput)
15971606
ASYNC_AddParam(threadDF, var = tpInput.activeADCs)
15981607
ASYNC_AddParam(threadDF, var = tpInput.timeStamp)
15991608
ASYNC_AddParam(threadDF, var = tpInput.timeStampUTC)
1609+
ASYNC_AddParam(threadDF, var = tpInput.cycleId)
16001610

16011611
return threadDF
16021612
End

0 commit comments

Comments
 (0)