def plot_philap_report_graphs_for_subject(subject_id, graphs_dir): # Download raw data if not present participant_details = load_philap_participant_details() try: airspeck_raw = load_personal_airspeck_file(subject_id, upload_type='manual', is_minute_averaged=False) airspeck = airspeck_raw.resample('1min').mean() respeck = load_respeck_file(subject_id, upload_type='manual') except: print( "Please download all Peeps data via download_all_philap_data(raw_airspeck=True) " "before calling this function") # Delete incorrect GPS. These coordinates are just outside the larger area of Delhi airspeck_raw.loc[airspeck_raw['gpsAccuracy'] > 1000, 'gpsLongitude':'gpsLatitude'] = np.nan airspeck_raw.loc[airspeck_raw['gpsLatitude'] < 10, 'gpsLongitude':'gpsLatitude'] = np.nan airspeck_raw.loc[airspeck_raw['gpsLatitude'] > 40, 'gpsLongitude':'gpsLatitude'] = np.nan airspeck_raw.loc[airspeck_raw['gpsLongitude'] < 10, 'gpsLongitude':'gpsLatitude'] = np.nan airspeck_raw.loc[airspeck_raw['gpsLongitude'] > 80, 'gpsLongitude':'gpsLatitude'] = np.nan home_gps = airspeck.loc[(1 < airspeck.index.hour) & (airspeck.index.hour <= 3)].mean() # If there was no personal data during the night, fall back on the GPS coordinates the researchers provided if pd.isnull(home_gps['gpsLatitude']): home_gps = get_home_gps_for_subject(subject_id, participant_details) # Select locations near home radius_home = 0.002 correction_factor = airspeck['gpsAccuracy'] * 0.00001 home_mask = (np.abs(airspeck['gpsLatitude'] - home_gps['gpsLatitude']) < radius_home + correction_factor) & \ (np.abs(airspeck['gpsLongitude'] - home_gps['gpsLongitude']) < radius_home + correction_factor) ################################## # Draw detailed exposure plot ################################## sns.set_style('darkgrid', {'xtick.bottom': True, 'xtick.major.size': 5}) fig, ax = plt.subplots(figsize=(15, 5)) if np.count_nonzero(home_mask) > 0: for ts in airspeck.loc[home_mask].index: ax.axvspan(ts, ts + pd.DateOffset(minutes=1), facecolor=CB_color_cycle[0], alpha=0.3, zorder=1) ax.scatter(airspeck.index, airspeck['pm2_5'], s=2, color='black', zorder=2) # Plot stationary airspeck home home_airspeck = load_static_airspeck_file(subject_id, suffix_filename='_home') if home_airspeck is not None and len(home_airspeck) > 0: ax.scatter(home_airspeck.index, home_airspeck['pm2_5'], s=2, color='blue') ax.set_ylabel("PM2.5 (μg/m³)") start = airspeck.index[0].replace(hour=0, minute=0, second=0) end = airspeck.index[-1].replace(hour=0, minute=0, second=0) + pd.DateOffset(days=1) ax.set_xlim(start, end) formatter = mdates.DateFormatter('%d.%m %Hh', tz=dateutil.tz.gettz( project_mapping['philap'][1])) ax.xaxis.set_major_formatter(formatter) ax.set_title( "Continuous PM2.5 personal exposure levels and ambient concentrations") fig.autofmt_xdate() home_patch = mpatches.Patch(color=CB_color_cycle[0], label='Home', alpha=0.3) airs_home_patch = Line2D(range(1), range(1), marker='o', color='#00000000', markerfacecolor="blue", label='Home sensor') airp_patch = Line2D(range(1), range(1), marker='o', color='#00000000', markerfacecolor="black", label='Personal sensor') plt.legend(handles=[home_patch, airp_patch, airs_home_patch]) plt.tight_layout() plt.savefig(graphs_dir + "{}_detailed_exposure.png".format(subject_id), dpi=300) plt.show() ################################## # Draw summary bar graph ################################## sns.set_style('darkgrid', {'xtick.bottom': False, 'xtick.major.size': 0.0}) home = airspeck.loc[home_mask, 'pm2_5'].mean() other = airspeck.loc[~home_mask, 'pm2_5'].mean() overall = airspeck['pm2_5'].mean() if home_airspeck is not None: home_ambient = home_airspeck['pm2_5'].mean() else: home_ambient = np.nan mean_values = [home, other, overall, home_ambient] fig, ax = plt.subplots(figsize=(8, 5)) ax.set_title( "Mean PM2.5 personal exposure levels and ambient concentrations") ax.bar(np.arange(len(mean_values)), mean_values, width=0.5, color=CB_color_cycle, edgecolor="none") ax.set_ylabel("PM2.5 (μg/m³)") ax.set_xlim(-0.5, len(mean_values) - 0.5) plt.xticks(np.arange(len(mean_values)), [ "Home\npersonal", "Other\npersonal", "Overall\npersonal", "Home\nambient" ]) plt.savefig(graphs_dir + "{}_mean_exposure.png".format(subject_id, subject_id), dpi=300) plt.show() ################################## # Draw map ################################## get_maps_image(airspeck_raw, graphs_dir + "{}_airspeck_map.png".format(subject_id), zoom=13) ################################## # Other statistics ################################## # Create new empty file open(graphs_dir + "{}_stats.txt".format(subject_id), 'w').close() # Append stats to this file with open(graphs_dir + "{}_stats.txt".format(subject_id), 'a') as f: f.write("Step count: {}\n".format(respeck['step_count'].sum())) f.write( "Mean breathing rate during night: {:.2f} breaths per minute\n". format(respeck.loc[(0 < respeck.index.hour) & (respeck.index.hour < 6), 'breathing_rate'].mean())) f.write("Mean breathing rate during day: {:.2f} breaths per minute\n". format(respeck.loc[(6 <= respeck.index.hour) & (respeck.index.hour <= 23), 'breathing_rate'].mean())) f.write("\nStart of recording: {}\n".format( airspeck.index[0].replace(tzinfo=None))) f.write("End of recording: {}\n".format( airspeck.index[-1].replace(tzinfo=None))) f.write("Total duration: {}\n".format(airspeck.index[-1] - airspeck.index[0])) f.write("Total recording time at home: {:.1f} h\n".format( np.count_nonzero(home_mask) / 60.))
def create_dublin_pixelgram_for_subject( subject_id, overwrite_pixelgram_if_already_exists=False): download_respeck_and_personal_airspeck_data(subject_id, upload_type='manual') respeck_data = load_respeck_file(subject_id, upload_type='manual') airspeck_data = load_personal_airspeck_file(subject_id, upload_type='manual') # Load correction factors for timezone corrections = pd.read_excel(dublin_timezones_correction_filepath).replace( np.nan, 0).set_index('subject_id') participant_details = load_dublin_participant_details() row = participant_details.loc[subject_id] # Load exposure period from_time = row['start_of_exposure_time_to_shs'] to_time = row['end_of_exposure_time_to_shs'] start_exposure = row['date_of_exposure_to_shs'].replace( hour=from_time.hour, minute=from_time.minute, second=from_time.second).to_pydatetime() + timedelta( hours=int(corrections.loc[subject_id, 'shs_times_difference'])) if not pd.isnull(row['end_date_of_exposure_to_shs']): end_exposure = row['end_date_of_exposure_to_shs'].replace( hour=to_time.hour, minute=to_time.minute, second=to_time.second).to_pydatetime() + timedelta( hours=int(corrections.loc[subject_id, 'shs_times_difference'])) else: end_exposure = row['date_of_exposure_to_shs'].replace( hour=to_time.hour, minute=to_time.minute, second=to_time.second).to_pydatetime() + timedelta( hours=int(corrections.loc[subject_id, 'shs_times_difference'])) # Load recording period from_time = row['start_time_of_monitoring'] start_recording = row['start_date_of_monitoring'].replace( hour=from_time.hour, minute=from_time.minute, second=from_time.second).to_pydatetime() + timedelta( hours=int(corrections.loc[subject_id, 'recording_times_difference'])) to_time = row['end_time_of_monitoring'] end_recording = row['end_date_of_monitoring'].replace( hour=to_time.hour, minute=to_time.minute, second=to_time.second).to_pydatetime() + timedelta( hours=int(corrections.loc[subject_id, 'recording_times_difference'])) # Look up timezone tz = timezone(project_mapping[subject_id[:3]][1]) print("Creating pixelgram for subject {}".format(subject_id)) plot_combined_pixelgram_dublin( subject_id, respeck_data, airspeck_data, exposure_period=[ tz.localize(start_exposure), tz.localize(end_exposure) ], recording_period=[ tz.localize(start_recording), tz.localize(end_recording) ], overwrite_if_already_exists=overwrite_pixelgram_if_already_exists)
def download_data_and_plot_combined_pixelgram( subject_id, timeframe=None, filter_out_not_worn_respeck=True, overwrite_pixelgram_if_already_exists=False, subject_visit_number=None, overwrite_data_if_already_exists=False, upload_type='automatic'): project_name = get_project_for_subject(subject_id) plot_dir = project_mapping[project_name][3] if subject_visit_number is None: label_files = "{}".format(subject_id) else: label_files = "{}({})".format(subject_id, subject_visit_number) pixelgram_filepath = plot_dir + "{}_combined_pixelgram.png".format( label_files) # Check if pixelgram already exists if not overwrite_pixelgram_if_already_exists and os.path.isfile( pixelgram_filepath): print("Pixelgram for subject {} already exists. Skipping subject.". format(label_files)) return # Download data if not present download_respeck_and_personal_airspeck_data( subject_id, upload_type=upload_type, timeframe=timeframe, overwrite_if_already_exists=overwrite_data_if_already_exists, subject_visit_number=subject_visit_number) # Load data and create plot respeck_data = load_respeck_file( subject_id, project_name=project_name, upload_type=upload_type, subject_visit_number=subject_visit_number, filter_out_not_worn=filter_out_not_worn_respeck) airspeck_data = load_personal_airspeck_file( subject_id, project_name=project_name, upload_type=upload_type, subject_visit_number=subject_visit_number) if len(respeck_data) == 0: print("RESpeck data for subject {} empty. Skipping subject.".format( label_files)) return if len(airspeck_data) == 0: print("Airspeck data for subject {} empty. Skipping subject.".format( label_files)) return if timeframe is not None: tz = timezone(project_mapping[project_name][1]) if timeframe[0].tzinfo is None: start_time = tz.localize(timeframe[0]) end_time = tz.localize(timeframe[1]) else: start_time = timeframe[0] end_time = timeframe[1] plot_combined_pixelgram( subject_id, respeck_data[start_time:end_time], airspeck_data[start_time:end_time], pixelgram_filepath, overwrite_if_already_exists=overwrite_pixelgram_if_already_exists, subject_visit_number=subject_visit_number) else: plot_combined_pixelgram( subject_id, respeck_data, airspeck_data, pixelgram_filepath, overwrite_if_already_exists=overwrite_pixelgram_if_already_exists, subject_visit_number=subject_visit_number)
def download_respeck_data_and_plot_pixelgram( subject_id, project_name=None, upload_type='automatic', timeframe=None, overwrite_pixelgram_if_already_exists=False, filter_out_not_worn=True, overwrite_data_if_already_exists=False, subject_visit_number=None): if project_name is None: project_name = get_project_for_subject(subject_id) plot_dir = project_mapping[project_name][3] label_files = "{}({})".format(subject_id, subject_visit_number) pixelgram_filepath = plot_dir + "{}_respeck_pixelgram.png".format( label_files) # Check if pixelgram already exists if not overwrite_pixelgram_if_already_exists and os.path.isfile( pixelgram_filepath): print("Pixelgram for subject {} already exists. Skipping subject.". format(label_files)) return # Download files if they weren't there yet before download_respeck_data( subject_id, upload_type=upload_type, timeframe=timeframe, overwrite_if_already_exists=overwrite_data_if_already_exists, subject_visit_number=subject_visit_number) respeck_data = load_respeck_file(subject_id, project_name, subject_visit_number=subject_visit_number, upload_type=upload_type, filter_out_not_worn=filter_out_not_worn) if len(respeck_data) == 0: print( "File for subject {} empty. Skipping subject.".format(subject_id)) return if timeframe is not None: tz = timezone(project_mapping[project_name][1]) if timeframe[0].tzinfo is None: start_time = tz.localize(timeframe[0]) end_time = tz.localize(timeframe[1]) else: start_time = timeframe[0] end_time = timeframe[1] plot_respeck_pixelgram( subject_id, respeck_data[start_time:end_time], pixelgram_filepath, overwrite_if_already_exists=overwrite_pixelgram_if_already_exists, subject_visit_number=subject_visit_number) else: plot_respeck_pixelgram( subject_id, respeck_data, pixelgram_filepath, overwrite_if_already_exists=overwrite_pixelgram_if_already_exists, subject_visit_number=subject_visit_number)
def plot_peeps_report_graphs_for_subject(subject_id, subject_visit_number=1, graphs_dir, max_value=100): # Download raw data if not present #download_all_peeps_data(download_raw_airspeck_data=True, phase=phase) participant_details = load_peeps_participant_details() calibration_date_pers, is_calibrated_pm_pers, airspeck = get_resampled_data( subject_id, subject_visit_number) if not is_calibrated_pm_pers: airspeck['pm2_5'] = airspeck['pm2_5'] * 0.60456 + 37.26849 #calibration_date_pers = 'Calibrated with median' respeck = load_respeck_file(subject_id, 'peeps', subject_visit_number=subject_visit_number, upload_type='manual') #All subject details all_visit_subj_details = participant_details.loc[ participant_details['Subject ID'] == subject_id] #Details for specific visit subj_details = all_visit_subj_details[ all_visit_subj_details['Visit number'] == subject_visit_number] infer = subj_details['Infer Home Coordinates'][0] if infer: home_gps = airspeck.loc[(1 < airspeck.index.hour) & (airspeck.index.hour <= 3)].mean() print('Subject ID: ' + str(subject_id) + ' home_gps: ' + str(home_gps)) # If there was no personal data during the night, fall back on the GPS coordinates the researchers provided #if pd.isnull(home_gps['gpsLatitude']): else: home_gps = get_home_gps_for_subject(subject_id, participant_details) # Select locations near home #radius_home = 0.01 radius_home = 0.002 home_id = get_home_id_for_subject(subject_id, participant_details) correction_factor = airspeck['gpsAccuracy'] * 0.00001 home_mask = (np.abs(airspeck['gpsLatitude'] - home_gps['gpsLatitude']) < radius_home + correction_factor) & \ (np.abs(airspeck['gpsLongitude'] - home_gps['gpsLongitude']) < radius_home + correction_factor) all_factors_ids = ['33B45C90B13731DE', 'E1EFA8FCA05B3FF9'] #Declare work and commute masks in case there is no work work_mask = np.zeros(len(airspeck)).astype(bool) commute_mask = np.zeros(len(airspeck)).astype(bool) radius_work = 0.01 if subject_id in ['PEV018', 'PEV066', 'PEV047', 'PEV076']: radius_work = 0.002 print('Smaller work radius set: {}'.format(radius_work)) work_id = get_work_id_for_subject(subject_id, participant_details) hasWorkLocation = True if (work_id == 'Not deployed'): hasWorkLocation = False work_airspeck = [] if hasWorkLocation: #We need a work location to establish commuting if subject_visit_number == 1: work_gps = peeps_work_id_to_gps_phase1[get_work_id_for_subject( subject_id, participant_details)] if subject_visit_number == 2: work_gps = peeps_work_id_to_gps[get_work_id_for_subject( subject_id, participant_details)] use_all_features = False calibration_date_work, is_calibrated_spmwork, is_calibrated_sgaswork, work_airspeck = load_static_airspeck_file( work_id, sensor_label="{}".format(subject_id), suffix_filename='_work', project_name='peeps', upload_type='automatic', calibrate_pm_and_gas=False, return_calibration_flag=False, use_all_features_for_pm_calibration=use_all_features) if pd.isnull(work_gps['gpsLatitude']): work_airspeck_lat = work_airspeck.gpsLatitude.loc[ work_airspeck.gpsLatitude > 0].dropna().mean() work_airspeck_lng = work_airspeck.gpsLongitude.loc[ work_airspeck.gpsLongitude > 0].dropna().mean() work_gps = { 'gpsLatitude': work_airspeck_lat, 'gpsLongitude': work_airspeck_lng } if pd.isnull(work_gps['gpsLatitude']): print('Assuming work is wherever subjcet is between 10 and 11am') work_gps = airspeck.loc[(10 < airspeck.index.hour) & (airspeck.index.hour <= 11)].mean() work_mask = (np.abs(airspeck['gpsLatitude'] - work_gps['gpsLatitude']) < radius_work + correction_factor) & \ (np.abs(airspeck['gpsLongitude'] - work_gps['gpsLongitude']) < radius_work + correction_factor) # Go through whole array and search for commuting begin_commute = 0 last_location = "" for idx in range(1, len(airspeck)): if (home_mask[idx] == True and home_mask[idx - 1] == False and last_location == "work") or \ (work_mask[idx] == True and work_mask[idx - 1] == False and last_location == "home"): #print('Finished commute') #commute_length = min(idx - begin_commute, 180) #if the commute is more than 3 hours it's not really a commute #print(commute_length) if (idx - begin_commute < 180): commute_mask[begin_commute:idx] = True elif (home_mask[idx] == False and home_mask[idx - 1] == True): print('Entering leaving home commute') begin_commute = idx last_location = "home" elif (work_mask[idx] == False and work_mask[idx - 1] == True): print('Entering leaving work commute') begin_commute = idx last_location = "work" #print('hello2') ################################## # Draw detailed exposure plot ################################## sns.set_style('whitegrid', {'xtick.bottom': True, 'xtick.major.size': 5}) fig, ax = plt.subplots(figsize=(15, 5)) #print(airspeck.loc[home_mask]) if np.count_nonzero(home_mask) > 0: for ts in airspeck.loc[home_mask].index: ax.axvspan(ts, ts + pd.DateOffset(minutes=1), facecolor=CB_color_cycle[0], alpha=0.3, zorder=1, lw=0) if np.count_nonzero(work_mask) > 0: for ts in airspeck.loc[work_mask].index: ax.axvspan(ts, ts + pd.DateOffset(minutes=1), facecolor=CB_color_cycle[1], alpha=0.3, zorder=1, lw=0) #print(np.count_nonzero(commute_mask)) if np.count_nonzero(commute_mask) > 0: for ts in airspeck.loc[commute_mask].index: ax.axvspan(ts, ts + pd.DateOffset(minutes=1), facecolor=CB_color_cycle[2], alpha=0.3, zorder=1, lw=0) #airspeck_plot = airspeck.resample('10min').mean() ax.scatter(airspeck.resample('10min').mean().index, airspeck.resample('10min').mean()['pm2_5'], s=2, color='black', zorder=2) # Plot stationary airspeck home use_all_features = False #if home_id in all_factors_ids: # use_all_features = True calibration_date_home, is_calibrated_spmhome, is_calibrated_sgashome, home_airspeck = load_static_airspeck_file( home_id, sensor_label="{}".format(subject_id), suffix_filename='_home', project_name='peeps', upload_type='automatic', calibrate_pm_and_gas=False, use_all_features_for_pm_calibration=use_all_features, return_calibration_flag=False) home_airspeck = load_static_airspeck_file(subject_id, suffix_filename='_home') #home_aispeck_plot = home_airspeck.resample('10min').mean() start_personal = airspeck.index[0].replace(hour=0, minute=0, second=0) end_personal = airspeck.index[-1].replace(hour=0, minute=0, second=0) + pd.DateOffset(days=1) start_home = start_personal end_home = end_personal if len(home_airspeck) > 0: ax.scatter(home_airspeck.resample('10min').mean().index, home_airspeck.resample('10min').mean()['pm2_5'], s=2, color=CB_color_cycle[0], zorder=2) start_home = home_airspeck.index[0].replace(hour=0, minute=0, second=0) end_home = home_airspeck.index[-1].replace( hour=0, minute=0, second=0) + pd.DateOffset(days=1) # Plot stationary airspeck work #work_airpseck is already loaded above #work_airspeck = load_static_airspeck_file(subject_id, suffix_filename='_work') #work_aispeck_plot = work_airspeck.resample('10min').mean() start_work = start_personal end_work = end_personal if len(work_airspeck) > 0: ax.scatter(work_airspeck.resample('10min').mean().index, work_airspeck.resample('10min').mean()['pm2_5'], s=2, color=CB_color_cycle[1], zorder=2) start_work = work_airspeck.index[0].replace(hour=0, minute=0, second=0) end_work = work_airspeck.index[-1].replace( hour=0, minute=0, second=0) + pd.DateOffset(days=1) ax.set_ylabel("PM2.5 (μg/m³)") ax.set_xlim(min(start_personal, start_home, start_work), max(end_personal, end_home, end_work)) formatter = mdates.DateFormatter('%d.%m %Hh', tz=dateutil.tz.gettz( project_mapping['peeps'][1])) ax.xaxis.set_major_formatter(formatter) ax.set_title( "Continuous PM2.5 personal exposure levels and ambient concentrations") fig.autofmt_xdate() home_patch = mpatches.Patch(color=CB_color_cycle[0], label='Home', alpha=0.3) work_patch = mpatches.Patch(color=CB_color_cycle[1], label='Work', alpha=0.3) commute_patch = mpatches.Patch(color=CB_color_cycle[2], label='Commute', alpha=0.5) airs_home_patch = Line2D(range(1), range(1), marker='o', color='#00000000', markerfacecolor=CB_color_cycle[0], label='Home sensor') airp_patch = Line2D(range(1), range(1), marker='o', color='#00000000', markerfacecolor="black", label='Personal sensor') airs_work_patch = Line2D(range(1), range(1), marker='o', color='#00000000', markerfacecolor=CB_color_cycle[1], label='Work sensor') plt.legend(handles=[ home_patch, work_patch, commute_patch, airp_patch, airs_home_patch, airs_work_patch ]) plt.tight_layout() plt.savefig(graphs_dir + "{}_detailed_exposure.png".format(subject_id), dpi=300) plt.show() ################################## # Draw summary bar graph ################################## sns.set_style('darkgrid', {'xtick.bottom': False, 'xtick.major.size': 0.0}) home = airspeck.loc[home_mask, 'pm2_5'].mean() work = airspeck.loc[work_mask, 'pm2_5'].mean() commute = airspeck.loc[commute_mask, 'pm2_5'].mean() other = airspeck.loc[~(work_mask | home_mask | commute_mask), 'pm2_5'].mean() overall = airspeck['pm2_5'].mean() home_ambient = home_airspeck['pm2_5'].mean() work_ambient = work_airspeck['pm2_5'].mean() mean_values = [ home, work, commute, other, overall, home_ambient, work_ambient ] fig, ax = plt.subplots(figsize=(8, 5)) ax.set_title( "Mean PM2.5 personal exposure levels and ambient concentrations") ax.bar(np.arange(7), mean_values, width=0.5, color=CB_color_cycle, edgecolor="none") plt.xticks(np.arange(7), [ "Home\npersonal", "Work\npersonal", "Commute\npersonal", "Other\npersonal", "Overall\npersonal", "Home\nambient", "Work\nambient" ]) ax.set_ylabel("PM2.5 (μg/m³)") plt.savefig(graphs_dir + "{}_mean_exposure.png".format(subject_id, subject_id), dpi=300) plt.show() ################################## # Draw map ################################## #print(airspeck) get_maps_image(airspeck, graphs_dir + "{}_airspeck_map.png".format(subject_id), zoom=13, max_value=max_value) ################################## # Other statistics ################################## # Append stats to this file with open(graphs_dir + "{}_stats.txt".format(subject_id), 'a') as f: if not is_calibrated_pm_pers: calibration_date_pers = 'Calibrated with median' if not is_calibrated_spmhome: calibration_date_home = 'Calibrated with median' if not is_calibrated_spmwork: calibration_date_work = 'Calibrated with median' f.write( "The personal, home and work data in this report were calibrated using colocation data from the following dates. If colocation data was unavailable, a median calibration based on other similar sensors was used.\n" ) f.write("Personal sensor: {}\n".format(calibration_date_pers)) f.write("Home sensor: {}\n".format(calibration_date_home)) f.write("Work sensor: {}\n".format(calibration_date_work)) f.write("Step count: {}\n".format(respeck['step_count'].sum())) f.write( "Mean breathing rate during night: {:.2f} breaths per minute\n". format(respeck.loc[(0 < respeck.index.hour) & (respeck.index.hour < 6), 'breathing_rate'].mean())) f.write("Mean breathing rate during day: {:.2f} breaths per minute\n". format(respeck.loc[(6 <= respeck.index.hour) & (respeck.index.hour <= 23), 'breathing_rate'].mean())) f.write("\nStart of recording: {}\n".format( airspeck.index[0].replace(tzinfo=None))) f.write("End of recording: {}\n".format( airspeck.index[-1].replace(tzinfo=None))) f.write("Total duration: {}\n".format(airspeck.index[-1] - airspeck.index[0])) f.write("Total recording time at work: {:.1f} h\n".format( np.count_nonzero(work_mask) / 60.)) f.write("Total recording time at home: {:.1f} h\n".format( np.count_nonzero(home_mask) / 60.)) f.write( "Total recording time during the journey between home and work: {:.1f} h\n" .format(np.count_nonzero(commute_mask) / 60.))