Skip to content

Commit

Permalink
🔧 Checkout pandemos context from feature/pandemos-datasocket-preproce…
Browse files Browse the repository at this point in the history
…ssing
  • Loading branch information
Karagappa authored and Karagappa committed Dec 5, 2024
1 parent 18a48da commit 16e35fd
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 56 deletions.
95 changes: 39 additions & 56 deletions frontend/src/data_sockets/PandemosContext.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,22 @@
// SPDX-FileCopyrightText: 2024 German Aerospace Center (DLR)
// SPDX-License-Identifier: Apache-2.0

import React, {createContext, useCallback, useEffect, useState} from 'react';
import React, {createContext, useCallback, useEffect, useMemo, useState} from 'react';
import crossfilter, {Crossfilter} from 'crossfilter2';
import agentList from '../../assets/pandemos/agents_lookup.json?url';
import locationList from '../../assets/pandemos/locations_lookup.json?url';
import trajectories from '../../assets/pandemos/trajectories.json?url';

export interface Agent {
/** ID of the agent (same as index) */
agent_id: number;
/** Location ID of the agent's home */
home_id: number;
/** Enum of the agent's age group (refer to key_info.md for more info) */
age_group: number;
}

export interface Location {
/** ID of the location (same as index) */
location_id: number;
/** Enum of the location's type (refer to key_info.md for more info) */
location_type: number;
/** Latitude of the location */
lat: number;
/** Longitude of the location */
lon: number;
}

export interface Trip {
/** Timestep in which the trip took place */
timestep: number;
/** ID of the agent who did the trip */
agent_id: number;
/** ID of the trip (same as index) */
trip_id: number;
/** ID of the start location */
start_location: number;
/** ID of the end location */
end_location: number;
/** Time in seconds when the trip started */
start_time: number;
/** Time in seconds when the trip ended */
end_time: number;
/** Enum of the mode of transportation used (refer to key_info.md for more info) */
transport_mode: number;
/** Enum of the activity type at the end of this trip (refer to key_info.md for more info) */
activity: number;
/** Enum of the infection state of this trip (refer to key_info.md for more info) */
infection_state: number;
}
import {Agent, Location, Trip, TripExpanded} from '../types/pandemos';

/** Data context for the pandemos data.
* Provides Crossfilter objects for agents, locations, and trips.
* Use .all() to get raw array.
*/
export const PandemosContext = createContext<{
agents: Crossfilter<Agent> | undefined;
locations: Crossfilter<Location> | undefined;
trips: Crossfilter<Trip> | undefined;
agents: Array<Agent> | undefined;
locations: Array<Location> | undefined;
trips: Array<Trip> | undefined;
expandedTrips: Crossfilter<TripExpanded> | undefined;
tripChains: Map<number, Array<Trip>> | undefined;
filteredTripChains: number[][] | undefined;
setFilteredTripChains: ((value: number[][]) => void) | undefined;
Expand All @@ -66,20 +25,23 @@ export const PandemosContext = createContext<{
agents: undefined,
locations: undefined,
trips: undefined,
expandedTrips: undefined,
tripChains: undefined,
filteredTripChains: undefined,
setFilteredTripChains: undefined,
});

// Create provider component
export const PandemosProvider = ({children}: {children: React.ReactNode}) => {
const [agents, setAgents] = useState<Crossfilter<Agent>>();
const [locations, setLocations] = useState<Crossfilter<Location>>();
const [trips, setTrips] = useState<Crossfilter<Trip>>();
const [agents, setAgents] = useState<Array<Agent>>();
const [locations, setLocations] = useState<Array<Location>>();
const [trips, setTrips] = useState<Array<Trip>>();

const [tripChains, setTripChains] = useState<Map<number, Array<Trip>>>();
const [filteredTripChains, setFilteredTripChains] = useState<number[][]>([]);



// Effect to fetch the data
useEffect(() => {
Promise.all([
Expand Down Expand Up @@ -120,28 +82,28 @@ export const PandemosProvider = ({children}: {children: React.ReactNode}) => {
// handle data on promises accept
([agents, locations, trips]: [Array<Agent>, Array<Location>, Array<Trip>]) => {
// setup crossfilter objects for each
setAgents(crossfilter(agents));
setLocations(crossfilter(locations));
setTrips(crossfilter(trips));
setAgents(agents);
setLocations(locations);
setTrips(trips);
},
// on promises reject
(reason) => console.error('Failed to parse Pandemos data.', reason)
);
// This should only run once when the page loads
// TODO: Lazy load when the pandemos tab is selected
// TODO: Lazy load when the pandemos tab is selected?
}, []);

const getLocation = useCallback(
(id: number) => {
return locations?.all().find((location) => location.location_id === id);
return locations?.find((location) => location.location_id === id);
},
[locations]
);

useEffect(() => {
const agentTrips = new Map<number, Array<Trip>>();

for (const trip of trips?.all() ?? []) {
for (const trip of trips ?? []) {
agentTrips.set(trip.agent_id, [...(agentTrips.get(trip.agent_id) ?? []), trip]);
}

Expand All @@ -158,13 +120,34 @@ export const PandemosProvider = ({children}: {children: React.ReactNode}) => {

setTripChains(tripChains);
}, [getLocation, locations, trips]);
// Preprocess a single crossfilter with information of agents & locations included in the trips

const expandedTrips = useMemo<crossfilter.Crossfilter<TripExpanded>>(() => {
if (trips && agents && locations) {
return crossfilter(
trips?.map((trip) => {
return (
({
...trip,
agent_age_group: agents[trip.agent_id].age_group,
start_location_type: locations[trip.start_location].location_type,
end_location_type: locations[trip.end_location].location_type,
} as TripExpanded) ?? {}
);
})
);
} else {
return crossfilter([]);
}
}, [agents, locations, trips]);

return (
<PandemosContext.Provider
value={{
agents,
locations,
trips,
expandedTrips,
tripChains,
filteredTripChains,
setFilteredTripChains,
Expand Down
142 changes: 142 additions & 0 deletions frontend/src/types/pandemos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// SPDX-FileCopyrightText: 2024 German Aerospace Center (DLR)
// SPDX-License-Identifier: Apache-2.0

/** Display names for the diffent enums of the pandemos data */
export namespace KeyInfo {
/** Locations */
export const location_type: Record<number, string> = {
/** Home */ 0: '🏡',
/** School */ 1: '🏫',
/** Work */ 2: '🏭/🏢',
/** Social Event */ 3: '🏟',
/** Shopping */ 4: '🏪',
/** Hospital */ 5: '🏥❗',
/** ICU */ 6: '🏥‼',
/** Car */ 7: '🚘',
/** Public */ 8: '⛲',
/** Transport */ 9: '🚍',
/** Cemetery */ 10: '⚰',
};

/** Location types returning string and not icons. -Pawan */
export const location_type_string: Record<number, string> = {
/** Home */ 0: 'Home',
/** School */ 1: 'School',
/** Work */ 2: 'Work',
/** Social Event */ 3: 'Social Event',
/** Shopping */ 4: 'Shopping',
/** Hospital */ 5: 'Hospital',
/** ICU */ 6: 'ICU',
/** Car */ 7: 'Car',
/** Public */ 8: 'Public',
/** Transport */ 9: 'Transport',
/** Cemetery */ 10: 'Cemetery',
};
/** Location types returning string and not icons. -Pawan */
export const transport_mode: Record<number, string> = {
/** Bike */ 0: '🚴‍♀️',
/** Car (Driver) */ 1: '🚘👤',
/** Car (Passenger) */ 2: '🚘👥',
/** Bus */ 3: '🚍',
/** Walking */ 4: '🚶‍♀️',
/** Other */ 5: '🛸',
/** Unknown */ 6: '❓',
};

export const transport_mode_string: Record<number, string> = {
/** Bike */ 0: 'Bike',
/** Car (Driver) */ 1: 'Car_Driver',
/** Car (Passenger) */ 2: 'Car_Passenger',
/** Bus */ 3: 'Bus',
/** Walking */ 4: 'Walking',
/** Other */ 5: 'Other',
/** Unknown */ 6: 'Unknown',
};

export const activity: Record<number, string> = {
/** Workplace */ 0: 'Workplace',
/** Education */ 1: 'Education',
/** Shopping */ 2: 'Shopping',
/** Leisure */ 3: 'Leisure',
/** Private Matters */ 4: 'Private Matters',
/** Other */ 5: 'Other',
/** Going Home */ 6: 'Going Home',
/** Unknown */ 7: 'Unknown',
};
export const infection_state: Record<number, string> = {
/** Susceptible */ 0: '🙂',
/** Infected with no symptoms */ 1: '🤔',
/** Infected with symptoms */ 2: '🤧',
/** Infected with severe symptoms */ 3: '🤒',
/** Infected with critical symptoms */ 4: '🤮',
/** Recovered */ 5: '😀',
/** Dead */ 6: '💀',
/** Unknown */ 7: '❓',
};

export const age: Record<number, string> = {
0: '0-4',
1: '5-14',
2: '15-34',
3: '35-39',
4: '60-79',
5: '80+',
};
}

export interface Agent {
/** ID of the agent (same as index) */
agent_id: number;
/** Location ID of the agent's home */
home_id: number;
/** Enum of the agent's age group (refer to key_info.md for more info) */
age_group: number;
}

export interface Location {
/** ID of the location (same as index) */
location_id: number;
/** Enum of the location's type (refer to key_info.md for more info) */
location_type: number;
/** Enum of the location's type (refer to key_info.md for more info) */
location_type_string: string;
/** Latitude of the location */
lat: number;
/** Longitude of the location */
lon: number;
}

export interface Trip {
/** Timestep in which the trip took place */
timestep: number;
/** ID of the agent who did the trip */
agent_id: number;
/** ID of the trip (same as index) */
trip_id: number;
/** ID of the start location */
start_location: number;
/** ID of the end location */
end_location: number;
/** Time in seconds when the trip started */
start_time: number;
/** Time in seconds when the trip ended */
end_time: number;
/** Enum of the mode of transportation used (refer to key_info.md for more info) */
transport_mode: number;
/** Enum of the activity type at the end of this trip (refer to key_info.md for more info) */
activity: number;
/** Enum of the infection state of this trip (refer to key_info.md for more info) */
infection_state: number;
}

export interface TripExpanded extends Trip {
agent_age_group: number;
start_location_type: number;
end_location_type: number;
}

export interface TripChain {
chain_id: number;
agent_id: number;
trips: Array<Trip>;
}

0 comments on commit 16e35fd

Please sign in to comment.