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, }
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], }
'$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], }
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)] }
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)] }