<jupyter_start><jupyter_text>Dataset StructureThis proof-of-concept eMOTIONAL Cities dataset was collected using the `pluma` prototype data acquisition platform. More details.<jupyter_code># data folder
start_time = '8:45'
end_time = '10:00'
origin = datetime.datetime(2021, 9, 12, 8, 37, 22)
bucket = 's3://emotional-cities/data/nrg/poc-v0/2021-09-12T08-37-00/'
s3fs = S3FileSystem()<jupyter_output><empty_output><jupyter_text>Audio DataEnvironmental audio was captured using binaural microphones on the participants' head. This data is used to measure directional ambient noise levels and also to synchronise various other media streams with the common Harp time reference.<jupyter_code>audiofreq = 44100
samples_per_buffer = 441
audiotime = pd.read_csv(f'{bucket}BackPackLogData/Acquisition_Binaural_2021-09-12T08_37_22.csv',
                        header=None,usecols=[0])
audiotime.columns = ['Timestamp']
audiotime.Timestamp = origin + pd.to_timedelta(audiotime.Timestamp, 's')
audiotime['Samples'] = (audiotime.index + 1) * samples_per_buffer
audiotime['RecordingTime'] = pd.to_timedelta((audiotime.index + 1) * samples_per_buffer / audiofreq, 's')
audio = wave.open(s3fs.open(f'{bucket}BackPackLogData/Acquisition_Binaural_2021-09-12T08_37_22.wav'))
binaural.between_time(audio, audiotime.Timestamp, '8:50', '8:50:10').plot(alpha=0.5,figsize=(15,4))
claps = pd.read_csv(os.path.join(bucket, 'Preprocessed/Acquisition_Binaural_2021-09-12T08_37_22_Claps.csv'),header=None)
claps.columns = ['Sample']
claps['RecordingTime'] = pd.to_timedelta(claps.Sample / audiofreq, 's')
claps['Buffer'] = claps.Sample // samples_per_buffer
claps['Timestamp'] = audiotime.Timestamp[claps.Buffer].reset_index(drop=True)
trials = claps.iloc[[11, 14, 17, 20, 34, 42, 46, 55]].reset_index(drop=True)
trial_labels = ['Portas do Sol','Escolas Gerais','Graça','Tram']
trial_colors = ['red', 'green', 'magenta', 'black']
trials = pd.concat([trials.iloc[0::2].add_prefix('Start').reset_index(drop=True),
                   trials.iloc[1::2].add_prefix('End').reset_index(drop=True)],
                   axis=1)
trials<jupyter_output><empty_output><jupyter_text>GPS DataLocation data was collected continuously throughout the entire walk using a GPS-RTK2 board.<jupyter_code># GNGGA with bounding box and geopandas for euclidean distance (sampling rate is 1Hz so speed is m/s)
gngga = gps.read(os.path.join(bucket, 'BackPackLogData/Acquisition_GNGGA_2021-09-12T08_37_22.csv'), origin=origin)
gdf = gpd.GeoDataFrame(geometry=gpd.points_from_xy(gngga.Longitude, gngga.Latitude, gngga.Altitude), crs='epsg:4326')
gdf.to_crs(epsg=3310,inplace=True)
gdf.index = gngga.index
gngga['Speed'] = gdf.distance(gdf.shift(1))
gps.plot(gngga, label='GPS')
fig, ax = plt.subplots(figsize=(8, 8))
gps.plotmap(gngga, ax)
gps.plot(gngga, ax)
for i in range(len(trials)):    
    gps.plot(gngga[trials.StartTimestamp[i]:trials.EndTimestamp[i]], ax, color=trial_colors[i], label=trial_labels[i])
ax.legend(bbox_to_anchor=(1.04,1), loc="upper left")<jupyter_output><empty_output><jupyter_text>Heart RateWe measured heart rate using two different sensors: ECG and Pulse Oximeter.<jupyter_code>ecgfreq = 50
ecgdist=10
ecgheight=[250, 2000]

oximeter = harp.read(s3fs.open(f'{bucket}BackPackLogData/Acquisition_BioReg34_2021-09-12T08_37_22.bin'),
                    names=['Oxygen','HeartRate','Confidence','Status'], origin=origin)
ecg = harp.read(s3fs.open(f'{bucket}BackPackLogData/Acquisition_BioReg35_2021-09-12T08_37_22.bin'), names=['V'], origin=origin)
ecgfilt = pd.DataFrame(bios.highpass_filter(ecg.V, cutoff=10, fs=ecgfreq, order=5), index=ecg.index, columns=ecg.columns)
fig, (ax2, ax1) = plt.subplots(2, 1, figsize=(15,8), sharex=True)
oxiclip = oximeter.between_time(start_time, end_time)
oxiclip.HeartRate[oxiclip.Confidence > 50].plot(ax=ax1)
oxiclip.Oxygen[oxiclip.Confidence > 50].plot(ax=ax2)
ax1.set_ylabel('heart rate (bpm)')
ax2.set_ylabel('oxygen level (%)')
ecg.between_time('9:48','9:48:10').plot(figsize=(15,4))
ecgdata = ecgfilt.between_time('9:48','9:48:10')
ecgdata.plot(figsize=(15,4))
beats, beatattributes = bios.ecgpeaks(ecgdata.V,height=ecgheight,distance=ecgdist)
plt.plot(beats, beatattributes['peak_heights'], 'r.')<jupyter_output><empty_output><jupyter_text>Electrodermal ActivityGalvanic skin response as a marker for stress was measured using an EDA sensor installed in the index finger.<jupyter_code>eda = harp.read(s3fs.open(f'{bucket}BackPackLogData/Acquisition_BioReg36_2021-09-12T08_37_22.bin'), names=['V'], origin=origin)<jupyter_output><empty_output><jupyter_text>Climate DataMicro-climate data was collected during the walk using the data acquisition system from Climateflux.<jupyter_code>climate = pd.read_csv(os.path.join(bucket, 'Climateflux/Lisbon_20210912_pr.csv'))
climate_time = pd.to_datetime(climate[climate.columns[0]])
climate['Timestamp'] = climate_time
climate = climate.drop(columns=climate.columns[0]).set_index('Timestamp')
climate<jupyter_output><empty_output><jupyter_text>Pupil DataEye tracking data was collected onto an Android phone using the Pupil Invisible system. Synchronization needs to be done also using audio pulses.<jupyter_code>pupiltrials = ['2021-09-12_08-43-04-6eda0cc4', '2021-09-12_09-07-19-8e04345b', '2021-09-12_09-23-44-075d4082', '2021-09-12_09-39-30-cf1a2884']
pupilstarts = [1952,467,215,798]
pupilends = [19664,16324,20748,23897]
pupilgaze = []
for i in range(len(pupiltrials)):
    gaze = pd.read_csv(os.path.join(bucket, 'PupilInvisible/{0}/exports/000/gaze_positions.csv'.format(pupiltrials[i])),usecols=range(5))
    gaze['Timestamp'] = pd.to_timedelta(gaze.gaze_timestamp - gaze.gaze_timestamp[i], 's') + trials.StartTimestamp[i]
    pupilgaze.append(gaze)
pupilgaze[0]<jupyter_output><empty_output><jupyter_text>CorrelationsIn the below section, we show some possible combination plots of correlations between the different data streams in space and time.  Heart rate dynamicsAn example investigation of whether heart rate correlates with different variables recorded during the walk, taking into account geospatial location and time. Below we start by looking at the distribution of inter-beat intervals during the four different routes in the walk.<jupyter_code>fig, axes = plt.subplots(1, len(trials), figsize=(20,4))
for i in range(len(trials)):
    ecgdata = ecgfilt[trials.StartTimestamp[i]:trials.EndTimestamp[i]].copy()
    beats, beatattributes = bios.ecgpeaks(ecgdata.V,height=ecgheight,distance=ecgdist)
    beats.to_series().diff()[1:].dt.total_seconds().plot(kind='hist',bins=100,range=[0,2],ax=axes[i],color=trial_colors[i],label=trial_labels[i])
    axes[i].set_xlabel('Time between beats (s)')
    axes[i].set_ylabel('Number of heartbeats')
    axes[i].legend()<jupyter_output><empty_output><jupyter_text>Next we investigate temporal correlations of heart-rate with temperature, humidity, altitude, and speed.<jupyter_code>fig, (ax3, ax4, ax2, ax5, ax1) = plt.subplots(5, 1, figsize=(7, 10), sharex=True, gridspec_kw={'height_ratios': [1, 1, 1, 1, 2]})
ecgdata = ecgfilt.between_time(start_time,end_time)
ecgheartrate = bios.heartrate(ecgdata.V, height=ecgheight, distance=ecgdist)

ecgheartrate.plot(ax=ax1,alpha=0.5,label='Idle')
ax2.plot(gngga.between_time(start_time,end_time).Altitude,alpha=0.5,label='Idle')
ax3.plot(climate.between_time(start_time,end_time)['JEC_Temperature_°C'],alpha=0.5,label='Idle')
ax4.plot(climate.between_time(start_time,end_time)['Lhu_Humidity_%RH'],alpha=0.5,label='Idle')
ax5.plot(gngga.between_time('8:48',end_time).Speed,alpha=0.5,label='Idle')

for i in range(len(trials)):
    ecgheartrate[trials.StartTimestamp[i]:trials.EndTimestamp[i]].plot(ax=ax1,color=trial_colors[i],label=trial_labels[i])
    ax2.plot(gngga[trials.StartTimestamp[i]:trials.EndTimestamp[i]].Altitude,color=trial_colors[i],label=trial_labels[i])
    ax3.plot(climate[trials.StartTimestamp[i]:trials.EndTimestamp[i]]['JEC_Temperature_°C'],color=trial_colors[i],label=trial_labels[i])
    ax4.plot(climate[trials.StartTimestamp[i]:trials.EndTimestamp[i]]['Lhu_Humidity_%RH'],color=trial_colors[i],label=trial_labels[i])
    ax5.plot(gngga[trials.StartTimestamp[i]:trials.EndTimestamp[i]].Speed,color=trial_colors[i],label=trial_labels[i])
ax1.set_ylabel('heart rate (bpm)')
ax2.set_ylabel('altitude (m)')
ax3.set_ylabel('temp. (ºC)')
ax4.set_ylabel('rel. humidity (%)')
ax5.set_ylabel('speed (m/s)')
ax3.set_ylim(20, 35)
ax2.legend(bbox_to_anchor=(1.14,1), loc="upper left")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1493223335297584, 'fraction_numerical': 0.05268120212139069, 'mean_word_length': 7.703589743589744, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '82375', 'license': 'MIT', 'n_tokens_mistral': 3502, 'n_tokens_neox': 3191, 'n_words': 500, 'path': 'src/poc.ipynb', 'repo_name': 'emotional-cities/notebooks', 'size': '8485'}