Skip to content
Snippets Groups Projects
Select Git revision
  • c88a578e5614300b12e9acb6664d440a1245c28c
  • master default protected
  • v0.5
  • v0.4
  • v0.3.1
  • v0.3
  • v0.2.3
  • v0.2.2
  • v0.2.0
  • v0.1.2
  • v0.1.1
  • v0.1.0
  • v0.0.1
13 results

setup.py

Blame
  • eventlog.py 7.86 KiB
    import pandas as pd
    import simplesimmodel as model
    import numpy as np
    from collections import OrderedDict
    import simpy
    from pm4py.objects.log.exporter.xes import exporter as xes_exporter
    from pm4py.objects.log.importer.xes import importer as xes_importer
    from pm4py.objects.log.obj import EventLog
    from pm4py.objects.log.obj import Trace
    from pm4py.objects.log.obj import Event
    import os
    
    """
    Event log generator for our simulation model:
    - generate an event log
    - update an event log (adding new events)
    - export event log
    - get current state of an event log
    """
    
    def add_start_event(process, event_id, case_id, activity, start_timestamp):
        process.event_log.append(event_id)
        process.event_log[event_id] = {
            'CaseID': case_id,
            'Activity': activity,
            'StartTimestamp': float(start_timestamp),
            'EndTimestamp': None
        }
        process.event_counter += 1
    
    
    def add_end_event(process, event_id, end_timestamp):
        event = process.event_log[event_id]
        event['EndTimestamp'] = end_timestamp
    
    
    def export_to_csv(process, file_path):
        event_log_df = pd.DataFrame.from_dict(process.event_log)
        event_log_df.to_csv(file_path, index=False)
    
    
    def export_to_xes(process, file_path):
        event_log = process.event_log
    
        # Create an empty event log object
        event_log_obj = EventLog()
    
        # Iterate over each event in the event log
        for event_data in event_log:
            # Create a new trace
            trace = Trace()
    
            # Create a new event
            event = Event()
    
            # Set the attributes of the event based on the dictionary values
            event['Activity'] = event_data['Activity']
            event['StartTimestamp'] = event_data['StartTimestamp']
            event['EndTimestamp'] = event_data['EndTimestamp']
            event['CaseID'] = event_data['CaseID']
    
            # Add the event to the trace
            trace.append(event)
    
            # Add the trace to the event log
            event_log_obj.append(trace)
    
        # Export the event log to XES format
        xes_exporter.apply(event_log_obj, file_path)
    
    
    def convert_to_dataframe(name):
        file_path = r"Frontend/upload/" + name 
        # print(path)
        file_extension = os.path.splitext(file_path)[1].lower()
        
        if file_extension == '.csv':
            event_log_df = pd.read_csv(file_path)
        elif file_extension == '.xes':
            # Read the XES file
            event_log = xes_importer.apply(file_path)
    
            # Extract the event attributes and create a list of dictionaries
            event_data = []
            for trace in event_log:
                for event in trace:
                    event_data.append(event)
    
            # Create a pandas DataFrame from the event data
            event_log_df = pd.DataFrame(event_data)
        else:
            print(f"Unsupported file type: {file_extension}")
    
        # print(event_log_df)
        return event_log_df
    
    
    def get_active_cases(name):
        event_log_df = convert_to_dataframe(name)
        
        active_cases = event_log_df.groupby('CaseID').filter(lambda x: 'order completed' not in x['Activity'].values)['CaseID'].unique().tolist()
        print(active_cases)
        return active_cases
    
    
    def get_state(case_id,name):
    
        process = np.zeros(13, dtype=int)
        num_s = 1
        process[0] = num_s
        num_ot = 4
        process[1] = num_ot
        num_sh_a = 2
        process[2] = num_sh_a
        num_sh_b = 2
        process[3] = num_sh_b
        num_sh_c = 2
        process[4] = num_sh_c
        num_m_a = 4
        process[5] = num_m_a
        num_m_b = 10
        process[6] = num_m_b
        num_p_a = 2
        process[7] = num_p_a
        num_p_b = 3
        process[8] = num_p_b
        num_p_c = 3
        process[9] = num_p_c
        num_ds_a = 25
        process[10] = num_ds_a
        num_ds_b = 40
        process[11] = num_ds_b
        num_ds_c = 45
        process[12] = num_ds_c
    
        case = np.zeros(15, dtype=int)
    
        activity_mapping = {
            'place order': 1,
            'arrange standard order': 2,
            'arrange custom order': 3,
            'pick from stock A': 4, 
            'pick from stock B': 5, 
            'pick from stock C': 6, 
            'manufacture A': 7, 
            'manufacture B': 8, 
            'pack A': 9,
            'pack B': 10,
            'pack C': 11,
            'attempt delivery A': 12,
            'attempt delivery B': 13,
            'attempt delivery C': 14,
            'order completed': 15,
        }
    
        event_log = convert_to_dataframe(name)
        # Sort the event log by case ID and start timestamp
        event_log.sort_values(by=['CaseID', 'StartTimestamp'], inplace=True)
    
        # Group the event log by case ID and get the last activity for each case
        last_activities = event_log.groupby('CaseID').tail(1).reset_index()
       
        # Remap the activity names to numbers using the mapping dictionary
        last_activities['Activity'] = last_activities['Activity'].map(activity_mapping)
    
        # Filter the cases where the end timestamp of the last activity is None or empty
        unfinished_cases = last_activities[last_activities['EndTimestamp'].isnull()]['CaseID'].tolist()
    
        # Update the state of the ressources given all unfinished cases
        for i in unfinished_cases:
            activity = last_activities[last_activities['CaseID'] == i]['Activity'].values[0]
            if activity == 1 or activity == 15:
                process[0] -= 1
            elif activity == 2 or activity == 3:
                process[1] -= 1
            else:
                process[activity-2] -= 1
    
        # Get the state of the case for the given Case ID
        filtered_log = event_log[event_log['CaseID'] == case_id]
        activities = filtered_log['Activity'].map(activity_mapping).tolist()
        for i in activities:
            case[i-1] += 1
    
        # Get the last event for the given Case ID
        event = last_activities[last_activities['CaseID'] == case_id]['Activity'].values[0]
    
        """
        state = {
            'process': process,
            'case': case,
            'event': event
        }
        """
    
        state = OrderedDict()
        state['case'] = case
        state['event'] = event
        state['process'] = process
    
        # print(state)
    
        return state
    
    # connect with frontend!!!
    def generate_event_log(time):
        ressources = [] 
        num_s = 1
        ressources.append(num_s+1)
        num_ot = 4
        ressources.append(num_ot+1)
        num_sh_a = 2
        ressources.append(num_sh_a+1)
        num_sh_b = 2
        ressources.append(num_sh_b+1)
        num_sh_c = 2
        ressources.append(num_sh_c+1)
        num_m_a = 4
        ressources.append(num_m_a+1)
        num_m_b = 10
        ressources.append(num_m_b+1)
        num_p_a = 2
        ressources.append(num_p_a+1)
        num_p_b = 3
        ressources.append(num_p_b+1)
        num_p_c = 3
        ressources.append(num_p_c+1)
        num_ds_a = 25
        ressources.append(num_ds_a+1)
        num_ds_b = 40
        ressources.append(num_ds_b+1)
        num_ds_c = 45
        ressources.append(num_ds_c+1)      
        
        # generate event log
        env = simpy.Environment()
        business_process = model.BusinessProcess(env, ressources)
        business_process.event_log_flag = True
        env.process(model.run_process(env, business_process))
        env.run(until = time)
        export_to_csv(business_process, r'Frontend/export/eventlog.csv')
        export_to_xes(business_process, r'Frontend/export/eventlog.xes')
    
    
    def show_active_cases(name):
        activity_mapping = {
            1: 'place order',
            2: 'arrange standard order',
            3: 'arrange custom order',
            4: 'pick from stock A', 
            5: 'pick from stock B', 
            6: 'pick from stock C', 
            7: 'manufacture A', 
            8: 'manufacture B', 
            9: 'pack A',
            10: 'pack B',
            11: 'pack C',
            12: 'attempt delivery A',
            13: 'attempt delivery B',
            14: 'attempt delivery C',
            15: 'order completed',
        }
    
        caselist = get_active_cases(name)
        reslist = []
        for case in caselist:
            state = get_state(case, name)
            trace = []
            events = state['case']
    
            for i in range(len(events)):
                if events[i] == 1:
                    trace.append(activity_mapping[i+1])     
    
            tup = (case, trace)
            reslist.append(tup)
    
        return reslist
    
    
    def main():
        # generate_event_log(10000)
        print(get_state(5, "eventlog.csv"))
    
    
    if __name__ == "__main__":
        main()