2019-11-01 19:26:51 +01:00
import pandas as pd
import numpy as np
import plotly . io as pio
import plotly . graph_objects as go
import datetime
2019-12-04 21:32:20 +01:00
def getDatesComplianceMatrix ( phone_sensed_bins ) :
dates = phone_sensed_bins . index
2019-11-01 19:26:51 +01:00
compliance_matrix = [ ]
for date in dates :
2019-12-04 21:32:20 +01:00
compliance_matrix . append ( phone_sensed_bins . loc [ date , : ] . tolist ( ) )
return dates , compliance_matrix
2019-11-01 19:26:51 +01:00
def getComplianceHeatmap ( dates , compliance_matrix , pid , output_path , bin_size ) :
bins_per_hour = int ( 60 / bin_size )
x_axis_labels = [ " {0:0=2d} " . format ( x / / bins_per_hour ) + " : " + \
" {0:0=2d} " . format ( x % bins_per_hour * bin_size ) for x in range ( 24 * bins_per_hour ) ]
plot = go . Figure ( data = go . Heatmap ( z = compliance_matrix ,
x = x_axis_labels ,
2019-11-07 18:31:11 +01:00
y = [ datetime . datetime . strftime ( date , ' % Y/ % m/ %d ' ) for date in dates ] ,
colorscale = ' Viridis ' ,
colorbar = { ' tick0 ' : 0 , ' dtick ' : 1 } ) )
2020-02-20 16:16:03 +01:00
plot . update_layout ( title = " Compliance heatmap.<br>Five-minute bins showing how many sensors logged at least one row of data in that period for " + pid + " <br>Label: " + label + " , device_id: " + device_id )
2020-03-23 23:24:19 +01:00
pio . write_html ( plot , file = output_path , auto_open = False , include_plotlyjs = " cdn " )
2019-11-01 19:26:51 +01:00
# get current patient id
pid = snakemake . params [ " pid " ]
2019-12-05 17:07:40 +01:00
bin_size = snakemake . params [ " bin_size " ]
2020-02-20 16:16:03 +01:00
2020-03-03 17:08:57 +01:00
with open ( snakemake . input [ " pid_file " ] , encoding = " ISO-8859-1 " ) as external_file :
2020-02-20 16:16:03 +01:00
external_file_content = external_file . readlines ( )
device_id = external_file_content [ 0 ] . split ( " , " ) [ - 1 ]
label = external_file_content [ 2 ]
phone_sensed_bins = pd . read_csv ( snakemake . input [ " sensor " ] , parse_dates = [ " local_date " ] , index_col = " local_date " )
2019-11-01 19:26:51 +01:00
2019-12-04 21:32:20 +01:00
if phone_sensed_bins . empty :
2020-03-03 17:08:57 +01:00
empty_html = open ( snakemake . output [ 0 ] , " w " , encoding = " ISO-8859-1 " )
2020-02-20 16:16:03 +01:00
empty_html . write ( " There is no sensor data for " + pid + " <br>Label: " + label + " , device_id: " + device_id )
2019-11-13 20:55:22 +01:00
empty_html . close ( )
else :
2019-12-04 21:32:20 +01:00
# resample to impute missing dates
phone_sensed_bins = phone_sensed_bins . resample ( " 1D " ) . asfreq ( ) . fillna ( 0 )
# get dates and compliance_matrix
dates , compliance_matrix = getDatesComplianceMatrix ( phone_sensed_bins )
2019-12-17 23:07:35 +01:00
# convert compliance_matrix from list to np.array and replace 0 with np.nan
compliance_matrix = np . asarray ( compliance_matrix )
compliance_matrix = np . where ( compliance_matrix == 0 , np . nan , compliance_matrix )
2019-11-13 20:55:22 +01:00
# get heatmap
2019-12-05 17:07:40 +01:00
getComplianceHeatmap ( dates , compliance_matrix , pid , snakemake . output [ 0 ] , bin_size )