app/assets/javascripts/specifics.js.coffee in hqmf2js-1.2.1 vs app/assets/javascripts/specifics.js.coffee in hqmf2js-1.3.0
- old
+ new
@@ -39,11 +39,15 @@
product
, [[]])
identity: ->
new hqmf.SpecificOccurrence([new Row(undefined)])
-
+
+ setIfNull: (events,subsets) ->
+ if (!events.specificContext? || events.length == 0)
+ events.specificContext=hqmf.SpecificsManager.identity()
+
getColumnIndex: (occurrenceID) ->
columnIndex = @indexLookup[occurrenceID]
if typeof columnIndex == "undefined"
throw "Unknown occurrence identifier: "+occurrenceID
columnIndex
@@ -52,11 +56,11 @@
new hqmf.SpecificOccurrence([])
extractEventsForLeftMost: (rows) ->
events = []
for row in rows
- events.push(@extractEvent(row.leftMost, row))
+ events.push(@extractEvent(row.leftMost, row)) if row.leftMost? || row.tempValue?
events
extractEvents: (key, rows) ->
events = []
for row in rows
@@ -141,21 +145,29 @@
if value.specificContext? and (value.isTrue() or negate)
result = result.union(value.specificContext) if value.specificContext?
if negate and (!result.hasRows() or result.hasSpecifics())
result = result.negate()
- # this is a little odd, but it appears when we have a negation with specifics we can ignore the logical result of the negation. See comment in intersectAll.
+ # this is a little odd, but it appears when we have a negation with specifics we can
+ # ignore the logical result of the negation. See comment in intersectAll.
# we need to verify that we actually have some occurrences
boolVal = new Boolean(true) if @occurrences.length > 0
boolVal.specificContext = result
boolVal
# copy the specifics parameters from an existing element onto the new value element
maintainSpecifics: (newElement, existingElement) ->
newElement.specificContext = existingElement.specificContext
newElement.specific_occurrence = existingElement.specific_occurrence
newElement
+
+ flattenToIds: (specificContext) ->
+ specificContext?.flattenToIds() || []
+
+ storeFinal: (key, result, target) ->
+ target[key] = hqmf.SpecificsManager.flattenToIds(result.specificContext)
+
@hqmf.SpecificsManager = new hqmf.SpecificsManagerSingleton
class hqmf.SpecificOccurrence
constructor: (rows=[])->
@@ -192,11 +204,21 @@
uniqueEvents: (columnIndices) ->
eventIds = []
for columnIndex in columnIndices
for row in @rows
event = row.values[columnIndex]
- eventIds.push(event.id) if event != hqmf.SpecificsManager.any and not (event.id in eventIds)
+ if event != hqmf.SpecificsManager.any and not (event.id in eventIds)
+ onlyOneMatch = true
+ # we want to check that we do not have multiple episodes of care matching on this row. If we do, then that means
+ # that we have a reliance on multiple episodes of care for this row when we can only rely on one. If we have multiple
+ # then we want to disregard this row.
+ if (columnIndices.length > 1)
+ for columnIndexInside in columnIndices
+ onlyOneMatch = false if (columnIndexInside != columnIndex and row.values[columnIndexInside] != hqmf.SpecificsManager.any)
+
+ if onlyOneMatch
+ eventIds.push(event.id)
eventIds.length
hasExactRow: (other) ->
for row in @rows
return true if row.equals(other)
@@ -322,24 +344,35 @@
LAST: ->
@applySubset(LAST)
RECENT: ->
@applySubset(RECENT)
+
+ hasLeftMost: ->
+ for row in @rows
+ if row.leftMost? || row.tempValue?
+ return true
+ return false
applySubset: (func) ->
- return this if !@hasSpecifics()
+ return this if !@hasSpecifics() || !@hasLeftMost()
resultRows = []
groupedRows = @group()
for groupKey, group of groupedRows
entries = func(hqmf.SpecificsManager.extractEventsForLeftMost(group))
- if entries.length > 0
- resultRows.push(entries[0].specificRow)
+ resultRows.push(entry.specificRow) for entry in entries
new hqmf.SpecificOccurrence(resultRows)
addIdentityRow: ->
@addRows(hqmf.SpecificsManager.identity().rows)
+ flattenToIds: ->
+ result = []
+ for row in @rows
+ result.push(row.flattenToIds())
+ result
+
class Row
# {'OccurrenceAEncounter':1, 'OccurrenceBEncounter'2}
constructor: (leftMost, occurrences={}) ->
throw "left most key must be a string or undefined was: #{leftMost}" if typeof(leftMost) != 'string' and typeof(leftMost) != 'undefined'
@length = hqmf.SpecificsManager.occurrences.length
@@ -436,28 +469,41 @@
# build specific for an entry given matching rows (with temporal references)
@buildRowsForMatching: (entryKey, entry, matchesKey, matches) ->
rows = []
for match in matches
- occurrences={}
- occurrences[entryKey] = entry
+
# from unions and crossproducts we may have a matches key that is a hash of object ids mapped to the specific occurrence key.
# this is because we may have multiple different specific occurrences on the right hand side if it came from a group
- if (_.isObject(matchesKey))
- occurrences[matchesKey[match.id]] = match
- else
- occurrences[matchesKey] = match
- rows.push(new Row(entryKey, occurrences))
+ # we may also have the same event mapping to multiple occurrences, so if we have a hash the value will be an array.
+ # we make both the UNION and CROSS casses look the same as the standard case by turning the standard into an array
+ matchKeys = (if _.isObject(matchesKey) then matchesKey[match.id] else [matchesKey])
+ if (matchKeys)
+ for matchKey in matchKeys
+ occurrences = {}
+ occurrences[entryKey] = entry
+ occurrences[matchKey] = match
+ rows.push(new Row(entryKey, occurrences))
rows
# build specific for a given entry (there are no temporal references)
@buildForDataCriteria: (entryKey, entries) ->
rows = []
for entry in entries
occurrences={}
occurrences[entryKey] = entry
rows.push(new Row(entryKey, occurrences))
rows
+
+ flattenToIds: ->
+ result = []
+ for value in @values
+ if (value == hqmf.SpecificsManager.any)
+ result.push(value)
+ else
+ result.push(value.id)
+ result
+
@Row = Row
###
Wrap methods to maintain specificContext and specific_occurrence