Example #1
0
def removePanel(panelID):
    del FandS[panelID]

    response = {
        "deletedPanelID": panelID,
        "minifiedFandS": helper.createMinifiedFandS()
    }

    return jsonify(response)
Example #2
0
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)
Example #3
0
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)
Example #4
0
def createMultipleSimpleSplittingPoints(
):  # cascading add is not required because multiple splitting points are added to new panel
    global FandS
    data = request.get_json()
    panelIDOfInputSeq = data["panelID"]
    ForSIDOfInputSeq = data["ForSID"]
    AVPairs = data["AVPairs"]
    currentInputForSID = ForSIDOfInputSeq

    for AVPair in AVPairs:
        # handle for av pair
        if AVPair["type"] == "AVPair":
            attributeName = AVPair["attributeName"]
            attributeValue = AVPair["attributeValue"]

            # init FandS
            newForSID = helper.getNewForSID(panelIDOfInputSeq)

            FandS[panelIDOfInputSeq][newForSID] = {
                "name": attributeName + "=" + attributeValue,
                "input": currentInputForSID + "-after",  # input must be after
                "output": None,
                "averageTime": {
                    "before": None,
                    "after": None
                },  # in second
                "averageNumberOfEvents": {
                    "before": None,
                    "after": None
                },
                "applyToSequences": True,
                "applyToRecordAttributes": False,
                "trueStart": {
                    "before": {},
                    "after": {},
                    "not": {}
                },
                "trueEnd": {
                    "before": {},
                    "after": {},
                    "not": {}
                }
            }

            # update output, averageTime, averageNumberOfEvents, trueStart and trueEnd
            helper.updateSimpleSPOutput(panelIDOfInputSeq, newForSID)

        # handle for event with multiple av pair
        if AVPair["type"] == "Pattern":
            name = AVPair["name"]
            eventMatchers = AVPair["eventMatchers"]
            orderedAVPairsForEachMatcher = AVPair[
                "orderedAVPairsForEachMatcher"]
            logicTableForEachMatcher = AVPair["logicTableForEachMatcher"]

            # init FandS
            newForSID = helper.getNewForSID(panelIDOfInputSeq)

            FandS[panelIDOfInputSeq][newForSID] = {
                "name": name,
                "input": ForSIDOfInputSeq + "-after",  # input must be after
                "output": None,
                "averageTime": {
                    "before": None,
                    "after": None
                },  # in second
                "averageNumberOfEvents": {
                    "before": None,
                    "after": None
                },
                "applyToSequences": True,
                "applyToRecordAttributes": False,
                "trueStart": {
                    "before": {},
                    "after": {},
                    "not": {}
                },
                "trueEnd": {
                    "before": {},
                    "after": {},
                    "not": {}
                },
                "eventMatchers": eventMatchers,
                "orderedAVPairsForEachMatcher": orderedAVPairsForEachMatcher,
                "logicTableForEachMatcher": logicTableForEachMatcher
            }

            # update output, averageTime, averageNumberOfEvents, trueStart and trueEnd
            helper.updatePatternSPOutput(panelIDOfInputSeq, newForSID)

        # update for next iteration
        currentInputForSID = newForSID

    response = {
        "updatedPanelID": panelIDOfInputSeq,
        "minifiedFandS": helper.createMinifiedFandS()
    }

    return jsonify(response)
Example #5
0
def createPatternSplittingPoint():
    global FandS
    data = request.get_json()
    panelIDOfInputSeq = data["panelID"]
    ForSIDOfInputSeq = data["ForSID"]
    name = data["name"]
    eventMatchers = data["eventMatchers"]
    orderedAVPairsForEachMatcher = data["orderedAVPairsForEachMatcher"]
    logicTableForEachMatcher = data["logicTableForEachMatcher"]

    # init FandS
    newForSID = helper.getNewForSID(panelIDOfInputSeq)

    FandS[panelIDOfInputSeq][newForSID] = {
        "name": name,
        "input": ForSIDOfInputSeq + "-after",  # input must be after
        "output": None,
        "averageTime": {
            "before": None,
            "after": None
        },  # in second
        "averageNumberOfEvents": {
            "before": None,
            "after": None
        },
        "applyToSequences": True,
        "applyToRecordAttributes": False,
        "trueStart": {
            "before": {},
            "after": {},
            "not": {}
        },
        "trueEnd": {
            "before": {},
            "after": {},
            "not": {}
        },
        "eventMatchers": eventMatchers,
        "orderedAVPairsForEachMatcher": orderedAVPairsForEachMatcher,
        "logicTableForEachMatcher": logicTableForEachMatcher
    }

    # update output, averageTime, averageNumberOfEvents, trueStart and trueEnd
    helper.updatePatternSPOutput(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
    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)
Example #6
0
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)