Sleep stages ============ Demonstration code for analysis of sleep stages using SleepStages(). Link to script: `feature_extraction/sleep_stages.py `_ .. code-block:: python import os import numpy as np import matplotlib.pyplot as plt from nnsa import SleepStages, AnnotationSet, Annotation, print_object_summary, SUPPORTED_RESULT_FILE_TYPES, \ read_result_from_file, assert_equal, EdfReader plt.close('all') Parameters. .. code-block:: python # Print the default parameters of SleepStages(): print(SleepStages().default_parameters()) # Descriptions of the parameters are documented in the default_parameters() code. # Create an instance of the SleepStages class with custom parameters, overruling some defaults: class_labels = ['QS', 'AS', 'AF'] ss = SleepStages( class_labels=class_labels, interpolate_artefacts_kwargs={'max_duration': 0} ) # See if the custom parameters were accepted: print('\nCustom parameters:') print(ss.parameters) Main method: sleep_stages. .. code-block:: python # Now that we have initialized a SleepStages object with certain parameters, we can run the sleep_stages method, # which converts text annotations to sleep stage labels. First we create some random annotations. annotation_set = AnnotationSet([ Annotation(onset=on, duration=du, text=te) for on, du, te in zip([0, 10, 50.3, 1020, 4002.3, 7000], [7.6, 20, 500, 2222, 2000, 100], ['QS TA', 'artefact', 'QS HVS', 'AS1', 'QS']) ]) # Print the annotations. annotation_set.print_all_annotations() # Convert the annotation_set to sleep stages using the custom parameters that were used when creating ss. result = ss.sleep_stages(annotation_set) # The returned object is a SleepStagesResult object, which is a high-level interface for # manipulating/visualizing/saving the result: print('\nSummary of result object:') print_object_summary(result) SleepStagesResult attributes. .. code-block:: python # The main attribute is annotation_set, which contains the sleep stages labels as annotations: print('result.annotation_set:') result.annotation_set.print_all_annotations() # Note at least 4 things that the sleep_stages method has done: # 1) Convert each annotation to either 'QS' (quiet sleep), 'NQS' (non quiet sleep) or 'NL' (no label, also # includes artefacts, dubious, etc.). Note that those class labels into which the annotations are converted can be # chosen via the class_mapping parameter. # 2) Fill 'empty'/unlabeled periods with 'NL' annotations. # 3) Interpolate/replace 'NL' segments when applicable (e.g. the artefact annotation is replaced by QS since it's # duration was short (shorter than the max_duration parameter) and surrounded by the same class label ('QS')). # 4) Merge successive annotations if their label is the same. # The labels of the classes and their mapping to class numbers are stored in the class_mapping attribute: print('result.class_mapping: {}'.format(result.class_mapping)) SleepStagesResult methods. .. code-block:: python # The methods allow to get certain information easily, some examples of available methods # (see docs for complete overview): print('Number of annotations per class:\n', result.count_annotations_per_class()) print('QS mask for query points:\n', result.create_mask(class_label='QS', query_times=np.array([0, 30, 60, 300, 750]))) print('Number of cycles going from QS -> AS -> QS:\n', result.cycle_count(class_label='QS', ignore_labels=['AF'])) print('Class numbers of annotations:\n', result.get_classes()) print('Times of intervals between QS segments:\n', result.inter_class_intervals(class_label='QS')) print('Interpolation of classes at query points:\n', result.interpolate_classes( query_times=np.array([0, 30, 60, 300, 750]), kind='previous')) print('Proportion of time in QS:\n', result.proportion(class_label='QS')) # We can also graphically visualize the sleep stages with a hypnogram. result.plot_hypnogram() Save the result. .. code-block:: python # We can save the result to any supported file. To list the supported file types/extensions: print('Supported result file types: {}'.format(SUPPORTED_RESULT_FILE_TYPES)) # E.g. save as hdf5 (the file type to save is automatically detected from the extension of the filename). filename = 'temp_result.hdf5' result.save_to_file(filename) # We can reload the result back to a SleepStagesCnnResult object: result_loaded = read_result_from_file(filename) # Remove temporary file. os.remove(filename) # Verify that the loaded object is equal to the original object: assert_equal(actual=result_loaded, desired=result) # Will raise an AssertionError if not equal. print('Loaded result object is equal to original object.')