Пример #1
0
def generate_location_spread_time_series(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = { 
        'experimentLabel': experimentLabel if experimentLabel != None else { '$exists': True }, 
        'event': 'PlayerLocationEvent',
        'time': { '$gte': start_time, '$lte': end_time },
    }
    intermediary_data = list(client.epilog.data2.aggregate([
        { '$match' : query },
        { '$sort': { 'time': 1 } },
        { '$project' : { '_id' : 0, 'player': 1, 'distances': 1, 'time': 1 } },
    ]))

    start_time = get_times(client, experimentLabel)[0] // (60*1000)
    proccessed_data = [{ player: { 'count': 0, 'total': 0 } for player in PLAYERS } for _ in range(60)]
    for event in intermediary_data:
        event_time = event['time'] // (60*1000)

        if (event_time - start_time) < 60:
            data = proccessed_data[(event_time - start_time)][event['player']]
            proccessed_data[(event_time - start_time)][event['player']] = {
                'total': data['total'] + sum(event['distances'].values()) / len(event['distances']),
                'count': data['count'] + 1
            }

    return {
        'series': [{
            'title': 'Average Distance Between All Members Over Time',
            'data': [sum([data[player]['total'] / data[player]['count'] if data[player]['count'] > 0 else 0 for player in PLAYERS]) / len(PLAYERS) for data in proccessed_data],
        }],
        'categories': [i for i in range(60)]
    }
def generate_trophy_count_column_chart(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = { 
        'experimentLabel': experimentLabel if experimentLabel != None else { '$exists': True }, 
        'event': 'CollectTrophyEvent',
        'time': { '$gte': start_time, '$lte': end_time },
    }
    intermediary_data = list(client.epilog.data2.aggregate([
        { '$match' : query },
        { '$project' : { '_id' : 0, 'player': 1 } },
        { '$group': { '_id' : '$player', 'total': { '$sum': 1 } } },
    ]));

    intermediary_data = sorted(intermediary_data, key=lambda x: x['_id'])

    return {
        'series': [
            { 
                'name': 'Trophy Count', 
                'data': [next((data['total'] for data in intermediary_data if data['_id'] == player), 0) for player in PLAYERS]
            }
        ],
        'categories': [UUID_MAP[player]['name'] for player in PLAYERS],
        'colors': [UUID_MAP[player]['color'] for player in PLAYERS],
    }
def generate_time_of_player_by_location_column_chart(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = { 
        'experimentLabel': experimentLabel if experimentLabel != None else { '$exists': True }, 
        'event': 'PlayerLocationEvent',
        'time': { '$gte': start_time, '$lte': end_time },
    }
    intermediary_data = list(client.epilog.data2.aggregate([
        { '$match' : query },
        { '$project' : { '_id' : 0, 'player': 1, 'zone': 1 } },
        { '$sort': { 'zone': 1 } },
        { '$group': { '_id' : { 'zone': '$zone', 'player': '$player'}, 'total': { '$sum': 1 } } },
        { '$group' : { 
            '_id' :  "$_id.player",
            'totals': { '$push': { 'zone': '$_id.zone', 'total': '$total'} }
            } 
        },
        { '$sort': { '_id': 1 } },
    ]))

    return {
        'series': [{ 
                'name': UUID_MAP[player]['name'], 
                'data': [
                    next((player_data['total'] for player_data in next(
                        (zone_data['totals'] for zone_data in intermediary_data if zone_data['_id'] == player), []) 
                    if player_data['zone'] == zone), 0)
                for zone in ZONES],
                'color': UUID_MAP[player]['color'],
            } for player in PLAYERS],
        'categories': ZONES,
    }
Пример #4
0
def generate_percent_duplicate_location_column_chart(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'PlayerLocationEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$sort': {
                    'time': 1
                }
            },
            {
                '$project': {
                    '_id': 0,
                    'player': 1,
                    'x': 1,
                    'y': 1,
                    'z': 1,
                    'time': 1
                }
            },
        ]))

    processed_data = {player: 0 for player in PLAYERS}
    previous_locations = {player: (None, None, None) for player in PLAYERS}
    travelled_set = set()

    for event in intermediary_data:
        x, y, z = floor(event['x']), floor(event['y']), floor(event['z'])
        if (x, y, z) != previous_locations[event['player']] and (
                x, y, z) in travelled_set:
            processed_data[event['player']] += 1
        previous_locations[event['player']] = (x, y, z)
        travelled_set.add((x, y, z))

    for player in PLAYERS:
        processed_data[player] = (processed_data[player] /
                                  len(travelled_set)) * 100.0

    return {
        'series': [{
            'name': 'Percentage Overlap',
            'data': [processed_data[player] for player in PLAYERS]
        }],
        'categories': [UUID_MAP[player]['name'] for player in PLAYERS],
        'colors': [UUID_MAP[player]['color'] for player in PLAYERS],
    }
def generate_trophy_timeline_step_chart(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'CollectTrophyEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$project': {
                    '_id': 0,
                    'time': {
                        '$floor': {
                            '$divide': ['$time', 1000 * 60]
                        }
                    }
                }
            },
            {
                '$sort': {
                    'time': 1
                }
            },
            {
                '$group': {
                    '_id': '$time',
                    'total': {
                        '$sum': 1
                    }
                }
            },
        ]))

    start_minute = start_time // (60 * 1000)
    game_timeline = [0 for _ in range(60)]
    cumulative_count = 0
    for i in range(60):
        event = next((data['total'] for data in intermediary_data
                      if int(data['_id']) == start_minute + i), 0)
        cumulative_count += event
        game_timeline[i] = cumulative_count

    return {
        'series': [{
            'name': 'Cumulative Trophy Count',
            'data': game_timeline
        }],
    }
def generate_sharing_column_chart(client, experimentLabel):
    collection = client.epilog.data2
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'PlayerPickupItemEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    cursor = collection.find(query, sort=[('time', pymongo.ASCENDING)])
    actions = ['given', 'taken']
    intermediary_data = {}
    for action in actions:
        intermediary_data[action] = {}
    intermediary_player_set = set()
    for event in cursor:
        if event['droppedBy'] == None:
            continue
        if event['droppedBy'] == event['player']:
            continue

        intermediary_player_set.add(event['player'])
        if event['player'] not in intermediary_data['taken']:
            intermediary_data['taken'][event['player']] = 0
        intermediary_data['taken'][event['player']] += 1
        if event['droppedBy'] not in intermediary_data['given']:
            intermediary_data['given'][event['droppedBy']] = 0
        intermediary_data['given'][event['droppedBy']] += 1

    return {
        'series': [{
            'name':
            action,
            'data': [
                intermediary_data[action][player] if
                (player in intermediary_data[action]) else 0
                for player in PLAYERS
            ]
        } for action in actions],
        'categories': [UUID_MAP[player]['name'] for player in PLAYERS],
    }
def generate_diversity_of_labor_by_player_column_chart(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = { 
        'experimentLabel': experimentLabel if experimentLabel != None else { '$exists': True }, 
        'event': {'$in': ['DoFarmEvent', 'OreBreakEvent', 'DuneBreakEvent',
                               'VillagerTradeEvent', 'CollectTrophyEvent', 'BarrelOpenedEvent', 'SolveMansionPuzzleEvent']},
        'time': { '$gte': start_time, '$lte': end_time },
    }
    intermediary_data = list(client.epilog.data2.aggregate([
        {'$match': query},
        {'$project': {'_id': 0, 'event': '$event', 'player': 1, 'zone': 1}},
        {'$group': {'_id': {'event': '$event', 'player': '$player'}, 'total': {'$sum': 1}}},
        {'$group': {
            '_id':  "$_id.event",
            'totals': {'$push': {'player': '$_id.player', 'total': '$total'}}
        }
        },
    ]))

    # normalize event totals
    for event_data in intermediary_data:
        total = 0
        for player_data in event_data['totals']:
            total += player_data['total']
        for player_data in event_data['totals']:
            player_data['total'] /= total
            player_data['total'] *= 100.0

    return {
        'series': [{
            'name': event,
            'data': [
                next((player_data['total'] for player_data in next(
                    (event_data['totals'] for event_data in intermediary_data if event_data['_id'] == event), [])
                    if player_data['player'] == player), 0)
                for player in PLAYERS
            ],
        } for event in EVENTS],
        'categories': [UUID_MAP[player]['name'] for player in PLAYERS],
    }
def generate_zone_timeline_chart(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'PlayerLocationEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$sort': {
                    'time': 1
                }
            },
            {
                '$project': {
                    '_id': 0,
                    'player': 1,
                    'zone': 1,
                    'time': 1
                }
            },
            {
                '$group': {
                    '_id': '$player',
                    'events': {
                        '$push': {
                            'zone': '$zone',
                            'time': '$time'
                        }
                    }
                }
            },
        ]))

    processed_data = {player: [] for player in PLAYERS}

    start_time = get_times(client, experimentLabel)[0] // (1000)
    for player_data in intermediary_data:
        previous_start_time = None
        previous_zone = None
        bucket = []

        for event in player_data['events']:
            zone, time = event['zone'], floor(event['time']) // 1000
            local_time = time - start_time

            if previous_start_time == None: previous_start_time = local_time
            if previous_zone == None: previous_zone = zone

            if zone != previous_zone:
                bucket.append({
                    'zone': previous_zone,
                    'range': [previous_start_time, local_time - 1]
                })
                previous_start_time = local_time
                previous_zone = zone

        if previous_start_time != player_data['events'][-1]['time'] // 1000:
            bucket.append({
                'zone': previous_zone,
                'range': [previous_start_time, local_time - 1]
            })
            previous_start_time = local_time
            previous_zone = zone

        processed_data[player_data['_id']] = bucket

    transformed_data = {zone: [] for zone in ZONES}
    for player in PLAYERS:
        for data in processed_data[player]:
            transformed_data[data['zone']].append({
                'x': UUID_MAP[player]['name'],
                'y': data['range']
            })

    return {
        'series': [{
            'name': zone,
            'data': transformed_data[zone],
            'color': ZONE_MAP[zone],
        } for zone in ZONES],
    }
Пример #9
0
                     '$sum': 1
                 },
                 'events': {
                     '$push': {
                         'time': '$time'
                     }
                 }
             }
         },
         {
             '$group': {
                 '_id': "$_id.player",
                 'totals': {
                     '$push': {
                         'special': '$_id.special',
                         'total': '$total',
                         'events': '$events'
                     }
                 }
             }
         },
     ]))
 start_time = get_times(client, experimentLabel)[0] // (60 * 1000)
 for entry in intermediary_data:
     print('--------------------------------')
     print(UUID_MAP[entry['_id']]['name'])
     for total in entry['totals']:
         times = sorted([
             a['time'] // (60 * 1000) - start_time for a in total['events']
         ])
         print(total['special'], total['total'], times)
def generate_location_spread_by_player_time_series(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'PlayerLocationEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$sort': {
                    'time': 1
                }
            },
            {
                '$project': {
                    '_id': 0,
                    'player': 1,
                    'distances': 1,
                    'time': 1
                }
            },
        ]))

    # TODO rename this var so its different from the total start, or reuse the total start
    start_time = get_times(client, experimentLabel)[0] // (60 * 1000)
    proccessed_data = {
        player: [{
            'total': 0,
            'count': 0
        } for _ in range(60)]
        for player in PLAYERS
    }
    for event in intermediary_data:
        event_time = event['time'] // (60 * 1000)

        if (event_time - start_time) < 60:
            data = proccessed_data[event['player']][(event_time - start_time)]
            proccessed_data[event['player']][(event_time - start_time)] = {
                'total':
                data['total'] +
                sum([event['distances'][uid]
                     for uid in event['distances']]) / len(event['distances']),
                'count':
                data['count'] + 1
            }

    return {
        'series': [{
            'name':
            UUID_MAP[player]['name'],
            'data':
            [(data['total'] / data['count'] if data['count'] > 0 else 0)
             for data in proccessed_data[player]],
            'color':
            UUID_MAP[player]['color'],
        } for player in PLAYERS],
        'categories': [i for i in range(60)]
    }
def generate_total_distance_column_chart(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'PlayerLocationEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$sort': {
                    'time': 1
                }
            },
            {
                '$project': {
                    '_id': 0,
                    'player': 1,
                    'x': 1,
                    'y': 1,
                    'z': 1,
                    'time': 1
                }
            },
            {
                '$group': {
                    '_id': '$player',
                    'events': {
                        '$push': {
                            'x': '$x',
                            'y': '$y',
                            'z': '$z',
                            'time': '$time'
                        }
                    }
                }
            },
        ]))

    processed_data = {player: 0 for player in PLAYERS}
    for player in PLAYERS:
        player_group = next(
            (group['events']
             for group in intermediary_data if group['_id'] == player), [])
        total_distance = 0.0
        for i in range(1, len(player_group)):
            a = player_group[i - 1]
            b = player_group[i]
            total_distance += ((b['x'] - a['x'])**2 + (b['y'] - a['y'])**2 +
                               (b['z'] - a['z'])**2)**0.5
        processed_data[player] = total_distance

    return {
        'series': [{
            'name': 'Total Distance Travelled',
            'data': [processed_data[player] for player in PLAYERS]
        }],
        'categories': [UUID_MAP[player]['name'] for player in PLAYERS],
        'colors': [UUID_MAP[player]['color'] for player in PLAYERS],
    }
Пример #12
0
def generate_special_items_over_time_unweighted_time_series(
        client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'UsingSpecialItemEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$sort': {
                    'time': 1
                }
            },
            {
                '$project': {
                    '_id': 0,
                    'player': 1,
                    'special': 1,
                    'time': 1
                }
            },
            {
                '$group': {
                    '_id': '$player',
                    'events': {
                        '$push': {
                            'special': '$special',
                            'time': {
                                '$floor': {
                                    '$divide': ['$time', 1000]
                                }
                            }
                        }
                    }
                }
            },
        ]))

    (start_time, end_time) = get_times(client, experimentLabel)
    processed_data = {}
    for player_data in intermediary_data:
        buckets = []
        for _ in range(60):
            buckets.append(None)
        for event in player_data['events']:
            local_event_time = (int(event['time']) - start_time // 1000) // 60
            if local_event_time < 60:
                buckets[local_event_time] = (0 if buckets[local_event_time]
                                             == None else
                                             buckets[local_event_time]) + 1
        processed_data[player_data['_id']] = interpolate_missing_values(
            buckets)

    return {
        'series': [{
            'name': UUID_MAP[player]['name'],
            'data': processed_data[player],
            'color': UUID_MAP[player]['color'],
        } for player in PLAYERS],
        'categories': [idx for idx, _ in enumerate(buckets)]
    }
Пример #13
0
def generate_special_items_over_time_weighted_time_series(
        client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'UsingSpecialItemEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$sort': {
                    'time': 1
                }
            },
            {
                '$project': {
                    '_id': 0,
                    'player': 1,
                    'special': 1,
                    'time': 1
                }
            },
            {
                '$group': {
                    '_id': '$player',
                    'events': {
                        '$push': {
                            'special': '$special',
                            'time': {
                                '$floor': {
                                    '$divide': ['$time', 1000]
                                }
                            }
                        }
                    }
                }
            },
        ]))

    # Normalize the values by their frequency. Wearing a helmet for 10 minutes
    # should be weighed the same as using the escape rope for 1 second
    items_to_value = {
        'hint_0': repeating(),
        'hint_1': repeating(),
        'hint_2': repeating(),
        'hint_3': repeating(),
        'hint_4': repeating(),
        'hint_5': repeating(),
        'hint_6': repeating(),
        'hint_7': repeating(),
        'hint_8': repeating(),
        'hint_9': repeating(),
        'hint_10': repeating(),
        'hint_11': repeating(),
        'hint_12': repeating(),
        'bow': sparse_use(),
        'boots': repeating(),
        'chestplate': repeating(),
        'leggings': repeating(),
        'helmet': repeating(),
        'sword': sparse_use(),
        'strong_boots': repeating(),
        'strong_chestplate': repeating(),
        'strong_leggings': repeating(),
        'strong_helmet': repeating(),
        'strong_sword': sparse_use(),
        'nether_brick_pickaxe': sparse_use(),
        'use_reveal_players': repeating(),
        'use_escape_rope': one_use(),
        'cave_torch': sparse_use(),
        'torch': sparse_use(),
        'fireworks': sparse_use(),
        'white_banner': sparse_use(),
        'use_glow_path': repeating(),
        'instant_heal_potion': one_use(),
        'speed_potion': repeating(),
        'invisibility_potion': repeating(),
        'trophy':
        0,  # investigate this? Hypothesis, we had someone wearing the skulls and it triggered the event...
    }

    start_time = list(
        client.epilog.data2.find(query).sort('time', 1).limit(1))[0]['time']
    processed_data = {}
    for player_data in intermediary_data:
        buckets = []
        for _ in range(60):
            buckets.append(None)
        for event in player_data['events']:
            local_event_time = (int(event['time']) - start_time // 1000) // 60
            if local_event_time < 60:
                buckets[local_event_time] = (
                    0 if buckets[local_event_time] == None else
                    buckets[local_event_time]
                ) + items_to_value[event['special']]
        processed_data[player_data['_id']] = interpolate_missing_values(
            buckets)

    return {
        'series': [{
            'name': UUID_MAP[player]['name'],
            'data': processed_data[player],
            'color': UUID_MAP[player]['color'],
        } for player in PLAYERS],
        'categories': [idx for idx, _ in enumerate(buckets)]
    }
def generate_time_of_player_by_location_pie_charts(client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        'event': 'PlayerLocationEvent',
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$project': {
                    '_id': 0,
                    'player': 1,
                    'zone': 1
                }
            },
            {
                '$sort': {
                    'zone': 1
                }
            },
            {
                '$group': {
                    '_id': {
                        'zone': '$zone',
                        'player': '$player'
                    },
                    'total': {
                        '$sum': 1
                    }
                }
            },
            {
                '$group': {
                    '_id': "$_id.player",
                    'totals': {
                        '$push': {
                            'zone': '$_id.zone',
                            'total': '$total'
                        }
                    }
                }
            },
            {
                '$sort': {
                    '_id': 1
                }
            },
        ]))

    # normalize event totals
    for event_data in intermediary_data:
        total = 0
        for player_data in event_data['totals']:
            total += player_data['total']
        for player_data in event_data['totals']:
            player_data['total'] /= total
            player_data['total'] *= 100.0

    return {
        'charts':
        [build_pie_chart(player, intermediary_data) for player in PLAYERS]
    }
def generate_distance_from_center_by_player_time_series(
        client, experimentLabel):
    (start_time, end_time) = get_times(client, experimentLabel)
    query = {
        'experimentLabel': experimentLabel if experimentLabel != None else {
            '$exists': True
        },
        "event": "PlayerLocationEvent",
        'time': {
            '$gte': start_time,
            '$lte': end_time
        },
    }
    intermediary_data = list(
        client.epilog.data2.aggregate([
            {
                '$match': query
            },
            {
                '$sort': {
                    'time': 1
                }
            },
            {
                '$project': {
                    '_id': 0,
                    'player': 1,
                    'x': 1,
                    'z': 1,
                    'time': 1
                }
            },
        ]))

    start_time = list(
        client.epilog.data2.find(query).sort(
            'time', 1).limit(1))[0]['time'] // (60 * 1000)
    proccessed_data = {
        player: [{
            'total': 0,
            'count': 0
        } for _ in range(60)]
        for player in PLAYERS
    }
    for event in intermediary_data:
        event_time = event['time'] // (60 * 1000)

        if (event_time - start_time) < 60:
            data = proccessed_data[event['player']][(event_time - start_time)]
            dx = event['x'] - 4
            dz = event['z'] - 0
            proccessed_data[event['player']][(event_time - start_time)] = {
                'total': data['total'] + (dx * dx + dz * dz)**0.5,
                'count': data['count'] + 1
            }

    return {
        'series': [{
            'name':
            UUID_MAP[player]['name'],
            'data':
            [(data['total'] / data['count'] if data['count'] > 0 else 0)
             for data in proccessed_data[player]],
            'color':
            UUID_MAP[player]['color'],
        } for player in PLAYERS],
        'categories': [i for i in range(60)]
    }