@@ -8,6 +8,7 @@ export getFactorType, getfnctype
8
8
export lsTypes, lsfTypes
9
9
export lsWho, lsfWho
10
10
export *
11
+ export findClosestTimestamp, findVariableNearTimestamp
11
12
12
13
* (a:: Symbol , b:: AbstractString ):: Symbol = Symbol (string (a,b))
13
14
@@ -320,3 +321,85 @@ function lsfWho(dfg::AbstractDFG, type::Symbol)::Vector{Symbol}
320
321
end
321
322
return labels
322
323
end
324
+
325
+
326
+ """
327
+ $SIGNATURES
328
+
329
+ Find and return the closest timestamp from two sets of Tuples. Also return the minimum delta-time (`::Millisecond`) and how many elements match from the two sets are separated by the minimum delta-time.
330
+ """
331
+ function findClosestTimestamp (setA:: Vector{Tuple{DateTime,T}} ,
332
+ setB:: Vector{Tuple{DateTime,S}} ) where {S,T}
333
+ #
334
+ # build matrix of delta times, ranges on rows x vars on columns
335
+ DT = Array {Millisecond, 2} (undef, length (setA), length (setB))
336
+ for i in 1 : length (setA), j in 1 : length (setB)
337
+ DT[i,j] = setB[j][1 ] - setA[i][1 ]
338
+ end
339
+
340
+ DT .= abs .(DT)
341
+
342
+ # absolute time differences
343
+ # DTi = (x->x.value).(DT) .|> abs
344
+
345
+ # find the smallest element
346
+ mdt = minimum (DT)
347
+ corrs = findall (x-> x== mdt, DT)
348
+
349
+ # return the closest timestamp, deltaT, number of correspondences
350
+ return corrs[1 ]. I, mdt, length (corrs)
351
+ end
352
+
353
+ """
354
+ $SIGNATURES
355
+
356
+ Find and return nearest variable labels per delta time. Function will filter on `regexFilter`, `tags`, and `solvable`.
357
+
358
+ DevNotes:
359
+ - TODO `number` should allow returning more than one for k-nearest matches.
360
+ - Future versions likely will require some optimization around the internal `getVariable` call.
361
+ - Perhaps a dedicated/efficient `getVariableTimestamp` for all DFG flavors.
362
+
363
+ Related
364
+
365
+ ls, getVariableIds, findClosestTimestamp
366
+ """
367
+ function findVariableNearTimestamp (dfg:: AbstractDFG ,
368
+ timest:: DateTime ,
369
+ regexFilter:: Union{Nothing, Regex} = nothing ;
370
+ tags:: Vector{Symbol} = Symbol[],
371
+ solvable:: Int = 0 ,
372
+ warnDuplicate:: Bool = true ,
373
+ number:: Int = 1 ):: Vector{Tuple{Vector{Symbol}, Millisecond}}
374
+ #
375
+ # get the variable labels based on filters
376
+ # syms = getVariableIds(dfg, regexFilter, tags=tags, solvable=solvable)
377
+ syms = getVariableIds (dfg, regexFilter, tags= tags, solvable= solvable)
378
+ # compile timestamps with label
379
+ # vars = map( x->getVariable(dfg, x), syms )
380
+ timeset = map (x-> (DFG. timestamp (getVariable (dfg,x)), x), syms)
381
+ mask = BitArray {1} (undef, length (syms))
382
+ fill! (mask, true )
383
+
384
+ RET = Vector {Tuple{Vector{Symbol},Millisecond}} ()
385
+ SYMS = Symbol[]
386
+ CORRS = 1
387
+ NUMBER = number
388
+ while 0 < CORRS + NUMBER
389
+ # get closest
390
+ link, mdt, corrs = findClosestTimestamp ([(timest,0 )], timeset[mask])
391
+ push! (SYMS, syms[link[2 ]])
392
+ mask[link[2 ]] = false
393
+ CORRS = corrs- 1
394
+ # last match, done with this delta time
395
+ if corrs == 1
396
+ NUMBER -= 1
397
+ push! (RET, (deepcopy (SYMS),mdt))
398
+ SYMS = Symbol[]
399
+ end
400
+ end
401
+ # warn if duplicates found
402
+ # warnDuplicate && 1 < corrs ? @warn("getVariableNearTimestamp found more than one variable at $timestamp") : nothing
403
+
404
+ return RET
405
+ end
0 commit comments