def createSimpleCategoricalFilter(): global FandS panelIDOfInputSeq = request.args["panelID"] ForSIDOfInputSeq = request.args["ForSID"] selectedAttrName = request.args["attributeName"] selectedAttrValue = request.args["attributeValue"] # init FandS newForSID = helper.getNewForSID(panelIDOfInputSeq) FandS[panelIDOfInputSeq][newForSID] = { "name": selectedAttrName + "=" + selectedAttrValue, "input": ForSIDOfInputSeq + "-after", # input must be after "output": None, "averageTime": { "after": None }, "averageNumberOfEvents": { "after": None }, "applyToSequences": False, "applyToRecordAttributes": True, "trueStart": { "after": {} }, "trueEnd": { "after": {} } } # update output helper.updateCategoricalFilterOutput(panelIDOfInputSeq, newForSID) # change input of the ForS with the same input as the created ForS ForSIDWithInputChanged = None for currentForSID in FandS[panelIDOfInputSeq]: if currentForSID != newForSID and currentForSID != ForSIDOfInputSeq: # a ForS can have its output as input inputStringOfUpdatedForS = ForSIDOfInputSeq + "-after" inputStringOfCurrentForS = FandS[panelIDOfInputSeq][currentForSID]["input"] if inputStringOfUpdatedForS == inputStringOfCurrentForS: ForSIDWithInputChanged = currentForSID FandS[panelIDOfInputSeq][currentForSID]["input"] = newForSID + "-after" break # update all subsequent ForS (all inputs are correct after the above step) currentForSID = ForSIDWithInputChanged while currentForSID != None: isPatternSplittingPoint = "orderedAVPairsForEachMatcher" in FandS[panelIDOfInputSeq][currentForSID] if isPatternSplittingPoint: helper.updatePatternSPOutput(panelIDOfInputSeq, currentForSID) if not isPatternSplittingPoint: helper.updateSimpleSPOutput(panelIDOfInputSeq, currentForSID) currentForSID = helper.getNextForSID(panelIDOfInputSeq, currentForSID) response = { "updatedPanelID": panelIDOfInputSeq, "minifiedFandS": helper.createMinifiedFandS() } return jsonify(response)
def removeSorF(): global FandS panelID = request.args["panelID"] ForSIDToBeDeleted = request.args["ForSID"] inputStringOfDeletedForS = FandS[panelID][ForSIDToBeDeleted]["input"] ForSIDAfterDeletedForS = helper.getNextForSID(panelID, ForSIDToBeDeleted) if ForSIDAfterDeletedForS != None: # change input of next ForS FandS[panelID][ForSIDAfterDeletedForS][ "input"] = inputStringOfDeletedForS # update all subsequent ForS currentForSID = ForSIDAfterDeletedForS while currentForSID != None: isSplittingPoint = FandS[panelID][currentForSID][ "applyToSequences"] isPatternSplittingPoint = "orderedAVPairsForEachMatcher" in FandS[ panelID][currentForSID] isNumerical = "<=" in FandS[panelID][currentForSID]["name"] if isSplittingPoint and isPatternSplittingPoint: helper.updatePatternSPOutput(panelID, currentForSID) if isSplittingPoint and not isPatternSplittingPoint: helper.updateSimpleSPOutput(panelID, currentForSID) if not isSplittingPoint and not isNumerical: helper.updateCategoricalFilterOutput(panelID, currentForSID) if not isSplittingPoint and isNumerical: helper.updateNumericalFilterOutput(panelID, currentForSID) currentForSID = helper.getNextForSID(panelID, currentForSID) del FandS[panelID][ForSIDToBeDeleted] response = { "updatedPanelID": panelID, "removedForSID": ForSIDToBeDeleted, "minifiedFandS": helper.createMinifiedFandS() } return jsonify(response)
def initFandSForNewPanel(): global FandS panelIDOfStartingSeq = request.args["panelID"] ForSIDOfStartingSeq = request.args["ForSID"] outputTypeOfStartingSeq = request.args["outputType"] clearPrevious = request.args["clearPrevious"] isPanelShowingAllSeq = panelIDOfStartingSeq == "0" and ForSIDOfStartingSeq == "0" and outputTypeOfStartingSeq == "0" currentPanelHasFilters = not isPanelShowingAllSeq and helper.hasFilters( panelIDOfStartingSeq) timeAndEventCountFilterList = [] # return to client startingEventSequencesByID = eventSequencesByID startingFilterName = "Start" trueStartByID = {} trueEndByID = {} if clearPrevious == "true": FandS.clear() if isPanelShowingAllSeq: for ID in startingEventSequencesByID: numberOfEventsForCurrentSequence = len( startingEventSequencesByID[ID]) firstEvent = startingEventSequencesByID[ID][0] lastEvent = startingEventSequencesByID[ID][ numberOfEventsForCurrentSequence - 1] trueStartTime = datetime.strptime(firstEvent[0], "%Y-%m-%dT%H:%M:%SZ") trueEndTime = datetime.strptime(lastEvent[0], "%Y-%m-%dT%H:%M:%SZ") trueStartByID[ID] = trueStartTime trueEndByID[ID] = trueEndTime if not isPanelShowingAllSeq and not currentPanelHasFilters: startingEventSequencesByID = FandS[panelIDOfStartingSeq][ ForSIDOfStartingSeq]["output"][outputTypeOfStartingSeq] startingFilterName = FandS[panelIDOfStartingSeq][ForSIDOfStartingSeq][ "name"] trueStartByID = FandS[panelIDOfStartingSeq][ForSIDOfStartingSeq][ "trueStart"][outputTypeOfStartingSeq] trueEndByID = FandS[panelIDOfStartingSeq][ForSIDOfStartingSeq][ "trueEnd"][outputTypeOfStartingSeq] if not isPanelShowingAllSeq and currentPanelHasFilters: results = helper.getIDListSatisfiedEventCountAndTime( panelIDOfStartingSeq) IDListSatisfiedEventCountAndTime = results[ "IDListSatisfiedEventCountAndTime"] timeAndEventCountFilterList = results["timeAndEventCountFilterList"] resultsWithoutFilters = helper.getStartingSeqWithoutFilters( panelIDOfStartingSeq, ForSIDOfStartingSeq, outputTypeOfStartingSeq, IDListSatisfiedEventCountAndTime) startingFilterName = FandS[panelIDOfStartingSeq][ForSIDOfStartingSeq][ "name"] startingEventSequencesByID = resultsWithoutFilters[ "startingEventSequencesByID"] trueStartByID = resultsWithoutFilters["trueStartByID"] trueEndByID = resultsWithoutFilters["trueEndByID"] # create new panel newPanelID = helper.getNewPanelID() FandS[newPanelID] = {} FandS[newPanelID]["0"] = { "name": startingFilterName, "input": "0-after", # input and output are the same "output": { "after": startingEventSequencesByID }, "averageTime": { "after": None }, "averageNumberOfEvents": { "after": None }, "applyToSequences": False, "applyToRecordAttributes": True, "trueStart": { "after": trueStartByID }, "trueEnd": { "after": trueEndByID } } # prevent division by zero if len(startingEventSequencesByID) == 0: FandS[newPanelID]["0"]["averageTime"]["after"] = 0 FandS[newPanelID]["0"]["averageNumberOfEvents"]["after"] = 0 # compute averageTime and averageNumberOfEvents else: sumOfTime = 0 sumOfNumberOfEvents = 0 for ID in startingEventSequencesByID: # add to sumOfNumberOfEvents numberOfEventsForCurrentSequence = len( startingEventSequencesByID[ID]) sumOfNumberOfEvents += numberOfEventsForCurrentSequence # add to sumOfTime startTimeObject = FandS[newPanelID]["0"]["trueStart"]["after"][ID] endTimeObject = FandS[newPanelID]["0"]["trueEnd"]["after"][ID] deltaT = endTimeObject - startTimeObject deltaTInSecond = deltaT.total_seconds() sumOfTime += deltaTInSecond averageTime = sumOfTime / len(startingEventSequencesByID) averageNumberOfEvents = sumOfNumberOfEvents / len( startingEventSequencesByID) FandS[newPanelID]["0"]["averageTime"]["after"] = averageTime FandS[newPanelID]["0"]["averageNumberOfEvents"][ "after"] = averageNumberOfEvents # add back the filters on the clicked panel if not isPanelShowingAllSeq and currentPanelHasFilters: # get all filters in the clicked panel except eventCount or time currentForSID = "0" allFiltersOnPanel = [] while currentForSID != None: isFilter = FandS[panelIDOfStartingSeq][currentForSID][ "applyToRecordAttributes"] isNumerical = "<=" in FandS[panelIDOfStartingSeq][currentForSID][ "name"] isEventCountOrTime = False if isNumerical: splittedName = FandS[panelIDOfStartingSeq][currentForSID][ "name"].split("<=") recordAttributeName = splittedName[1] isEventCountOrTime = (recordAttributeName == "eventCount") or (recordAttributeName == "time") # push filter only if it is not eventCount or time if isFilter and not isEventCountOrTime and currentForSID != "0": allFiltersOnPanel.append( FandS[panelIDOfStartingSeq][currentForSID]) currentForSID = helper.getNextForSID(panelIDOfStartingSeq, currentForSID) # create FandS for each filter previousForSID = "0" for filter in allFiltersOnPanel: newForSID = helper.getNewForSID(newPanelID) filterName = filter["name"] FandS[newPanelID][newForSID] = { "name": filterName, "input": previousForSID + "-after", "output": None, "averageTime": { "after": None }, "averageNumberOfEvents": { "after": None }, "applyToSequences": False, "applyToRecordAttributes": True, "trueStart": { "after": {} }, "trueEnd": { "after": {} } } previousForSID = newForSID # update output of all FandS currentFilterID = helper.getNextForSID(newPanelID, "0") while currentFilterID != None: isNumerical = "<=" in FandS[newPanelID][currentFilterID]["name"] if not isNumerical: helper.updateCategoricalFilterOutput(newPanelID, currentFilterID) if isNumerical: helper.updateNumericalFilterOutput(newPanelID, currentFilterID) currentFilterID = helper.getNextForSID(newPanelID, currentFilterID) response = { "newPanelID": newPanelID, "minifiedFandS": helper.createMinifiedFandS(), "timeAndEventCountFilterList": timeAndEventCountFilterList } return jsonify(response)